iT邦幫忙

2025 iThome 鐵人賽

DAY 8
0

今天的目標與挑戰

昨天完成了 n8n 工作流程的 JSON 處理與穩定性完善,今天要先將 AI 生成的會議摘要和任務清單整合到 Notion 資料庫中。

  • 建立 GIGI 工作室的 Notion 資料庫結構
  • 設定 Notion API 整合與認證配置
  • 在 n8n 中新增 Notion 節點
  • 建立專案與會議的關聯機制
  • 實現摘要與任務自動寫入指定資料庫

Step 1:建立 Notion 資料庫結構

1.1 建立主頁面架構

先在 Notion 中建立主頁面,並設定部門結構

  1. 建立主頁面:在 Notion 中新增主頁面,並命名為「GIGI 工作室
  2. 新增部門頁面:在主頁面下建立子頁面
    • 📢 內容創意組
    • 📋 營運支援組
    • 💻 技術開發組

1.2 建立「專案」資料庫

在主頁面中建立整頁資料庫,並且命名為「GIGI 工作室專案庫

資料庫欄位設定

欄位名稱 欄位類型 建立步驟 設定說明
專案名稱 標題 (Title) 預設欄位,重新命名 資料庫主欄位
狀態 狀態 (Status) 新增屬性 → 狀態 選項:「提案中」、「規劃中」、「執行中」、「待驗收」、「已完成」
專案負責人 人員 (Person) 新增屬性 → 人員 可指派單一負責人
主責團隊 多選 (Multi-select) 新增屬性 → 多選 選項:「內容創意組」、「營運支援組」、「技術開發組」
時程 日期 (Date) 新增屬性 → 日期 啟用日期範圍,設定開始與結束日期
重要級別 選取 (Select) 新增屬性 → 選取 選項:「High」、「Medium」、「Low」
專案目標 文字 (Text) 新增屬性 → 文字 長文字模式
交付成果 文字 (Text) 新增屬性 → 文字 長文字模式
相關會議 關聯 (Relation) 新增屬性 → 關聯 稍後會設定,待會議資料庫建立完成
專案資源 檔案與媒體 (Files & media) 新增屬性 → 檔案與媒體 可上傳多個檔案

1.3 建立「會議記錄」資料庫

在子頁面「技術開發組」中建立整頁資料庫,並且命名為「會議記錄

資料庫欄位設定

欄位名稱 欄位類型 建立步驟 設定說明
會議主題 標題 (Title) 預設欄位,重新命名 資料庫主欄位
會議日期 日期 (Date) 新增屬性 → 日期 僅日期,不含時間
會議類型 多選 (Multi-select) 新增屬性 → 多選 選項:「團隊同步」、「專案討論」、「創意發想」、「決策會議」
參與夥伴 人員 (Person) 新增屬性 → 人員 可選擇多人
討論專案 關聯 (Relation) 新增屬性 → 關聯 關聯到「GIGI 工作室專案庫」
摘要狀態 狀態 (Status) 新增屬性 → 狀態 選項:「待處理」、「摘要生成中」、「已完成」
會議摘要 文字 (Text) 新增屬性 → 文字 長文字模式,AI 生成內容
重要結論 文字 (Text) 新增屬性 → 文字 長文字模式
行動任務 文字 (Text) 新增屬性 → 文字 長文字模式,AI 提取內容
任務指派 人員 (Person) 新增屬性 → 人員 可指派多人
完成期限 日期 (Date) 新增屬性 → 日期 僅日期
會議附件 檔案與媒體 (Files & media) 新增屬性 → 檔案與媒體 可上傳多個檔案
錄音檔案連結 連結 (URL) 新增屬性 → 連結 雲端錄音檔連結
建立時間 建立時間 (Created time) 新增屬性 → 建立時間 系統自動產生

1.4 設定資料庫關聯

建立雙向關聯

  1. 在「會議記錄」中,新增屬性「關聯關係」
  2. 選擇關聯資料庫:「GIGI 工作室專案庫
  3. 設定「123 限制」為「1 個頁面」(一個會議對應一個主要專案)
  4. 將雙向關聯設為「開啟」,並將「相關屬性名稱」命名為「會議記錄」

Step 2:設定 Notion API 整合與認證配置

2.1 建立 Notion Integration

  1. 前往 Notion Integrations 頁面
  2. 點擊「+ 新整合」。
  3. 填寫整合資訊
    • 整合名稱M2A Agent
    • 關聯工作空間:選擇自己的 Notion
    • 類型:內部
  4. 點擊「儲存」後,會跳出更詳細的整合頁面
  5. 確保「讀取內容」、「更新內容」和「插入內容」已勾選
  6. 記下「內部整合密鑰
    Marketplace Integration Settings

2.2 授權資料庫

剛建立的 M2A Agent 預設無法存取任何頁面,必須手動授權

  1. 分別進入「GIGI 工作室專案庫」和「會議紀錄」這兩個資料庫。
  2. 點擊右上角的三個點「...」選單,選擇「連接」。
  3. 搜尋並選擇 M2A Agent,點擊「確認」。

