如何自動將 Gmail 附件保存到 Google 雲端硬盤

Eva

本文推薦給以下人群:

  • 想要自動整理和保存電子郵件附件的人
  • 每天收到大量附件的人
  • 想要更方便地使用 Gmail 的人

當您每天使用 Gmail 時,經常會收到許多附件。
特別是對於獨資經營者和自由職業者來說,保持這些文件的組織和安全非常重要。
但每次都要手動保存比較麻煩,而且還有誤刪除的風險。
此外,隨著您收到的電子郵件數量增加,您的 Google 帳戶可能會滿。

本文將向您展示如何使用 Google Apps 腳本 (GAS) 自動將 Gmail 附件保存到 Google 雲端硬盤。
還包含源代碼,因此任何人都可以按照本文中的步驟輕鬆設置它。

目錄

需要準備什麼

首先,讓我們看一下實現這種自動化所需的工具和帳戶。

  • Gmail 帳戶:用於接收附件的 Gmail 帳戶
  • 谷歌云端硬盤帳戶:Google Drive 保存文件
  • Google Apps腳本(GAS):Google提供的腳本環境

Google Apps Script (GAS) 是一個腳本環境,用於自動化各種 Google 服務(Gmail、Google Drive、Google 日曆等)。即使您沒有編程經驗,也可以使用簡單的腳本自動執行任務。

在 Google Drive 中創建目標文件夾並獲取文件夾 ID

首先,按照以下步驟將其保存到 Google 雲端硬盤。創建一個文件夾來保存附件死亡,獲取文件夾ID請。

  1. 打開 Google 雲端硬盤並創建一個要保存附件的文件夾。
  2. 打開創建的文件夾
  3. 檢查瀏覽器地址欄中顯示的 URL 並獲取文件夾 ID

示例:https://drive.google.com/drive/u/0/folders/XXXXXXXXXXXXXXXX
上述 URL 的“XXXXXXXXXXXXXXXXXX”部分是文件夾 ID。

打開 Google 雲端硬盤並創建一個要保存附件的文件夾。

谷歌云端硬盤打開右鍵單擊空白處死亡,點擊【新建文件夾】請。

在 Google Drive 中創建目標文件夾並獲取文件夾 ID

當您單擊[新建文件夾]時,將彈出一個顯示“新建文件夾”的屏幕。

在其中輸入描述性名稱並單擊“創建”請。

在本文中,為了便於理解,我們將使用“Gmail”。

在 Google Drive 中創建目標文件夾並獲取文件夾 ID

打開創建的文件夾

單擊 [創建] 將返回到上一屏幕,顯示您創建的文件夾。

請打開該文件夾。

在 Google Drive 中創建目標文件夾並獲取文件夾 ID

檢查/複製文件夾 ID

檢查瀏覽器地址欄中顯示的 URL,檢查/複製文件夾 ID請。

示例:https://drive.google.com/drive/u/0/folders/XXXXXXXXXXXXXXXX
上述 URL 的“XXXXXXXXXXXXXXXXXX”部分是文件夾 ID。

在 Google Drive 中創建目標文件夾並獲取文件夾 ID

使用 Google Apps 腳本 (GAS) 創建並運行新項目

保存附件的文件夾谷歌云端硬盤創建完上面的文件夾並獲取文件夾ID後,我們將繼續使用Google Apps腳本(GAS)進行操作。

按照以下步驟在 Google Apps 腳本 (GAS) 中創建項目。

訪問 Google Apps 腳本 (GAS) 並單擊“新建項目”

Google Apps腳本(GAS)訪問單擊新建項目請。

使用 Google Apps 腳本 (GAS) 創建並運行新項目

將項目重命名為更有意義的名稱

單擊“新建項目”後,下一步是單擊[無標題項目]請。

使用 Google Apps 腳本 (GAS) 創建並運行新項目

單擊“無標題項目”,將彈出一個窗口,顯示“重命名項目”。

在其中輸入描述性名稱請。

在本例中,我們將選擇“Gmail自動保存附件”。

輸入名字後,在右下角單擊重命名請。

使用 Google Apps 腳本 (GAS) 創建並運行新項目

粘貼源代碼並單擊“保存”

單擊[重命名]返回上一屏幕並確認項目名稱已更改。

下一個,複製源代碼(GAS用於自動將Gmail附件保存到Google Drive)並將其粘貼到右側框架中請。

