Google Apps Script 自動化對 Google Drive 的操作(一)列出所有檔案 ID 與相關資訊 (2021 鐵人賽 D9)

如果你很急著用,可以直接使用這份 Add-On: Drive Explorer,功能還蠻強大的!自己寫的好處是,如果你想結合其他功能會比較方便。對於想知道怎麼做的人,讓我們開始吧!

目標

現在幾乎每天都會打開 Google Drive,但有時當檔案一多,就會面臨兩個問題——權限設置不清,當一個人加入或離職時,要重複好幾次開開關關。又或是要將不同的線上文件寄信並分享給不同人,這些都會需要知道檔案 ID。有沒有一個快速的方式,可以讓我們抓出特定資料夾內的檔案 ID,並用一個表格管理權限呢?

  1. 要怎麼列出 Google Drive 中的檔案 ID 們?
  2. 要怎麼取得 Google Drive 中的檔案們的權限?
  3. 要怎麼設定 Google Drive 中的檔案們的權限給不同人?

這次的主題我們會分成兩天寫。第一題會在今天跟大家分享,明天會針對第二題與第三題。那我們就開始吧!


Q1. 要怎麼列出 Google Drive 中的檔案 ID 們?

Step 1 開啟 Google Sheet,並串起 GAS

因為我們要用到 Google Sheet ,所以一樣用其作為開啟的管道。借用一下 D8 的影片,來說明怎麼樣開啟一個有連結 GAS 的 Google Sheet。

Google Apps Script 自動化對 Google Drive 的操作(一)列出所有檔案 ID 與相關資訊 (2021 鐵人賽 D9)插图

一樣執行時會有「需要驗證」出現,讓我借用一下 D2 的影片。

Google Apps Script 自動化對 Google Drive 的操作(一)列出所有檔案 ID 與相關資訊 (2021 鐵人賽 D9)插图1

Step 2 確認要抓的 Google Drive 位置,並將其 ID 記錄到 GAS 上

這邊我們開一個資料夾,並且在裡面設置一些檔案,其中有一些是有子目錄的。要注意裡面有個「demo」資料夾

Google Apps Script 自動化對 Google Drive 的操作(一)列出所有檔案 ID 與相關資訊 (2021 鐵人賽 D9)插图2

那這邊要特別提一下「ID」的概念,每一個 Google 產品都有特定的 ID,位置可以參考這張圖

Google Apps Script 自動化對 Google Drive 的操作(一)列出所有檔案 ID 與相關資訊 (2021 鐵人賽 D9)插图3

這邊提供兩種取得方式——

Google Apps Script 自動化對 Google Drive 的操作(一)列出所有檔案 ID 與相關資訊 (2021 鐵人賽 D9)插图4

一種是直接從網址上複製,另一種是按右鍵時會出現的。這邊用影片解釋。好,那當我們取得要抓的檔案 ID 後,就是將其丟到 GAS 上,一樣開一個 environment.gs 存放資料。這邊示範完整的流程——

Google Apps Script 自動化對 Google Drive 的操作(一)列出所有檔案 ID 與相關資訊 (2021 鐵人賽 D9)插图5

Step 3 讀單一資料夾內的檔案、名稱與ID

在 Google Drive 官方定義的 API 中,主要會將能操作的物件分成三種,分別是 FolderFileUser。會用不同的 API 讀取。

Google Apps Script 自動化對 Google Drive 的操作(一)列出所有檔案 ID 與相關資訊 (2021 鐵人賽 D9)插图6

我們來拆解步驟——

  1. 透過 getFolderById() 讀取 Folder 。
  2. 讀到資料夾後,再接著用 getFiles() 會讀出 files (實際上是 fileIterator,但可以理解成「很多檔案」就是)。
  3. 這個 files (fileIterator)會將這個資料夾內的檔案一個個列出來,這邊我列出它的檔名(getName())和 ID(getId())。

完整程式碼在這——

function readFiles(){
  let folder = DriveApp.getFolderById(drive_ID);
  let files = folder.getFiles();
  let file_arr = []
  while (files.hasNext()) {
    let file = files.next();
    file_arr.push([file.getName(),file.getId()]);
  };
  Logger.log(file_arr);
}

跑起來長這樣——

Google Apps Script 自動化對 Google Drive 的操作(一)列出所有檔案 ID 與相關資訊 (2021 鐵人賽 D9)插图7