剛建立的 Integration 可能不會馬上出現在搜尋列表中,請多嘗試重新整理頁面 (Ctrl+R)

會議記錄資料庫連結M2A Agent
會議記錄資料庫連結M2A Agent成功


Step 3:在 n8n 中新增 Notion 節點

3.1 建立 Notion 認證

  1. 在 n8n 裡點擊左上角的加號「+」,再點擊「Credentials」。

  2. 搜尋並選擇「Notion API」。
    Add Notion credential

  3. 填寫認證資訊:

    • Credential nameM2A Agent Notion Credential
    • Internal Integration Secret:貼上剛才記下的整合密鑰
  4. 點擊「Save」儲存,儲存的同時,n8n 也會自動幫你確認連線
    M2A Agent Notion Credential Connection tested successfully

3.2 設定 Notion 節點

回到 M2A Agent工作流

  1. 在「AI 摘要與任務提取」節點後,新增一個「Notion」節點。
  2. Action 選擇 Create a database page
  3. 將節點重新命名為「寫入會議紀錄」。
  4. Credential to connect with 選擇剛建立的 M2A Agent Notion Credential
  5. Database 選擇「會議紀錄」資料庫。
  6. Title 就是會議主題的欄位:AI會議摘要 {{ new Date().toLocaleDateString('zh-TW') }}
  7. 在下面的 Properties 區塊 ,點擊「Add Property」,並使用表達式 (Expression) 將「AI 摘要與任務提取」節點的輸出,對應到 Notion 的各個欄位:
    • 會議日期: {{ new Date().toISOString().split('T')[0] }}
    • 行動任務: {{ $('AI 摘要與任務提取').item.json.summary }}
    • 其他欄位依此類推...

3.3 更新回應節點

修改「Respond to Webhook」節點的 JSON 回應

{
  "ai_processing": {
    "status": "success",
    "summary": {{ JSON.stringify($('AI 摘要與任務提取').item.json.summary) }},
    "tasks": {{ JSON.stringify($('AI 摘要與任務提取').item.json.tasks) }}
  },
  "notion_storage": {
    "status": "success",
    "message": "會議記錄已成功寫入 Notion",
    "notion_page_url": {{ JSON.stringify($json.url) }}
  }
}

Step 4:測試與驗證完整流程

4.1 準備測試資料

建立測試檔案 test_notion_integration.py

import os
from src.mcp_agent import MCPAgent

def main():
    audio_file_path = "recording/技術開發組會議錄音檔.mp3"
    webhook_url = "http://localhost:5678/webhook/m2a-test"

    if not os.path.exists(audio_file_path):
        print(f"錯誤:找不到指定的錄音檔案:{audio_file_path}")
        return

    agent = MCPAgent(model_name="medium", webhook_url=webhook_url)

    instruction = "請整理這次會議的重點,並列出所有待辦事項以及負責人與截止日期。"

    print(f"正在處理的檔案:{audio_file_path}")
    print(f"使用的指令:{instruction}")

    # 執行音訊處理
    result = agent.process_audio(audio_file_path, instruction)

    print("最終結果:", result)


if __name__ == "__main__":
    main()

4.2 執行測試

python test_notion_integration.py

4.3 驗證測試結果

成功結果

最終結果: {'ai_processing': {'status': 'success', 'summary': '這次會議主要討論了幾個項目:\n\n1. **使用者認證系統**:需要在週五前完成 JWT 的整合,確保 API 安全。\n2. ** 環境配置**:志明負責將 Flask 應用程式 Dark 化,並準備相應的配置檔案(DarkField 和 DarkCompose.yml),要求在週三前完成。\n3. **錯誤處理機制**:小美需研究並解決上次的 Timeout 問題,特別是 M8n 的錯誤處理機制。\n4. **工作流設計**:小美負責設計 M8n 的工作流,並在週四前完成可運作的 Webflow,進行團隊測試。同時,她還需開始規劃晚上的客製化規則以監環境配置**:志明負責將 Flask 應用程式 Dark 化,並準備相應的配置檔案(DarkField 和 DarkCompose.yml),要求在週三前完成。\n3. **錯誤處理機制**:小美需研究並解決上次的 Timeout 問題,特別是 M8n 的錯誤處理機制。\n4. **工作流設計**:小美負責設計 M8n 的工作流,並在週四前完成可運作的 Webflow,進行團隊測試。同時,她還需開始規劃晚上的客製化規則以監控非預期的 API 呼叫。\n5. **系統壓力測試**:志明和小美需準備並提交後端 API 和 M8n 的壓力測試腳本,並在週五下午三點前推上 GitHub。這樣可以在週末進行完整的整合測試。\n\n會 議結束時,確認沒有其他問題,並強調了各項任務的截止時間及責任分配。', 'tasks': '行動項目與待辦事項:\n\n1. **使用者認證系統**\n   - 在週五前完成 JWT 的整合,確保 API 安全 。\n   \n2. **環境配置**\n   - 志明負責將 Flask 應用程式 Dark 化,並準備相應的配置檔案(DarkField 和 DarkCompose.yml)。\n   - 要求在週三前完成。\n\n3. **錯誤處理機制**\n   - 小美需研究並解決上次的 Timeout 問題,特別是 M8n 的錯誤處理機制。\n\n4. **工作流設計**\n   - 小美負責設計 M8n 的工作流,並在週四前完成可運作的 Webflow,進行團隊測試。\n   - 同時開始規劃晚上的客製化規則以監控非預期的 API 呼叫。\n\n5. **系統壓力測試**\n   - 志明和小美需準備並提交後端 API 和 M8n 的壓力測試腳本,並在週五下午三點前推上 GitHub。\n   - 在週末進行完整的整合測試。'}, 'notion_storage': {'status': 'success', 'message': '會議記錄已成功寫入 Notion', 'notion_page_url': 'https://www.notion.so/'}}