請刪除默認代碼後粘貼。

function saveEmailAttachmentsToDrive() {
  // ユーザー設定 - ここを変更してください
  var settings = {
    excludedEmailAddresses: ['[email protected]', '[email protected]'], // 処理対象外のメールアドレス
    folderId: 'xxxxxxxxxxxxxxxxxxxxxx', // 添付ファイルを保存するGoogleドライブフォルダのID
    maxThreads: 30, // 一度に処理するスレッド数
    waitTime: 3000, // ファイル保存後の待機時間(ミリ秒)
    retryCount: 3 // 保存失敗時の再試行回数
  };

  var startTime = new Date(); // 処理開始時間の記録

  // フォルダ、ログファイル、処理済み添付ファイルID、処理済みスレッドIDの取得
  var folder = DriveApp.getFolderById(settings.folderId); // 保存先のGoogleドライブフォルダを取得
  var logFile = getLogFile(); // ログファイルを取得または作成
  var processedAttachments = getProcessedSet('processedAttachments'); // 既に処理された添付ファイルIDを取得
  var processedThreads = getProcessedSet('processedThreads'); // 既に処理されたスレッドIDを取得
  var start = getStartIndex(); // 前回の実行位置を取得

  try {
    var threads = GmailApp.getInboxThreads(start, settings.maxThreads); // 指定された数のスレッドを取得
    if (threads.length === 0) { // スレッドが存在しない場合の処理
      logMessage(logFile, "全ての添付ファイルを保存しました。");
      PropertiesService.getScriptProperties().deleteProperty('start'); // 全スレッドを処理済みの場合、開始位置をリセット
      return;
    }

    threads.forEach(thread => {
      if (!processedThreads.has(thread.getId())) { // まだ処理していないスレッドか確認
        processThread(thread, settings, folder, processedAttachments, logFile); // スレッド内のメッセージを処理
        processedThreads.add(thread.getId()); // 処理済みスレッドIDを記録
      }
    });

    PropertiesService.getScriptProperties().setProperty('start', (start + settings.maxThreads).toString()); // 次回の開始位置を更新
    saveProcessedSet('processedAttachments', processedAttachments); // 処理済み添付ファイルIDを保存
    saveProcessedSet('processedThreads', processedThreads); // 処理済みスレッドIDを保存
    logMessage(logFile, "スレッドの一部を処理しました。次回実行時に続きます。");

  } catch (e) {
    logError(logFile, "スレッドの処理中にエラーが発生しました: " + e.toString()); // エラーログを記録
  } finally {
    var endTime = new Date(); // 処理終了時間の記録
    var duration = (endTime - startTime) / 1000; // 処理時間を秒単位で計算
    logMessage(logFile, `処理時間: ${duration} 秒`); // 処理時間をログに記録
  }
}

// スレッド内のメッセージと添付ファイルを処理する関数
function processThread(thread, settings, folder, processedAttachments, logFile) {
  thread.getMessages().forEach(message => { // スレッド内の各メッセージを処理
    var sender = message.getFrom() || "noname"; // 送信者のメールアドレスを取得、存在しない場合は"noname"
    if (settings.excludedEmailAddresses.some(email => sender.includes(email))) return; // 対象外メールアドレスの場合スキップ

    var formattedDateTime = formatDateTime(message.getDate()); // メッセージの受信日時をフォーマット
    message.getAttachments().forEach((attachment, index) => { // メッセージ内の各添付ファイルを処理
      processAttachment(message, attachment, index, sender, formattedDateTime, folder, processedAttachments, logFile, settings.waitTime, settings.retryCount);
    });
  });
}

