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

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

GAS×Gemini 表單自動建立行事曆事件

GAS×Gemini 表單自動建立行事曆事件 — 賴家榮 AI 教學

Overview這一課你會做出什麼

你會做出一套自動排程系統:使用者透過 Google 表單描述需求與時間,Gemini 幫你解析出事件標題、日期與時段,Apps Script 就自動在你的 Google 行事曆建立對應事件,不用再手動輸入。

Key Takeaways

  • 用 Google 表單收集預約或約會需求,送出即觸發
  • 讓 Gemini 從一段自然語言中解析出標題、日期、開始與結束時間
  • 要求 Gemini 回傳結構化 JSON,程式好解析、少出錯
  • 用 CalendarApp 自動建立行事曆事件並邀請對方
  • 金鑰放 PropertiesService 安全保管,不寫死在程式裡
  • 設定表單提交觸發器,整個排程流程全自動

這套流程很適合接受預約諮詢、會議報名、課程約課這類場景。使用者只要用日常口吻寫「我想約下週三下午三點討論合作」,Gemini 就能讀懂並轉成正確時間,程式立刻幫你把事件排進行事曆。

Why先看情境:這解決什麼問題

假設你提供一對一諮詢服務,客戶透過表單告訴你想約的時間。麻煩的是,大家寫法五花八門:有人寫「8/5 早上十點」、有人寫「下週二下午」、有人寫「明天晚上七點半」。你得一筆一筆看懂,再手動打開行事曆換算成正確日期時間、建立事件,件數一多就容易看錯、排錯,甚至撞期。

有了 GAS 加上 Gemini,這些口語化的時間描述可以自動被解析。表單送出後,程式把需求丟給 Gemini,請它換算成標準日期時間並回傳 JSON,接著用 CalendarApp 直接建立事件、寄出邀請。你不再需要人工換算與輸入,行事曆自動排好,也能第一時間避免撞期,把心力留給真正重要的諮詢內容。

Prepare動手前準備

Checklist

  • 一個可正常使用的 Google 帳號(免費版即可)
  • 一組 Gemini API 金鑰:到 ai.google.dev 登入後建立並複製備用
  • 一份 Google 表單,包含「姓名」「Email」「需求與希望時間」三個問題
  • 表單已連結到一份 Google 試算表方便留存
  • 確認你的 Google 行事曆可正常新增事件(就是平常在用的那個)

Steps一步一步實作

1打開表單的指令碼編輯器

動作在 Google 表單編輯畫面右上角點三個點,選「指令碼編輯器」,開啟空白的 Apps Script 專案。

常見地雷務必從表單進入,才能綁定表單提交事件;從試算表進入會綁錯對象。

2設定 Gemini 金鑰

動作左側齒輪「專案設定」,到「指令碼屬性」新增一組:名稱 GEMINI_API_KEY,值貼上金鑰,按儲存。

常見地雷貼上時檢查前後有沒有多餘空白或換行,否則 API 會回未授權錯誤。

3貼上 askGemini 共用函式

動作刪掉預設的 myFunction,貼上本文的 askGemini 函式,它負責呼叫 Gemini 並回傳純文字。

常見地雷回傳值有時會被包在程式碼區塊記號裡,主流程要先清掉再解析 JSON。

4撰寫主流程函式

動作貼上 onFormSubmit 主函式,它會取需求文字、請 Gemini 解析成 JSON、再用 CalendarApp 建立事件。

常見地雷提示詞要明確告訴 AI 今天的日期,它才能正確換算「下週三」這類相對時間。

5第一次授權

動作上方函式選 onFormSubmit 按「執行」,跳出授權時選帳號、點進階、允許存取行事曆與網路。

常見地雷會出現未驗證警告屬正常,這是你自己的專案,往下點允許即可。

6建立表單提交觸發器

動作左側鬧鐘「觸發條件」,新增觸發,函式選 onFormSubmit,事件來源「來自表單」,類型「表單提交時」。

