首頁/AI 講義/數位工具・自動化

數位工具・自動化 · Workspace+GAS+Gemini約 12 分鐘Automation

跨 App 同步:Sheets 串 Docs 與行事曆

跨 App 同步:Sheets 串 Docs 與行事曆 — 賴家榮 AI 教學

整體概覽|Overview

很多團隊的痛點是同一份資料要重複填三次:試算表登記一次、開會通知寫進行事曆一次、專案摘要再貼進 Google 文件一次。這篇教你用 Google Apps Script(GAS)把三個 App 串成一條自動化流程,只要在 Sheets 填一列,就自動建立行事曆事件、把 Gemini 整理過的摘要寫進 Docs。

Key Takeaways

  • 一次輸入、三處同步:在 Sheets 填資料,Docs 與行事曆自動更新。
  • Gemini 負責整理雜亂文字,並判斷資料是否需要建立提醒。
  • 全程用免費的 GAS 執行,不需要架伺服器,也不用寫前端。
  • 金鑰用 PropertiesService 保管,不會寫死在程式碼裡。
  • 零基礎也能跟著做,從新增專案到跑通只要十來分鐘。
  • 同一套骨架可延伸到報表、通知、跟進信等更多情境。

本文以「專案登記表」為例:每一列代表一個專案,包含名稱、負責人、截止日、原始備註。跑完流程後,Gemini 會把備註整理成一段清楚的專案摘要寫進指定的 Google 文件,同時在行事曆建立截止日提醒。你只要維護一張 Sheets 就好。

為什麼要這樣做|Why

手動在多個 App 之間搬資料,最大的問題不是慢,而是「會錯」。日期打錯、負責人漏掉、摘要前後不一致,這些錯誤往往到出事才發現。把流程交給程式,機器不會忘記步驟,也不會手滑。

而 Gemini 補上了程式做不到的那一塊:理解與判斷。原始備註常常是零散的口語筆記,人要花時間讀懂再改寫;讓 Gemini 先整理成結構清楚的摘要,再由 GAS 寫進文件,等於把「理解文字」和「搬運資料」兩件事分別交給最擅長的工具。

開始前準備|Prepare

Checklist

  • 一個 Google 帳號,並能開啟 Google 試算表、文件、行事曆。
  • 到 Google AI Studio 申請一組 Gemini API 金鑰(免費額度即可)。
  • 準備一張 Sheets,第一列為標題:專案名稱、負責人、截止日、備註、狀態。
  • 準備一份空白 Google 文件,記下網址中的文件 ID。
  • 知道你要寫入事件的行事曆 ID(預設可用主行事曆)。

實作步驟|Steps

1開啟指令碼編輯器

動作在試算表點「擴充功能 → Apps Script」,開啟綁定這張表的指令碼專案。

常見地雷若從雲端硬碟另開獨立指令碼,就抓不到 getActiveSpreadsheet(),請務必從試算表進入。

2設定 API 金鑰

動作左側「專案設定 → 指令碼屬性」新增一筆,名稱填 GEMINI_API_KEY,值貼上你的金鑰。

常見地雷不要把金鑰直接寫在程式碼裡,否則分享指令碼時會外洩。

3貼入 askGemini 函式

動作在編輯器貼上下方第一段共用函式,之後所有呼叫 Gemini 的地方都用它。

常見地雷網址中的模型名稱要與你有權限的版本一致,否則會回傳 404。

4設定文件與行事曆 ID

動作在主流程開頭把 DOC_ID 換成你的文件 ID,行事曆用 getDefaultCalendar() 或指定 ID。

常見地雷文件 ID 是網址 /d/ 與 /edit 中間那串,不要整段網址貼上。

5貼入主流程

動作貼上第二段 syncProjects(),它會逐列讀取未處理的專案並同步。

常見地雷用「狀態」欄位標記已處理,避免每次執行都重複建立事件。

6首次執行並授權