// 添付ファイルを処理し、フォルダに保存する関数
function processAttachment(message, attachment, index, sender, formattedDateTime, folder, processedAttachments, logFile, waitTime, retryCount) {
  var attachmentId = generateAttachmentId(message, attachment, index); // 添付ファイルIDを生成
  if (processedAttachments.has(attachmentId)) return; // 既に処理済みの添付ファイルはスキップ

  var uniqueFileName = getUniqueFileName(folder, cleanFileName(`${sender}_${formattedDateTime}_${attachment.getName()}`), message.getId(), index); // 一意のファイル名を生成
  var saved = false; // 保存フラグの初期化

  for (var attempt = 0; attempt < retryCount; attempt++) { // 再試行回数分ループ
    try {
      var attachmentFile = folder.createFile(attachment.copyBlob()); // 添付ファイルをフォルダに保存
      attachmentFile.setName(uniqueFileName); // ファイル名を設定
      processedAttachments.add(attachmentId); // 添付ファイルIDを記録
      saved = true; // 保存成功フラグを立てる
      break; // 保存に成功したらループを抜ける
    } catch (e) {
      logError(logFile, `ファイルの保存に失敗しました (試行回数: ${attempt + 1}): ${e.toString()}`); // 保存失敗時のエラーログを記録
      Utilities.sleep(waitTime); // 保存失敗時に待機時間を設定
    }
  }

  if (!saved) {
    logError(logFile, "ファイルの保存に最終的に失敗しました: " + uniqueFileName); // 保存が最終的に失敗した場合のエラーログを記録
  }
}

// 添付ファイルIDを生成する関数(メッセージIDと添付ファイルのハッシュ値を使用)
function generateAttachmentId(message, attachment, index) {
  // 添付ファイルの内容をMD5ハッシュ化して一意のIDを生成
  var hash = Utilities.computeDigest(Utilities.DigestAlgorithm.MD5, attachment.getBytes()).map(byte => {
    var v = (byte < 0 ? byte + 256 : byte).toString(16); // バイト値を16進数に変換
    return v.length == 1 ? "0" + v : v; // 1桁の値は2桁に揃える
  }).join("");
  return `${message.getId()}_${hash}`; // メッセージIDとハッシュ値を組み合わせて一意のIDを生成
}

// 日付と時間をフォーマットする関数
function formatDateTime(date) {
  // 年月日_時分の形式にフォーマット
  return `${date.getFullYear().toString().slice(-2)}${String(date.getMonth() + 1).padStart(2, '0')}${String(date.getDate()).padStart(2, '0')}_${String(date.getHours()).padStart(2, '0')}${String(date.getMinutes()).padStart(2, '0')}`;
}

