日曆與文件:會議前自動準備、會議後自動記錄
你最近一次開會前,有沒有發生過這個場景:手邊的日曆提醒叫你「5 分鐘後會議」,你才開始手忙腳亂地翻上次開會的記錄、找客戶背景資料、把昨晚的草稿截圖複製貼上到聊天室——然後帶著「剛才沒準備好」的感覺進了會議室。
開完會又是另一場悲劇。好不容易記在手機備忘錄的要點、畫在便利貼上的決議、截圖下來的討論串,最後有沒有整理成文件、存在哪裡,過了一週自己也記不清楚了。
這兩件事都可以讓機器幫你做掉。
這堂學什麼
- Google Calendar 與 Docs 的 OAuth 憑證設定:新手最大關卡,五步驟完整圖解,做一次終身有效
- 工作流程 A:Email / 訊息 → AI 抽取時間地點主題 → 自動建立 Google Calendar 事件
- 工作流程 B:每天早上 8:00,讀取今日行程 → AI 整理背景資料 → 推送到 Gmail / Telegram
- 工作流程 C:把原始會議筆記貼進 Webhook → AI 結構化整理 → 自動存入 Google Docs 歸檔
- 對照表:Google Workspace 內建 Gemini 功能 vs n8n,什麼場景用哪個(2026 現況)
觀念一:兩條自動化流水線,覆蓋整個會議週期
先看整體架構再動手,才不會三條流程搞混:

左邊「會議前」這條,起點是一封會議邀約信或訊息,終點是早晨行事曆簡報推到你手上。右邊「會議後」這條,起點是你會議中記的亂七八糟筆記,終點是一份整理好的 Google Docs 存進歸檔資料夾。
兩條流程用到的 Google 服務不同,但同一組 OAuth 憑證可以全部覆蓋:只要在 Google Cloud 同時開啟 Calendar API、Docs API、Drive API,做一次設定就夠。
觀念二:Gemini 內建功能 vs n8n 自訂流程,先搞清楚選哪個
2026 年的 Google Workspace 已經深度整合 Gemini:Calendar 可以用自然語言約會議、Google Meet 有「幫我記錄」功能、Docs 可以讓 Gemini 直接幫你起草。這些功能夠用的話不一定要 n8n——但有幾個場景 n8n 是唯一選項:

關鍵差異只有一句話:Gemini 是「問一次,回答一次」的互動模式;n8n 是「接好一次,永遠自動跑」的排程模式。早晨簡報推播、自動偵測 Gmail 建事件這種「你不需要記得觸發」的需求,只有 n8n 做得到。
前置必做:Google OAuth 憑證設定