好那你會發現一個問題,是這邊並沒有列出「資料夾」。仔細一看會發現我們裡面並沒有我們在 Step 2 埋梗的「資料夾」 demo ,那請問我們要如何抓到 demo 與裡面的小資料夾(還有資料)?

Step 4 打開子目錄內的目錄

Step 3 我們是用 getFiles(),這邊我們就帶大家來看看 getFolders() 怎麼樣讀取。

這邊我們要用到的技巧叫做 DP (Dynamic Programming),簡單來說就是(1)在根目錄(或目標位置)執行 DP,去發現子目錄,而(2)進到每個子目錄後,一旦發現還有子子目錄,就會再執行一次 DP,並且不斷重複到找到全部的位置為止。

程式碼長這樣,是直接借用 rpm 在 Stakeholder 的回應:Google apps script – iterate folder and subfolder,覺得寫得很好懂。其中的 getSubFolders(parent) 中還有 getSubFolders(child)的寫法,就是所謂的 DP。

function getSubFolders(parent) {
  parent = parent.getId();
  let childFolder = DriveApp.getFolderById(parent).getFolders();
  while(childFolder.hasNext()) {
    let child = childFolder.next();
    Logger.log(child.getName());
    getSubFolders(child);
  }
  return;
}

function listFolders() {
  let parentFolder = DriveApp.getFolderById(drive_ID);
  let childFolders = parentFolder.getFolders();
  while(childFolders.hasNext()) {
    let child = childFolders.next();
    Logger.log(child.getName());
    getSubFolders(child);
  }
}

好,那執行起來會長什麼樣子呢?(可以參考 Step 2 的架構圖)——

Google Apps Script 自動化對 Google Drive 的操作(一)列出所有檔案 ID 與相關資訊 (2021 鐵人賽 D9)插图8

但這樣只有列出「目錄」,又要怎麼樣列出所有檔案,包括子目錄內的檔案呢?讓我們從 Step 5 來看看。

Step 5 列出所有檔案,包括子目錄內的檔案們

這邊就要結合我們的 Step 3 和 Step 4 啦。我們先將 Step 3 改寫成會讀取輸入的 Folder Object 的 function。

function readFilesInFolder(folder){
  let files = folder.getFiles();
  while (files.hasNext()) {
    let file = files.next();
    Logger.log([file.getName(),file.getId()]);
  };
}

接著,在將上面這段放入 Step 4 中。

function getSubFolders(parent) {
  parent = parent.getId();
  let childFolder = DriveApp.getFolderById(parent).getFolders();
  while(childFolder.hasNext()) {
    let child = childFolder.next();
    Logger.log(child.getName());
    readFilesInFolder(child)
    getSubFolders(child);
  }
  return;
}

function listFolders() {
  let parentFolder = DriveApp.getFolderById(drive_ID);
  readFilesInFolder(parentFolder)
  let childFolders = parentFolder.getFolders();
  while(childFolders.hasNext()) {
    let child = childFolders.next();
    Logger.log(child.getName());
    readFilesInFolder(child);
    getSubFolders(child);
  }
}

那接著我們執行看看——

Google Apps Script 自動化對 Google Drive 的操作(一)列出所有檔案 ID 與相關資訊 (2021 鐵人賽 D9)插图9

補充的是,有人問說如果是在一進去 Google Drive 的根目錄(沒有 ID 的部分),要怎麼讀?其實就是直接 getFiles() 就行了。這邊是修改 官方範例的程式碼 供大家參考。

function readAllFiles(){
    // Log the name of every file in the user's Drive.
    let files = DriveApp.getFiles();
    while (files.hasNext()) {
      let file = files.next();
      Logger.log(file.getName());
    }
}

一樣按執行就好囉!好,那今天學了…

  1. 檔案 ID 與獲取方式
  2. 檔案列出方式
  3. 資料夾列出方式
  4. 結合檔案與資料夾的列出方式

接著可以將結果參考 D8 寫入 Google Sheet。好,那今天就是我們的 D9,明天 D10 會繼續介紹結合讀取檔案後的操作模式。

如果還有問題,透過留言之外,也可以到 Facebook Group,想開很久這次鐵人賽才真的開起來哈哈哈,歡迎來當 Founding Member。如果不想錯過可以訂閱按讚小鈴鐺(?),也歡迎留言跟我說你還想知道什麼做法/主題。我們明天見。

目錄

Scroll to Top