// ファイル名をクリーンアップする関数
function cleanFileName(fileName) {
  // ファイル名に使用できない文字を削除
  return fileName.replace(/[\/:*?"<>|]/g, '');
}

// 一意のファイル名を生成する関数
function getUniqueFileName(folder, baseFileName, messageId, index) {
  var extension = baseFileName.slice(baseFileName.lastIndexOf('.')); // ファイルの拡張子を取得
  var baseName = baseFileName.slice(0, baseFileName.lastIndexOf('.')); // ファイル名のベース部分を取得
  var uniqueFileName = `${baseName}_${messageId}_${index}${extension}`; // 一意のファイル名を生成

  if (!folder.getFilesByName(uniqueFileName).hasNext()) return uniqueFileName; // ファイル名が重複していない場合そのまま返す
  return `${baseName}_${new Date().getTime()}_${messageId}_${index}${extension}`; // ファイル名が重複する場合タイムスタンプを追加して返す
}

// ログファイルを取得または作成する関数
function getLogFile() {
  var logFileName = 'email_attachment_log.txt'; // ログファイルの名前
  var logFiles = DriveApp.getFilesByName(logFileName); // ログファイルを取得
  return logFiles.hasNext() ? logFiles.next() : DriveApp.createFile(logFileName, ''); // 既存のログファイルがあればそれを使用、なければ新規作成
}

// エラーログを記録する関数
function logMessage(logFile, message) {
  var logContent = logFile.getBlob().getDataAsString(); // ログファイルの内容を取得
  logFile.setContent(logContent + `${new Date().toLocaleString()} - ${message}n`); // 新しいログメッセージを追加して保存
}

// エラーログを記録する関数
function logError(logFile, message) {
  logMessage(logFile, `ERROR: ${message}`); // エラーログを記録
}

// 処理済みIDセットを取得する関数
function getProcessedSet(property) {
  var processedSet = PropertiesService.getUserProperties().getProperty(property); // プロパティから処理済みIDセットを取得
  return processedSet ? new Set(JSON.parse(processedSet)) : new Set(); // JSONからセットに変換して返す
}

// 処理済みIDセットを保存する関数
function saveProcessedSet(property, processedSet) {
  PropertiesService.getUserProperties().setProperty(property, JSON.stringify(Array.from(processedSet))); // セットをJSONに変換して保存
}

// 開始位置を取得する関数
function getStartIndex() {
  var start = PropertiesService.getScriptProperties().getProperty('start'); // 前回の実行位置を取得
  return start ? parseInt(start, 10) : 0; // 数値に変換して返す、存在しない場合は0を返す
}

粘貼源碼後,在左上角單擊“保存”請。

使用 Google Apps 腳本 (GAS) 創建並運行新項目

粘貼 Google Drive 文件夾 ID,然後單擊 [保存]

下一個,在 Google Drive 中創建目標文件夾並獲取文件夾 ID獲得與將文件夾 ID 粘貼到 xxxxxxxxxxxxx 下面的位置請。

folderId: 'xxxxxxxxxxxxxx', // 添付ファイルを保存するGoogleドライブフォルダのID

粘貼後,它將如下所示:

folderId: '1hjnn0L64MM9ZSqKjtW5BDjtP8BaQkeKN', // 添付ファイルを保存するGoogleドライブフォルダのID

粘貼文件夾 ID 並重試單擊“保存”請。

使用 Google Apps 腳本 (GAS) 創建並運行新項目

單擊[▶運行]

保存項目後,接下來是左上角單擊 [▶ 運行]請。

使用 Google Apps 腳本 (GAS) 創建並運行新項目

點擊【檢查權限】

單擊 [▶ 運行],將彈出一個窗口,顯示“需要授權”。

點擊【檢查權限】請。

使用 Google Apps 腳本 (GAS) 創建並運行新項目

選擇要使用的 Google 帳戶

當您單擊[檢查權限]時,將打開一個標有“選擇帳戶”的窗口。

這裡這個選擇使用 Google Apps 腳本 (GAS) 的帳戶(您要為其自動保存附件的 Gmail 帳戶)請。

使用 Google Apps 腳本 (GAS) 創建並運行新項目

點擊【詳情】

當您選擇一個帳戶時,您將被重定向到一個屏幕,顯示“此應用程序尚未經過 Google 驗證”。

顯示此消息是因為我創建了自己的 Google Apps 腳本 (GAS)。

在左下角點擊【詳情】請。

使用 Google Apps 腳本 (GAS) 創建並運行新項目

點擊【前往(不安全頁面)】

單擊[詳細信息]以展開屏幕。

在其中點擊【前往(不安全頁面)】請。

使用 Google Apps 腳本 (GAS) 創建並運行新項目

單擊[允許]

當我點擊[轉到(不安全頁面)]時,會顯示一條消息“請求訪問您的 Google 帳戶”。

滾動到底部並單擊[允許]請。

如果您允許,您的 Gmail 地址將收到一封電子郵件,內容為:“您已被授予訪問您的 Google 帳戶以保存 Gmail 自動保存附件的權限。”

使用 Google Apps 腳本 (GAS) 創建並運行新項目

確認自動將 Gmail 附件保存到 Google Drive 中指定文件夾的腳本已執行。

單擊“允許”將運行一個腳本,該腳本會自動將 Gmail 附件保存到 Google 雲端硬盤中的指定文件夾。

使用 Google Apps 腳本 (GAS) 創建並運行新項目

驗證附件是否保存在 Google 雲端硬盤的指定文件夾中

如果您在運行時打開 Google 雲端硬盤中的指定文件夾,您可以看到正在保存附件。

了解更多詳情關於引入腳本的內容正如 中所解釋的,它是一種一次檢查最新 30 封電子郵件並保存附件的機制。
如果 30 項中沒有附件,則不會保存任何內容。

使用 Google Apps 腳本 (GAS) 創建並運行新項目

使用觸發功能將其設置為定期自動運行

最後,我們將使用Google Apps Script(GAS)的觸發功能來設置此腳本定期自動運行。

每次手動按下執行按鈕沒有問題,但使用觸發功能有以下優點。

  1. 實現自動化:通過設置觸發功能可以自動執行腳本。這使您可以自動執行日常任務,而無需手動運行腳本。例如,您可以將腳本設置為每小時運行一次,以便新附件自動保存到 Google 雲端硬盤。
  2. 在線執行:觸發​​器在 Google 的服務器上運行,因此您的計算機不需要一直處於開啟狀態。完成初始設置後,新附件將在指定時間自動保存到 Google 雲端硬盤。

從這裡開始,我們將使用實際屏幕以易於理解的方式解釋如何使用觸發功能設置定期自動執行的腳本。

不是必需的,所以如果不需要自動執行則無需設置。

打開您想要自動運行的Google Apps腳本(GAS),然後單擊[觸發器]

Google Apps腳本(GAS)轉至 ,打開您想要自動運行的 Google Apps 腳本 (GAS),然後點擊【觸發】請。

使用觸發功能將其設置為定期自動運行

單擊添加觸發器

點擊【觸發】,進入觸發設置界面。

在右下角單擊添加觸發器請。

使用觸發功能將其設置為定期自動運行

在“選擇時間間隔(小時)”中選擇“每小時”,然後點擊右下角的“保存”。

當您單擊[添加觸發器]時,將出現一個屏幕,您可以在其中選擇要使用哪種觸發器來運行腳本。

這次,我想自動運行一個腳本,每小時自動將 Gmail 附件保存到 Google Drive,所以我首先編寫它。在“選擇時間間隔(小時)”中選擇“每小時”,然後點擊右下角的“保存”。請。

使用觸發功能將其設置為定期自動運行

選擇Google賬戶自動運行腳本

當您單擊[保存]時,將出現一個顯示“選擇帳戶”的窗口。

選擇Google賬戶自動運行腳本請。

使用觸發功能將其設置為定期自動運行

點擊【高級】

當您選擇 Google 帳戶自動運行腳本時,您將看到一個屏幕,顯示“Google 尚未驗證此應用程序。”

在其中點擊【高級】請。

使用觸發功能將其設置為定期自動運行

單擊[轉到...]

單擊“高級”,屏幕將向底部展開。

在其中單擊[轉到...]請。

使用觸發功能將其設置為定期自動運行

單擊[允許]

下一個單擊[允許]請。

使用觸發功能將其設置為定期自動運行

確保已設置觸發器

單擊[允許]返回觸發設置屏幕並確認觸發已設置。

自動保存 Gmail 附件的腳本現在每小時運行一次。

使用觸發功能將其設置為定期自動運行

腳本主要功能及內容

下面我們就介紹一下引入腳本的主要功能和內容。

該腳本會查看您的 Gmail 收件箱,檢查新電子郵件,並自動將所有附件保存到 Google 雲端硬盤。它還具有防止再次保存來自特定發件人的電子郵件和已保存的文件的功能。

可編輯部分

首先,我們將介紹每個用戶可以編輯的部分。

  // ユーザー設定 - ここを変更してください
  var settings = {
    excludedEmailAddresses: ['[email protected]', '[email protected]'], // 処理対象外のメールアドレス
    folderId: '1hjnn0L64MM9ZSqKjtW5BDjtP8BaQkeKN', // 添付ファイルを保存するGoogleドライブフォルダのID
    maxThreads: 30, // 一度に処理するスレッド数
    waitTime: 3000, // ファイル保存後の待機時間(ミリ秒)
    retryCount: 3 // 保存失敗時の再試行回数
  };

開頭的這部分可以根據用戶的環境進行編輯。

建議閱讀:Windows 11 顯示更多選項 將上下文菜單恢復為 Windows 10 規格

指定不受處理的電子郵件地址

例如,如果您不想保存已發送電子郵件的附件,或者不想保存特定人員發送的電子郵件的附件,請編輯以下地址。

excludedEmailAddresses: ['[email protected]', '[email protected]'], // 処理対象外のメールアドレス

Google 雲端硬盤文件夾 ID

可以在以下部分中更改用於保存附加文件的文件夾 ID。

folderId: '1hjnn0L64MM9ZSqKjtW5BDjtP8BaQkeKN', // 添付ファイルを保存するGoogleドライブフォルダのID

一次處理的電子郵件數量

如果您收到大量電子郵件,請更改 maxThreads 數量。
增加數量將增加一次可以處理的電子郵件數量。

即使我將其設置為 999 項,也會超時。
這會受到附加文件大小的影響,但將數字設置為 70 或更少是安全的。

maxThreads: 30, // 一度に処理するスレッド数

關於保存的附件文件的名稱

發件人[電子郵件受保護],若接收日期時間為2024年6月29日13:25,原文件名為invoice.pdf,消息ID為123456789,索引為0,則轉換並保存如下。

[電子郵件受保護]_240629_1325_請求書_123456789_0.pdf

此轉換可防止您保存同一文件兩次。

錯誤處理

如果保存文件失敗,它將重試並記錄錯誤消息(如果問題仍然存在)。

日誌是email_attachment_log.txt它將自動在 Google Drive 上創建並使用該名稱。
該日誌文件會不斷增長,因此請定期刪除它。
*即使刪除整個文件,它也會自動重新創建。

防止重複處理

該程序旨在避免重複保存同一電子郵件或附件。
這是通過存儲電子郵件線程 ID 和附件 ID 來實現的。

首先,我們來談談線程ID。
Gmail 電子郵件線程被分配了一個唯一的 ID。
該程序保存處理後的線程ID,並在下次執行時檢查是否包含相同的線程ID。
如果線程 ID 已保存,則該線程將被跳過。
這可以防止同一線程中的電子郵件再次被處理。

接下來,我們來談談附件 ID。
附件ID是使用消息ID和附件內容唯一生成的。
具體來說,使用MD5的方法對附件的內容進行散列,並通過組合散列值和消息ID來創建ID。
也保存此 ID,並在下次運行時檢查它。如果存儲了相同的 ID,則該附件將被跳過。
這可以防止再次保存具有相同內容的文件。

這樣,通過管理線程 ID 和附件文件 ID,我們可以防止重複處理。這可以防止同一電子郵件或文件被多次處理。

常問問題

這個腳本是如何工作的?

此腳本從您的 Gmail 收件箱檢索電子郵件,並將其中包含的附件​​​​保存到指定的 Google 雲端硬盤文件夾中。保存線程 ID 和附件 ID 以防止重複處理。

我應該在哪裡設置附件的目標文件夾?

將“folderId”值設置為要保存到的 Google 雲端硬盤文件夾的 ID。該 ID 是文件夾 URL 的一部分(例如,https://drive.google.com/drive/folders/folder ID)。

如何排除來自特定電子郵件地址的電子郵件?

將您要排除的電子郵件地址添加到“excludedEmailAddresses”。來自此處所寫地址的電子郵件將不會被處理。

我可以更改一次處理的電子郵件數量嗎?

是的,您可以通過更改“maxThreads”值來設置一次處理的電子郵件數量。例如,設置 maxThreads: 50 將一次處理 50 個線程。

附件保存時的文件名是什麼?

附件將轉換為包含發件人電子郵件地址、接收日期和時間、原始文件名、郵件 ID 和附件索引的名稱。

如何防止同一個附件被多次保存?

該腳本會保存處理後的線程 ID 和附件 ID,因此不會再次處理相同的附件。

在哪裡可以看到腳本的錯誤日誌?

錯誤日誌記錄在 Google 雲端硬盤的 email_attachment_log.txt 文件中。該文件包含處理期間發生的任何錯誤的詳細信息。

如果運行腳本時保存失敗怎麼辦?

設置重試次數,最多嘗試 3 次,直到保存成功。如果失敗,將會記錄在錯誤日誌中。

我可以在附件名稱中包含電子郵件主題和正文嗎?

當前腳本的文件名中不包含主題或正文,但您可以通過修改代碼來實現。例如,您可以使用 message.getSubject() 獲取主題並將其附加到文件名中。

是否可以只保存某些文件格式?

是的,可以通過在 processAttachment 函數中添加條件來檢查文件格式。例如,要僅保存 PDF 文件,請添加 if (attachment.getContentType() === 'application/pdf') 等條件。

有沒有辦法重置已處理的附件 ID?

要重置已處理的附件 ID,請在 Google Apps 腳本編輯器中運行 PropertiesService.getUserProperties().deleteProperty('processedAttachments')。

我可以將此腳本用於多個 Gmail 帳戶嗎?

這可以通過為每個 Gmail 帳戶單獨設置腳本來實現。在每個帳戶中創建一個 Google Apps 腳本項目並配置該腳本。

是否可以通過電子郵件接收腳本執行結果的通知?

是的,您可以在腳本末尾使用“MailApp.sendEmail”,通過電子郵件通知您執行結果。這使您可以立即知道流程何時完成或是否發生錯誤。

我可以更改已保存文件的命名約定嗎?

是的,您可以通過修改“getUniqueFileName”函數來自定義文件命名約定。例如,您可以更改文件名以包含主題。

有關其他 Google 服務的文章

單擊此處查看有關其他 Google 服務的文章。請看一下。