《零基礎快速入門:GenAI 搭配 Google Apps Script 的工作自動化寶典》Chapter 4-2 真實案例:自動整理 Google Drive 裡的檔案

1. 引言 (Introduction)

今天我們來聊聊一個有趣的自動化案例。
有沒有想過,為什麼你的 Google Drive 總是那麼亂?
是不是每天上傳一堆文件、照片,通通都堆在同一個地方?
這篇文章會告訴你如何利用 GenAI 和 Google Apps Script 來自動整理 Google Drive 裡的檔案。
不需要程式經驗,只要簡單幾個步驟,你的檔案就會井然有序。

2. 案例背景 (Case Background)

我為了貪圖方便,
每次上傳檔案到 Google Drive 都亂丟,
常常直接無腦就放在根目錄下,
久而久之就亂七八糟、雜亂無章。

是說因為現在搜尋功能太方便,
不照資料夾整理歸檔也沒什麼關係,
只要檔案名稱取得好,想找的時候一樣可以輕鬆找到。
(至於檔案如何命名,這又是另一種藝術了)

不過根目錄下亂七八糟,
檔案清單長不見底,
看了總是心情不太好。

能不能至少照著檔案類型來分類歸檔呢?

3. 解決方案:如何使用 GenAI (Solution: How to Use GenAI)

解決方案其實很簡單,我們可以使用 GenAI 來生成整理 Google Drive 的程式碼。
以下就是我實際在做這個程式的時候,跟 ChatGPT 來回對話的過程。
因為 ChatGPT 的回應都落落長,我直接以摘要記載。
完整的對話過程,請見 https://chatgpt.com/share/66f0247e-e2b4-800e-92c0-d2f1cccb9a92

Henry: 請幫我用 Google Apps Script 寫一段程式,將我的 google drive 根目錄下的所有檔案依照副檔名來分類到不同的資料夾。
ChatGPT: (給了一段程式)

(我突然想到這個搬移檔案的動作很難備份,所以又繼續問)
Henry: 這個程式執行完,我還可以復原嗎?
ChatGPT: (提供了新版的程式碼,加上了紀錄與還原的功能)

(我又發現如果根據副檔名來分類,很多沒有副檔名的檔案會被忽略。例如 Google Sheets/Slides 都是沒有副檔名的。所以我又繼續問)
Henry: 如果是 google sheets or google slides 的檔案,抓得出來嗎?
ChatGPT: (改進程式碼,變成可以整理 Google Sheets/Slides 的檔案)
Henry: 可以把 google 其它常用的 MIME Type 也列入處理嗎?
ChatGPT: (改進程式碼,變成可以整理 Google 各種檔案的程式碼)

(我發現新的程式漏了紀錄功能,所以再問)
Henry: 剛剛的「改進程式來記錄原檔案位置」怎麼不見了?
ChatGPT: (補上了紀錄功能)

(想到我之後可能需要「最後修改日期」這個資訊來協助判斷)
Henry: 很好,請在紀錄的 sheet 裡加一個欄位:last modified date。
ChatGPT: (改進程式碼,加上了 Last Modified Date 欄位)

4. Google Apps Script 解說

如果功能測試都符合預期,
那其實沒有必要深究這個程式裡每一行在做什麼。
全部複製貼上執行便是。

