補充課・2026-09-25 新增

先看設計歷程:這條工作流是怎麼想出來的

老師新錄了一支 13 分鐘的影片,不教按鈕,講動手之前的規劃:用軟體開發生命週期的角度,從探索、提案、規格、設計到任務清單,每一步都寫下理由和怎麼驗證。想知道為什麼節點長這樣、為什麼不用帳密、為什麼快照判斷寫成「分鐘 < 10」,先看這一頁。

→ 進入「設計歷程」補充課(含影片與投影片圖解)

第 1 節

這門課在做什麼

老師本身專攻資料庫與商業智慧,資料清洗、轉換的流程很熟,但 n8n 之前只裝好沒真的用過。這堂課的想法是:讓 AI Agent 直接幫你設定 n8n 工作流,並且自動部署和測試。拿來練手的題目,是抓臺北市 YouBike 2.0 的即時站點資料,按時間存進 Google Drive。

一句話看懂:每 10 分鐘抓一次資料 → 先檢查資料是不是好的 → 好的才存。存成兩種檔:一份永遠是最新的,另一份每小時留一張歷史快照。
檔案多久更新用途
ubike_latest.json每 10 分鐘覆蓋一次永遠是最新一份,給要看「現在狀況」的程式讀
ubike_YYYYMMDD_HH00.json每小時一份(整點那次)保留歷史,日後分析使用量變化

資料原樣保存、不改欄位。抓回來的東西如果不是合法 JSON 或是空的,這次執行就直接失敗,Drive 上原本的好檔案不會被壞資料蓋掉。

第 2 節

工作流全貌:一條主幹、兩條支線

左邊是觸發器,每 10 分鐘叫一次;中間抓資料、驗證;驗證過了分成兩條支線同時處理。

n8n 編輯器畫面:YouBike 2.0 同步到 Google Drive 工作流🔍 點圖放大
n8n 編輯器實際畫面。上排是支線 A(維護 latest 檔),下排是支線 B(整點快照)。
工作流結構圖,依節點座標排列🔍 點圖放大
講義裡的結構圖,照 n8n 畫布上的節點座標畫的。
Google Drive UbikeData 資料夾🔍 點圖放大
跑起來之後 Google Drive 的樣子。注意有兩個 ubike_20260925_0900.json,原因在第 5 節「目前的限制」。

第 3 節

十個節點,一個一個看

  1. 每 10 分鐘(Schedule Trigger)排程 */10 * * * *,每小時 0、10、20…50 分各跑一次,一天 144 次。它本身不帶資料,只是「開始」的訊號。
  2. 取得 YouBike 即時資料(HTTP Request)GET 臺北市開放資料的 youbike_immediate.json;逾時 30 秒、失敗重試 3 次、每次隔 5 秒。回應故意用「文字」接收,不讓 n8n 自動拆成上千筆,整份資料只算一筆,後面只要處理一次。
  3. 驗證並產生檔案(Code)整條流程的關卡:解析失敗或不是非空陣列就丟錯誤、整次停止;通過的話算出臺北時間、判斷是不是整點、把原始文字轉成要上傳的檔案。
  4. 搜尋 ubike_latest.json(Google Drive · Search)在指定資料夾找這個檔名,排除垃圾桶。關鍵設定 alwaysOutputData:找不到也要往下走,不然第一次執行會卡在這裡。
  5. 帶入檔案內容(Code)搜尋結果只有檔案資訊、沒有內容,所以回頭把第 3 步做好的檔案拿回來,連同找到的檔案 ID 一起往下傳。
  6. latest 已存在?(If)有檔案 ID 就走「更新」,沒有就走「建立」。
  7. 更新 ubike_latest.json(Google Drive · Update)用同一個檔案 ID 覆蓋內容。ID 不變,別的程式或分享連結永遠讀得到最新的。
  8. 建立 ubike_latest.json(Google Drive · Upload)只有第一次執行,或檔案被刪掉後,才會走到這裡。
  9. 是整點快照?(If)只有整點那次往下走,其他時間這條支線直接結束。
  10. 上傳整點快照(Google Drive · Upload)用 ubike_20260925_1400.json 這種檔名上傳,每小時新增一個,不覆蓋舊的。

第 3 步的驗證流程

