跳到主要內容

部落格

不定期分享最新資訊文章

  • article-Zeabur 停止營運後,n8n 搬去哪?Railway、Coolify 費用與搬遷教學

    2026/10/19

    AI自動化 n8n 雲端部署
    Zeabur 停止營運後,n8n 搬去哪?Railway、Coolify 費用與搬遷教學

    原本穩定運作的 n8n 自動化,突然遇到部署平台宣布停止營運,接下來該怎麼辦? 我原本把 n8n 部署在 Zeabur,用它串接 LINE 官方帳號、Google 服務、Webhook 和 AI 工作流程。真正讓人擔心的,不只是重新部署 n8n,而是工作流程、Credentials、資料庫和加密金鑰能不能完整搬走。 我整理了兩個方向:**Railway 適合先把服務快速搬起來;Coolify 搭配 VPS,適合願意自行管理伺服器、也準備部署更多服務的人。**本文包含費用參考、備份清單和切換步驟。這是一份搬遷規劃與教學整理,並不表示我已完成 Railway 或 Coolify 的實際遷移驗證。 Zeabur 什麼時候停止營運?Zeabur 在 2026 年 10 月 17 日公告將逐步結束平台營運。官方也說明,2026 年 10 月 14 日發生內部系統及部分客戶服務遭外部人士入侵的資安事件,調查與後續報告仍在進行。 時程 官方公告的安排 2026 年 10 月 17 日起 停止新購專用伺服器與網域,開始受理帳戶餘額退款等申請 2026 年 12 月 1 日起 共享叢集服務暫停;專用伺服器停止續費 2026 年 12 月 1 日至 31 日 專用伺服器依個別到期日陸續關閉 2026 年 12 月 31 日 所有專用伺服器和共享叢集停止服務 **12 月 31 日是全部服務停止的最後日期,不代表每一個服務都能運作到那一天。**共享叢集自 12 月 1 日起會暫停運作,但公告表示使用者仍可手動恢復服務以備份資料;專用伺服器則要依自己的到期日安排。資料刪除日期、最晚匯出期限和 Support 停止服務日期仍待另行公告。建議先確認自己使用的服務類型與到期日,盡早做一份獨立備份。 完整時程以 Zeabur 停止營運公告 為準。 Railway 和 Coolify,哪一種比較適合搬 n8n?兩者都能部署 n8n,但你要負責的事情不一樣。 項目 Railway Coolify + VPS 服務型態 雲端應用平台,提供部署、網域、Volume 和用量介面 自架部署管理平台,安裝在自己租用或管理的伺服器上 主機維護 平台處理較多底層工作 自己處理作業系統、Coolify、網路和安全更新 費用模式 方案最低費用加上資源用量 Coolify 自架軟體免平台授權費,另付 VPS、備份和儲存費 比較適合 想先恢復單套 n8n、降低伺服器管理工作 想在同一台 VPS 管理多個網站、資料庫或自動化服務 主要取捨 用量上升時帳單也會變動 主機可自行管理,但維護和故障排查責任較多 Railway 有新加坡部署區域,對台灣使用者可以列入考慮;Coolify 的連線品質則會跟你選的 VPS 機房有關。Railway 官方有 n8n 部署指南,Coolify 官方列出 SQLite、PostgreSQL,以及 PostgreSQL 加 Worker 的 n8n 部署方式,見 Coolify 的 n8n 文件。 如果現在最重要的是縮短停機時間,先選熟悉度較高、能快速驗證的方案。只有一套 n8n 時,Railway 通常比較省管理工;如果平常就會管理 Linux、Docker 和備份,而且還要部署其他服務,Coolify 才比較容易發揮主機共享的彈性。哪個方案比較便宜,要連同實際用量、備份和維護時間一起比較。 Railway 和 Coolify 每月大約多少錢?以下列出 2026 年 10 月 19 日查到的官方價格,金額以美元計;方案、費率、稅金和地區供應可能調整,開通前請再看服務商的最新帳單說明。 Railway:US$5 是最低月費,不是固定上限Railway Hobby 每月最低 US$5,這筆費用包含 US$5 的資源用量額度。若當月資源使用 US$3,仍支付 US$5;若使用 US$8,總額約為 US$8。超過額度後,CPU、記憶體、Volume 儲存和網路傳輸都會影響帳單。 資源 Railway 公布的費率 RAM US$10/GB/月 CPU US$20/vCPU/月 Volume 儲存 US$0.15/GB/月 對外流量 US$0.05/GB 這些費率是按實際使用量計費,不代表服務設定了多少上限就一定會用滿。n8n 長時間開機時,記憶體與持久化儲存都會持續影響費用;Workflow 執行量、AI 節點、檔案處理和對外流量則會讓 CPU 或流量成本增加。Railway 建議先部署並觀察一段時間,再從 Workspace 的用量頁估算帳單。更多細節見 Railway 方案與價格 和 官方定價頁。 Coolify:軟體免費,主機和備份仍需付費Coolify 自架版不用支付平台授權費,但 VPS、公開 IPv4、主機備份、額外儲存和異地備份仍會產生成本。以下用歐洲 Hetzner Cloud 與 DigitalOcean 的公開價格作示例,並把主機備份計入試算: 方案示例 主機費 IPv4/每日備份 約計月費 Hetzner CX23 US$6.49 IPv4 US$0.60、主機備份約 US$1.30 約 US$8.39 Hetzner CX33 US$9.99 IPv4 US$0.60、主機備份約 US$2.00 約 US$12.59 DigitalOcean Basic Droplet,4GB RAM/2 vCPU US$24.00 每日 Droplet 備份約 US$7.20 約 US$31.20 Hetzner 兩個價格是德國/芬蘭區域、未含 VAT、未含 IPv4 的月價;備份費以該主機月價的 20% 計。DigitalOcean 每日 Droplet 備份按 Droplet 費用的 30% 計算。費用只供初步比較,沒有包含獨立異地備份、網域、額外磁碟、超額流量、可能的稅金,以及自行維護所花的時間。來源可查看 Hetzner 2026 年價格調整、Hetzner IPv4 價格、Hetzner 雲端備份費用說明 和 DigitalOcean Droplet 價格。 Coolify 官方建議執行它的伺服器至少有 2 個 CPU 核心、2GB RAM 和 10GB 可用磁碟;這是 Coolify 本身的最低需求,不等於同一台主機也執行 n8n、PostgreSQL 和其他服務時一定足夠。請按實際負載留出資源,並監測磁碟和記憶體。完整條件見 Coolify 自架指南。 搬家之前,先備份這四類資料只匯出 Workflow JSON 不等於完成 n8n 系統備份。搬遷前先盤點資料庫類型、n8n 版本、Volume 掛載、網域、環境變數名稱、自訂節點,以及是否有外部檔案儲存。 1. 匯出 Workflow 和 Credentials可以在 n8n 介面逐一匯出重要 Workflow;若有服務 Terminal,也可使用 CLI 批次匯出: 12n8n export:workflow --backup --output=/home/node/.n8n/migration/workflows/n8n export:credentials --backup --output=/home/node/.n8n/migration/credentials/ --backup 會分別輸出 Workflow 和 Credentials。這份匯出不包含使用者、執行紀錄、Variables、整個 n8n 設定或加密金鑰,因此不能取代完整備份。Credentials 和其匯出檔都要當成機密資料保存,不可上傳到公開 GitHub 或貼在公開討論區。 2. 備份 SQLite 或 PostgreSQL先確認目前使用哪種資料庫。若環境變數有 DB_TYPE=postgresdb 或 DB_POSTGRESDB_HOST,通常代表使用 PostgreSQL;如果沒有另外設定,可能是預設 SQLite,仍要透過服務設定和實際檔案確認。 **SQLite:**先停止 n8n 的寫入,再備份 .n8n 持久化目錄。n8n 官方提醒,n8n 正在寫入時直接複製 SQLite 資料庫,備份可能不一致。Zeabur 的離線備份只涵蓋服務掛載的持久化 Volume;備份前要確認 .n8n 確實在該 Volume 中,備份完成再下載並確認檔案可讀。 **PostgreSQL:**備份資料庫,也要另外保存 n8n 的 .n8n 目錄。Zeabur 官方文件說 PostgreSQL 備份使用 pg_dumpall 並輸出標準 .sql 格式;這種 SQL 備份應依格式使用 psql 還原,不能把所有 .sql 檔都當成 pg_restore 使用的 custom archive。若另外使用 pg_dump 匯出單一資料庫,先確認輸出格式,再選擇相符的還原工具,並處理資料庫角色及權限差異。 Zeabur 文件也說明,備份保留 7 天;需要長期留存時要自行下載到 Zeabur 以外的位置。操作方式與格式可查閱 Zeabur 備份文件。 3. 保存原本的加密金鑰n8n 的 Credentials 以原本的加密金鑰加密。金鑰可能在 .n8n/config,也可能由 N8N_ENCRYPTION_KEY 提供。還原到新環境時必須沿用原本的金鑰;如果資料庫搬過去卻使用新的金鑰,既有 Credentials 可能無法解密。不要為了搬遷任意更換這個金鑰。 n8n 官方完整備份說明指出,SQLite 需要 .n8n 資料夾;PostgreSQL 則需要資料庫備份和 .n8n 資料夾。若使用外部 S3 等二進位檔案儲存、自訂檔案路徑或自訂節點,也要另外備份。詳細內容見 n8n 備份與還原文件。 4. 留一份可實際還原的備份下載完成不代表還原一定成功。建議至少保留兩份備份,其中一份放在 Zeabur 以外的安全位置;以測試環境確認 Workflow 可以載入、Credentials 可以解密、資料庫可連線,再進行正式切換。備份檔及金鑰不要放在公開 Git 儲存庫。 若想先熟悉舊環境的部署方式,可以參考站內的 n8n 部署到 Zeabur 教學;LINE Webhook 的檢查方式也可參考 n8n 串接 LINE Bot Webhook。 如何把 n8n 搬到 Railway?Railway 的官方指南提供 n8n Docker Image 和一鍵範本兩種方式。搬遷時先沿用原本的 n8n 版本和資料庫類型,讓「換平台、升級 n8n、切換資料庫」不要同時發生;確認服務運作後,再另外安排升級。 1. 建立服務和持久化 Volume建立 Railway Project,選擇接近使用者的區域;Railway 有 Singapore 的 Southeast Asia Metal 區域。建立 n8n 服務時可用官方範本,或從 Docker Image 部署 n8nio/n8n。 n8n 預設將資料放在 /home/node/.n8n。建立 Volume 並掛載到這個路徑,否則重新部署後,SQLite 資料庫或本機設定可能不會保留。若使用 PostgreSQL,資料庫也需要自己的持久化與備份規劃。 2. 設定網域、時間與 Webhook依 Railway 導引設定服務連接埠與公開網址。常見設定如下,實際值依你的網域與 n8n 版本調整: 環境變數 設定方向 N8N_PORT Railway 官方 n8n 指南使用 ${{PORT}} N8N_PROTOCOL 公開 HTTPS 網站使用 https N8N_WEBHOOK_URL 設為完整的公開網址,例如 https://n8n.example.com/ GENERIC_TIMEZONE、TZ 例如 Asia/Taipei,並確認排程時區 N8N_EDITOR_BASE_URL 若有自訂網域,設為編輯器網址 N8N_ENCRYPTION_KEY 使用原本的值,透過平台安全的 Secret/Variables 欄位設定 反向代理層數要依實際網路架構判斷,只有符合 n8n 的代理設定情境時才設定 N8N_PROXY_HOPS。n8n 官方文件標示,從 2.35.0 起 WEBHOOK_URL 已棄用,改用 N8N_WEBHOOK_URL;舊名稱目前仍是別名,但會出現棄用提醒。Railway 指南仍列出 WEBHOOK_URL 範例,部署時請以正在使用的 n8n 版本和 n8n 官方文件為準。 如果原本使用 PostgreSQL,在新服務設定 DB_TYPE=postgresdb 和對應資料庫連線變數;恢復資料庫後仍要保留 /home/node/.n8n,其中可能存有加密金鑰和其他本機資料。Railway 的 Docker Image、Volume 與變數範例見 Railway n8n 部署指南,n8n 的 Webhook 變數說明見 n8n Endpoints 環境變數文件。 3. 還原後先在測試環境驗證SQLite 和 SQLite 搬遷時,確認 n8n 已停止寫入,再將原本 .n8n 資料還原到 Volume;PostgreSQL 則先建立目標資料庫,再依備份格式匯入,並確認使用原本的加密金鑰。不要把 SQLite 備份檔直接當成 PostgreSQL 備份匯入。 先用新網址登入,檢查 Workflow、Credentials、使用者和自訂節點。建立少量測試 Workflow 確認觸發和輸出正常,最後再處理正式 Webhook 與排程切換。 Railway Volume 可建立手動或排程備份,但官方說明指出,Volume 備份只能還原到同一個 Project 和 Environment。它適合平台內復原,不能取代下載到其他平台的獨立備份。參考 Railway Volume 備份說明。 如何在 VPS 上安裝 Coolify 並部署 n8n?Coolify 是自架的部署管理工具,並不附送 VPS。你要先租用 Linux 主機,再維護作業系統、Coolify、網路、資料庫和備份。Coolify 官方建議自架管理主機至少具備 2 個 CPU 核心、2GB RAM 和 10GB 磁碟;如果同機執行 n8n 和 PostgreSQL,應依實際負載預留更多資源。 1. 準備 VPS 和 Coolify選擇有 SSH 權限的 VPS,確認機房、規格和備份價格。Coolify 官方提供自動安裝方式,執行前請從 Coolify 官方安裝文件 核對主機需求和最新指令;該文件的安裝範例如下: 1curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash 安裝後盡快建立管理員帳號,限制管理介面的公開存取,並備份 /data/coolify/source/.env。這個檔案含有復原 Coolify 所需的重要秘密值,不要提交到 Git 或貼到公開頁面。防火牆只開放服務實際需要的連接埠;n8n 的內部連接埠和 PostgreSQL 5432 通常不應直接暴露到公網。 2. 選擇 n8n 部署組合Coolify 的 n8n 文件列出三種常見組合:n8n + SQLite 適合簡單或測試用途;n8n + PostgreSQL 適合需要獨立資料庫的正式服務;n8n + PostgreSQL + Redis + Worker 則增加佇列和並行執行元件。服務越多,資源、監控和還原流程也越複雜,不需要一開始就採用 Worker 組合。 綁定自己的網域並啟用 HTTPS 後,還原原本的 .n8n 與資料庫。搬遷前後都沿用同一個 Encryption Key,並逐一確認環境變數名稱和檔案掛載位置。Coolify 的 PostgreSQL 備份可以排程,也可上傳到 S3 相容儲存;但 Coolify 平台自身的備份與應用程式、資料庫、Volume 的備份是不同項目,請分開設計。官方資料可參考 Coolify 資料庫備份 和 Coolify 執行個體備份。 Webhook 和排程切換,怎麼避免重複執行?n8n 換了網域後,LINE 官方帳號、表單服務、網站和其他外部平台可能仍呼叫舊的 Webhook URL。請逐一更新來源平台的 Webhook 網址和 OAuth Callback/Redirect URI。 若有串 LINE 官方帳號,可到 LINE Developers Console 更新 Webhook URL,先按 Verify,再實際傳送一則訊息,檢查 n8n 是否收到事件並正常回覆。**Verify 成功只代表驗證請求能到達端點,不能代替完整 Workflow 測試。**Google OAuth、Gmail、Google Calendar 等整合也要檢查重新導向網址和授權狀態。 切換正式排程時,不要讓新舊 n8n 同時執行相同的正式 Workflow,否則可能重複寄信、寫入資料或回覆 LINE。可以照以下順序操作: 先在新環境用測試資料驗證 Workflow 和 Credentials。 暫停舊環境的正式排程,等待進行中的執行結束。 做一次最後備份,將最後變更同步到新環境。 更新 Webhook、OAuth Callback 和 DNS 等外部設定。 啟用新環境的正式 Workflow,送出真實但可控的測試事件。 觀察執行紀錄和外部回應,再依備份政策處理舊環境。 搬遷時要一起檢查哪些資安設定?這次搬家也是重新盤點憑證與備份的時機。平台帳號和 n8n 管理員帳號使用強密碼並啟用 MFA;備份存放在受控位置,保留異地副本並定期測試還原。API Key、OAuth Client Secret 或資料庫密碼若可能受到資安事件影響,請依服務商建議和憑證用途逐一輪替。 **不要把 n8n 的 Encryption Key 當成一般 API Key 隨意更換。**它用來解密資料庫中已儲存的 Credentials。搬遷時要先帶著原金鑰完成還原;若日後要更換,應先查閱 n8n 官方支援的作法,並確認有可還原的完整備份。 不要把包含 Credentials、Encryption Key、Coolify .env 或資料庫密碼的檔案放進公開 GitHub。Workflow 和設定範本若需版本管理,先移除秘密值,使用平台提供的 Secret 管理功能保存真實憑證。 我會怎麼選?如果目標是先讓一套 n8n 盡快恢復,我會先評估 Railway:部署入口較直接,有新加坡區域,費用可以從使用量開始觀察。Hobby 的 US$5 是最低月費和包含的用量額度,不是無上限的固定價。 如果你已經會管理 Linux 和 Docker,也有多個網站、資料庫或自動化服務要集中管理,再評估 Coolify + VPS。Coolify 軟體自架免費,但主機、備份、異地儲存、資安更新和故障排除都由自己負責;把這些時間也算進總成本,才看得出是否真的划算。 我會分成三階段處理:先完成安全備份和測試還原;再用熟悉的平台恢復正式流程;最後把環境變數範本、備份清單、Webhook 更新和還原步驟整理成 SOP。這樣下一次更換平台時,搬遷就不必從頭猜一次。 常見問答 (FAQ)Q1:只匯出 n8n Workflow JSON,可以完整搬家嗎?不行。完整搬遷還要依資料庫類型備份 SQLite 或 PostgreSQL、保存原本的 Encryption Key,並檢查 .n8n 目錄、自訂節點和外部檔案儲存。CLI 匯出主要是 Workflow 和 Credentials,不包含完整執行紀錄與所有系統設定。 Q2:Railway Hobby 每月只要 US$5 嗎?US$5 是 Railway Hobby 的最低月費,並包含 US$5 的資源用量額度。若實際用量超過額度,帳單會隨 CPU、記憶體、Volume 和流量增加;部署後應查看用量頁,不要把最低費用當成固定上限。 Q3:Coolify 一定比 Railway 便宜嗎?不一定。Coolify 自架軟體免平台授權費,但 VPS、IP、備份、異地儲存、維護時間和故障處理都要納入。只有一套 n8n 時,Railway 省下的管理工可能更有價值;多個服務共用主機時,Coolify 才可能降低整體單位成本。 Q4:搬遷時可以讓新舊 n8n 同時運作嗎?可以在測試期間讓新環境保持未啟用正式排程,但不要讓兩邊同時執行相同的正式 Workflow。正式切換前先暫停舊排程、等待執行完成、做最後備份,再更新 Webhook 並啟用新環境,避免重複寄信或處理資料。 Q5:如果現在無法登入 Zeabur,資料是不是就救不回來?不一定。請先查看 Zeabur 官方公告並聯絡 Zeabur Support,詢問服務狀態、可用的備份和資料匯出方式。公告指出共享叢集服務暫停後仍可手動恢復以備份資料;是否能存取個別服務,則要以當下狀況和官方支援回覆為準。 官方參考資料 Zeabur 停止營運公告 Zeabur 備份文件 Railway 方案與價格 Railway n8n 部署指南 Railway 部署區域 Railway Volume 備份 n8n 備份與還原 n8n Webhook 環境變數 Coolify 自架指南 Coolify n8n 部署文件 Coolify 資料庫備份 Coolify 執行個體備份 Hetzner 2026 年價格調整 Hetzner IPv4 價格 Hetzner 雲端備份費用說明 DigitalOcean Droplet 價格 DigitalOcean 備份價格 本文整理日期:2026 年 10 月 19 日。平台時程、價格、功能與介面可能調整,請以官方最新資料為準。本文是搬遷規劃與教學整理,並未宣稱已完成實際搬遷。 #n8n #Zeabur #Railway #Coolify #AI自動化 #雲端部署 #VibeCoding

  • article-n8n 自架版 AI Assistant:One-line setup、Sandbox 與 Zeabur 架構

    2026/8/26

    AI自動化 n8n n8n新手教學
    n8n 自架版 AI Assistant:One-line setup、Sandbox 與 Zeabur 架構

    如果你跟我一樣是自己架 n8n,最近這個更新很值得注意。 n8n 官方社群公告指出,從 n8n 2.35 開始,Self-hosted AI Assistant 的設定流程變得簡單許多。以前要自己開啟相關模組、準備 Sandbox、設定模型,再視需要接上 Web Search;現在新的 Docker-based n8n instance 可以透過 One-line setup 預先建立 Sandbox、SearXNG 與 AI Assistant,最後再由你在 UI 中連接模型提供者。 不過,這次更新真正重要的地方,不只是「安裝變簡單」。 它讓 n8n 的使用方式開始從: 我自己拖 Node、寫 Expression、測試 Workflow。 慢慢走向: 我先把需求描述清楚,再讓 AI 協助我建構 Workflow。 官方目前仍將 Self-hosted AI Assistant 標示為 preview,功能與行為可能持續變動。本文因此會把版本與環境變數視為「目前文件的設定方式」,正式環境升級前仍要重新確認官方說明、備份與資料邊界。 先說結論:One-line setup 解決快速開始,不等於完成 Production 架構新的 One-line setup 適合: 第一次在本機學習 n8n。 想快速測試 AI Assistant 的 Workflow Builder。 想做 Demo 或驗證自動化想法。 不想一開始就手寫完整的 Docker Compose。 它不會替你完成所有事情。Docker 仍然要先安裝並啟動,模型 API 金鑰仍然要自己準備;SQLite、HTTPS、備份、權限與 Sandbox 隔離,也要按照正式環境需求重新設計。 可以先用這張表定位自己的路線: 你的情境 先選哪一條路線 判斷重點 新環境、本機測試或短期 Demo One-line setup + n8n-sandbox 先快速驗證 AI Workflow Builder。 已有 Zeabur + n8n + PostgreSQL + task-runner 保留既有服務,Sandbox 評估 Daytona 不必為了 AI Assistant 重建整套正式環境。 資料不能離開指定基礎設施 自架 n8n-sandbox,或暫不啟用 Builder 先確認 privileged Runner、資料政策與隔離邊界。 如果你已經有一套正在運作的 Zeabur + n8n + PostgreSQL 架構,也不需要為了 AI Assistant 直接打掉重來。比較合理的做法是先理解既有元件的責任,再決定要把 Sandbox 放在哪裡。 AI Assistant 不是 AI Agent Node:先分清楚兩個層次這兩個名字很像,但負責的工作不同。 AI Agent Node:工作流裡的一個節點以前我們在 n8n 裡使用 AI,通常會把 AI Agent 拉進 Workflow: 123456789Webhook ↓AI Agent ↓OpenAI / Claude / Gemini ↓Google Sheets ↓LINE 這裡的 AI Agent 是 Workflow 裡的一個處理步驟。它可以理解輸入、呼叫工具、查詢資料,再把結果傳給下一個 Node。 AI Assistant:幫你製作 Workflow 的助手AI Assistant 位於另一個層次。它不是你最後交付給使用者的 Workflow,而是協助你規劃、建立與修正 Workflow 的建構助手。 你可以這樣描述需求: 幫我建立一個 LINE 預約系統。收到 LINE Webhook 後判斷使用者操作;如果使用者要預約,就讀取 Google Calendar 的可預約時段,再產生 LINE Flex Message;預約成功後,把資料寫進 Google Sheets。 以前你可能要自己完成: 123456789找 Node ↓設定 Credential ↓寫 Expression ↓查 API 文件 ↓測試與除錯 AI Assistant 想協助的是: 12345678910111213理解需求 ↓規劃 Workflow ↓產生 Workflow 程式碼 ↓在 Sandbox 中編譯與測試 ↓修正錯誤 ↓產生有效的 Workflow JSON ↓儲存到 n8n 所以 n8n 的學習重點,會逐漸從「我知道每個 Node 在哪裡」延伸到「我能不能把需求、資料結構與限制描述清楚」。 如果你想先理解 LLM 與 AI Agent Node 的選擇差異,也可以延伸閱讀 何時該用 LLM?何時該派 AI Agent 上場?。 Self-hosted AI Assistant 其實由三個部分組成可以先用這個架構理解: 123456789101112 ┌─ OpenAI ├─ Anthropic你 → n8n AI Assistant ─ OpenRouter └─ OpenAI-compatible API │ ├──────── Web Search │ ├─ Brave Search │ └─ SearXNG │ └──────── Sandbox ├─ n8n-sandbox └─ Daytona 1. Model Provider:AI 的大腦你仍然要自行選擇模型提供者並準備 API Key,例如: Anthropic。 OpenAI。 OpenRouter。 其他 OpenAI-compatible API。 n8n 不會附送模型,也不會替你支付模型使用費。One-line setup 做的是準備 AI Assistant 所需的執行環境;模型連線與費用仍然由你的模型提供者決定。 2. Sandbox:AI 的隔離工作區AI Assistant 的 Workflow Builder 不是只回傳一段文字。它可能需要建立檔案、寫入 TypeScript、執行編譯器、安裝套件、執行程式,再根據錯誤反覆修正。 這些工作不應直接在正式 n8n Host 上執行,因此需要一個專用 Sandbox: 123456789AI Assistant ↓寫入 workflow.ts ↓TypeScript type-check ↓執行並產生 Workflow JSON ↓驗證成功後才交回 n8n 如果沒有可用的 Sandbox,Workflow Builder 的能力就無法完整使用。要注意的是,Sandbox 提供的是程式碼執行隔離,不等於自動完成權限控管、資料遮罩或人工作業確認。 3. Web Search:讓 AI 查得到最新資料如果你要求 AI 協助串接最新 API,它可能需要查詢官方文件、Endpoint、Authentication 或 Request Format。Web Search 就是提供這一層能力。 依照 n8n 目前的 Instance AI 設定文件,搜尋提供者的優先順序是: 12345Brave API Key ↓ 沒有SearXNG URL ↓ 都沒有Web Search disabled 沒有 Search Provider 時,fetch-url 仍可能可以使用,但 AI Assistant 不會具備主動 Web Search 能力。若希望搜尋也留在自己的基礎設施,可以考慮在同一個網路環境部署 SearXNG;若追求較少維護元件,則可評估 Brave Search。 新環境:One-line setup 會幫你準備什麼?執行前先準備 DockerOne-line setup 不會替你安裝 Docker。先確認 Docker Engine 或 Docker Desktop 已啟動,而且 Docker Compose v2 可以使用: 1docker compose version Windows 使用者若要依照 POSIX shell 流程執行,建議使用 Docker Desktop 搭配 WSL2,並在 WSL Terminal 中操作。不同平台與 Docker 版本仍應以官方文件的當期說明為準。 官方快速指令在準備好的目錄執行: 1curl -fsSL https://get.n8n.io | sh 它不是「免安裝 Docker」,而是把原本要自己撰寫與組合的 Docker Compose 設定、資料卷、Sandbox 與 Web Search 服務整理成較容易開始的流程。完成後通常可以從以下位置開啟 n8n: 1http://localhost:5678 One-line setup 背後的服務官方 Docker Compose 文件中的主要元件包括: 12345n8n├── sandbox-certs├── sandbox-api├── sandbox-runner-1└── searxng n8n:Workflow Editor 與主要應用程式。 sandbox-certs:產生 Sandbox 服務需要的 TLS 憑證。 sandbox-api:n8n 與 Sandbox 溝通的控制層。 sandbox-runner-1:建立與執行 Sandbox 的 Runner。 searxng:AI Assistant 的 Web Search 後端。 這個快速架構預設沒有另外建立 PostgreSQL 服務,測試環境通常會使用 SQLite。若要長期承載團隊或企業工作流,資料庫、備份與復原策略要另外規劃。 遠端腳本不要盲目直接執行curl ... | sh 很方便,但它也代表把遠端下載的內容直接交給 shell。即使來源是官方,重要主機仍可先下載、閱讀,再執行: 123curl -fsSL https://get.n8n.io -o get-n8n.shless get-n8n.shsh get-n8n.sh 正式環境還要確認目前目錄、資料卷、備份與更新策略,不要把測試環境的指令直接套到含有重要資料的主機。 既有 n8n:不要為了 AI Assistant 直接重建整套環境如果你已經使用 Docker 或 Zeabur 部署 n8n,建議採取漸進式流程: 123456789101112131415備份 Workflow、Credentials 與資料庫 ↓確認目前 n8n 版本與升級相容性 ↓升級到支援 AI Assistant 的版本 ↓確認原有 Workflow 正常 ↓設定 Model Provider ↓選擇 Sandbox Provider ↓選擇 Brave Search 或 SearXNG ↓用測試 Workflow 驗證 AI Assistant 官方公告將 n8n 2.35 或更新版本列為 Self-hosted AI Assistant 的前提之一,但版本與設定仍會更新。不要只因為看到一個新的功能,就直接替換正在服務中的 n8n;先確認資料庫、Encryption Key、Webhook、Credentials 與現有 Workflow 都能復原。 Sandbox 有兩種路線:n8n-sandbox 或 Daytona這是整篇最容易被忽略、但最值得先做決策的部分。 方案一:n8n-sandboxn8n-sandbox 是由你自己管理的 Sandbox 服務。以 Docker Compose 部署時,n8n、Sandbox API、Runner 與 SearXNG 可以放在同一套基礎設施中: 1234567自己的 VPS 或 Docker Host│├── n8n├── PostgreSQL├── SearXNG├── sandbox-api└── sandbox-runner-1 它的優點是控制權高,資料與執行環境可以盡量留在自己的 Infrastructure,適合: 本機開發。 課程 Demo。 測試 AI Workflow Builder。 有能力維護 Docker-in-Docker 的自架環境。 公司政策要求資料不能離開指定基礎設施。 但要注意,官方 Compose 中的 sandbox-runner-1 使用 privileged: true,而且透過 Docker-in-Docker 建立與執行其他 Sandbox Container。這不是一般的 PostgreSQL 或 n8n Container;官方文件也提醒不要把 Runner 的連接埠暴露到 Internet,並應將它視為高權限元件。 官方文件目前以至少 4 GB RAM、2 vCPU 作為這套 Compose Sandbox 的起始資源參考。實際需求仍會受到同時執行的 Workflow、模型與 Sandbox 工作量影響,不能把它當成所有 Production 環境的保證規格。 方案二:DaytonaDaytona 是另一個 Sandbox Provider。架構會變成: 1234567891011你的 n8n Host│├── n8n├── PostgreSQL└── Web Search │ │ API ↓ Daytona │ └── AI Sandbox Container n8n 透過 Daytona API 建立或管理隔離的 Sandbox,AI Assistant 在其中寫檔案、執行 TypeScript、檢查錯誤,再把通過驗證的 Workflow 交回 n8n。這樣 AI 建構程式碼的執行環境就不必與正式 n8n Host 共用同一個 Docker-in-Docker Runner。 Daytona 的代價是增加第三方服務依賴、API Key、使用量與費用。更重要的是,AI Assistant 建構過程所需的檔案與資料可能進入外部 Sandbox;如果你的流程包含高度機敏企業資料、金融資料或特殊個資,必須先做資料邊界與供應商政策審查。 兩種 Sandbox 怎麼選? 使用情境 建議與理由 個人電腦測試、課程或短期 Demo 選 n8n-sandbox,先用 Docker Compose 快速重現環境。 完全 Self-hosted、資料希望留在自己的基礎設施 選 n8n-sandbox,但要接受 privileged Docker-in-Docker Runner 的維運與安全責任。 已有正式 n8n、希望降低維運 評估 Daytona,避免自行維護高權限 Sandbox Runner。 Zeabur 上的既有 n8n 保留 n8n、PostgreSQL 與 task-runner,Sandbox 優先評估 Daytona。 資料不得離開指定環境 先以資料政策與隔離要求為前提,評估自架 n8n-sandbox 或暫不啟用 Builder。 Self-hosted 不代表「所有東西都一定要塞在同一台 Server」。比較成熟的判斷方式是:哪些核心資料與自動化服務值得自己管理,哪些短生命週期的 AI 執行環境可以交給專門的 Sandbox Provider。 Zeabur + n8n + PostgreSQL + task-runner:我會怎麼選?如果你的現有架構是: 12345Zeabur Project│├── PostgreSQL├── task-runner└── n8n 我會先保留這套核心環境,讓 AI Assistant 的 Sandbox 走 Daytona: 12345678910Zeabur│├── PostgreSQL├── task-runner├── n8n└── SearXNG(可選) │ └──────── API ──────── Daytona │ └── AI Sandbox 原因不是 Daytona 一定比較安全或一定比較便宜,而是這個選擇與 Zeabur 的部署方式比較相容。 task-runner 不等於 AI Assistant Sandbox這裡非常容易混淆。 官方 task runners 文件把 task runner 定位為執行 Code Node 中 JavaScript 與 Python 程式碼的機制;它可以作為 n8n 的外部 Runner,隔離一般 Workflow 執行時的使用者程式碼。 AI Assistant Sandbox 則負責另一個流程: 123456789AI Assistant ↓建立 workflow.ts ↓執行 TypeScript 編譯與測試 ↓修正錯誤 ↓產生有效 Workflow JSON 因此: 1task-runner ≠ AI Assistant Sandbox 即使 Zeabur 裡已經有 task-runner,也不代表 AI Assistant 的 Workflow Builder 已經具備可用的 Sandbox。兩者可以同時存在,角色也不互相取代。 為什麼不直接把 n8n-sandbox 塞進 Zeabur?Zeabur 官方目前說明,不能直接從 Docker Compose YAML 部署服務;可以改用 Dockerfile、Docker Image 或轉成 Zeabur Template YAML 等方式組合服務。 而 n8n 官方 Sandbox Compose 還包含 sandbox-api、sandbox-runner-1、TLS 憑證,以及 privileged: true 的 Docker-in-Docker Runner。這代表它不是把一個普通 Docker Image 加進專案就結束。 如果你真的想在 Zeabur 部署自架 Sandbox,需要逐項確認: 目前使用的 Server 或 Plan 是否支援所需的高權限容器能力。 Sandbox API 與 Runner 能否以 Zeabur 支援的 Template 或服務方式部署。 內部網路、TLS、Runner 註冊與持久化資料如何配置。 Runner 是否會被錯誤暴露到公開網路。 發生 Sandbox 失敗時,n8n 與 PostgreSQL 是否仍然可用。 如果只是想在既有 Zeabur n8n 上加入 AI Assistant,我不會把這些基礎設施風險當成第一個實驗步驟。 Zeabur + Daytona 的取捨12345678910正式自動化平台Zeabur├── n8n├── PostgreSQL├── task-runner└── SearXNG(可選)AI 建構工作區Daytona└── Sandbox 優點: 不用先改動目前正常運作的 n8n、PostgreSQL 與 task-runner。 不必在 Zeabur 內維護 Docker-in-Docker privileged Runner。 正式 n8n 與 AI 建構程式碼的執行環境分開。 Daytona 發生問題時,主要影響 AI Workflow Builder,不一定等於既有 Workflow Runtime 全部停止。 缺點: 多一個外部服務、帳號、API Key、費用與供應商依賴。 AI Assistant 的 Sandbox 資訊可能進入第三方環境,需要檢查資料政策。 Daytona 的 API、方案、計費與支援範圍會變動,不能把本文的選擇當成永久答案。 所以我的判斷會是: n8n、PostgreSQL、task-runner 與搜尋服務自己控制;AI Assistant 的臨時執行環境交給 Daytona。 但如果企業資料政策不允許資料離開指定 Infrastructure,就應該改評估自架 n8n-sandbox,或先不要啟用 AI Workflow Builder。 Web Search:Brave Search 還是 SearXNG?這個選擇可以獨立於 Sandbox Provider。 選 Brave Search適合希望減少自行維護服務的人: 12345Zeabur└── n8n ├── Model Provider ├── Daytona Sandbox └── Brave Search API 需要管理 API Key 與使用量,也要確認資料是否符合公司的第三方服務政策。 選 SearXNG適合希望把搜尋服務放在自己控制的網路環境的人: 12345Zeabur├── n8n└── SearXNG │ └── 內部網路 SearXNG 是一般服務,與需要 privileged Docker-in-Docker 的 Sandbox Runner 不同。這也是為什麼在 Zeabur 架 SearXNG,通常比直接照搬整套 n8n-sandbox Compose 更容易拆分與管理。 設定時可以參考哪些環境變數?以下只展示名稱與結構,不要把真實 API Key 寫進公開文章、Git Repository 或截圖: 1234N8N_INSTANCE_AI_SANDBOX_ENABLED=trueN8N_INSTANCE_AI_SANDBOX_PROVIDER=daytonaDAYTONA_API_URL=https://app.daytona.io/apiDAYTONA_API_KEY=請填入自己的金鑰 如果採用 n8n-sandbox,則要依目前版本的官方設定文件提供 Sandbox Service URL 與必要的認證資訊。以目前設定文件的概念,可以先理解成: 1234N8N_INSTANCE_AI_SANDBOX_ENABLED=trueN8N_INSTANCE_AI_SANDBOX_PROVIDER=n8n-sandboxN8N_SANDBOX_SERVICE_URL=http://sandbox-api:8080N8N_SANDBOX_SERVICE_API_KEY=請填入自己的 Sandbox 金鑰 不同 n8n 版本的 Compose 範例與環境變數名稱可能調整,不要直接複製舊文章中的設定到 Production;部署前應以當期官方文件與 UI 中的 Sandbox connection 為準。 Web Search 的設定概念則是: 12345# Brave 有設定時優先使用 BraveINSTANCE_AI_BRAVE_SEARCH_API_KEY=請填入自己的金鑰# 或使用自架 SearXNGN8N_INSTANCE_AI_SEARXNG_URL=http://searxng:8080 實際欄位可在 n8n UI 的 Instance AI 設定中管理;如果同時設定兩者,依目前官方 configuration 文件,Brave 會優先於 SearXNG。 我會用這五個能力迎接 Vibe Automation這個更新不代表以後不用學 n8n。相反地,以下五個能力會更重要: 1. 需求描述不要只說「我想自動化」,而要說清楚: 當 A 發生時,取得 B 資料,判斷 C 條件,再執行 D;如果失敗,要通知誰、留下什麼紀錄? 2. 流程設計AI 可以產生 Workflow,但你仍然要判斷流程是否合理: 1234567891011Trigger ↓驗證輸入 ↓讀取資料 ↓判斷條件 ├── 成功路徑 └── 例外路徑 ↓通知與紀錄 3. 資料結構你至少要看得懂輸入與輸出的 JSON,才能判斷 AI 是否接錯欄位: 12345678910{ "customer": { "name": "王小明", "phone": "09xxxxxxxx" }, "appointment": { "date": "2026-09-01", "time": "14:00" }} 4. 系統整合Workflow 的價值不在於 Node 越多,而在於它能否穩定串接 Webhook、資料庫、API、LINE、Google Calendar 與通知服務。 5. 判斷 AI 做得對不對AI 產生的 Workflow 仍然需要測試: 1234567891011正常輸入 ↓邊界條件 ↓Credential 失效 ↓API timeout ↓重複事件 ↓資料是否正確寫入 「可以產生」與「可以安全交付」是兩件不同的事。 我的建議:先保留現在的 n8n,再逐步接上 AI Assistant如果你的 n8n 已經架在 Zeabur,而且 PostgreSQL、task-runner、Webhook 與既有 Workflow 都正常,我會採用以下順序: 12345678910111213① 備份目前 n8n、PostgreSQL 與 Credentials ↓② 確認目前版本與官方 AI Assistant 相容性 ↓③ 升級 n8n,先驗證原有 Workflow ↓④ 在 n8n 設定 OpenAI / Anthropic / OpenRouter 等模型 ↓⑤ Sandbox 選 Daytona,或依資料政策自架 n8n-sandbox ↓⑥ Web Search 選 Brave,或在 Zeabur 部署 SearXNG ↓⑦ 用測試 Workflow 驗證建構、修正與儲存流程 不要因為想玩一個新功能,就先把正常環境打掉重來。 Self-hosted 真正重要的能力,不是「什麼東西都自己架」,而是: 哪些東西值得自己管理,哪些東西交給專門服務反而更合理? 對 Zeabur + n8n 來說,我目前會把界線畫在: 1234567核心自動化平台與資料 ↓由 Zeabur 控制AI Assistant 的短生命週期執行環境 ↓交給 Daytona,或依資料政策自架 Sandbox 這樣既保留 Self-hosted n8n 的控制力,也不必為了 AI Assistant 把所有基礎設施一次複雜化。 參考文件 n8n Community:AI Assistant on self-hosted n8n: easier setup in 2.35 n8n 官方 One-line setup 文件 n8n 官方 Docker Compose 安裝文件 n8n Instance AI configuration n8n Instance AI sandboxing n8n task runners 文件 Zeabur:Deploying with Dockerfile 常見問答 (FAQ)Q1:One-line setup 會自動安裝 Docker 嗎?不會。你必須先安裝並啟動 Docker,且 docker compose version 可以正常執行;One-line setup 主要負責建立 n8n、Sandbox、SearXNG 與相關 Docker Compose 設定。 Q2:n8n 的 task-runner 和 AI Assistant Sandbox 是同一個東西嗎?不是。task-runner 主要負責執行 Workflow 中 Code Node 的 JavaScript 或 Python 程式碼;AI Assistant Sandbox 則提供 Workflow Builder 建立檔案、編譯 TypeScript、執行測試與產生 Workflow JSON 的隔離工作區。 Q3:n8n-sandbox 和 Daytona 該怎麼選?n8n-sandbox 適合本機開發、測試與希望所有資料留在自己 Infrastructure 的環境;Daytona 適合希望把 AI 產生程式碼的執行環境與正式 n8n Host 分開、降低自維護 Docker-in-Docker 複雜度的 Production 情境。若資料不得離開指定環境,應優先評估自架 Sandbox 或暫不啟用 Workflow Builder。 Q4:如果我已經在 Zeabur 使用 n8n 和 task-runner,還需要 Sandbox 嗎?需要。task-runner 不會自動提供 AI Assistant Workflow Builder 所需的 Sandbox;兩者用途不同,可以同時存在。你仍然要另外設定 n8n-sandbox 或 Daytona 作為 Sandbox Provider。 Q5:Daytona 會帶來哪些風險或成本?Daytona 會增加第三方服務依賴、API Key、使用量與費用,而且 AI Assistant 建構過程的檔案與資料可能進入外部 Sandbox。使用前應檢查企業資料政策、供應商條款、敏感資料遮罩與可接受的服務中斷範圍。 Q6:沒有 Web Search Provider 時,AI Assistant 還能使用嗎?可以使用部分功能,但主動 Web Search 會被停用;依目前 n8n 設定文件,fetch-url 仍可能可用。若需要查詢最新 API 文件,應設定 Brave Search 或 SearXNG,並確認搜尋資料的合規要求。 Q7:One-line setup 適合直接拿來跑企業 Production 嗎?它適合快速學習、測試與 Demo,但不等於完整的企業 Production 架構。正式環境仍要評估 PostgreSQL、HTTPS、備份與復原、權限、監控、更新回滾、Sandbox 隔離與資料邊界。

  • article-n8n 自架新手指南:One-line setup 一行指令建立 Docker Compose、AI Assistant 與 Sandbox

    2026/8/26

    AI自動化 n8n n8n新手教學
    n8n 自架新手指南:One-line setup 一行指令建立 Docker Compose、AI Assistant 與 Sandbox

    如果你以前自己架過 n8n,應該很清楚第一次安裝時會遇到多少名詞:Docker、Docker Compose、Volume、環境變數、Secret,還有 AI Assistant 需要的模型與搜尋服務。 現在 n8n 官方提供了 One-line setup。準備好 Docker 並確認它正在執行後,只要在 Terminal 貼上一行指令,就能建立一套全新的 n8n 本機環境: 1curl -fsSL https://get.n8n.io | sh 這不代表 Docker 被「免安裝」了,而是 n8n 把原本要自己撰寫與組合的 Docker Compose 設定、資料卷、Secret,以及 AI Assistant 的支援服務,整理成一個較容易開始的安裝流程。 本文依照 n8n 官方 One-line setup 文件 整理。安裝指令、版本政策與支援的模型提供者都可能更新,實際執行前仍應以官方文件為準。 One-line setup 適合什麼情境?官方把這套流程定位為 全新 n8n instance 的快速安裝方式。它特別適合以下情境: 第一次在本機學習 n8n。 想快速做 Demo 或測試 AI Assistant。 不想一開始就手寫完整的 Docker Compose 檔案。 想先把環境跑起來,再逐步理解 Docker、Volume 與環境變數。 如果你已經使用自己的 Docker Compose 架構自架 n8n,不需要為了 One-line setup 重新安裝。它不是既有環境的強制遷移工具;正在使用 npm 安裝的既有 instance,目前也不會因為這個腳本出現就立刻失效。 執行前需要準備什麼?先安裝並啟動 DockerOne-line setup 不會替你安裝 Docker。你需要先安裝 Docker,並讓 Docker daemon 在背景執行。 這套流程特別需要 Docker Compose v2 plugin,也就是下面這個指令可以使用: 1docker compose version 不要把它和舊版的獨立指令混淆: 1docker-compose 官方文件要求的是 docker compose,不是舊式的 docker-compose。如果你使用 Podman、Colima 或其他相容引擎,也需要準備好帶有 Compose plugin 的 Docker CLI,並正確指向它的 socket。 macOS、Linux 與 Windows 的差異在 macOS 或 Linux 上,通常是安裝 Docker Desktop 或 Docker Engine,確認服務啟動後直接從 Terminal 執行指令。 Windows 的 PowerShell 與 Command Prompt 不能直接按照 POSIX shell script 的方式執行這套安裝流程。官方建議使用: 1234Docker Desktop+ WSL2+ Docker Desktop 的 WSL2 integration+ WSL Terminal Git Bash 理論上可以執行 shell script,但官方文件表示尚未完成端到端驗證;Windows 使用者優先採用 WSL 會比較穩妥。 一行指令會幫你建立什麼?在你想放置 n8n 的目錄開啟 Terminal,執行: 1curl -fsSL https://get.n8n.io | sh 腳本會依序檢查 Docker 是否存在、Docker daemon 是否正在執行,以及 Docker Compose v2 是否可用。接著在目前目錄建立 n8n/ 資料夾,並準備相關設定: 1234n8n/├── compose.yml├── .env└── searxng-settings.yml 第一次執行時,它還會下載需要的 Docker image、建立資料卷並啟動服務。正常完成後,可以開啟: 1http://localhost:5678 官方範例輸出也會顯示資料儲存在 ./n8n,並使用名為 n8n-data 的 Docker volume。若同一個資料夾已經完成設定,再次執行通常只會提示目前已經存在,不會任意覆蓋既有環境。 內建的服務包含哪些?One-line setup 的價值不只是把 n8n 主程式啟動,它也會準備 AI Assistant 需要的基礎服務。 1. n8n Workflow Editorn8n 本身是視覺化的 Workflow Editor,可以用節點串接 Trigger、Webhook、API、Google Sheets、Gmail、LINE 與 AI Agent 等服務。 如果你還不熟悉 n8n,可以先閱讀站內的 n8n 自動化工具介紹與 AI 輔助安裝教學,先建立工作流與節點的基本概念。 2. 內建資料庫:SQLite這套快速安裝預設使用 SQLite。它是一個直接存在檔案中的輕量資料庫,不需要另外架設資料庫伺服器,適合個人學習、測試與 Demo。 SQLite 會保存工作流、憑證與執行紀錄,因此「只是刪除容器」和「刪除 volume」是完全不同的操作。後面會專門說明資料風險。 3. AI Assistant 的 Sandbox當 AI Assistant 協助產生或執行程式碼時,One-line setup 會一併啟動 n8n 提供的 bundled sandbox。可以把它理解成一個與 n8n 主程式分開的執行環境,讓 AI 產生的程式碼有獨立的執行位置。 這對本機測試很方便,但「有 Sandbox」不等於完成企業級的安全架構。正式環境仍要評估權限、網路隔離、資源限制與 Sandbox provider。 4. 網頁搜尋支援服務安裝器會產生 searxng-settings.yml,並啟動 AI Assistant 使用的 bundled search tool。官方文件將它描述為預設的搜尋支援服務,讓 AI Assistant 可以在需要時查找網頁資料。 如果你想改用 Brave Search,也可以在 ./n8n/.env 設定 INSTANCE_AI_BRAVE_SEARCH_API_KEY。這不是啟用 n8n 的必要條件,而是替換搜尋提供者的選項。 AI 模型仍然要自己準備這裡是最容易誤會的地方:One-line setup 不會附送 AI 模型,也不會替你支付模型 API 費用。 它準備的是 AI Assistant 的執行環境;你仍然要在 n8n 介面中加入自己的模型提供者與 API key。官方文件提供兩種做法: n8n 啟動後,進入 instance 的 AI 設定介面加入模型 API key。 在登入前直接編輯 ./n8n/.env,填入 N8N_INSTANCE_AI_MODEL_API_KEY。 例如環境變數名稱會長這樣: 1N8N_INSTANCE_AI_MODEL_API_KEY= 填入自己的 key 後,重新啟動 n8n: 1docker compose -f ./n8n/compose.yml up -d 模型提供者與可用設定會隨 n8n 版本及方案變動,請以官方的 Set up the AI Assistant 文件 為準。API key 不要寫進公開文章、Git repository 或截圖中。 AI Assistant 和 AI Agent Node 不一樣這兩個名稱很像,但負責的事情不同。 AI Agent Node:工作流裡的 AIAI Agent Node 是你拖進工作流的節點。例如: 1234567LINE↓AI Agent↓Google Calendar↓回覆 LINE 它是工作流中的一個處理步驟,負責依照你的設定理解輸入、呼叫工具,再把結果傳給下一個節點。 AI Assistant:幫你製作工作流的助手AI Assistant 比較像工作流建構階段的協作者。你可以描述需求,例如: 收到 Gmail 後,自動判斷是不是客戶詢價信;如果是,就寫入 Google Sheets。 它的目標是協助你規劃或建立工作流,而不是取代工作流中的 AI Agent Node。 如果你想深入理解 LLM 和 AI Agent 的選擇差異,可以延伸閱讀 何時該用 LLM?何時該派 AI Agent 上場?。 安裝後最常用的 Docker 指令One-line setup 降低了第一次安裝的門檻,但基本的啟停指令仍然值得記住。 停止 n8n1docker compose -f ./n8n/compose.yml down 這會停止服務,通常不會主動刪除資料卷。 重新啟動 n8n1docker compose -f ./n8n/compose.yml up -d 升級到較新的版本1curl -fsSL https://get.n8n.io | sh -s -- --upgrade 官方腳本也提供版本控制參數。若要指定版本,請依官方文件當下支援的格式執行,例如: 1curl -fsSL https://get.n8n.io | sh -s -- --version 2.31.4 版本號只是範例,升級前要先確認相容性、備份資料與官方的版本說明。 只產生設定、不立即啟動如果你想先檢查設定檔,再決定何時啟動,可以使用: 1curl -fsSL https://get.n8n.io | sh -s -- --no-start 想查看腳本可用的選項,則可以使用: 1curl -fsSL https://get.n8n.io | sh -s -- --help 執行遠端腳本前,先檢查內容curl ... | sh 很方便,但它代表你把遠端下載的內容直接交給 shell 執行。即使來源是官方,也建議對公司環境或重要主機採用「先下載、先閱讀、再執行」的方式: 123curl -fsSL https://get.n8n.io -o get-n8n.shless get-n8n.shsh get-n8n.sh 檢查腳本時,可以特別留意它會連線到哪些服務、會建立或修改哪些檔案,以及目前版本是否符合你的部署計畫。不要把未知來源的安裝指令直接套用到含有重要資料的主機上。 down 和 down -v 的資料風險下面兩個指令看起來只差一個參數,後果卻完全不同: 1docker compose -f ./n8n/compose.yml down 1docker compose -f ./n8n/compose.yml down -v down 主要是停止並移除容器;down -v 會連同 Docker volume 一起刪除。官方卸載流程還會接著刪除 ./n8n 資料夾,因此工作流、憑證與執行紀錄都有可能一起消失。 只想暫停 n8n 時,不要把 -v 當成習慣性參數。真的要移除環境前,先確認備份、資料保留需求與目前所在的目錄。 One-line setup 可以直接拿來跑 Production 嗎?可以啟動,不代表已經完成 Production 架構。 One-line setup 的預設值非常適合「快速開始」:SQLite 不需要額外資料庫、bundled sandbox 不需要先設計 provider、服務也只需要從本機的 localhost:5678 開始使用。 但如果要把 n8n 放進團隊或公司的正式自動化環境,還要另外處理: PostgreSQL 或其他正式資料庫架構。 Domain、HTTPS 與 Reverse Proxy。 Workflow、Credential 與執行資料的備份及還原。 Sandbox 的隔離方式、權限與資源限制。 Webhook 對外開放後的驗證、監控與告警。 更新、回滾與版本相容性。 官方目前建議團隊或 Production 環境評估 PostgreSQL;Sandbox 則建議另外研究 Daytona 等正式 provider。這也是為什麼我會把 One-line setup 定位成「學習版與快速驗證的起點」,而不是企業部署的完整答案。 我會怎麼分三個階段使用?Level 1:本機學習版123Docker Desktop+ One-line setup+ SQLite 適合第一次接觸 n8n、課程教學、測試 AI Assistant 與驗證工作流想法。 Level 2:個人長期使用版12345VPS+ Docker Compose+ Domain+ HTTPS+ 備份 適合個人自動化、LINE Bot、Webhook 與需要 24 小時執行的流程。這個階段要開始理解資料卷、反向代理、更新與復原。 Level 3:企業 Production1234567Docker 或 Kubernetes+ PostgreSQL+ Reverse Proxy+ Backup+ Monitoring+ 隔離的 Sandbox+ 權限管理 這才是需要系統性評估可用性、安全性、權限、備份與維運成本的正式架構。 n8n 正在往 Docker-first 方向前進官方 One-line setup 文件目前寫明,預計在 2026 年 10 月推出 n8n 3.0 後,新的 n8n 安裝將不再採用以前的: 12npm install n8nnpx n8n 而是以 Docker 為主要發佈方式。這項時程與安裝政策仍可能隨官方版本調整,不能把文章中的日期當成永久不變的承諾;但方向已經很清楚:未來學習 n8n 自架,Docker Compose 會越來越接近基本功。 有趣的是,你不一定要在第一天就完全學會 Docker,才能開始使用 Docker。One-line setup 把「理解容器架構」與「先把服務跑起來」拆成兩個階段,讓新手可以先完成第一次成功啟動,再逐步補上 Compose、Volume、網路與安全性的知識。 結論:它解決的是快速開始,不是架構設計如果你以前看到「自架 n8n」就因為 Docker Compose 而放棄,現在確實值得重新試一次:先安裝並啟動 Docker,再用一行指令建立 n8n、SQLite、AI Assistant 支援服務與 Sandbox。 但也要記得三件事: Docker 仍然要自己安裝,One-line setup 只是簡化 n8n 的 Compose 設定。 AI 模型與 API key 仍然要自己準備,快速安裝不等於附送模型。 本機 Demo 與企業 Production 是兩種不同的架構問題,PostgreSQL、HTTPS、備份與安全隔離不能省略。 真正重要的改變,是把新手的起點從「我要先讀完所有 Docker 文件」變成「我先把 n8n 跑起來,再理解它怎麼運作」。自動化的入口,確實又降低了一階。 參考文件 n8n One-line setup 官方文件 n8n Set up the AI Assistant 官方文件 Docker 安裝文件 常見問答 (FAQ)Q1:One-line setup 會自動安裝 Docker 嗎?不會。你必須先安裝並啟動 Docker,而且需要可以使用 docker compose 的 Docker Compose v2 plugin;One-line setup 主要負責建立 n8n 的 Compose 設定與啟動相關服務。 Q2:One-line setup 有附送 AI 模型或 API key 嗎?沒有。它會準備 AI Assistant 使用的 Sandbox 與搜尋支援服務,但你仍然需要在 n8n 的 AI 設定介面或 ./n8n/.env 中加入自己的模型提供者 API key。 Q3:docker compose down 和 docker compose down -v 有什麼不同?docker compose down 主要停止並移除容器;docker compose down -v 會連同 Docker volume 一起刪除,可能造成工作流、憑證與執行紀錄遺失,因此不能把 -v 當成一般停機指令。 Q4:One-line setup 適合直接部署公司的 Production n8n 嗎?它適合快速學習、測試與 Demo;公司的 Production 環境通常還需要 PostgreSQL、HTTPS、Reverse Proxy、備份、監控、權限控管,以及更完整的 Sandbox 隔離設計。 Q5:AI Assistant 和 AI Agent Node 是同一個功能嗎?不是。AI Agent Node 是工作流裡負責理解輸入、使用工具或產生結果的節點;AI Assistant 則是協助你規劃或建立 n8n 工作流的建構助手。

  • article-如何打造 Google 表單作業繳交與自動寄信催繳系統? | (EP.4) n8n 自動化講師應用教學

    2026/5/4

    AI自動化 n8n 自動化講師應用
    如何打造 Google 表單作業繳交與自動寄信催繳系統? | (EP.4) n8n 自動化講師應用教學

    每次批改作業前,你是否還在手動打開試算表,一行一行比對學生名單?這種「人工核對」方式不只費時,更容易出現遺漏。這篇教學,我們將實作一套完整的 n8n 自動化系統,讓表單填交、狀態判斷到催繳通知全程零人工介入。 這套系統的核心概念是:「資料收集 → 標準化 → 期限比對 → 自動記錄」。只要學生一送出表單,整個流程就自動啟動,你只需要定期查看試算表即可。接下來,我們拆解 Flow A:Google Form 提交作業 → 寫入 submissions 的每一個節點。 整體流程架構這個自動化系統由兩個工作流組成: 工作流 功能 Flow A(本篇) Google 表單提交 → 標準化欄位 → 查詢作業設定 → 判斷準時/遲交 → 寫入 submissions Flow B(下一篇) 每日定時觸發 → 比對未交名單 → 自動寄信催繳 本篇聚焦在 Flow A,帶你從觸發器開始,逐步建立整個接收與記錄流程。 步驟一:Google Sheets Trigger — 監聽新提交許多人會直覺選用「Google Forms Trigger」,但我們這裡刻意改用 Google Sheets Trigger,原因在於 Google Form 的回覆會自動同步到「原始回覆」工作表,而 Sheets Trigger 更穩定、也更容易控制觸發時機。 設定方式: Document:選擇你的試算表 Sheet:選擇「原始回覆」分頁 Event:設為 Row Added(有新資料列加入時觸發) 每當學生提交 Google 表單,這個 Trigger 就會收到一筆新資料,並自動啟動後續流程。 步驟二:Set Submission Fields — 標準化欄位名稱Google 表單的欄位名稱是中文(例如「學號」、「時間戳記」),在跨節點傳遞時容易因編碼問題出錯。這個節點的任務,就是把中文欄位名稱對應成英文標準欄位: 表單原始欄位 標準化後欄位名稱 時間戳記 submitted_at 學號 student_id 姓名 student_name Email email 作業代號 assignment_id 作業檔案 file_url 另外也固定寫入 source: "google_form",方便未來如果有其他提交來源(如 LINE Bot、API)時,能快速識別資料來源。 步驟三:Get Assignment — 查詢作業設定資料標準化後,系統需要知道「這份作業的截止時間是什麼時候?」。這些資訊不寫死在程式碼裡,而是統一存放在 assignments 工作表中,讓你隨時調整而不需要修改 workflow。 assignments 工作表的欄位結構建議如下: 欄位 說明 作業代號 與表單選項一致,例如 homework_0102 作業名稱 作業的顯示名稱 due_at 截止時間,格式為 ISO 8601(例如 2025-01-15T23:59:00+08:00) is_active 是否啟用,填 1 表示啟用、0 表示關閉 這個節點以 assignment_id 和 is_active = 1 作為篩選條件,一次查詢就能取得對應的截止時間與作業名稱。is_active 的設計讓你在作業結束後,只需要把值從 1 改成 0,系統就不會再接受該代號的新提交。 步驟四:Compute Status — 計算準時 / 遲交狀態這是整個 Flow A 最關鍵的節點。由於 Google 表單的「時間戳記」格式是台灣慣用的 2025/1/15 上午 9:30:00,並非標準的 ISO 格式,JavaScript 原生的 new Date() 無法直接解析,因此我們需要自己撰寫解析函式。 以下是這個 Code 節點執行的三件事: 1. 解析台灣時間格式1234567891011121314function parseTaiwanDateTime(text) { const m = String(text).trim().match( /^(\d{4})\/(\d{1,2})\/(\d{1,2})\s+(上午|下午)\s+(\d{1,2}):(\d{2}):(\d{2})$/ ); if (!m) return null; let [, y, mo, d, ap, h, mi, s] = m; h = Number(h); if (ap === '下午' && h !== 12) h += 12; if (ap === '上午' && h === 12) h = 0; return { y: Number(y), mo: Number(mo), d: Number(d), h, mi: Number(mi), s: Number(s) };} 這個函式用正規表達式拆解時間字串,並正確處理「上午 12 點 = 午夜」、「下午 12 點 = 中午」這兩個 12 小時制的常見陷阱。 2. 比對截止時間,判斷狀態123456const submittedAtDate = new Date(parts.y, parts.mo - 1, parts.d, parts.h, parts.mi, parts.s);const dueAtDate = new Date(dueAtText); // due_at 為 ISO 格式,可直接解析const delayMinutes = Math.max(0, Math.floor((submittedAtDate - dueAtDate) / 60000));const status = submittedAtDate <= dueAtDate ? 'on_time' : 'late'; delayMinutes 只有在遲交時才有意義,Math.max(0, ...) 確保準時繳交的延遲值不會出現負數。 3. 提取 Google Drive 檔案 ID學生上傳的作業檔案,Google 表單只記錄一個 Drive 分享連結,實際的檔案 ID 藏在 URL 裡。我們用以下邏輯把它抽出來,方便後續流程(例如自動下載或批改)直接取用: 123456789101112function extractDriveFileId(url) { const patterns = [ /[?&]id=([a-zA-Z0-9_-]+)/, /\/d\/([a-zA-Z0-9_-]+)/, /\/file\/d\/([a-zA-Z0-9_-]+)/ ]; for (const pattern of patterns) { const match = String(url).match(pattern); if (match) return match[1]; } return '';} 這個函式相容三種常見的 Google Drive 連結格式,只要是合法的 Drive URL,都能正確提取。 步驟五:Append to submissions — 寫入資料庫完成狀態計算後,最後一步是將所有資料追加寫入 submissions 工作表,這張表就是你的「繳交記錄資料庫」。 每一筆記錄包含: 欄位 說明 assignment_id 作業代號 student_id / student_name 學生學號與姓名 email 聯絡信箱(催繳用) submitted_at 原始台灣時間字串 submitted_at_iso 轉換後的 ISO 格式時間(+08:00) due_at 作業截止時間 status on_time 或 late delay_minutes 遲交分鐘數(準時者為 0) file_url 原始分享連結 drive_file_id 抽取出的 Drive 檔案 ID 有了這張表,Flow B(自動催繳)只需要用 status = 'late' 或比對「誰的名字不在 submissions 裡」,就能精準找出需要提醒的人。 應用延伸這套流程的設計概念可以輕鬆複用到各種情境: 企業培訓:員工每月繳交學習心得,逾期自動提醒主管 合約文件催收:客戶 onboarding 必備文件,系統自動追蹤回收率 跨部門進度回報:專案每週回報表,自動標記哪些人尚未填寫 活動報名核對:比對報名名單與實際繳費記錄 只要情境符合「收件 → 對照截止時間 → 記錄狀態」的邏輯,這套架構都能直接套用。 常見問答 (FAQ)Q:為什麼用 Google Sheets Trigger,而不是直接用 Google Forms Trigger?A:Google Sheets Trigger 比 Google Forms Trigger 更穩定,觸發延遲也更低。此外,Google Form 回覆預設就會寫入連動的試算表,因此監聽 Sheets 的「新增列」事件,功能上完全等效,且更容易在試算表直接觀察與除錯資料。 Q:台灣時間的「上午/下午」格式真的不能直接用 new Date() 解析嗎?A:對,new Date("2025/1/15 上午 9:30:00") 在不同 JavaScript 環境下行為不一致,部分環境會回傳 Invalid Date。在 n8n 的 Code 節點環境中,含有「上午」、「下午」中文字符的時間字串無法被原生 Date() 正確解析,必須自行用正規表達式拆解後再重組為 Date 物件。 Q:assignments 表的 is_active 欄位有什麼用?A:這是一個「開關」設計。當一份作業的截止日已過,你只需要把 is_active 從 1 改為 0,Get Assignment 節點就找不到這筆資料,後續流程會中斷並報錯,避免過期作業繼續被記錄。這讓你不需要修改任何程式碼,純粹靠試算表資料來控制哪些作業「仍在接收中」。 Q:delay_minutes 為什麼要用 Math.max(0, …) 防止負數?A:遲交判斷式是 submittedAt - dueAt。準時繳交時,這個差值是負數,代表「提早了幾分鐘」。但 delay_minutes 欄位的語義是「延遲了多少分鐘」,對準時的同學來說應該是 0 而不是負數,Math.max(0, ...) 確保寫入資料庫的值語義清晰。 Q:drive_file_id 提取有什麼用途?A:Google Drive 的分享連結有多種格式(含 /d/、?id=、/file/d/ 等),直接儲存 URL 不方便後續程式化操作。提取 drive_file_id 後,後續節點可以直接呼叫 Google Drive API,例如:自動將檔案移到指定資料夾、設定閱讀權限、或讓 AI 節點直接讀取文件內容進行自動批改。 Q:如果學生重複提交怎麼辦?系統會判斷成最新一筆嗎?A:目前 Flow A 的設計是「每筆提交都寫入」,不會自動去重。如果你需要「同一個學生只保留最後一筆」,可以在 Append 節點之前加入一個 Google Sheets 查詢節點,先確認該 student_id + assignment_id 是否已有資料,再決定要覆寫還是新增。或者在 submissions 表的後處理(如 Flow B)中,以 student_id 分組取最新時間的那筆即可。 Q:這套系統可以只用 Google 試算表和 n8n,不需要其他付費工具嗎?A:可以,本篇所有流程都只使用 Google Sheets(免費)+ n8n(可自架 Community 版免費使用)。整套系統零額外費用,適合教育機構或預算有限的團隊直接部署。

  • article-如何建立自動化課程提醒系統?串接 Google Sheets 與自動寄信流程教學 | (EP.3) n8n 自動化講師應用教學

    2026/5/3

    AI自動化 n8n 自動化講師應用
    如何建立自動化課程提醒系統?串接 Google Sheets 與自動寄信流程教學 | (EP.3) n8n 自動化講師應用教學

    為什麼需要升級你的課程提醒系統?在上一堂課中,我們完成了基礎的課程確認信機制。今天這一集要往上一層,打造「課前提醒信」的升級版流程。 升級的核心差異在於:這次要跨兩張工作表整合資料。 正式名單:記錄學員姓名、學號、信箱、上課日期、寄信狀態 課程主表:記錄各課程的教材連結、Google Meet 連結、注意事項 光靠正式名單無法完成完整的提醒信,必須同時讀取課程主表,動態帶入課程資訊後才能寄出。這樣設計的好處是:只要更新課程主表,所有學員收到的資訊就自動跟著更新,不需要逐一手動調整。 完整工作流架構(6 個節點)1234567891011Schedule Trigger ↓Get row(s) in 課程主表 ↓Get row(s) in 正式名單 ↓篩出明天有課並合併課程主表(Code 節點) ↓Send a message(Gmail 節點) ↓Append or update row in sheet(回寫狀態) 節點詳解節點 1|Schedule Trigger — 定時觸發設定每天固定時間自動執行整條流程。測試階段可先設為「每分鐘」,正式上線後改成每天早上 08:00,讓提醒信固定在前一天早上寄出。 💡 重點:排程觸發並不代表一定會寄信。後面的 Code 節點會做篩選,若當天沒有符合條件的學員,整條流程會安靜地結束,不做任何動作。 節點 2|Get row(s) in 課程主表 — 讀取課程資訊從 Google Sheets 的「課程主表」工作表讀取所有課程資料,包含: 欄位 說明 課程名稱 用來做跨表比對的 key 上課日期 輔助比對,確認課程場次 上課方式 線上 / 實體,輔助比對 教材連結 帶入提醒信 Google meeting 連結 帶入提醒信 注意事項 帶入提醒信 這個節點先執行,讓後面的 Code 節點可以引用課程主表的資料做合併。 節點 3|Get row(s) in 正式名單 — 讀取學員名單從「正式名單」工作表讀取所有學員資料。關鍵欄位: 欄位 說明 姓名 / 學號 / 信箱 學員基本資料 課程名稱 / 上課日期 / 上課方式 用來對應課程主表 已寄確認信(Yes/No) 篩選條件之一 已寄提醒信(Yes/No) 篩選條件之一(防重複寄信的關鍵) ⚠️ 此節點開啟 Execute Once 模式,確保不論上一節點輸出幾筆課程資料,名單只會被讀取一次。 節點 4|Code 節點 — 篩選與合併(核心邏輯)這是整條流程最重要的節點。它做兩件事: 篩選:從正式名單中找出「明天上課 + 已寄確認信 + 尚未寄提醒信」的學員 合併:依課程名稱、日期、上課方式對應課程主表,帶入教材連結、會議連結與注意事項 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162const result = [];// 取得課程主表所有資料const courseRows = $("Get row(s) in 課程主表").all().map(item => item.json);// 計算明天的年月日const tomorrow = new Date();tomorrow.setDate(tomorrow.getDate() + 1);const tYear = tomorrow.getFullYear();const tMonth = tomorrow.getMonth() + 1;const tDay = tomorrow.getDate();for (const item of items) { const row = item.json; const date = row["上課日期"]; // 格式:YYYY/M/D const confirm = row["已寄確認信(Yes/No)"]; const reminder = row["已寄提醒信(Yes/No)"]; if (!date) continue; // 解析日期字串 const parts = String(date).trim().split('/'); if (parts.length !== 3) continue; const y = parseInt(parts[0], 10); const m = parseInt(parts[1], 10); const d = parseInt(parts[2], 10); // 三個篩選條件:明天上課 + 已寄確認信 + 尚未寄提醒信 if ( y === tYear && m === tMonth && d === tDay && confirm === "Yes" && reminder !== "Yes" ) { // 從課程主表找出對應課程(以課程名稱為主,日期與方式為輔) const matchedCourse = courseRows.find(course => { const sameName = String(course["課程名稱"] || "").trim() === String(row["課程名稱"] || "").trim(); const sameDate = !course["上課日期"] || String(course["上課日期"]).trim() === String(row["上課日期"] || "").trim(); const sameType = !course["上課方式"] || String(course["上課方式"]).trim() === String(row["上課方式"] || "").trim(); return sameName && sameDate && sameType; }) || {}; result.push({ json: { row_number: row["row_number"], name: row["姓名"], student_id: row["學號"], email: row["信箱"], course: row["課程名稱"], date: row["上課日期"], type: row["上課方式"], register_time: row["報名時間"], material_url: matchedCourse["教材連結"] || "", meeting_url: matchedCourse["Google meeting 連結"] || "", note: matchedCourse["注意事項"] || "" } }); }}return result; 💡 關鍵設計:reminder !== "Yes" 而非 === "No",是為了相容欄位空白的初始狀態,不需要預先手動填入 No。 節點 5|Send a message — 寄送 Gmail 提醒信使用 Gmail 節點寄送個人化課前提醒信,以動態變數帶入所有學員與課程資訊: 信件主旨: 1課前提醒|{{ $json.course }}(明天上課) 信件內文: 123456789101112131415161718Hi {{ $json.name }}({{ $json.student_id }}),您好:提醒您,您報名的課程將於明天開始。📘 課程名稱:{{ $json.course }}📅 上課日期:{{ $json.date }}📍 上課方式:{{ $json.type }}📚 教材連結:{{ $json.material_url }}💻 Google meeting 連結:{{ $json.meeting_url }}📝 注意事項:{{ $json.note }}請提前確認上課安排,謝謝! 每一位符合條件的學員都會收到專屬的個人化信件,課程資訊直接來自課程主表,不需要人工填寫。 節點 6|Append or update row — 回寫寄信狀態信件成功寄出後,立刻回寫正式名單: 欄位 寫入值 已寄確認信(Yes/No) YES 已寄提醒信(Yes/No) YES 使用學號作為 matching key,精準對應每一位學員的那一行,不會誤改到其他人的資料。 這是防止重複寄信的最後防線:下次排程觸發時,這筆學員的 已寄提醒信 已經是 YES,Code 節點的篩選條件 reminder !== "Yes" 就不會再把他納入,信件不會重複寄出。 節點式設計觀念:切入 AI Agent 前的必修課養成加 Sticky Note 的習慣工作流每個節點旁都應該加上「Sticky Note 說明卡」,清楚標明這個節點的作用、篩選條件與注意事項。工作流越長越複雜,這個習慣越重要。六個月後回來看自己的流程,不需要重新推理就能立刻讀懂。 先搞懂資料流,再用 AI AgentAI Agent 非常擅長處理彈性指令,但它並不擅長「精確控制資料欄位的讀取與寫入」。如果你還不清楚「這個節點的 input 長什麼樣、output 輸出什麼欄位」,直接交給 AI Agent 很容易產生幻覺或資料串接錯誤,而且你不知道問題在哪裡。 節點式自動化是 AI Agent 的基礎。搞懂每個節點的輸入輸出、資料結構與篩選邏輯之後,你在指揮 AI Agent 時才能給出精確指令,真正發揮自動化的價值。 常見問答 (FAQ)Q:為什麼篩選條件用 reminder !== "Yes" 而不是 === "No"?A:因為新學員剛登錄到正式名單時,「已寄提醒信」欄位通常是空白,而不是填了 No。如果用 === "No" 篩選,空白欄位的學員就會被漏掉,永遠收不到提醒信。改用 !== "Yes" 可以同時涵蓋「空白」與「No」這兩種初始狀態,新學員不需要預先手動填任何值,流程就能正確運作。 Q:日期格式不對會怎樣?流程會報錯嗎?A:Code 節點已做防護處理:若 split('/') 切割後不是三段,就直接 continue 跳過該筆資料,不會讓整條流程中斷。但學員仍然不會收到信,因此務必統一正式名單的日期格式為 YYYY/M/D(例如 2026/5/10)。可以在 Google Sheets 設定欄位格式或加入資料驗證,從來源端防止格式錯誤。 Q:課程主表找不到對應的課程時,信件會少哪些資訊?A:Code 節點在找不到對應課程時,matchedCourse 會是空物件 {},material_url、meeting_url、note 都會變成空字串 ""。信件仍然會寄出,但這三個欄位會是空白。建議在寄信後檢查一下是否有空白連結,可以在 Code 節點加一行 console.log 印出未匹配的課程名稱,方便追查是哪裡打錯字或格式不一致。 Q:已寄確認信還不是 Yes 的學員,為什麼不寄提醒信給他們?A:這是刻意設計的業務邏輯:確認信代表這位學員的報名資料已被人工審核過。如果一位學員還沒收到確認信,表示他的資料可能還在審核中,貿然寄出提醒信可能會造成混亂(例如報名失敗的學員收到提醒)。流程設計的順序是:確認信(審核通過)→ 提醒信(課前一天)。 Q:如果同一位學員報名了多門課,會正確對應到每門課的教材嗎?A:會。課程主表的比對邏輯是「課程名稱 + 上課日期 + 上課方式」三欄都相符才算匹配。只要正式名單每一行對應一筆報名記錄(一行 = 一位學員 + 一門課),就能各自找到對應的課程主表資料,不會混用。 Q:Google Sheets 回寫時,為什麼要用「學號」當 matching key,而不是行號?A:行號(row_number)在 Google Sheets 中不是穩定的識別碼。只要有人新增或刪除其他行,同一位學員的行號就會改變,回寫時就會寫到錯誤的行。「學號」是每位學員唯一且不變的識別碼,能確保 appendOrUpdate 精準更新到正確那一行,是更安全的設計。 Q:我想加入「上課前兩天」也寄一次提醒,該怎麼做?A:有兩種做法: 加一個新欄位:在正式名單新增「已寄兩天前提醒信(Yes/No)」欄位,複製一套相同的流程,把 tomorrow.setDate(tomorrow.getDate() + 1) 改為 + 2,並把篩選與回寫條件改為對應新欄位。 用排程 + 天數變數:讓 Code 節點讀取一個「提前天數」變數,由外部控制要篩選幾天後的名單,一套流程就能同時處理不同時間點的提醒。 對初學者來說,做法一比較直覺,不容易出錯。 Q:排程一直跑,但完全沒有寄出任何信,怎麼除錯?A:按以下順序逐步檢查: Code 節點輸出:手動執行流程,查看 Code 節點輸出了幾筆資料。如果是 0 筆,表示篩選條件沒有命中任何學員。 確認日期格式:正式名單的上課日期是否真的是 YYYY/M/D 格式?有沒有多餘空格或全形斜線? 確認狀態欄位:已寄確認信 是否已填 Yes(注意大小寫)?已寄提醒信 是否是空白或 No? 確認明天日期:把 Code 節點加一行 console.log(tYear, tMonth, tDay) 確認系統時區計算是否正確(n8n 的時區設定可能與你的本地時區不同)。 課程主表對應:確認課程主表中的課程名稱和正式名單完全一致,包括空格與標點符號。

  • article-如何打造全自動「課前提醒」工作流?告別手動寄信的自動化教學 | (EP.2) n8n 自動化講師應用教學

    2026/5/3

    AI自動化 n8n 自動化講師應用
    如何打造全自動「課前提醒」工作流?告別手動寄信的自動化教學 | (EP.2) n8n 自動化講師應用教學

    為什麼你需要自動化「課前提醒」流程?開課前一天,你還在逐一比對報名名單、複製貼上學員 Email、手動確認哪些人已寄、哪些人還沒寄嗎? 這樣的手動流程不只耗費時間,更容易因疏失而遺漏學員,導致出席率下降。對於同時管理多門課程的講師來說,這更是沉重的行政負擔。 透過 n8n 建立自動化工作流,系統會每天自動執行以下動作: 讀取你的 Google Sheets 報名名單 篩選出「明天上課」且「尚未收到提醒信」的學員 自動寄出客製化提醒信件 將發送狀態回寫至試算表,確保不重複發送 從此,課前提醒變成零人工介入的全自動流程。 工作流架構總覽在開始設定前,先了解整體流程的設計邏輯,有助於你在遇到問題時快速定位: 1排程觸發 → 讀取 Google Sheets → Code 節點篩選 → 發送 Email → 回寫狀態 節點 功能 說明 Schedule Trigger 定時啟動 每天指定時間自動執行 Google Sheets 讀取名單 取得所有報名學員資料 Code 條件篩選 過濾出需要提醒的對象 Email 發送信件 寄出客製化提醒信 Google Sheets 回寫狀態 標記「已寄送」避免重複 Google Sheets 欄位設定建議在開始建立工作流之前,請確認你的 Google Sheets「正式名單」工作表包含以下欄位: 欄位名稱 說明 範例值 姓名 學員姓名 王小明 學號 學員學號(作為唯一識別碼) A001 信箱 學員 Email [email protected] 課程名稱 課程名稱 AI自動化入門班 上課日期 上課日期 2026/05/10 上課方式 實體 / 線上 / 混合等 線上 已寄確認信(Yes/No) 是否已寄出報名確認信 Yes 已寄提醒信(Yes/No) 是否已寄出課前提醒信 No 重要: 上課日期 欄位請使用 YYYY/MM/DD 格式(斜線分隔),Code 節點的篩選邏輯是以此格式進行比對。 如何快速完成工作流環境部署?這套自動化流程的設計邏輯非常清晰:定時觸發 ➔ 讀取名單 ➔ 條件篩選 ➔ 發送信件 ➔ 更新狀態。以下是具體的節點設定步驟: 步驟一:設定排程觸發器 (Schedule Trigger)工作流的第一步是設定啟動時間。加入 Schedule Trigger 節點,建議設定為每天早上 8 點自動執行,確保學員在上課前一天有充裕時間收到提醒。 實際工作流中同時保留了 Manual Trigger,方便你在測試時用手動方式隨時觸發,無需等待排程時間。 開發測試建議: 先使用 Manual Trigger(點擊「Execute workflow」)手動測試整條流程 或將 Schedule Trigger 的頻率暫時改為「每分鐘」,方便即時驗證 確認整體流程無誤後,再改回每天一次的排程 步驟二:讀取 Google Sheets 名單加入 Google Sheets 節點,選擇「Get Many Rows」操作,一次讀取「正式名單」工作表的所有資料。 設定要點: Spreadsheet:選擇你的報名表試算表 Sheet:選擇「正式名單」工作表 資料全部抓回後,交給後面的 Code 節點篩選——這樣最穩,不容易因試算表結構變動而出錯 步驟三:篩選需要提醒的學員 (Code 節點)這是整個工作流的核心邏輯。加入 Code 節點(節點名稱:「篩出明天有課」),貼入以下篩選程式碼: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748const result = [];const tomorrow = new Date();tomorrow.setDate(tomorrow.getDate() + 1);const tYear = tomorrow.getFullYear();const tMonth = tomorrow.getMonth() + 1;const tDay = tomorrow.getDate();for (const item of items) { const row = item.json; const date = row["上課日期"]; const confirm = row["已寄確認信(Yes/No)"]; const reminder = row["已寄提醒信(Yes/No)"]; if (!date) continue; const parts = String(date).trim().split('/'); if (parts.length !== 3) continue; const y = parseInt(parts[0], 10); const m = parseInt(parts[1], 10); const d = parseInt(parts[2], 10); if ( y === tYear && m === tMonth && d === tDay && confirm === "Yes" && reminder !== "Yes" ) { result.push({ json: { row_number: row["row_number"], name: row["姓名"], student_id: row["學號"], email: row["信箱"], course: row["課程名稱"], date: row["上課日期"], type: row["上課方式"], register_time: row["報名時間"] } }); }}return result; 程式碼說明: 明天日期拆解為年、月、日三個數字,再與試算表的 YYYY/MM/DD 格式逐項比對,避免字串比較因格式差異失敗 三重條件過濾:日期符合 且 已寄確認信 = Yes 且 尚未寄提醒信 「已寄確認信」的前提很重要——代表學員已完成報名流程,才需要發提醒 Code 節點同時將中文欄位名稱重新命名為英文(name、email、student_id…),讓後續的 Gmail 節點可以用更簡潔的變數名稱取值 步驟四:自動發送客製化 Email 提醒信確認篩選名單後,加入 Gmail 節點(使用 Gmail OAuth2 授權)。因為前面的 Code 節點已將欄位重新命名為英文,這裡可以直接使用簡潔的變數名稱: 收件人:{{ $json.email }} 主旨:課前提醒|{{ $json.course }} 信件內文範例: 123456789Hi {{ $json.name }}({{ $json.student_id }}),您好:提醒您,您報名的課程即將開始。📘 課程名稱:{{ $json.course }}📅 上課日期:{{ $json.date }}📍 上課方式:{{ $json.type }}請提前確認上課安排,謝謝! 注意:Gmail 節點的「Append Attribution」建議關閉(appendAttribution: false),避免信件底部出現 n8n 的廣告署名,影響專業形象。 步驟五:回寫狀態,杜絕重複發送這是整個工作流中最不能遺漏的一環。信件成功寄出後,必須回到 Google Sheets 將學員的提醒信狀態更新為 Yes。 加入第二個 Google Sheets 節點,操作選擇「Append or Update Row」: Matching Column(比對欄位):學號——以學號作為唯一識別,確保更新到正確的列 更新欄位:已寄提醒信(Yes/No) 設定為 Yes 來源資料從 Code 節點取得:{{ $('篩出明天有課').item.json.student_id }} 使用「學號」而非「列號」做比對有一個重要優點:即使試算表的排序或列數改變,更新也不會寫入錯誤的列。 若沒有這個步驟,下次排程執行時,系統會對同一批學員再次寄信,造成學員困擾與信任損失。 下一步:讓工作流更進階完成這套課前提醒後,你已省下每次開課前大量的手動作業時間。在下一堂進階課程中,我們將教你如何: 在信件中動態帶入專屬課程連結與 Google Meet 視訊網址 加入課前注意事項附件,打造更專業的學員體驗 建立多課程並行管理的工作流架構,適用於同時開設多門課的講師 常見問答 (FAQ)Q:Google Sheets 欄位名稱和教學不一樣,程式碼需要完整改寫嗎?A:不需要。只需在 Code 節點中修改對應的欄位名稱即可。例如,若你的日期欄位叫做「課程日期」而非「上課日期」,只需將程式碼中的 row["上課日期"] 替換為 row["課程日期"],其餘篩選邏輯完全不變。Google Sheets 回寫節點的 Matching Column 也需要同步修改。建議先在試算表統一欄位命名,後續維護會更輕鬆。 Q:如果想改成「開課前三天」寄送提醒,如何調整?A:在 Code 節點中,將日期計算的 +1 改為 +3 即可: 12345// 修改前(明天)tomorrow.setDate(tomorrow.getDate() + 1);// 修改後(三天後)tomorrow.setDate(tomorrow.getDate() + 3); 其餘的 Gmail 節點與回寫邏輯完全不需要變動。若你想同時在「三天前」和「一天前」各發一次提醒,建議分別建立兩條獨立的工作流,各自有各自的回寫欄位(如「已寄三日提醒信」和「已寄前日提醒信」),這樣狀態管理最清晰,不容易互相干擾。 Q:測試時不小心寄出太多信怎麼辦?A:在開發與測試階段,請採取以下保護措施: 修改收件人:在 Email 節點暫時將收件人從 {{ $json.Email }} 改為你自己的測試信箱 停用 Email 節點:在工作流中右鍵點擊 Email 節點,選擇「Disable」,僅觀察資料流輸出的 JSON 內容 限制資料筆數:在 Google Sheets 節點設定「Limit」,一次只讀取 1~2 筆資料進行測試 確認篩選條件與回寫狀態(Yes/No)都正確後,再關閉所有限制、改回真實收件人。 Q:為什麼系統會重複寄信給同一位學員?A:這是最常見的錯誤,通常由以下原因造成: 步驟五的回寫節點未正確執行:請確認工作流最後有成功更新「已寄提醒信(Yes/No)」欄位。執行後手動打開試算表,確認欄位值是否已改為 Yes。 欄位名稱不完全一致:Code 節點中的 row["已寄提醒信(Yes/No)"] 必須與 Google Sheets 的欄位標題逐字相同,包含括號與標點符號,差一個字就會讀到 undefined,導致條件永遠成立。 Matching Column 設定錯誤:回寫節點若 Matching Column 設定不正確,更新可能寫入到錯誤的列,讓原始列的狀態維持 No。 除錯建議:在 Code 節點篩選結果中,暫時加入 console.log(JSON.stringify(row)) 印出每筆資料的完整欄位名稱,就能快速確認試算表傳回的欄位名稱是否與程式碼一致。 Q:我的課程同時有多個梯次,同一門課有不同上課日期,工作流支援嗎?A:完全支援,工作流的設計本身就是逐筆比對每位學員的 ClassDate,因此同一門課的不同梯次只要在 Google Sheets 中各自有一列記錄,系統就能精準對應每位學員的實際上課日期,不會混淆。若你的報名表裡有多門課程,同樣適用,篩選邏輯只關心「日期」和「狀態」,與課程名稱無關。 Q:工作流使用的是 Gmail 節點,還是一般的 Email 節點?有什麼差別?A:本工作流使用的是 Gmail 節點(搭配 Gmail OAuth2 授權),不是通用的 Email (SMTP) 節點。兩者的差異如下: 節點 授權方式 適合情境 Gmail Google OAuth 授權 使用 Gmail 帳號發信,設定簡單、顯示名稱友善 Email (SMTP) 填入 SMTP 伺服器設定 使用自訂網域信箱(如 [email protected]) 若你已有 Google Workspace 帳號,Gmail 節點是最快速的選擇——完成 OAuth 授權後即可使用,無需額外的 SMTP 設定。若你希望以機構網域信箱發信,則改用 SMTP 節點,品牌形象更專業,但需要向你的郵件服務商取得 SMTP 憑證。 Q:如果某位學員的 Email 信箱填寫錯誤,工作流會報錯嗎?A:當 Email 節點遇到無效信箱(如格式錯誤或不存在的地址),工作流預設會中斷並報錯,導致後續學員的信件也無法寄出,狀態也不會被回寫。 建議解法:在 Email 節點的「Settings」中開啟「Continue On Fail」選項,讓工作流在遇到單一錯誤時跳過該筆資料,繼續處理下一位學員。同時,可以在後方加入一個通知節點(如 Line Notify 或 Slack),在寄信失敗時主動告警,讓你能即時追蹤並手動補寄。 Q:n8n 自架版(Self-hosted)和 n8n Cloud 的設定方式有差異嗎?A:工作流的節點邏輯和設定方式完全相同,差異主要在環境維護層面: n8n Cloud:免維護、開箱即用,適合個人講師或小型工作室,但有使用量限制與月費 Self-hosted:需自行部署伺服器(如 Railway、Render 或 VPS),免費且可無限使用,但需負責更新與備份 若你是第一次建立自動化工作流,建議先從 n8n Cloud 的免費方案開始體驗,熟悉流程後再考慮自架。

  • article-打造 Google 表單與 Gmail 自動回信報名系統 | (EP.1) n8n 自動化講師應用教學

    2026/5/2

    AI自動化 n8n 自動化講師應用
    打造 Google 表單與 Gmail 自動回信報名系統 | (EP.1) n8n 自動化講師應用教學

    為什麼你需要一套自動化報名系統?今天我們要實作一個很多講師與活動主辦人夢寐以求的工具:用 n8n 打造 Google 表單 × Gmail 全自動報名回信系統。 你是否曾有這樣的經驗:活動開放報名後,一個下午都在反覆開啟試算表,手動一筆一筆貼上確認信收件人,再逐一寄出?這種流程不只費時,還容易漏寄或寄錯。 透過本文介紹的 n8n 自動化流程,只要學員送出 Google 表單,系統就會自動: 彙整報名資料到試算表 篩選並建立正式名單 發送個人化確認信 更新寄件完成狀態 從此,報名通知這件事,你完全不需要再碰。 自動化工作流的五大關鍵步驟這套系統的核心邏輯分為以下五個步驟,環環相扣、自成閉環: 學員提交表單: 學員填寫包含姓名、學號、Email、課程名稱等資訊的 Google 報名表單並送出。 原始資料彙整: 表單回應自動同步至 Google 試算表的「原始資料」工作表,作為所有後續處理的來源。 正式名單拋轉: n8n 定期掃描原始資料,將尚未處理的新報名者篩選出來,整理後寫入「正式名單」工作表。 自動觸發寄信: 根據正式名單中的 Email 與報名資訊,系統透過 Gmail 自動發送個人化確認信,信件內容可包含上課時間、地點或 Google Meet 連結。 更新寄件狀態: 信件成功送出後,系統自動將該筆資料的寄信欄位標記為「Yes」,完成整個自動化閉環,方便隨時查閱進度。 關鍵設計概念: 以「寄信狀態是否為 Yes」作為判斷依據,確保每位報名者只收到一封確認信,不重複、不漏寄。 拆解 n8n 節點:五個節點完成全流程在 n8n 畫布中,我們用五個節點串起整套流程。以下逐一說明各節點的用途與設定重點: 1. Schedule Trigger(定時排程觸發)設定每分鐘(或自訂頻率)自動觸發流程。n8n 會定期「醒來」掃描試算表,確認是否有新報名者需要處理。 2. Google Sheets:讀取原始資料撈取「原始資料」工作表中所有尚未同步至正式名單的新資料列,作為後續節點的輸入來源。 3. Google Sheets:寫入正式名單將清洗過的報名資料(姓名、Email、課程代碼等)寫入正式名單工作表,同時預設「確認信」欄位為空白,作為待處理的標記。 4. Gmail Node(發送確認信)從正式名單中讀取 Email,套入預先設計好的信件範本,自動發送報名成功通知。信件內容可使用 n8n 的表達式(Expression)動態帶入學員姓名、課程名稱等個人化資訊。 5. Google Sheets:更新寄件狀態這是整套流程最關鍵的一步。Gmail 節點成功執行後,立即回寫試算表,將該筆資料的「確認信」欄位更新為「Yes」。若寄信失敗,此步驟不會執行,狀態維持空白,讓管理員一眼識別異常並手動補寄。 延伸應用:上課前提醒信這套邏輯同樣可以套用在「活動前一天的提醒信」:新增一個獨立的 n8n 排程,掃描正式名單中「提醒信」欄位為空白的學員,批次發信並標記「Yes」,一套模板即可重複使用。 常見問答 (FAQ)Q:我沒有程式背景,能自己做出這套流程嗎?A:完全可以!n8n 採用視覺化的節點拖拉介面,不需要撰寫任何程式碼。本文及對應的 YouTube 教學影片都有完整的逐步示範,只要跟著操作就能建立起整套流程。建議先用 n8n Cloud 試用版(免費)快速上手,再視需求考慮自架。 Q:n8n 的觸發頻率可以自訂嗎?每分鐘跑一次會不會太頻繁?A:可以完全自訂。「每分鐘」是教學中用於快速測試的設定。正式部署時,建議根據活動規模調整:一般課程每 5~15 分鐘跑一次即可。n8n 的 Schedule Trigger 支援 cron 語法,可設定任意時間間隔或指定時段(例如僅在工作時間執行)。 Q:如果報名者填錯 Email,系統會怎麼處理?A:若 Email 格式錯誤,Gmail Node 會拋出錯誤並中斷後續流程,「更新寄件狀態為 Yes」的步驟便不會執行。管理員只需過濾試算表中「確認信」欄位為空白的列,即可快速找出所有未成功寄達的報名者,進行人工確認與補寄。這個設計確保了問題的可追蹤性。 Q:這套流程使用的 Google 服務需要付費嗎?A:不需要。Google Forms、Google Sheets 與 Gmail 均為免費方案即可使用,沒有特殊 API 費用。n8n 本身提供免費的雲端試用方案(n8n Cloud),若需大量執行或長期使用,可選擇付費方案或自架免費的開源版本。 Q:確認信的內容可以個人化嗎?能自動帶入學員姓名嗎?A:可以。n8n 的 Gmail Node 支援 Expression(表達式)功能,可以直接引用前置節點傳入的欄位變數,例如 {{ $json.name }} 帶入姓名、{{ $json.course }} 帶入課程名稱。不需要任何程式基礎,直接在信件編輯框中點選「插入變數」即可完成個人化設定。 Q:這套系統可以同時管理多個課程或活動嗎?A:可以。有兩種常見做法:(1)分開工作表: 在同一份 Google 試算表中,為每個課程新增獨立的工作表,搭配對應的 n8n 流程或分支判斷節點;(2)統一管理: 在表單中加入「課程名稱」欄位,以此欄位進行篩選,在同一套 n8n 流程中以條件分支(If Node)分流處理不同課程的信件範本。 Q:這套流程可以套用到企業內部的報名系統嗎?A:完全適用。企業內部的講座、教育訓練、會議邀約等場景,只需替換 Google 表單欄位與 Gmail 信件範本即可直接套用。更進一步,企業用戶可搭配 Google Workspace 的共享試算表,讓多位管理員同時查看報名狀態,達到跨部門協作的效果。

  • article-n8n 專案前端架構指南:需要用 PWA 嗎?何時該選擇 Next.js 或 Vite?

    2026/4/30

    AI自動化 n8n 前端架構 PWA
    n8n 專案前端架構指南:需要用 PWA 嗎?何時該選擇 Next.js 或 Vite?

    在執行眾多 n8n 專案時,開發者與系統架構師最常面臨的一個核心問題就是:「前端要不要做成 PWA?如果要,那還需要用 Next.js 嗎?」 這篇文章將為你釐清技術盲點,提供一份實務上的前端架構決策指南,幫助你把預算與開發時間花在刀口上。 什麼是 PWA?為何它與 n8n 專案是絕配?PWA(Progressive Web App,漸進式網路應用程式)用一句話來解釋就是: 讓網站用起來像 App,但本質上它仍然是一個網站。 初學者這樣理解: 你可以把 PWA 想像成「偽裝成 App 的網頁」。使用者不需要去 App Store 下載安裝,直接在手機瀏覽器打開你的網址,按一下「加入主畫面」,之後就能像一般 App 一樣點 Icon 啟動,看不到網址列,有全螢幕體驗,甚至能收到推播通知。 PWA 賦予了網頁端以下幾個強大的能力: 可以直接加入手機主畫面(擁有專屬 App Icon) 支援全螢幕開啟(隱藏瀏覽器的網址列與 UI) 支援系統級的推播通知 (Push Notifications) 具備基本離線快取能力(即使暫時斷網,頁面也不會整片空白) 啟動速度大幅提升 為什麼 n8n 非常適合導入 PWA?n8n 是什麼? 簡單說,n8n 是一套「自動化流程工具」,讓你不用寫程式也能串接各種服務(例如:收到一封 Email 就自動發 Slack 通知、表單送出就自動建立一筆資料庫記錄)。n8n 本身負責後端邏輯,而前端介面(也就是使用者看到、點擊的那個畫面)就是我們這篇文章要討論的重點。 通常 n8n 的前端應用場景會包含:表單填寫送出 Webhook、點擊按鈕觸發 Workflow、透過 Dashboard 查看自動化執行結果,以及接收 Workflow 的成功或失敗通知。 這類型的介面本質上是**「操作型工具 + 行動使用場景」**,這恰好就是 PWA 技術最能發揮價值的領域。 導入 PWA 的 3 大實質優勢1. 沉浸式的「工具感」大幅提升使用 PWA,使用者的心智模型會從「打開一個網頁」轉換成「打開一個專屬 App」。對於企業內部工具 (Internal Tools) 或提供給特定客戶的專用系統來說,這種體驗上的升級是非常顯著的。 2. 終極的低安裝門檻無需經過 App Store 或 Google Play Store 繁瑣的流程: 免審核、免上架費用 不用等待應用程式更新發佈 使用者只需打開網址,點擊「加入主畫面」即可完成安裝 3. 即時推播通知(完美契合自動化流程)這點對於 n8n 專案極具價值。你可以針對以下情境發送推播: Workflow 成功/失敗通知 Webhook 觸發的即時提醒 長時任務完成提示這能讓自動化流程變得「即時且有感」。 導入前必看的現實面與限制在決定使用 PWA 前,你必須了解以下幾個現實狀況: PWA 不會自動拯救糟糕的 UX: 真正影響使用者體驗的,是你的 UI 介面是否有做到 Mobile-first(行動優先)以及操作流程是否足夠簡化。 iOS 系統的先天限制: 雖然蘋果已開放支援 Web Push,但在背景執行能力上依然較弱,且部分進階硬體 API 仍受限。 離線功能不是 n8n 專案的重點: n8n 的核心極度依賴 Server 與 API。PWA 的離線功能頂多讓前端「開得起來」,但在沒有網路的情況下,並無法執行實質的自動化操作。 架構抉擇:你的 n8n 專案真的需要 Next.js 嗎?先講結論:多數 n8n 前端的 PWA 專案,根本不需要用到 Next.js。 初學者補充:Vite 與 Next.js 都是什麼? Vite(發音:維特)是一個超快速的前端開發工具,幫你打包程式碼、啟動本地開發伺服器。它做出來的網站是「純前端網頁」,由瀏覽器負責全部的渲染工作。 Next.js 則是建立在 React 上的全端框架,除了前端以外,它還能在伺服器端產生 HTML(SSR),讓搜尋引擎更容易抓取頁面內容,也可以寫後端 API。代價是架構更複雜、部署要求更高。 什麼情況推薦「使用 Vite 就好」?如果你的專案屬於以下類型,強烈建議使用 Vite: 企業內部營運工具(員工才看得到,不需要被 Google 搜尋到) 封閉式的客戶操作介面(要登入才進得去) 單純的 Webhook 觸發頁面或資料表單 登入後才能使用的系統 完全不需要 SEO(搜尋引擎優化) 💡 推薦技術組合(Vite 方案): 1234// 前端核心配置建議Framework: Vite + React (或 Vue)Styling: Tailwind CSSPWA Plugin: vite-plugin-pwa 優點: 開發極快、架構單純、靜態部署超輕量且成本極低(部署到 Cloudflare Pages 或 Netlify 免費方案就夠用)。 什麼情況才「必須使用 Next.js」?當你的專案具有以下需求時,Next.js 才是正確的選擇: 需要 SEO 排名的公開頁面(如官方網站、部落格、產品介紹頁) 包含 Landing Page 或大量的內容行銷頁面 需要 SSR(伺服器端渲染)來優化首次載入速度 需要內建後端 API(透過 API Routes,例如自行處理付款或發送 Email 而不想另外建後端) 具備複雜的登入與權限控管機制 想將「公開行銷頁 + 客戶入口網站 + 後台系統」整合在同一個全端專案中 一個簡單的判斷標準: 問自己「這個頁面,我希望在 Google 上搜尋得到嗎?」如果答案是「不需要,使用者都是登入後才進入的」,那麼 Vite 就夠了。 n8n 專案實務推薦架構與 PWA 最小實作指南🏆 最常用且高效的推薦架構這是目前業界開發 n8n 前端最穩定且快速的技術棧: 核心框架: Vite + React 樣式管理: Tailwind CSS 狀態與資料獲取: TanStack Query (React Query) 會員與權限: Supabase 或 Firebase Auth 後端自動化: n8n Webhook / API PWA 支援: vite-plugin-pwa 🚀 PWA 最小可行性實作 (MVP) 先做這 4 步不需要一開始就追求完美的 PWA 功能,先用最低成本完成以下設定,體驗就能立即升級: 建立並配置 manifest.json 檔案。這個檔案告訴瀏覽器「我這個網站是一個 App」,包含 App 名稱、顏色主題、Icon 路徑等基本資訊。 將顯示模式設定為全螢幕:"display": "standalone"。standalone 模式讓使用者從主畫面點開 App 時,不會看到瀏覽器的網址列,視覺上更像一個真正的 App。 準備並配置各尺寸的 App Icon。至少需要 192x192 和 512x512 兩種尺寸的 PNG 圖示,分別對應一般螢幕和高解析度螢幕。 設定基本的 Service Worker(僅針對 UI 靜態資源進行快取)。Service Worker 是一段在背景執行的程式,負責快取你的 HTML、CSS、JS 等靜態檔案。使用 vite-plugin-pwa 時,這部分大多可以自動產生,不需要手動撰寫。 (進階優化:未來可再逐步加入搭配 n8n 的 Push 通知、離線 Fallback 頁面及 Background Sync)。 常見問答 (FAQ)Q:我完全沒有前端開發經驗,這篇文章說的 Vite、React、Next.js 到底是什麼關係?A:用一個比喻來解釋:你想蓋一棟房子(網站)。 React 是你蓋房子用的「磚塊材料」,負責讓畫面變得互動、動態。 Vite 是「建築工具箱」,幫你把磚塊快速組裝起來,在本機開發時極速預覽成果。它蓋出來的是一棟「只有客戶端(瀏覽器)能自己運作」的房子。 Next.js 則是一套「更豪華的建築解決方案」,除了客戶端以外,還內建了伺服器(工廠),可以在送到瀏覽器之前就先把頁面做好,讓 Google 搜尋引擎更容易讀懂。代價是架構更複雜、需要付費的伺服器來部署。 對於大多數 n8n 的配套工具頁面來說,Vite + React 就已經非常足夠。 Q:我的 n8n 專案主要是內部人員每天使用,導入 PWA 值得嗎?A:非常值得!內部工具是 PWA 效益最高的場景。員工只要將網頁加入手機主畫面,就能獲得像原生 App 一樣的全螢幕體驗與快速啟動,大幅降低每天開啟瀏覽器輸入網址的摩擦力。此外,若搭配推播通知,工作流程完成時能主動提醒員工,不需要員工自行刷新頁面確認。 Q:如果我的前端介面只是偶爾用來看 n8n 的執行 Dashboard,還需要做 PWA 嗎?A:幫助有限。如果使用頻率極低(例如一週看一次的報表或儀表板),使用者通常不會有意願將它加入主畫面。這種情況下,只需確保網頁具備良好的響應式設計 (RWD)(也就是在手機上瀏覽時,版面能自動調整,不會跑版)即可,PWA 帶來的額外好處相對有限。 Q:為了追求 SEO,我是不是一定要把架構改成 Next.js?A:取決於你的頁面性質。如果該頁面是「產品官網」或「部落格」,那麼需要 Next.js 的 SSR/SSG 來優化 SEO(因為這些技術讓 Google 的爬蟲更容易讀取頁面內容)。但如果你只是做一個「登入後才能操作的 n8n 自動化工具台」,搜尋引擎爬蟲根本進不去,此時用 Vite 建立 SPA (單頁應用程式) 反而是最省時省力的做法。 什麼是 SSR 和 SSG? SSR(Server-Side Rendering,伺服器端渲染): 每次有人打開頁面,伺服器臨時產生完整的 HTML 再回傳,適合內容會頻繁更新的頁面(如新聞網站)。 SSG(Static Site Generation,靜態網站生成): 在部署前就把所有頁面預先產生成靜態 HTML 檔案,速度最快,適合不常變動的頁面(如部落格、產品介紹頁)。 Q:我該怎麼讓使用者在 iPhone 上也能「加入主畫面」?A:在 iPhone 上,使用者需要用 Safari 瀏覽器(不能是 Chrome)打開你的網址,點選下方的「分享」按鈕(方塊加箭頭圖示),再選擇「加入主畫面」。iOS 的限制是,只有 Safari 支援 PWA 的加入主畫面功能,其他瀏覽器不行。建議在你的網頁上放置一段操作說明或引導提示,方便不熟悉的使用者找到這個功能。 Q:Push 通知(推播)要怎麼跟 n8n 搭配使用?A:整體流程是這樣的: 使用者在你的前端網頁上點擊「允許通知」。 瀏覽器產生一組專屬於該使用者設備的「推播憑證」(Push Subscription),你的前端把這組憑證儲存到資料庫(例如 Supabase)。 當 n8n 的 Workflow 完成或出現特定事件時,n8n 呼叫一個負責發送推播的 API(例如用 Web Push 協議發送)。 使用者的手機收到通知。 這個流程不需要額外建立推播伺服器,整合成本相對可控。 Q:我現有的 n8n 前端已經用 Vite 做好了,中途改成 Next.js 值得嗎?A:通常不建議,除非出現明確的需求驅動(例如你突然決定要把這個工具做成公開的 SaaS 產品、需要 SEO 流量)。架構遷移的成本遠比想像中高:除了移植元件外,還需要調整路由邏輯、部署方式,以及原本不需要的伺服器設定。先問自己「Vite 的哪個限制讓你卡住了?」,如果說不出具體的問題,那就不需要換。

  • article-Instagram Graph API 打造 IG 自動發文系統 (結合 Cloudinary) | (EP11) n8n 自動化 API 串接教學

    2026/4/18

    AI自動化 n8n API串接 社群行銷
    Instagram Graph API 打造 IG 自動發文系統 (結合 Cloudinary) | (EP11) n8n 自動化 API 串接教學

    在上一篇教學中,我們介紹了 如何透過 Facebook Graph API 自動發布多圖貼文。今天,我們將進一步把自動化版圖擴展到 Instagram (IG)。 透過 n8n、Instagram Graph API,並結合 Cloudinary 作為圖片的公開圖床,我們可以打造一套「一鍵自動多平台發文」的系統。這篇文章將帶你拆解整個 n8n 工作流程,並一步步完成必要的 API 權限申請。 系統運作流程解析:IG 自動發文的底層邏輯在正式動手之前,我們先理解 n8n 節點的運作邏輯。要透過 API 發布 IG 貼文,流程如下: 表單提交 (Form Submission): 接收要發布的文字內容與圖片檔案。 圖片檢查與圖床轉換: IG API 嚴格規定,圖片必須是一個「公開可存取的網址 (Public URL)」。因此,我們必須先將圖片上傳至 Cloudinary 以取得公開網址。 建立 Instagram 容器 (Create Container): 根據 Meta 官方內容發佈文件,我們需要先用圖片網址與貼文內容建立一個 Media Container。 等待緩衝 (Wait): 設定約 30 秒的緩衝時間,避免 Meta 伺服器處理過慢導致後續請求失敗。 正式發佈 (Publish): 獲取 Container ID 後,執行最終的發佈動作。 延伸閱讀: 更詳細的 n8n IG API 串接原理,可參考 n8n Instagram API 實戰指南。 步驟一:如何設定 Meta 開發者應用程式與取得 IG 權杖?要讓系統代為發文,我們必須先在 Meta 開發者平台申請專屬的應用程式與存取權杖 (Access Token)。 1. 建立 Meta 應用程式前往 Meta 開發者應用程式介面 (Apps): 點擊「建立應用程式」,選擇「其他」>「企業商家」。 填寫應用程式名稱(例如:n8n-ig-auto-post)與聯絡信箱。 2. 設定隱私權政策網址為了讓應用程式能順利上線,Meta 要求提供隱私權政策網址: 可利用免費工具 PrivacyPolicies.com 快速生成一份基本的隱私權條款。 將生成的專屬網址複製,貼回到 Meta 應用程式的「基本資料 > 隱私權政策網址」中並儲存。 將應用程式狀態切換為 「上線 (Live)」。 3. 新增 Instagram 測試人員與轉換專業帳號由於應用程式尚未經過繁瑣的官方審查,我們需要將自己的 IG 帳號加入「測試人員」: 在 Meta 後台左側選單進入「應用程式角色 > 角色」。 新增「Instagram 測試人員」,輸入你的 IG 帳號。 重要提醒: 你的 IG 帳號必須切換為 「專業帳號 (商業或創作者)」,否則無法透過 API 發文! 打開手機 IG App,進入「設定 > 網站權限 > 應用程式和網站 > 測試人員邀請」,點擊「接受」。 4. 取得 Access Token 與 IG ID 回到 Meta 開發者後台,設定「Instagram 圖形 API」。 使用「圖形 API 測試工具 (Graph API Explorer)」。 勾選所有與 instagram_manage_* 及 instagram_content_publish 相關的權限。 點擊「Generate Access Token (產生存取權杖)」,並將這串落長的 Token 複製保存。 同時記下你的 Instagram ID,這兩個值將會填入 n8n 的設定中。(註:測試用的 Token 預設有效限期約為 2 個月,過期需重新產生。) 步驟二:為什麼需要 Cloudinary?如何設定免憑證上傳?如前所述,IG Graph API 不接受直接傳送本機圖片,只接受公開網址。我們使用 Cloudinary 來做自動化圖床。 1. 取得 Cloud Name登入 Cloudinary 控制台,在 Dashboard (儀表板) 找到你的 Cloud Name,這會是 n8n API 呼叫的基礎路徑。 2. 設定 Unsigned Upload Preset (無簽章上傳預設)在設定自動化時,為了安全性與便利性,我們 不使用 API Key 與 API Secret,而是改用 Upload Preset Name。 進入 Cloudinary 的「Settings > API Keys > Upload」。 點擊「Add Upload Preset」。 將 Signing mode 設定為 Unsigned。 設定一個你專屬的 Upload preset name (例如:n8n-try-2026),並設定要存放的資料夾名稱 (Folder)。 儲存後,將這個 Preset Name 複製下來。 為什麼不直接使用 API Key?將 API Secret 寫死在前端或簡單的工作流中存在資安風險。Unsigned Upload Preset 允許你在不暴露核心密鑰的情況下,讓系統把檔案上傳到指定資料夾,是自動化流程中最推薦的簡化做法。詳情可參考這篇探討:為何 n8n 教學愛用 Cloudinary Upload Preset?安全與便利的平衡。 步驟三:整合 n8n 節點並執行測試最後,我們回到 n8n 介面,將剛剛取得的參數填入對應的資料表或節點中: Cloudinary 節點設定: 將 Cloud Name 與 Upload Preset Name 填入。 Instagram 節點設定: 將 IG ID 與 Access Token 填入 Authorization 欄位。 觸發流程: 打開 n8n 的表單提交 (Form Trigger),上傳一張圖片並輸入測試文字。 驗證結果: 執行流程後,打開你的 Instagram 頁面,就可以看到圖片已經成功透過 n8n 自動發布了! 常見問答 (FAQ)Q:為什麼流程執行成功,但 IG 上卻沒有出現貼文,或出現權限錯誤?A:這通常是最常見的設定問題,建議依序檢查以下幾項: 你的 IG 帳號是否已切換為 專業帳號(創作者或商業)。 該 IG 帳號是否已正確加入 Meta App 的 Instagram 測試人員,並且已在手機上接受邀請。 產生 Access Token 時,是否有勾選 instagram_content_publish、instagram_basic 等必要權限。 你的 IG 是否有正確綁定對應的 Facebook Page。許多 Meta API 權限是透過粉專與商業資產關聯來驗證的。 如果以上都確認無誤,建議回頭檢查 n8n 的 HTTP Request 回傳內容,Meta 通常會在錯誤訊息中直接指出是權限不足、帳號資格不符,還是參數格式有問題。 Q:為什麼圖片已經上傳到 Cloudinary,但 Instagram API 還是說 image_url 無效?A:因為「有網址」不等於「符合 IG API 可讀取的公開網址」。你需要確認: 該圖片網址可以在 無痕模式 直接開啟,不需要登入、不會跳轉、也不會出現權限限制。 網址指向的是 實際圖片檔,而不是預覽頁、下載頁或帶驗證機制的暫時連結。 圖片格式為常見可支援格式,例如 jpg 或 png。 圖片尺寸與比例不要過於極端,避免 Meta 在建立容器時失敗。 最穩定的做法,就是使用 Cloudinary 上傳後取得的 secure_url 當作 image_url,不要自行拼接其他可能會失效的連結。 Q:為什麼流程中要加 Wait 節點?可以直接建立容器後馬上 Publish 嗎?A:理論上可以連續呼叫,但實務上不建議。因為 Meta 在建立 Media Container 後,還需要一點時間處理圖片內容;若你太快發送 Publish 請求,就可能出現容器尚未就緒、發文失敗,或偶發性的 API 錯誤。 因此在 n8n 中加入約 20 到 30 秒的 Wait,是一種很常見也很實用的穩定化做法。如果你想再更精準一些,也可以改成輪詢 Container 狀態,確認處理完成後再執行 Publish。 Q:這套流程可以直接發 Reels、限時動態或多張輪播貼文嗎?A:這篇教學的流程主要針對 單張圖片貼文。若你要發: 輪播貼文:通常需要建立多個媒體項目,再組成 Carousel Container,流程會比單張圖複雜。 Reels:需要改用影片上傳與對應的發佈流程,參數與等待時間也不同。 限時動態:支援情況與發佈方式需依 Meta API 當前規範確認,不能直接套用一般貼文邏輯。 也就是說,這篇文章適合作為「IG 自動發文入門版」,如果你後續要延伸到更多貼文型態,建議再額外拆成不同 workflow 來做。 Q:Cloudinary 的 Unsigned Upload 安全嗎?會不會被別人亂傳圖片?A:Unsigned Upload 本質上是只要知道 Preset Name 就能上傳,因此有一定風險。但你可以透過 Cloudinary 後台針對該 Preset 設定「檔案格式限制」、「檔案大小限制」甚至是「上傳後轉檔規則」,來避免遭惡意濫用。對於個人自動化用途而言,比起洩漏 API Secret,這是相對安全且輕量的做法。 如果你是要提供給團隊或正式商業場景使用,建議再往前一步: 將上傳來源限制在特定流程或後端。 規劃專用資料夾,方便管理與清理。 定期輪替 Upload Preset,避免長期暴露固定入口。 監控 Cloudinary 使用量,避免異常流量造成額外成本。 Q:我的自動發文系統突然失效了,發生了什麼事?A:最可能的原因是 Meta Access Token 過期。透過 Graph API 測試工具生成的 Token 通常只有 60 天左右的效期。若要長期自動化,建議在到期前透過 API 延長權杖效期,或是定期手動重新生成一次並更新至 n8n 中。 除了 Token 之外,也建議同步檢查: Meta App 是否仍維持上線狀態。 測試帳號是否仍保有測試人員身分。 Cloudinary Preset 是否被修改、停用或刪除。 n8n 中的節點參數是否被其他人誤改。 Q:這套流程適合正式營運使用嗎?還是只適合測試?A:可以用於正式營運,但前提是你要把它從「可跑」升級成「可維護」: 權杖更新機制要制度化,不能等過期才手動補救。 n8n 流程要加上錯誤通知,例如失敗時寄 Email、發 Slack 或 LINE Notify。 圖片、文案、發文時間最好有資料表或資料庫可追蹤。 若有多人使用,建議加入審核機制,避免錯發或重複發文。 如果你只是個人品牌、小型工作室,這篇教學已足夠作為第一版;但若你是企業團隊,後續應把監控、權限管理與例外處理一併補上。 Q:如果我想把這個流程擴充成「一鍵同步發 Facebook + Instagram」,要怎麼做?A:這正是 n8n 很適合發揮的地方。你可以把「表單輸入」或「內容資料表」當成單一來源,接著分流到不同平台節點: 一條流程處理 Cloudinary 圖片上傳。 一條分支送往 Facebook Graph API。 另一條分支送往 Instagram Graph API。 最後把各平台回傳結果寫回 Google Sheets、Airtable 或 Notion。 這樣你就能把原本重複操作的社群發文,整理成一套真正可複用的多平台內容發布系統。

  • article-使用 Facebook Graph API 自動發布多圖貼文 | (EP10) n8n 自動化 API 串接教學

    2026/4/4

    AI自動化 n8n API串接 社群行銷
    使用 Facebook Graph API 自動發布多圖貼文 | (EP10) n8n 自動化 API 串接教學

    如果你正在找「n8n Facebook 多圖貼文教學」、「Facebook attached_media 怎麼設定」或「n8n 如何一次發布多張圖片到 Facebook」,這篇就是針對這些問題整理的實戰版本。 先前我們分享過如何透過 n8n 模板自動發布「單圖加單文」到 Facebook。今天這篇文章,我們將進一步把流程升級成一次發布多張圖片的 Facebook 貼文,並直接拆解多數人最常卡住的 attached_media、/photos 與 binary 判斷問題。 如果你還沒完成 Page ID、長期 Page Access Token 或單圖發文設定,建議先閱讀上一篇:n8n 串接 Facebook 自動發文教學:Meta API、Page ID、長期 Token 完整指南。 這篇文章可以把它理解成上一篇的進階版:前一篇解決「先發得出去」,這一篇解決「如何穩定改成多圖發文」。 如何在 n8n 表單中開啟多檔案上傳功能?在原本的預設模板中,表單 (Form) 節點僅支援單張圖片與一篇文章。若要實現多圖上傳,我們必須先從觸發器 (Trigger) 著手修改。 請進入 n8n 的 Form Trigger 節點,找到設定並勾選 Multiple Files 功能。開啟此選項後,表單就能一次接收多張圖片的輸入。為了確認功能正常運作,建議先進行測試,例如輸入標題「test 0403 多圖」並同時上傳三張圖片,藉此確認資料是否成功進入後續的工作流中。 破解 API 迷思:為什麼 Facebook Graph API 其實不吃 JSON?這是在串接 Facebook Graph API 時最容易踩到的坑!許多人在查閱 Meta 官方文件時,會看到官方範例給的都是 JSON 格式。然而,當你實際在 n8n 中將 Content-Type 設為 JSON 時,常常會遇到發文失敗或行為異常的狀況。 經過測試與 AI 的輔助分析,我們得出了一個重要結論:Facebook Graph API 預設其實是接收 url-encoded 與 form-data 格式,而非 JSON。 在 n8n 的 HTTP Request 節點中,最佳的實踐方式是: 主體內容 (Body): 使用 form-urlencoded 模式,將 Token、Message 與整理好的 attached_media 傳送出去,這樣不僅容易發送,穩定度也最高。 圖片上傳 (Photo Upload): 使用 form-data 的方式來傳送二進位 (Binary) 的圖片檔案。 請果斷放棄使用 JSON 格式來修改多圖貼文,直接採用 form-urlencoded 與 form-data,能幫你省下大量的除錯時間。 實戰解析:多圖貼文真正要改的是什麼?很多人第一次改 Facebook 多圖貼文時,會以為只要把 attached_media[0] 改成 attached_media[1]、attached_media[2] 就好。實際上不是這樣。 多圖貼文的核心不是「多加幾個欄位」,而是整個流程要改成先上傳圖片、再集中發文。 正確流程如下: 表單允許一次上傳多個檔案 把每張圖拆成獨立 item 每張圖各自呼叫 POST /photos,並設定為未發佈 收集每張圖回傳的 photo id 最後只呼叫一次 POST /feed,把所有 media_fbid 一起送進 attached_media 換句話說,你不是直接把多張圖片塞進同一次照片上傳請求,而是先把每張圖變成 temporary photo,最後再用一篇貼文把它們組起來。 最短版修改清單如果你手上已經有上一篇的單圖工作流,要改成多圖版,實務上先完成這 5 件事就夠了: Form Trigger 把 Multiple Files 改成 true 原本的「如果圖片不存在」條件,改成檢查 Object.keys($binary ?? {}).length === 0 新增一個 Code 節點,把多張圖片展開成多個 item 新增一個 Code 節點,把所有 photo id 整理成 attached_media 最後發文的節點,把 attached_media[0] 改成整個 attached_media 陣列 如果你是用既有模板直接改,這 5 項通常就是變更範圍的 80%。剩下的問題,多半都是權限、Graph API 版本,或請求格式設定錯誤。 多圖上傳的資料處理與判斷邏輯1. 先展開圖片,再逐張上傳表單收到多張圖片後,n8n 內部通常不會直接變成多筆獨立資料,而是先包在同一個輸入裡。這時要先新增一個節點,把圖片展開成一張圖一個 item,後面的 Facebook 上傳節點才能逐張處理。 這一步的重點不是「看起來有三張圖」,而是流程裡真的要變成三個可迭代的 item。只有這樣,後面的 POST /photos 才能對每張圖各自拿到一個 photo id。 2. 每張圖都先走 POST /photosFacebook 多圖貼文不是直接把多張 binary 一次送到 /feed。正確做法是每張圖先打一次 /{page_id}/photos,並設定為不立即發佈,讓 Facebook 先建立暫存照片。 等每張圖都成功回傳 ID 之後,才進到最後一個發文節點。這也是很多人一直測不通的原因,因為他們跳過了「先建立 temporary photo」這一步。 3. 最後一次把所有 media_fbid 組回 attached_media當你拿到多張圖的 photo id 後,接下來不是再一張一張發貼文,而是把所有 ID 整理成 Facebook 要的格式,例如: 12345[ { "media_fbid": "photo_id_1" }, { "media_fbid": "photo_id_2" }, { "media_fbid": "photo_id_3" }] 最後只呼叫一次 POST /feed,並把整包 attached_media 傳出去,這樣 Facebook 才會把它視為同一篇多圖貼文。 4. 「是否有圖片」的判斷邏輯也要一起改單圖流程常見的寫法,通常是假設只有一個固定欄位,例如 binary.data 或某個指定圖片名稱。但多圖流程下,這種判斷很容易失準,因為二進位檔案不再只有單一鍵值。 比較穩的做法,是直接檢查目前是否真的存在任何 binary 檔案: 12345if (Object.keys($binary ?? {}).length === 0) { // 沒有圖片,走純文字貼文流程} else { // 有圖片,走圖片上傳與多圖發文流程} 這段寫法的好處是,不需要綁死某個圖片欄位名稱,對單張圖、多張圖、甚至沒有圖片的情境都比較穩。 可直接參考的 Code Node 範例如果你想更快落地,下面這兩段可以作為 Code 節點的參考起點。實際欄位名稱還是要依你的工作流資料結構微調,但核心思路就是這樣。 範例 1:展開多張圖片這個節點的目的是把同一筆輸入裡的多張 binary 圖片,拆成多個 item,讓後面的 POST /photos 可以逐張執行。 1234567891011121314const binaryEntries = Object.entries($binary ?? {});return binaryEntries.map(([key, file]) => { return { json: { ...$json, binaryKey: key, fileName: file.fileName ?? key, }, binary: { [key]: file, }, };}); 這段的重點是: 先用 Object.entries($binary ?? {}) 取出所有圖片 每張圖各自回傳成一個 item 保留原本的 $json,避免後面發文文案或其他欄位不見 範例 2:整理成 attached_media當每張圖片都上傳到 POST /photos 後,Facebook 會回傳各自的 id。接下來就要把這些 id 整理成最後發文節點要吃的格式。 12345678910111213const attached_media = $input.all().map((item) => { return { media_fbid: item.json.id, };});return [ { json: { attached_media, }, },]; 如果你的最後一個發文節點還需要貼文文字、Page ID 或其他欄位,就記得在這裡一起帶回去,不要只剩 attached_media。 最後發文節點要注意什麼?整理完之後,最後一個 POST /feed 節點要送的,不再是單一的 attached_media[0],而是整包 attached_media。也就是說,這一步的重點不只是欄位名稱改掉,而是前面的資料形狀已經從單張圖邏輯,變成多張圖陣列邏輯。 跨平台自動發文的策略與考量在學會了 Facebook 多圖發文後,你可能會想:「我能不能把這個多圖工作流直接套用到 Instagram、Threads、X (Twitter) 或 LinkedIn 上?」 這裡要特別提醒,每個社群平台的 API 設計與支援度皆不相同。Facebook 接受的 attached_media 多圖陣列格式,放到其他平台可能會導致報錯。如果你追求的是「一鍵同時發布到所有平台」,那麼維持**「一圖一文」**會是最安全、兼容性最高的方式。 然而,如果你是為了深入學習 API 串接與自動化邏輯,強烈建議你親手實作一次專屬於 Facebook 的多圖發文流程。這能幫助你透徹理解 API 格式的差異、陣列資料的轉換,大幅提升你的 n8n 實戰能力! 常見問答 (FAQ)Q:多圖貼文是不是只要多加幾個 attached_media[1]、attached_media[2] 就可以?A:不行。這是最常見的誤解。Facebook 多圖貼文的重點不是多塞幾個欄位,而是要先讓每張圖各自上傳成未發佈照片,再把所有 photo id 組成 attached_media 後一次送進 POST /feed。如果你只是在原本單圖節點上多加幾個欄位,通常流程會不穩,或根本不會被 Facebook 正確識別成同一篇多圖貼文。 Q:在 n8n 裡,正確的多圖發文順序是什麼?A:最穩的順序是這樣: 表單開啟多檔上傳 將多張圖展開成多個 item 每張圖各自呼叫 POST /photos 收集所有回傳的 photo id 最後呼叫一次 POST /feed,把所有 media_fbid 傳進 attached_media 如果你的流程不是這個順序,通常就是之後會卡住的地方。 Q:為什麼我照著官方文件用 JSON 傳多圖,還是一直失敗?A:因為官方文件的範例格式,不代表在 n8n 裡就是最穩的做法。實務上,Facebook Graph API 在這類發文情境下,通常用 application/x-www-form-urlencoded 與 multipart/form-data 會更穩。簡單說: 圖片上傳用 form-data 最後發文用 form-urlencoded 如果你整段流程都硬用 JSON,常見結果就是欄位格式對了,但請求仍然失敗,或 Facebook 不照你預期解析。 Q:為什麼「是否有圖片」這個判斷在多圖版容易壞掉?A:因為單圖流程通常只檢查某一個固定欄位,例如 binary.data。但多圖上傳時,binary 的結構不一定只會有單一鍵值,所以原本那種寫死欄位名稱的判斷方式常常會失準。比較穩的寫法是: 1Object.keys($binary ?? {}).length === 0 這樣你判斷的是「現在到底有沒有任何圖片檔」,而不是賭某個欄位名稱剛好存在。 Q:表單已經開了 Multiple Files,為什麼還是不能直接發多圖?A:因為 Multiple Files 只解決「前端可以一次上傳多張圖」,沒有幫你完成後面的資料整理。你還是得自己把圖片展開、逐張上傳、收集 ID、再整理成 attached_media。也就是說,表單只是入口,多圖貼文能不能成功,關鍵仍然在後面的工作流設計。 Q:多圖流程測試時,最少要驗證哪些情境?A:至少要測這 3 種: 沒有圖片,只發純文字 只有 1 張圖片 一次上傳多張圖片 如果這三種都能正常執行,代表你的條件分流、binary 判斷、圖片上傳與最後發文邏輯大致是穩的。只測「三張圖剛好成功一次」其實不夠,因為很多錯誤都發生在無圖或單圖情境切換時。 Q:如果我要沿用上一篇單圖模板,最少要改哪些地方?A:最小修改範圍就是本文前面那 5 項: Form Trigger 開啟 Multiple Files 調整「是否有圖片」判斷 新增圖片展開節點 新增 attached_media 整理節點 把最後發文欄位從單一 attached_media[0] 改成整個 attached_media 你可以把它理解成:前面多了一段「圖片預處理」,最後一段則從「單圖發文」改成「多圖組裝後發文」。 Q:如果發文節點一直報權限錯誤,是多圖流程寫錯了嗎?A:不一定。多圖流程錯誤與權限錯誤是兩件事。如果你看到的是 OAuth、permission、scope 相關訊息,通常先檢查的不是 attached_media,而是: 你現在用的是不是正確的 Page Token 權限是否包含 pages_manage_posts Page ID 是否對應到同一個粉專 這類問題比較接近授權設定,而不是多圖組裝本身。需要的話可以回頭對照上一篇的 Token 教學一起排查。 Q:這篇流程可以直接套到 Instagram 或其他平台嗎?A:不建議直接照搬。這篇的重點是 Facebook Page 的多圖貼文流程,而 attached_media 這種組法本身就帶有平台特性。若你是做跨平台自動發文,最穩的策略通常還是先維持「一圖一文」,再依各平台 API 能力逐一擴充,而不是假設 Facebook 的多圖格式能通用。 參考資料 Meta Developers:Page Posts 上一篇:n8n 串接 Facebook 自動發文教學