不過稍微瞄一下程式內容也是有益無害。
以下是這個程式的內容說明,
沒興趣的話,可以跳過不看。
有興趣的話,可以先快速瀏覽一下程式碼裡面用中文寫的註解。

  function organizeFilesByExtensionOrMimeTypeWithBackup() {
    // 建立試算表來記錄檔案位置及資訊
    var sheet = createBackupSheet();

    // 定義根目錄,即需要分類檔案的目錄
    var rootFolder = DriveApp.getRootFolder();

    // 取得根目錄中的所有檔案
    var files = rootFolder.getFiles();

    // 用來記錄處理過的資料夾,避免重複創建
    var typeFolders = {};

    // 定義 MIME type 對應的資料夾名稱,用來識別 Google 特有的檔案類型
    var mimeTypeFolders = {
      "application/vnd.google-apps.spreadsheet": "Google Sheets", // Google 試算表
      "application/vnd.google-apps.presentation": "Google Slides", // Google 簡報
      "application/vnd.google-apps.document": "Google Docs", // Google 文件
      "application/vnd.google-apps.form": "Google Forms", // Google 表單
      "application/vnd.google-apps.drawing": "Google Drawings", // Google 繪圖
      "application/vnd.google-apps.map": "Google My Maps", // Google 地圖
      "application/vnd.google-apps.site": "Google Sites", // Google 網站
      "application/vnd.google-apps.fusiontable": "Google Fusion Tables" // Google 資料表
    };

    // 記錄試算表中的行數,從第二行開始
    var row = 2;

    // 開始逐個處理每個檔案
    while (files.hasNext()) {
      var file = files.next(); // 獲取下一個檔案
      var fileName = file.getName(); // 取得檔案名稱
      var fileId = file.getId(); // 取得檔案 ID,用於識別檔案
      var mimeType = file.getMimeType(); // 取得檔案的 MIME type
      var lastModifiedDate = file.getLastUpdated(); // 取得檔案的最後修改日期
      var extension = ""; // 初始化副檔名變數

      // 檢查檔案的 MIME type 是否為 Google 特有類型
      if (mimeTypeFolders[mimeType]) {
        extension = mimeTypeFolders[mimeType]; // 如果是 Google 檔案類型,使用對應名稱
      } else {
        // 處理一般檔案,根據副檔名進行分類
        extension = fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase();

        // 如果檔案沒有副檔名,略過該檔案
        if (fileName.lastIndexOf('.') === -1) {
          continue;
        }
      }

      // 記錄檔案的相關資訊到試算表
      sheet.getRange(row, 1).setValue(fileId); // 記錄檔案 ID
      sheet.getRange(row, 2).setValue(fileName); // 記錄檔案名稱
      sheet.getRange(row, 3).setValue("Root"); // 記錄原始位置(根目錄)
      sheet.getRange(row, 5).setValue(lastModifiedDate); // 記錄最後修改日期

      // 檢查是否已經存在該類型的資料夾,如果沒有,則創建新的資料夾
      if (!typeFolders[extension]) {
        var newFolder = rootFolder.createFolder("自動整理之" + extension + " Files"); // 創建資料夾
        typeFolders[extension] = newFolder; // 儲存資料夾引用,避免重複創建
      }

      // 將檔案移動到對應的資料夾
      file.moveTo(typeFolders[extension]);

      // 更新試算表中的新資料夾名稱
      sheet.getRange(row, 4).setValue(typeFolders[extension].getName());

      // 行數加一,準備處理下一個檔案
      row++;
    }
  }

  // 創建備份用的 Google 試算表
  function createBackupSheet() {
    // 創建新的試算表來記錄檔案資訊
    var spreadsheet = SpreadsheetApp.create('File Backup');
    var sheet = spreadsheet.getActiveSheet();

    // 在試算表第一行設定欄位名稱
    sheet.getRange(1, 1).setValue('File ID');
    sheet.getRange(1, 2).setValue('File Name');
    sheet.getRange(1, 3).setValue('Original Location');
    sheet.getRange(1, 4).setValue('New Location');
    sheet.getRange(1, 5).setValue('Last Modified Date');

    return sheet; // 回傳試算表對象
  }

說明
organizeFilesByExtensionOrMimeTypeWithBackup()
這是主程式,負責遍歷根目錄中的所有檔案,根據檔案的副檔名或 MIME type 來分類,並將每個檔案移動到對應的資料夾。移動前會記錄檔案的資訊到試算表。
createBackupSheet():這個函式會建立一個 Google 試算表,並設置欄位名稱(檔案 ID、檔案名稱、原始位置、新位置、最後修改日期),用來記錄每個檔案的相關資訊。
這段程式的主要流程:

  1. 建立一個用來記錄檔案資訊的 Google 試算表。
  2. 遍歷 Google Drive 根目錄中的所有檔案。
  3. 根據檔案的副檔名或 MIME type 進行分類。
  4. 將檔案移動到對應的資料夾。
  5. 在試算表中記錄每個檔案的 ID、名稱、原始位置、新位置、以及最後修改日期,以便將來可以參照這些記錄進行復原。

5. 測試與結果

讓我們來看看實際運行的效果:


當程式運行後,你會發現所有文件都被自動整理到了正確的資料夾裡。
這樣的自動化功能,
可以幫你省下大量時間,
也避免了手動整理帶來的錯誤。

6. 進階提示

如果你想進一步優化這個自動化流程,
這裡有幾個小靈感,
你可以拿去跟 ChatGPT 討論。

  • 根據檔案的創建日期來做條件化處理。
    例如過於老舊的檔案,直接另外存到「Archive」資料夾。
  • 根據關鍵字來做條件化處理。
    例如當檔名中含有「發票」這個關鍵字,
    就另外存放到「發票」資料夾。
    當檔名中含有「test」這個關鍵字,就直接刪掉。

7. 結論 (Conclusion)

這個自動化案例再次告訴我們,
即使不會寫程式,
也可以利用 GenAI 和 Google Apps Script 來完成看似複雜的工作。

整理 Google Drive 這種無腦卻耗時費力的任務,
透過程式自動化就變得輕而易舉。

最重要的是,
這個自動化流程並不是只有這個案例可以用,
你可以稍加變化,然後應用在其他地方。