0. 前言
在生活中我們不乏有需要分享的資料,但針對那些需要在期限內收回的我們則往往會忘記。
就像是圖書館今日借出了文件資料,現實中通常只能依靠催促,但在科技上我們則會透過 ePub 設定過期時效,當時間到點之後電子檔就會自我毀損不再提供功能。
而此時我們就可以依靠定時器,在指定的時間點處理事項,不必擔心事後遺忘。
1. 重點
2. 內容
2.1. 資料遷移
在我們進入正題之前,我希望先介紹如何在磁碟中進行檔案與資料夾的增刪改查,讓各位先清楚其架構。
現在各位看到上圖我準備了空資料夾 1 與 2,而紅框的圖片則是我們待會進行示範的素材,此時若我們透過 右鍵 >> Share >> Copy Link,將網址複製出來將類似以下格式,其中的 file 代表其屬性,而在 d 之後的 33 位字元便是普遍檔案的 File ID 。
https://drive.google.com/file/d/1nraXFA4oTV4KaBPvxIZfSsECpM_M1MHH/view?usp=drive_link
而如果是像 Google Docs Editors,當我們進入編輯頁面後則會看到是 44 位字元,可以看到並不歸屬於普通的 file 分類,而會各自呈現 document, spreadsheet, presentation 與 forms 等等標籤。
https://docs.google.com/document/d/1T8UI3P4S9PkBALRtI9mck3ORGDmVk0XG-fKd0k2vQlo/edit
此時我們在往上看到雲端磁碟的網址尾端,除了 My Drive 之外都能直接夠看到這個資料夾的 Folder ID 。而這也不代表 My Drive 沒有 ID,在結構下它也屬資料夾,只是必須透過 Apps Script 的回應取得。
https://drive.google.com/drive/folders/1Dtsmmoh_57RDAi50Nl3lpaP5H7wsQ-DG
而正是有這些 ID,我們的檔案就算搬遷了,擁有權限的人還是可以正常連線到。而此時就是為何私人檔案或小組作業千萬別偷懶開放 Everyone,透過猜網址的辦法不安好心的用戶也能夠抓取到檔案。
那我們接著就先進入到 Apps Script 的簡單示範,我們將設定好參數中所有的 ID。那可以看到針對檔案的讀取我們使用 DriveApp.get####ById,另外其實有 ByName 方法用名稱搜尋但個人並不推薦。
var file = DriveApp.getFileById('FILE_ID');
var folder_001 = DriveApp.getFolderById('FOLDER_1_ID');
var folder_002 = DriveApp.getFolderById('FOLDER_2_ID');
2.2.1. 檔案副本
接著先執行看看 copy 方法,完成後應該會在資料夾 1 出現同名的檔案。那各位應該有注意到三種不同的makeCopy 格式,第一種就是我們在同資料夾內 ctrl c / v 會產出帶有 Copy 字樣的檔案,此時在同路徑下想要客製化檔名就要依靠第二種,而最後的第三種則又包含要儲存到哪個資料夾。
// Make a copy of file
function copy() {
try {
// // Make a copy under same root
// file.makeCopy();
// file.makeCopy(`${NAME}`);
file.makeCopy(file.getName(), folder_001);
} catch (error) { console.error(error); }
}
2.2.2. 檔案命名
我們接著針對該副本進行處理,複製其 ID 並替換程式碼的設定。
再來我們測試 rename 方法的效果,在上一部我們用過 getName 取得檔名,而這次我們則是用 setName 將其重新命名,在範例我們檢查是否變成 TESTING 字樣。
// Rename file
function rename() {
try { file.setName(`TESTING`); } catch (error) { console.error(error); }
}
2.2.3. 檔案遷移
那再來我們將嘗試將檔案變換位置,接著執行看看我們的 move 方法,應該會將檔案轉到不同資料夾。
// Move file
function move() {
try {
file.moveTo(folder_002);
console.log('Moved file from folder 1 to 2');
}
catch (error) { console.error(error); }
}
2.2.4. 軟性刪除(Soft Delete)
我們所謂的軟性刪除是指給予檔案標籤,而尚未實際刪除檔案,常見於垃圾筒的功能。我們接著執行 trash 方法,並到垃圾桶檢查是否有刪除該檔案。
// Soft Delete
function trash() {
try {
file.setTrashed(true);
console.log('Moved file to trash can');
} catch (error) { console.error(error); }
}
2.2.5. 硬性刪除(Hard Delete)
反之硬性刪除則是直接從磁碟完全刪除,而此時我們就必須先仰賴額外的 Service >> 選擇 Drive API 。
我們選擇 Drive API 最新版的 V3,並維持預設的呼叫名稱: Drive 。
完成後再來試試 remove 方法,過後檔案應該從垃圾桶直接被刪除,阿當然也可直接套用於磁碟檔案。
// Hard Delete
function remove() {
try {
Drive.Files.remove(file.getId());
console.log('Removed file permanently');
} catch (error) { console.error(error); }
}
2.2. 權限定時
總算來到我們的實作,那我們的目的就是在特定時間重設檔案的權限,或者套用剛剛的所學。若你剛剛有按照上面的步驟嘗試,請記得將最開始定義檔案 ID 與 資料夾 ID 的部份註解,否則會報錯找不到檔案。
// Update sharing permission of folder
//
// - Get all users already registered on list
// -- Remove Viewers
// -- Remove Editors
// - Reset folder permission
function updateFolderPermissions() {
let folderId = 'YOUR_FOLDER_ID';
console.warn('# RUN - updateFolderPermissions()');
try {
let folder = DriveApp.getFolderById(folderId);
// Remove existing permissions
// let editors = folder.getEditors();
// let viewers = folder.getViewers();
// editors.forEach(function(editor) {
// folder.removeEditor(editor);
// });
// viewers.forEach(function(viewer) {
// folder.removeViewer(viewer);
// });
// @ 適用範圍 Access Type
// @ 分配權限 Permission Type
folder.setSharing(DriveApp.Access.PRIVATE, DriveApp.Permission.NONE);
} catch (error) {
console.error(error);
}
console.warn('# END - updateFolderPermissions()');
}
那我們接著就要學到簡易的 Trigger,並利用簡易的時間格式設定時間,選擇左側選單的 Trigger >> 右下角新增,並依照以下設定。那關於右側當程式出錯寄信的頻率,我一般都選即時以立即進行排錯。
那現在我將資料夾先設為 Everyone is Viewer,並設定時間於當日的 22:30 分來測試看看結果。此時重整頁面後會看到 Who has access 多了一顆綠色的地球圖樣。
3. 後話
那在這篇之中,我們簡單帶過磁碟檔案的基礎變動方式,以及單次定時的方式。
但目前定時的方式稍加麻煩必須每次手動調整,而在下回我們則會更進一步使用物件屬性,透過時間的比對自動刪除超過時限的特定檔案。
4. 參考
[1] Class DriveApp — Official Doc
https://developers.google.com/apps-script/reference/drive/drive-app
5. 素材
[1] 圖片素材 by QuAn_
https://www.pixiv.net/users/6657532