Step 1:建立(或沿用) Google Cloud 專案
前往 console.cloud.google.com,用你的 Google 帳號登入。點頂部導覽列的專案下拉選單 → New project。名稱隨意取(例如 n8n-google-automation),Location 選 No organization,按 Create。
如果你已經在第 2 課建了專案,直接選那個即可,不需要重建。
Step 2:啟用三個 API
左側選單 → APIs & Services → Library。依序搜尋並啟用以下三個 API(每個都要點進去按 Enable):
Google Calendar APIGoogle Docs APIGoogle Drive API(Docs 相關操作依賴它)
啟用後,APIs & Services → Enabled APIs 裡會看到這三個列出來。沒有這步的話,n8n 操作時會報錯:Google Calendar API has not been used in project XXX before or it is disabled。
Step 3:設定 OAuth 同意畫面並發佈
左側 → APIs & Services → OAuth consent screen。
- 點 Get started(新版 Cloud Console 介面)
- App name:填一個識別名稱,例如
n8n 自動化 - User support email 和 Developer contact:填你自己的 email
- Audience:選 External(個人帳號只有這個選項)
- 其餘留預設,一路 Continue 到底儲存
**最重要的一步,很多人跳過:**回到 OAuth consent screen 主頁面,找到 Publishing status 欄位,點 Publish App → 確認。
不做這個動作,你的 OAuth token 只會活 7 天,之後每個工作流程都會開始報 Token has been expired or revoked 錯誤,要重新授權一次。把 App 發佈到 Production 狀態就可以永久有效(不需要通過 Google 審核,個人使用不影響)。
Step 4:建立 OAuth 用戶端 ID
左側 → APIs & Services → Credentials → + Create credentials → OAuth client ID。
- Application type:選 Web application
- Name:取個識別名(如
n8n-client) - Authorized redirect URIs:先開另一個分頁到 n8n 新增 credential 頁面,複製 OAuth Redirect URL(格式像
https://你的n8n網址/rest/oauth2-credential/callback)貼進來
按 Create 後會彈出視窗顯示 Client ID 和 Client Secret,先不要關掉,下一步要用。
Step 5:在 n8n 新增 Google Calendar 憑證
回到 n8n,左側 → Credentials → Add credential → 搜尋 Google Calendar OAuth2 API。
把上一步的 Client ID 和 Client Secret 貼進對應欄位,然後按 Sign in with Google。瀏覽器會跳出 Google 授權頁面——正常操作下可能會看到「此應用程式未經驗證」的警告,點 Advanced → Go to n8n 自動化(unsafe) 繼續,這是因為你的 app 沒有通過 Google 官方審核,但你自己用自己的帳號完全安全。
授權完成後,n8n 顯示綠色勾 → Save,憑證設定完成。
Google Docs 和 Google Drive 的 credential 照相同步驟再建一次(選對應的節點類型),但同一個 Client ID/Secret 可以重複使用。
手把手實戰
工作流程 A:Email 收到會議邀約 → 自動建日曆事件

節點 1:Gmail Trigger — 篩選會議相關信件
新增 Gmail Trigger 節點。
- Trigger On:New Email
- Filters → Subject contains:(留空,改用 AI 判斷,避免中英文關鍵字漏掉)
- Polling interval:5 minutes 即可
實務上如果你的信箱量很大,可以加 Gmail Label 篩選(先在 Gmail 建一個「待處理-會議」標籤,讓信件規則自動套用),這樣 Trigger 只讀有這個標籤的信,不會把每封信都送進流程。
節點 2:AI 節點 — 判斷是否為會議信 + 抽取資訊
新增 Basic LLM Chain 節點(或 AI Agent 節點)。Model 接 OpenAI GPT-4o mini 或 Claude Haiku,夠用且便宜。
System Prompt:
你是一個行程管理助理。你會收到一封 Email 的主旨與內文。
請判斷這封信是否包含明確的會議邀約資訊(有時間、地點或視訊連結)。
如果是,請以 JSON 格式輸出以下欄位:
{
"is_meeting": true,
"title": "會議主題",
"datetime_start": "ISO 8601 格式,含時區,例如 2026-07-08T15:00:00+08:00",
"datetime_end": "ISO 8601 格式,沒有就用 datetime_start 加 1 小時",
"location": "地點或視訊連結,沒有就填 null",
"attendees": ["與會者 email 清單,沒有就填空陣列"],
"description": "一句話說明這場會議的目的"
}
如果不是會議信,輸出: {"is_meeting": false}
今天日期: {{$now.format('YYYY-MM-DD')}}
User Message(接 Gmail Trigger 輸出):
主旨:{{$json.subject}}
內文:{{$json.text}}
節點 3:IF 節點 — 過濾掉非會議信
新增 IF 節點。
- Condition:Value 1 =
{{$json.output.is_meeting}}(AI 輸出的 JSON 欄位),Operation = Is true
True 分支繼續往下建事件;False 分支接 No Operation 節點結束(不做任何事)。
這一步是防呆:確保只有真正有會議資訊的信才會觸發建事件,不然你信箱裡隨便一封提到「下週」的信都會撞進 Calendar。
節點 4:Google Calendar — 建立事件
新增 Google Calendar 節點。
- Credential:選剛才設定好的 Google Calendar OAuth2
- Resource:Event
- Operation:Create
- Calendar ID:選
primary(你的主日曆),或輸入特定日曆的 email ID
欄位對應如下:
| Google Calendar 欄位 | 填入值 |
|---|---|
| Title | {{$json.output.title}} |
| Start Time | {{$json.output.datetime_start}} |
| End Time | {{$json.output.datetime_end}} |
| Location | {{$json.output.location}} |
| Description | {{$json.output.description}} |
存檔後點 Test workflow,找一封真實的會議信測試——成功的話 Google Calendar 裡會出現這個事件。
工作流程 B:每天早上推送今日行程簡報

節點 1:Schedule Trigger — 每天早上 8 點觸發
新增 Schedule Trigger 節點。
- Trigger Interval:Cron expression
- Cron:
0 8 * * 1-5(週一到週五早上 8:00)
如果你要改成每天都跑,把 1-5 改成 *。
節點 2:Google Calendar — 讀取今日事件
新增 Google Calendar 節點。
- Resource:Event
- Operation:Get Many
- Calendar ID:
primary - Time Min:
{{$now.startOf('day').toISO()}}(今天 00:00) - Time Max:
{{$now.endOf('day').toISO()}}(今天 23:59) - Single Run:開啟
- Return All:開啟
這樣會拿回一個陣列,每個元素是一個今日事件的資料物件。
節點 3:Code 節點 — 把事件清單整理成文字
Google Calendar 回傳的 JSON 欄位很多、很亂。新增一個 Code 節點,把需要的欄位整理成乾淨的文字,再傳給 AI:
const events = $input.all().map(item => item.json);
if (events.length === 0) {
return [{ json: { events_text: '今天沒有任何行程。' } }];
}
const lines = events.map(e => {
const start = e.start?.dateTime
? new Date(e.start.dateTime).toLocaleTimeString('zh-TW', { hour: '2-digit', minute: '2-digit', timeZone: 'Asia/Taipei' })
: '全天';
const end = e.end?.dateTime
? new Date(e.end.dateTime).toLocaleTimeString('zh-TW', { hour: '2-digit', minute: '2-digit', timeZone: 'Asia/Taipei' })
: '';
const time = end ? `${start}–${end}` : start;
const loc = e.location ? ` @ ${e.location}` : '';
const desc = e.description ? `\n 說明:${e.description.slice(0, 100)}` : '';
return `• ${time} ${e.summary}${loc}${desc}`;
});
return [{ json: { events_text: lines.join('\n'), count: events.length } }];
```</div>
<div class="step"><h4>節點 4:AI 節點 — 產生今日簡報文字</h4>
**System Prompt:**
```text
你是一個個人助理。請根據以下今日行程清單,產生一段簡短的早晨簡報。
格式要求:
1. 第一行:「早安!今天 X 月 X 日(星期X),共 N 場行程。」
2. 列出每場會議的時間、名稱、地點(如有)
3. 對每場會議給一句準備提示(需要帶什麼資料、需要提前確認什麼)
4. 最後一行:「今天加油!」
語氣輕鬆、口語,字數控制在 200 字以內。
User Message:
今天是 {{$now.format('YYYY年M月D日 dddd')}}。
行程清單:
{{$json.events_text}}
```</div>
<div class="step"><h4>節點 5:傳送 — Gmail 寄信給自己</h4>
新增 **Gmail** 節點。
- **Operation**:Send
- **To**:你自己的 email
- **Subject**:`📅 {{$now.format('M/D')}} 今日行程簡報`
- **Message**:接 AI 輸出的 `{{$json.output}}`(或 `{{$json.text}}`,依 AI 節點類型而定)
如果你偏好 Telegram,改接 **Telegram** 節點(需先用 BotFather 建 Bot,第 6 課會詳細說)。</div>
</div>
---
### 工作流程 C:原始會議筆記 → AI 摘要 → 存 Google Docs

這條流程的觸發方式最靈活:用 **Webhook** 接受 POST 請求,你可以從任何地方觸發——手機的捷徑 app、瀏覽器書籤、甚至直接用 `curl`。
<div class="steps">
<div class="step"><h4>節點 1:Webhook — 接收原始筆記</h4>
新增 **Webhook** 節點。
- **HTTP Method**:POST
- **Path**:取個好記的名稱,例如 `meeting-notes`
- **Authentication**:Header Auth(設一組 secret token 保護這個端點)
- **Response Mode**:Respond Immediately(不讓呼叫端等 AI 跑完)
n8n 會給你一個 Webhook URL,格式是:
```text
https://你的n8n網址/webhook/meeting-notes
你傳送的 JSON Body 格式設計成:
{
"meeting_title": "Q3 預算討論",
"date": "2026-07-08",
"raw_notes": "討論Q3預算,小明說先砍行銷費,阿花說不行會影響Q4,最後決定下週四再開一次,阿花帶數字,小明提替代方案"
}
```</div>
<div class="step"><h4>節點 2:AI 節點 — 產生結構化會議記錄</h4>
**System Prompt:**
```text
你是一個專業的會議記錄整理師。
請根據提供的原始筆記,產生一份結構完整的會議記錄。
輸出格式(Markdown):
## 會議摘要
(2-3 句話說明這場會議討論了什麼)
## 決議事項
(條列式,已確定的結論)
## 待辦清單
(條列式,每項格式:- [ ] 負責人:待辦內容 / 截止日期)
## 下次會議
(如有提到,填入時間與議題;沒有就填「未排定」)
## 原始筆記備份
(把原始筆記原文附在最後,供日後查閱)
語言:繁體中文。如果原始筆記資訊不足以判斷某個欄位,標注「資訊不足」。
User Message:
會議名稱:{{$json.body.meeting_title}}
日期:{{$json.body.date}}
原始筆記:
{{$json.body.raw_notes}}
```</div>
<div class="step"><h4>節點 3:Google Docs — 建立文件</h4>
n8n 的 Google Docs 節點目前(2026)支援 **Create** 和 **Get** 操作,但「建立時直接寫入內容」有限制:Create 操作只接受純文字,無法直接傳入 Markdown 格式。
**做法一:先 Create 空文件,再用 HTTP Request 節點呼叫 Docs API 插入內容(支援格式)**:
第一步,Google Docs 節點:
- **Operation**:Create
- **Title**:`{{$json.body.date}} {{$json.body.meeting_title}}`
這個節點執行後會回傳新文件的 `documentId`。
第二步,新增 **HTTP Request** 節點:
- **Method**:POST
- **URL**:`https://docs.googleapis.com/v1/documents/{{$('Google Docs').item.json.documentId}}:batchUpdate`
- **Authentication**:Generic Credential Type → Google OAuth2 API(選剛才建的 Docs credential)
- **Body (JSON)**:
```json
{
"requests": [
{
"insertText": {
"location": { "index": 1 },
"text": "{{$('AI 節點').item.json.output}}"
}
}
]
}
做法二(更快速):直接把 AI 輸出的文字寫進 Google Drive 的純文字檔案。用 Google Drive 節點 Upload 一個 .txt 或 .md 檔案到指定資料夾。格式化雖然少一點,但夠用且步驟簡單。
這堂課推薦新手先用做法二,確認流程通了,有需要再升級做法一。
節點 4:Gmail — 寄通知信附上 Docs 連結
新增 Gmail 節點。
- To:你自己的 email
- Subject:
✅ 會議記錄已存檔:{{$json.body.meeting_title}} - Message:
{{$json.body.meeting_title}} 的會議記錄已整理完成並存入 Google Docs。
📎 開啟記錄:https://docs.google.com/document/d/{{$('Google Docs').item.json.documentId}}
日期:{{$json.body.date}}
這樣每次觸發之後,你的信箱都會有一封帶 Docs 連結的確認信。
常見坑
坑 1:Error 400: redirect_uri_mismatch
OAuth 授權時出現這個錯誤,意思是「Google 那邊紀錄的 Redirect URI 和 n8n 送過來的不一樣」。十之八九是 Redirect URI 複製錯了——常見狀況是多了或少了結尾的斜線、或是 n8n 網址有大小寫差異。
解法:回到 Google Cloud Console → Credentials → 你的 OAuth 用戶端 → 把 Authorized redirect URIs 裡的值刪掉,重新到 n8n 的 credential 設定頁複製 OAuth Redirect URL(確保你複製的是 n8n 顯示的原始值,不是自己打的),貼進去存檔再試。
坑 2:過了 7 天突然所有 Google 流程全部報錯 Token has been expired or revoked
這是最常見的新手坑:建 OAuth 應用程式時忘記點 Publish App,讓 app 留在 Testing 狀態,Google 就會強制讓 token 7 天後失效。
解法很簡單:Google Cloud Console → APIs & Services → OAuth consent screen → Publishing status → 按 Publish App → 確認。發佈後不需要重新建 credential,token 在到期前還可以繼續用;如果剛好已過期,重新到 n8n credential 按 Sign in with Google 重授權一次就好。
坑 3:Google Calendar API has not been enabled
全文錯誤:Google Calendar API has not been used in project 123456789 before or it is disabled. Enable it by visiting...
這是 API 沒開啟的意思。按照錯誤訊息附的連結直接點進去開啟,或回到 Cloud Console → APIs & Services → Library 手動搜尋啟用。注意:有時候你開了 Calendar API,但忘了開 Google Drive API(Docs 節點依賴它),也會出現類似錯誤,建議這三個 API 一次全部啟用。
坑 4:AI 輸出的日期格式讓 Google Calendar 節點建立失敗
症狀:工作流程在 Google Calendar 節點報 Invalid time value 或 400 Bad Request。
根本原因:AI 沒有照你要求的 ISO 8601 格式輸出,而是輸出了「下週三下午三點」或「07/08 15:00」這種格式。
解法有兩個:
- 在 Prompt 裡加強說明並給具體範例:
datetime_start 範例:2026-07-08T15:00:00+08:00,並加一句「注意:一定要包含時區 +08:00」 - 在 AI 節點和 Calendar 節點中間加一個 Code 節點做格式驗證:
const output = JSON.parse($json.output); // AI 輸出通常是字串
const dt = new Date(output.datetime_start);
if (isNaN(dt.getTime())) {
throw new Error(`無效的日期格式:${output.datetime_start}`);
}
return [{ json: output }];
這樣格式錯誤的話整條流程會在這個節點停下並拋出清楚的錯誤訊息,不會讓壞資料繼續往下走。
坑 5:Google Docs Create 節點建了空文件,但 batchUpdate 寫入時報 403
症狀:文件建立成功,HTTP Request 打 batchUpdate 時報 403 Insufficient Permission。
原因:你建 credential 時 scope 不足。Google Docs API 需要 https://www.googleapis.com/auth/documents 這個 scope。n8n 的 Google Docs OAuth2 credential 預設會帶這個 scope,但如果你用的是 Generic OAuth2 credential 自己設定,要手動加上去。
解法:刪掉舊的 credential,重新建一個類型為 Google Docs OAuth2 API 的 credential(不是通用 OAuth2),n8n 會自動帶正確的 scope。
作業
設定 OAuth 憑證:在 Google Cloud Console 走完五步驟,建好 Google Calendar 和 Google Docs 兩個 credential,確認 Publishing status 已設為 In Production。截圖存下來備查。
跑工作流程 A:找一封真實的會議邀約信(或自己寫一封假的測試信),手動觸發測試,確認 Google Calendar 裡出現對應事件,檢查時間、地點是否正確抽取。
跑工作流程 B:把 Schedule Trigger 暫時改成「手動觸發」先測試一次,確認能讀到今日行程並收到簡報信。沒問題後再改回 Cron 排程啟用。
選做:建完工作流程 C 之後,試著從手機發一次 Webhook(可用 iPhone 的「捷徑」app 或 Android 的 HTTP Request 捷徑),把剛才某場會議的隨手筆記傳進去,看它變成一份整齊的 Google Docs。
下一課預告
第 1 到第 5 課,你已經分別解決了 Drive 歸檔、Gmail 摘要、Sheets 自動報表、以及今天的行事曆與文件。但這幾條流程現在是分開的,互不知道彼此的存在——Gmail 觸發了一個流程,Calendar 觸發了另一個,Docs 又是另一個入口。
最後一課要把這些拼在一起:設計一個個人文件自動化中樞,讓這些流程能共用資訊、互相觸發、統一呈現在一個看板上。你會學到 n8n 的 Sub-workflow(子流程)設計、流程之間如何傳遞資料,以及怎麼建一個 Dashboard 讓你一眼掌握整個自動化系統的狀態。從分散的工具變成一個有機的系統,第 6 課見。