動作從函式清單選 syncProjects,按執行,跳出授權視窗時允許存取試算表、文件與行事曆。

常見地雷第一次會出現「未驗證的應用程式」警告,點「進階 → 前往」即可,那是你自己的指令碼。

7驗證結果

動作回到行事曆看是否新增了截止日事件,打開 Google 文件確認 Gemini 摘要已寫入。

常見地雷若文件沒更新,先看執行紀錄有沒有錯誤,通常是 DOC_ID 或金鑰設錯。

8設定自動觸發

動作在「觸發器」新增一個,選 syncProjects、事件來源為時間驅動,例如每小時執行一次。

常見地雷時間驅動觸發器有每日執行時間配額,頻率別設太密集。

下面第一段是所有文章共用的 Gemini 呼叫函式,請原封不動貼進指令碼。它會從屬性服務讀出金鑰,用 UrlFetchApp 呼叫 Gemini,並取出回覆文字。

function askGemini(prompt) {
  const key = PropertiesService.getScriptProperties().getProperty('GEMINI_API_KEY');
  const url = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=' + key;
  const payload = { contents: [{ parts: [{ text: prompt }] }] };
  const res = UrlFetchApp.fetch(url, { method:'post', contentType:'application/json', payload: JSON.stringify(payload), muteHttpExceptions:true });
  return JSON.parse(res.getContentText()).candidates[0].content.parts[0].text.trim();
}

第二段是主流程:逐列讀取試算表中尚未處理的專案,請 Gemini 把備註整理成專案摘要,寫進 Google 文件,並在行事曆建立截止日提醒,最後把狀態標記為已同步。

const DOC_ID = '你的Google文件ID';

function syncProjects() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('專案登記表');
  const data = sheet.getDataRange().getValues();
  const doc = DocumentApp.openById(DOC_ID);
  const body = doc.getBody();
  const cal = CalendarApp.getDefaultCalendar();

  for (let i = 1; i < data.length; i++) {
    const [name, owner, due, note, status] = data[i];
    if (status === '已同步' || !name) continue;

    const prompt = '你是專案助理,請把以下備註整理成一段約80字、語氣專業的專案摘要,只回內容:\n專案:' + name + '\n負責人:' + owner + '\n備註:' + note;
    const summary = askGemini(prompt);

    body.appendParagraph(name + '(' + owner + ')').setHeading(DocumentApp.ParagraphHeading.HEADING2);
    body.appendParagraph(summary);

    if (due) {
      const d = new Date(due);
      cal.createAllDayEvent('【截止】' + name, d, { description: owner + '|' + summary });
    }
    sheet.getRange(i + 1, 5).setValue('已同步');
  }
  doc.saveAndClose();
}

流程一覽|Flow

資料從 Sheets 流向 Docs 與行事曆
1你在試算表新增一列專案資料
2時間觸發器啟動 syncProjects()
3程式讀取狀態非「已同步」的列
4Gemini 把備註整理成專案摘要
5摘要寫入 Google 文件、截止日建立行事曆事件
6該列狀態標記為「已同步」避免重複

整條流程的關鍵是「狀態欄」這個開關:它讓程式知道哪些列還沒處理,是避免重複建立事件、也是讓流程可以安全反覆執行的核心設計。

實用技巧|Tips

常見問題|FAQ

常見問題 FAQ

為什麼一定要用狀態欄,不能每次全部重跑嗎?

可以全部重跑,但那會在行事曆和文件裡重複建立一模一樣的內容,越跑越亂。狀態欄就像一個記號,告訴程式哪些列已經處理過、哪些是新的。這樣不論你手動執行幾次,或觸發器每小時跑一次,都只會處理新增或改動的列,既省 Gemini 的呼叫次數,也不會產生垃圾資料。

文件 ID 到底要填哪一段?