4.4 在 Notion 中確認結果

  1. 前往「技術開發組」→「會議記錄」資料庫
  2. 確認是否有新建立的會議記錄
  3. 檢查每個欄位是否正確填入
    • ✅ 會議主題:AI會議摘要 2025/9/18
    • ✅ 會議日期:2025年09月18日
    • ✅ 摘要狀態:已完成
    • ✅ 會議摘要:包含完整的 AI 摘要內容
    • ✅ 行動任務:包含提取的任務清單
      AI會議摘要上
      AI會議摘要下

兩次關鍵失敗

我自己測試的時候,我遇到了兩個關鍵的失敗。

5.1 第一次失敗:Timeout 超時錯誤

  • 狀況:「AI 摘要與任務提取」節點報錯 "timeout of 120000ms exceeded",但是後面的 Notion 節點卻成功的寫入了這個錯誤訊息。
  • 問題分析:本地端的 LM Studio 模型處理需要時間,超過了 n8n Code 節點預設的 120 秒等待上限,所以 Code 節點就不等了,直接進入 catch 區塊回傳錯誤,後面的節點也算是成功接收了這個「錯誤的資訊」。
  • 解決方案:在「AI 摘要與任務提取」節點裡面的兩個「AI 摘要」與「任務提取」,將 n8n 原生的 this.helpers.httpRequest() 輔助函式裡面的 timeout 參數,將其延長為 5 分鐘也就是300,000 毫秒,給 AI 模型足夠的思考時間。
const response = await this.helpers.httpRequest({
  method: 'POST',
  url: 'http://host.docker.internal:1234/v1/chat/completions',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(taskPayload),
  timeout: 300000
});

5.2 第二次失敗:Invalid JSON 錯誤

我自己的測試裡,我有加一個「Notion寫入結果驗證」的 Code 節點。

  • 狀況:延長 Timeout 後,Notion 成功寫入正確內容,但是最後的「Respond to Webhook」節點卻報 "Invalid JSON in 'Response Body' field" 的錯誤。同時 VS Code 的測試腳本也報 Expecting value: line 1 column 1 (char 0) 的錯誤。
  • 問題分析:這是典型的「同步等待」問題。整個流程(包含耗時 4-5 分鐘的 AI 處理)執行時間太長,Python 測試腳本等不及,因此主動斷開了連線。當流程跑到 n8n 的 Respond to Webhook 節點終於要回應時,發現連線已經斷掉了,因此報錯。
  • 解決方案:簡化工作流程和「Respond to Webhook」的 JSON 內容。
  1. 刪除中間用來驗證的 Notion寫入結果驗證 Code 節點。
  2. 將「寫入會議紀錄」節點直接連接到「Respond to Webhook」節點。
  3. 修改「Respond to Webhook」的 Response Body,只回傳必要的資訊。

修改後的 Response Body 表達式

{
  "ai_processing": {
    "status": "success",
    "summary": {{ JSON.stringify($('AI 摘要與任務提取').item.json.summary) }},
    "tasks": {{ JSON.stringify($('AI 摘要與任務提取').item.json.tasks) }}
  },
  "notion_storage": {
    "status": "success",
    "message": "會議記錄已成功寫入 Notion",
    "notion_page_url": {{ JSON.stringify($json.url) }}
  }
}

今天的成果總結

完成項目

  • 成功建立 GIGI 工作室的 Notion 資料庫架構
  • 設定完整的 Notion API 整合與認證機制
  • 在 n8n 工作流中新增 Notion 節點並完成設定
  • 實現 AI 摘要與任務的自動化資料庫寫入
  • 建立雙向關聯機制,連結專案與會議記錄
  • 完成端到端的整合測試與驗證

心得

今天 Notion API 的整合讓我學會了如何處理外部服務的認證與權限管理,還有在面對 Timeout 超時與 Invalid JSON 錯誤時,我意識到區分「客戶端等待超時」和「服務端處理超時」的重要性。

透過調整 HTTP Request 的 timeout 參數和最佳化 Respond to Webhook 的資料來源,我也學會了如何在同步模式下,建構一個能處理長時間任務且穩定的工作流程。

🎯 明天計劃

建立通知系統整合,讓團隊成員在會議摘要完成時能即時收到 LINE 的通知。


上一篇
Day 7 n8n 工作流 JSON 處理與穩定性完善
系列文
打造基於 MCP 協議與 n8n 工作流的會議處理 Agent8
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言