常見地雷來源選錯成時間驅動就不會在送出時觸發,務必選「來自表單」。

7實際填表測試

動作填一筆例如「我想約 8/5 下午三點討論網站設計」送出,打開行事曆看該時段是否自動出現事件。

常見地雷若時間跑掉,多半是時區沒設對,程式裡已指定 Asia/Taipei,也檢查行事曆本身時區。

以下兩段程式碼是核心。第一段 askGemini 為共用 AI 呼叫函式,請原樣照抄;第二段 onFormSubmit 負責解析時間並建立行事曆事件。重點在於「請 AI 回傳 JSON」,程式解析結構化資料比解析自由文字穩定許多。

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();
}
function onFormSubmit(e) {
  // 1. 取出表單回覆,組成需求文字
  const items = e.response.getItemResponses();
  let email = '';
  let need = '';
  items.forEach(function(it) {
    const title = it.getItem().getTitle();
    const ans = it.getResponse();
    if (title.indexOf('Email') !== -1) email = ans;
    else need += title + ':' + ans + '\n';
  });

  // 2. 告訴 Gemini 今天日期,請它回傳結構化 JSON
  const today = Utilities.formatDate(new Date(), 'Asia/Taipei', 'yyyy-MM-dd');
  const prompt = '今天是 ' + today + '(台灣時間)。請從以下需求解析出行程資訊,' +
    '只回傳 JSON,格式為 {"title":"事件標題","start":"yyyy-MM-dd HH:mm","end":"yyyy-MM-dd HH:mm"},' +
    '不要加任何說明或程式碼記號。若未指定結束時間,預設為開始後一小時。\n\n需求:\n' + need;
  let raw = askGemini(prompt);
  raw = raw.replace(/```json/gi, '').replace(/```/g, '').trim();
  const info = JSON.parse(raw);

  // 3. 把字串時間轉成 Date(台灣時區)
  const start = new Date(info.start.replace(' ', 'T') + ':00+08:00');
  const end = new Date(info.end.replace(' ', 'T') + ':00+08:00');

  // 4. 用 CalendarApp 建立事件並邀請對方
  const cal = CalendarApp.getDefaultCalendar();
  const options = { description: need };
  if (email) options.guests = email;
  cal.createEvent(info.title, start, end, options);
}

Flow一張圖看懂流程

表單自動排程流程
1使用者填寫需求與希望時間並送出表單
2表單提交觸發器啟動 onFormSubmit
3程式整理出需求文字與對方 Email
4告訴 Gemini 今天日期,請它回傳含標題與起訖時間的 JSON
5程式清掉多餘記號並解析 JSON
6把字串時間轉成台灣時區的 Date
7用 CalendarApp 建立事件並寄出邀請

用文字描述就是:表單送出後觸發程式,程式整理出需求文字,並附上今天日期一起交給 Gemini,請它把口語時間換算成標準格式並以 JSON 回傳;程式解析出標題與起訖時間後,轉成台灣時區的 Date 物件,最後用 CalendarApp 建立事件,若有填 Email 就一併寄出邀請,全程不需人工換算與輸入。

Tips常見錯誤與優化

FAQ常見問題 Q&A

常見問題 FAQ

為什麼要請 Gemini 回傳 JSON,直接給我文字不行嗎?

文字格式每次都不太一樣,程式很難穩定抓出時間。要求回傳固定的 JSON 結構後,程式只要用 JSON.parse 就能精準取得標題、開始與結束時間,大幅降低解析錯誤。這是讓 AI 輸出「可被程式使用」的關鍵技巧,比事後用字串搜尋去猜時間可靠得多,也讓整套流程更容易維護。

使用者寫「下週三」「明天」這種相對時間,AI 真的算得出來嗎?

算得出來,前提是你在提示詞裡明確告訴它今天的日期。程式會先用 formatDate 取得台灣今天的日期,寫進提示詞開頭,AI 就能以此為基準推算相對時間。若不給基準日期,AI 只能亂猜,結果通常會錯。給了今天日期後,「下週三」「明天晚上七點」這類說法都能正確換算成標準時間。