打開你的 Google 文件,看網址會像 docs.google.com/document/d/一長串英數字/edit,那串英數字就是文件 ID,只要複製 /d/ 和 /edit 中間的部分。不要把整段網址貼進 DOC_ID,也不要把試算表 ID 誤填進來。填錯最常見的錯誤訊息是找不到文件或沒有權限。

Gemini 回傳的摘要有時候會多一句廢話怎麼辦?

這通常是提示詞不夠明確造成的。你可以在提示詞裡明講「只回內容、不要加開場白、不要加結尾」,並限定字數,例如「約80字」。若還是不穩,可以在程式裡對回傳文字做簡單清理,例如去掉開頭的「好的」「以下是」這類詞。把規則寫進提示詞,效果比事後清理更好。

行事曆事件建立在哪個行事曆?

範例用 CalendarApp.getDefaultCalendar(),也就是你的主行事曆。如果想寫進團隊共用行事曆,改用 CalendarApp.getCalendarById('行事曆ID'),ID 可在行事曆設定的「整合日曆」區塊找到。記得你要對那個行事曆有編輯權限,否則會建立失敗。

觸發器每小時跑一次會不會太耗額度?

Gemini 免費額度以每分鐘與每日請求數計算,每小時處理幾筆新資料通常綽綽有餘。真正要注意的是 GAS 本身的每日執行時間配額。如果資料量不大,每小時甚至每天一次都夠用;資料量大時再考慮批次處理或降低頻率。

可以反過來,改資料時自動更新已建立的事件嗎?

可以,但要多存一個對應關係。做法是建立事件後,把回傳的事件 ID 存回試算表的某一欄,下次執行時若該列已有事件 ID,就用 getEventById() 抓出來更新,而不是新建。這會讓程式稍微複雜一點,建議先把基本同步跑順,再加上這個進階功能。

為什麼第一次執行會跳出嚇人的警告?

因為這是你自己剛寫、還沒經過 Google 審核的指令碼,系統一律會提醒「未驗證的應用程式」。這是正常的,點「進階」再點「前往(不安全)」就能繼續授權。只要程式是你自己寫的、你看得懂它要做什麼,就可以放心授權。

三個 App 的授權要分開處理嗎?

不用,Apps Script 會在第一次執行時,根據你程式用到的服務一次列出所有需要的權限,例如讀寫試算表、文件、行事曆與連外網路。你只要在那個視窗一次同意即可。之後除非你新增用到其他服務的程式碼,否則不會再跳授權。

如果某一列資料有問題,會讓整個流程停掉嗎?

以目前的寫法,如果某列讓 Gemini 或某個 App 出錯,迴圈會中斷,後面的列就不會處理。實務上建議在迴圈內用 try/catch 包住,出錯時記錄該列並繼續下一列,這樣單筆壞資料不會拖垮整批。先跑通基本版,再加上防呆是比較好的順序。

這套流程可以給不會寫程式的同事用嗎?

可以,這正是它的好處。同事只要會在試算表填資料就行,程式在背景自動跑。你甚至可以把手動執行的按鈕做成試算表的自訂選單,或乾脆全靠觸發器定時執行,讓同事完全感覺不到程式的存在,只看到資料自己同步好了。

延伸與諮詢|CTA

把重複的資料搬運交給流程,人就能專心在需要判斷的事情上。這套 Sheets 串 Docs 與行事曆的骨架,是所有 Workspace 自動化的起點,值得先練熟。

想讓團隊用 AI+自動化把重複工作交給流程?賴家榮提供 Workspace/GAS/Gemini 企業內訓與大學課程。

預約授課・免費諮詢

本文為賴家榮 AI 教學中心原創教學內容;想讓團隊學會用 AI,歡迎看AI 課程或預約授課 →

代表圖片來源:圖片來源:Pexels

Your turn

把 AI,變成團隊真的用得上的能力。

不論你在哪個產業,賴家榮都能帶團隊把 AI 學到真的用得上。

預約授課・免費諮詢