驗證並產生檔案的判斷流程圖🔍 點圖放大
兩道關卡:是不是合法 JSON、是不是非空陣列。任何一關沒過就 throw,本次不寫入任何檔案。
為什麼整點判斷用「分鐘 < 10」而不是「分鐘 = 0」?排程不一定準時,n8n 忙碌或容器剛重啟時,整點那次可能拖到 00:01、00:02 才跑。只要落在整點後 10 分鐘內都算整點,快照就不會漏;排程每 10 分鐘一次,所以每小時也只會有一次落在這個區間。

第 4 節

一次執行怎麼跑

n8n 的 executionOrder: v1 規則是:分岔時先把一條支線跑到底,再跑下一條,順序看節點在畫布上的位置由上而下。支線 A 在上面,所以一定先處理 latest,再處理整點快照。

一次執行的完整時序圖🔍 點圖放大
完整時序:觸發 → 抓資料(含重試)→ 驗證 → 支線 A 搜尋與更新/建立 → 支線 B 整點上傳。

一小時內會發生什麼

14:00 到 15:00 的執行時間軸🔍 點圖放大
以 14:00–15:00 為例:只有 14:00 那次判定為整點快照,其餘五次只覆蓋 latest。
一天下來:ubike_latest.json 維持 1 個檔、被覆蓋 144 次;快照新增 24 個檔。

第 5 節

出錯怎麼辦:保護機制與目前的限制

可能的狀況保護機制結果
API 暫時沒回應或很慢逾時 30 秒、重試 3 次多數會重試成功;都失敗就本次失敗
API 回傳錯誤頁或截斷的 JSON第 3 步 JSON 解析失敗就 throw不寫入,Drive 保留上次的正確資料
API 回傳空陣列第 3 步陣列檢查不寫入
第一次執行,Drive 還沒有 latest 檔第 4 步 alwaysOutputData走「建立」分支
latest 檔被丟進垃圾桶搜尋條件排除垃圾桶視為不存在,重新建立
排程延遲幾分鐘整點判斷用分鐘 < 10快照不會漏
還沒完成 Google 授權—Drive 節點失敗:Unable to sign without access token

目前的限制(講義自己列的)

第 6 節

部署:Docker 容器+AI 在 VS Code 裡開發

部署架構圖:主機 .env、容器 n8n-ubike、Google Drive🔍 點圖放大
主機上的 .env 與工作流 JSON 在建置時放進容器;容器每次啟動都匯入並啟用工作流,首次啟動時用 .env 的值產生 Google 憑證。
項目說明
憑證Drive 節點都引用同一個 OAuth2 憑證「Google Drive (Ubike)」,容器首次啟動時由範本檔配合 .env 的 Client ID/Secret 產生
環境變數第 4、8、10 步用 $env.UBIKE_FOLDER_ID 取資料夾,換資料夾只要改 .env 再重啟
工作流更新容器每次啟動都用映像裡的 JSON 蓋掉工作流。要改流程請改 workflows/ubike-drive-sync.json 再 docker compose up -d --build;直接在 n8n 畫面上改的,下次重啟就會被蓋掉
OAuth 回呼網址http://localhost:5679/rest/oauth2-credential/callback,要和 Google Cloud Console 登記的完全一致
為什麼 JSON 裡寫 "active": false,畫面上卻是 Active?這是刻意的:檔案裡保持停用,容器啟動時由 entrypoint.sh 匯入後再執行 n8n update:workflow --active=true 開起來。所以「以 git 裡的 JSON 為正本」本來就是這套設計。
VS Code 工作區與 Claude Code 面板🔍 點圖放大
在 VS Code 工作區裡由 Claude Code 寫工作流 JSON、docker-compose、.env 範本,再一步步帶你完成 n8n owner 帳號與 Google 授權。

第 7 節

延伸練習

  1. 讓快照不重複:照支線 A 的做法,上傳快照前先搜尋同名檔,有就更新、沒有才建立。
  2. 讓 AI 直接操作 n8n:n8n 有 REST API,社群也有 n8n-mcp 這個 MCP 伺服器。Claude Code 接上 n8n 的 API 金鑰後,可以直接建立、更新、啟用工作流、讀執行紀錄,不用每次改 JSON 再重建容器。
  3. 從存檔走向分析:每小時一份約 924 KB,一年約 8 GB。要分析使用量變化,可以在同一條流程多接一個節點,把資料按「站點 × 時間」攤平寫進 PostgreSQL 或 BigQuery,這正是 BI 的主場。
  4. 省掉沒變的寫入:比對來源資料的更新時間,跟上一次一樣就跳過。
  5. 快照保留期限:加一條每天跑一次的支線,刪掉超過 N 天的快照。