建立出來的事件時間差了八小時,是哪裡出問題?

這是時區沒對齊造成的。行事曆與 Date 物件如果沒有明確指定時區,程式可能把時間當成 UTC 世界標準時間,台灣比它快八小時,就會整整差八小時。程式碼在組 Date 時已補上 +08:00,並用 Asia/Taipei 格式化日期。若仍有偏差,請檢查你的 Google 行事曆設定中的時區是否也設為台北。

如果 Gemini 回傳的 JSON 格式壞掉,程式會怎樣?

沒有防護的話 JSON.parse 會直接報錯,該筆需求就沒建立事件。建議用 try/catch 把解析與建立包起來,一旦失敗就用 GmailApp 寄一封信通知你,附上原始需求,讓你手動補建。這樣即使 AI 偶爾出錯,資料也不會默默消失,你能在第一時間補救,整套流程更可靠。

這樣建立的事件,對方會收到邀請通知嗎?

會,只要表單有收集到對方的 Email,程式就把它放進 guests 選項,CalendarApp 建立事件時會寄出邀請信給對方,對方也能在自己的行事曆看到並回覆出席與否。如果你不想自動邀請,只想在自己行事曆留個記錄,把 guests 那段拿掉即可,事件一樣會建立,只是不對外寄通知。

需求裡完全沒提到時間,AI 會亂編一個時間嗎?

有可能,所以要在程式端加防呆。你可以在提示詞要求:若無法判斷時間就把 start 回傳空字串。程式解析後若發現時間為空,就不要建立事件,改寄信通知你這筆需求缺時間,請對方補充。這樣能避免 AI 硬湊一個不存在的時間,導致行事曆出現莫名其妙的事件。

可以指定建立到某個特定行事曆,而不是預設那個嗎?

可以。把 CalendarApp.getDefaultCalendar 換成 CalendarApp.getCalendarById,傳入你要用的行事曆 ID。行事曆 ID 可在 Google 行事曆的該行事曆設定頁面找到,通常是一串以 group.calendar.google.com 結尾的字串。這在你想把工作預約與私人行程分開時特別實用,例如專門建一個「客戶諮詢」行事曆來收這些自動事件。

同一個時段如果已經有事件,程式會自動避開撞期嗎?

預設不會,它會照建。若要避免撞期,可在建立前用 CalendarApp 的 getEvents 查詢該時段是否已有事件,有的話就不建立、改寄信通知你另約時間。這需要多寫幾行判斷,但對接受預約的場景很值得,能避免同一時段被排兩件事,也讓你在自動化之餘保有對行程的掌控。

Gemini 的免費額度夠用嗎?會不會很快就用完?

以個人接受預約的量來說綽綽有餘。Gemini 免費方案有每分鐘與每日的呼叫上限,而每筆表單只呼叫一次 API,除非你短時間湧入大量表單,否則很難碰到上限。若真的量大,可改成把需求先存起來、每隔一段時間批次處理,就能把呼叫集中、降低碰到頻率限制的機會。

我完全不會寫程式,照著做真的能完成嗎?

可以。你不需要自己從零寫程式,兩段核心程式碼直接複製貼上即可,其餘就是照著步驟在畫面上點選:設金鑰、貼程式、授權、設觸發器。整個過程沒有需要你自己發明的邏輯。建議第一次先用簡單的測試需求走一遍,確認事件成功建立,熟悉流程後再依自己的表單欄位微調提示詞就好。

CTA下一步

當口語化的時間描述都能自動變成行事曆事件,你等於幫自己請了一位不會看錯時間的排程助理。把這招學起來,再結合 Gmail 與雲端硬碟,就能打造一整套從收件到排程的自動化工作流。

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

預約授課・免費諮詢

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

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

Your turn

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

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

預約授課・免費諮詢