n8n webhookn8n LINE webhookn8n Slack webhookn8n Stripe webhookevent-drivenproduction

n8n webhook 實戰:接收 LINE/Slack/Stripe 事件並觸發多步驟自動化

n8n webhook 不是接通就完事。本文用 LINE Messaging API、Slack Events API、Stripe webhook 三大主流事件源,拆解多步驟分支設計、簽章驗證、去重、200 race condition,附 production 配置範例與 30 天落地檢核表。

N8NMarket 2026年5月15日 16 分鐘閱讀

n8n webhook 真正的價值不是「接通網址」,而是把 LINE、Slack、Stripe 這類外部事件變成多步驟自動化的起點。本文用三條主線事件源示範完整 production 設計:簽章驗證、payload 去重、200 OK race condition、Switch 分支與 Sub-Workflow 解耦,最後給一張 30 天落地檢核表。看完直接能複製進你的 n8n instance。

webhook 接事件前,先想清楚這三件事

很多人第一次串 webhook,看官方文件填好 URL、貼進外部服務後台就以為完工。實際在 production 跑兩週,三類問題會浮上來:上游重送導致同一事件處理兩次、簽章沒驗導致誰都能 POST 假資料、處理時間太長導致上游 timeout 又重試。這三件事決定 webhook 能不能撐住流量。

你接的是「event」不是「request」

LINE 的 message event、Slack 的 message.channels event、Stripe 的 charge.succeeded,本質上都是上游服務「告訴你發生了什麼」,不是用戶在等你回應。這代表三件事:

  • 上游會 retry。LINE 在 timeout 後會重送,Stripe 預設 3 天內最多 16 次重試,Slack 失敗後 1 分鐘到 1 小時內重送。webhook handler 不做去重,等於同一筆訂單可能扣 16 次。
  • 回 200 是「我收到了」,不是「我處理完了」。多步驟工作流跑 30 秒,webhook 要在 5 秒內回 200,剩下的非同步跑。
  • 簽章驗證是 webhook 的「身分證」。沒驗簽章,攻擊者隨便發一筆 charge.succeeded 你就送貨,這種事 2024 Stripe 安全報告抓到 11% 的整合方都沒做。

如果你還不熟 webhook 節點本身的設定,先看 n8n Webhook 完全攻略 把基礎打好;不確定 Test URL 跟 Production URL 差在哪,補 Webhook Trigger Essentials。本篇預設你已經能接通 webhook,要解的是「接通之後怎麼撐 production」。

多步驟自動化的三件套

把 webhook 變成真正的工作流,要靠三個 n8n 元件組合:

元件作用何時用
Webhook Trigger接事件、回 200、傳遞 payload入口節點,永遠在最前
Switch 節點依 event type 分流同一個 URL 收多種事件時必用
Execute Sub-Workflow把長流程解耦、可重用處理時間 > 5 秒或要重用邏輯

加上 Error Trigger 把失敗的 event 推到 dead letter queue,這套四件式就是 production webhook 的標準骨架。三大事件源的差別只是 payload 結構、簽章演算法、retry 行為,骨架完全一樣。

LINE Messaging API → n8n:接訊息事件並觸發多步驟自動化

LINE 是台灣最常見的 webhook 整合入口,從客服機器人到外送通知都跑在上面。LINE webhook 一次 POST 可能帶多個 event(陣列),每個 event 有獨立的 replyToken,replyToken 30 秒過期一次性用完。

端點與簽章

在 LINE Developers Console 設定 Webhook URL 指向 n8n:

https://n8n.yourdomain.com/webhook/line/messaging

LINE 會在每個 request 帶 x-line-signature header,值是 channel secret 對 raw body 算的 HMAC-SHA256,base64 編碼。簽章驗證一定要用 raw body,不是 parsed JSON,n8n Webhook 節點要把「Binary Data」或「Response Mode → Last Node」配合 Function 節點處理。

簽章驗證的 Function 節點範例:

const crypto = require('crypto');
const channelSecret = $env.LINE_CHANNEL_SECRET;
const signature = $request.headers['x-line-signature'];
const body = $request.rawBody;
const expected = crypto
  .createHmac('SHA256', channelSecret)
  .update(body)
  .digest('base64');
if (signature !== expected) {
  throw new Error('invalid LINE signature');
}
return $input.all();

簽章不對直接 throw,n8n 預設會回 500,LINE 看到 500 會 retry,但因為簽章本來就不對,retry 也不會通過——這正是想要的行為,垃圾流量不會被處理。

多步驟分支設計

LINE event 有 messagefollowpostbackbeacon 等類型,至少要分流:

  1. message + type=text → 走 NLU/LLM 分析,依意圖呼叫 sub-workflow
  2. message + type=image/audio → 下載媒體、跑 OCR 或語音轉文字
  3. follow → 寫使用者進 CRM、發歡迎訊息
  4. postback → 處理 Rich Menu 或 quick reply 的動作

主 workflow 在 Webhook → 驗簽 → Split In Batches(拆陣列)→ Switch 之後,每個分支立刻 Execute Sub-Workflow 並 wait: false,避免主流程被卡住。replyToken 必須在 30 秒內用掉,多步驟流程超過 30 秒就要改用 Push Message API。

production 一個常見坑:Reply API 跟 Push API 計費邏輯不同,Reply 不算配額,Push 算配額。每個月底如果看到推播配額炸開,多半是 reply 超時被迫改 push。

在地化雷區

LINE 官方 webhook 配額 1000 event/sec,新 channel 預設只給 100,要寫信申請才會放寬。如果你的 n8n 跑在台灣的小機器上,記得把 webhook entrypoint 跟 sub-workflow 分開:entrypoint 只做驗簽 + 入 queue,後續處理走另一條 workflow 拉 queue,避免 LINE 同秒灌進 500 個 event 直接打掛 n8n。

Slack Events API → n8n:把 channel message 變客服分流

Slack 的 Events API 比 LINE 多一道「URL Verification challenge」:第一次設定 webhook 時 Slack 會打一個 type=url_verification 的 request,你必須在 3 秒內回傳 challenge 欄位原樣,否則 Slack 不認你的 URL。

端點與 challenge

n8n 的 Webhook 節點預設會回固定 JSON,要應付 challenge 必須改成「Response Mode: Last Node」,由 Function 節點動態判斷:

const body = $input.first().json;
if (body.type === 'url_verification') {
  return [{ json: { challenge: body.challenge } }];
}
// 一般事件繼續往下
return $input.all();

Slack 簽章驗證跟 LINE 類似,但用 x-slack-signature + x-slack-request-timestamp 兩個 header。timestamp 超過 5 分鐘的 request 要直接拒絕,避免 replay attack。

const ts = $request.headers['x-slack-request-timestamp'];
if (Math.abs(Date.now() / 1000 - ts) > 300) {
  throw new Error('stale slack request');
}
const sigBase = `v0:${ts}:${$request.rawBody}`;
const expected = 'v0=' + crypto
  .createHmac('SHA256', $env.SLACK_SIGNING_SECRET)
  .update(sigBase)
  .digest('hex');
if ($request.headers['x-slack-signature'] !== expected) {
  throw new Error('invalid slack signature');
}

event_callback 多步驟分流

Slack 把訊息事件包在 event_callback 裡,內部 event.type 才是真正的事件名稱。常見分流:

  • event.type=message + channel_type=channel → 公開頻道訊息,過濾 bot 自己發的(避免迴圈)
  • event.type=app_mention → 直接呼叫機器人,跑意圖分類
  • event.type=reaction_added → 觸發審核/封存等行政流程

production 第一個雷是 bot 自己發訊息又被 webhook 接回來,n8n 主流程跟 Slack send message 形成無限迴圈,10 分鐘就會把 Slack 速率限制炸掉。每個 message event 進來先檢查 event.bot_id,是自己的 bot 直接 short-circuit 回 200。

第二個雷是 3 秒回應上限。Slack 規定 webhook 必須 3 秒內回 200,否則視為失敗會重送。多步驟工作流超過 3 秒就要切兩段:主 workflow 收事件、入 queue、立即回 200;另一個 cron workflow 每 30 秒拉 queue 跑後續邏輯。

客服分流實作範例

把 #support 頻道的 mention 變成多步驟客服流程:

  1. Webhook 接 app_mention,立刻回 200
  2. Sub-Workflow A:呼叫 OpenAI 分類問題(技術 / 帳務 / 商務)
  3. Switch 依分類分流:
    • 技術 → 開 Linear ticket、回貼 Slack thread
    • 帳務 → 查 Stripe customer、推送 invoice link
    • 商務 → 寫 HubSpot lead、通知業務 channel
  4. Error Trigger:把失敗的 event 推 DLQ + Slack alert 給 oncall

Sub-Workflow A 跑 LLM 平均 2.5 秒,Switch 之後每個分支 13 秒,總共 46 秒。如果不切兩段、不立刻回 200,每三個 event 就會被 Slack 視為 timeout 重送一次,整套客服流程資料會亂掉。

Stripe webhook → n8n:把付款事件接成多步驟 fulfillment

Stripe 是 webhook 整合裡最不能出錯的一塊。錯一次就是真的少收一筆錢或多送一筆貨,客服跟財務當天炸鍋。

endpoint 與簽章驗證

Stripe Dashboard 加 endpoint 後會給一個 whsec_xxx 的 signing secret,每個 endpoint 一組。簽章在 Stripe-Signature header 裡,格式是 t=timestamp,v1=signature,timestamp 超過 5 分鐘要拒絕。

const sig = $request.headers['stripe-signature'];
const parts = Object.fromEntries(
  sig.split(',').map(kv => kv.split('=')),
);
const payload = `${parts.t}.${$request.rawBody}`;
const expected = crypto
  .createHmac('SHA256', $env.STRIPE_WEBHOOK_SECRET)
  .update(payload)
  .digest('hex');
if (parts.v1 !== expected) {
  throw new Error('invalid stripe signature');
}
if (Math.abs(Date.now()/1000 - Number(parts.t)) > 300) {
  throw new Error('stale stripe webhook');
}

多步驟 fulfillment 流程

一筆訂單收到 checkout.session.completed 之後的標準四步:

  1. 去重檢查:用 event.id 查 PostgreSQL stripe_events_processed 表,命中就直接 short-circuit 回 200
  2. 狀態落地:寫 order 表(status=paid),這步要在開票之前完成
  3. 後處理 fan-out:開發票 / 寄收據 / 通知 Slack / 加 LINE 好友贈品 → 全部走 Execute Sub-Workflow wait: false
  4. 回 200:主流程在 5 秒內回完,後續任務各自跑各自的 retry

Stripe 同一個 event 在 72 小時內最多重送 16 次,間隔指數退讓。沒做 event.id 去重的工作流,遇到 Stripe 限流恢復時會把同一筆訂單觸發 fulfillment 16 次。配套要做的不只 webhook 入口去重,下游每個 API 呼叫也都要帶 idempotency-key,金流類至少要走 Stripe 原生的 Idempotency-Key header,這部分跟 n8n credentials 安全管理 提到的 secret rotation 一樣不能省。

該訂閱哪些事件

不是每個 Stripe event 都要接,訂太多 Dashboard 也會雜。三類主流 fulfillment:

事件用途retry 風險
checkout.session.completed一次性付款的訂單成立高(最容易重複送貨)
invoice.payment_succeeded訂閱續費成功中(要對齊 subscription_id)
customer.subscription.deleted訂閱取消 / 到期低(但下游 access 控制要同步)
charge.refunded退款中(要回收會員權益)

production 建議 endpoint 只訂這 4 個事件 + customer.subscription.updated,其他先別開。每多訂一個事件,Switch 就要多一條分支,沒有對應 fulfillment 邏輯就會堆積在 execution log。

三大事件源共通的 production 雷區

三條主線串完,把共通雷區一次說清楚。這四件事任何一條沒做,production 跑兩週都會踩。

1. 簽章驗證一定要在最前

n8n Webhook 節點之後第一個節點就要驗簽章,不可以在跑完 LLM、寫完 DB 之後才驗。理由:

  • LLM 跟 DB 都會消耗 quota / cost,攻擊者打假 webhook 你還會花錢
  • 簽章驗證失敗要走另一條 Error Workflow,把 IP + payload + 失敗時間寫 audit table,七天內同一 IP 失敗 100 次就走防火牆 ban

2. event 去重要在驗簽之後、業務邏輯之前

去重表設計三欄就夠:event_id(primary key)、source(line / slack / stripe)、processed_at。每個 webhook 進來先 INSERT,違反 unique 就 short-circuit 回 200。為什麼是 INSERT 不是 SELECT?因為 SELECT 之後 INSERT 中間有 race window,兩個併發 request 都會通過 SELECT 然後都進入處理。

去重表至少留 90 天,Stripe 重送窗口才 3 天,但 LINE/Slack/Stripe 後台可以手動重送任何歷史 event,留 90 天能擋住手動 replay 也誤觸發 fulfillment。

3. 200 OK 的 race condition

webhook handler 真正的 contract 是:在上游 timeout 之前回 200。每個服務的 timeout 不同:

  • LINE:30 秒(replyToken 過期上限)
  • Slack:3 秒(events.api 規定)
  • Stripe:30 秒(之後判定為失敗會重送)

多步驟工作流 99% 跑不完上面任何一個,必須入 queue 立刻回 200。n8n 的 Queue Mode 內建 Redis-backed queue,production 用法是 Webhook → 驗簽 → 去重 INSERT → push job → 回 200 全部在 1 秒內完成。後續處理由 worker 拉 job,獨立 retry。

4. 失敗不能憑空消失

任何步驟掛掉,event payload 必須落地 dead letter queue。三大事件源都有可能在某段下游 API 掛掉(OpenAI、HubSpot、自家 CRM),DLQ 確保事件不會憑空消失。完整 DLQ + 三級告警設計可以接 n8n error handling 三層模式 那一套:retry 處理 transient、alert 確保有人看到、DLQ 確保 event 不會消失。

多步驟分支怎麼設:Switch + Sub-Workflow + Error Trigger 三件套

把 webhook 變多步驟工作流,分支結構決定維護成本。三種錯誤示範跟一種正確做法。

反面教材

單一條長 workflow:webhook → 驗簽 → 去重 → IF → IF → IF → 寫 DB → 寫 Slack → 寫 LINE → …。問題是任何一段失敗整條重 retry,且 event log 看不出哪一步壞掉,debug 要逐節點開 execution。

用 HTTP Request 自己呼叫自己:webhook handler 呼叫另一個 n8n webhook 處理長流程。問題是多繞一層網路、簽章重做、execution log 對不上來源 event。

全部塞 Function 節點寫 JS:把整條流程寫進 Code 節點,n8n 變成「跑 JS 的容器」。維護性歸零,新人完全看不懂。

正確結構

Webhook Trigger

Function:驗簽

PostgreSQL:INSERT event_id(去重)

Respond to Webhook:回 200

Switch:依 event type 分流
  ├─ message → Execute Sub-Workflow A(wait:false)
  ├─ payment → Execute Sub-Workflow B(wait:false)
  └─ default → Execute Sub-Workflow C(wait:false)
  
Error Trigger

PostgreSQL:寫 DLQ

Slack:通知 oncall(依嚴重度分級)

Sub-Workflow 各自獨立 retry、獨立 execution log、獨立版本控制。主 workflow 30 天內不會動,sub-workflow 每週可以無痛改一次。

Switch 節點的常見坑

  • 預設 mode 是「Expression」,rule 寫錯 n8n 不會 lint 出來,event 就靜默走到 default
  • 「Send data to all matching outputs」打開後一個 event 會觸發多個分支,通常不是想要的行為,要關掉
  • 分支命名要跟 sub-workflow 命名一致,例如 line-messagewf-line-message,搜尋時不會亂

30 天落地檢核表

從零開始把這套 production webhook 鋪上線的 30 天節奏:

任務完成標準
D+0開 n8n production instance,HTTPS 完備、Queue Mode 啟用webhook 可被外部 POST 進來
D+3接 Stripe webhook、驗簽 + 去重表Stripe Dashboard 重送 1 個 test event,DB 只寫一筆
D+7接 LINE Messaging API,分流 message / follow / postbackLINE 官方測試訊息能跑完 sub-workflow 並回應
D+10接 Slack Events API,過 challenge + 跑 app_mentionSlack 後台 event 狀態全部 200
D+14建 DLQ table + Error Trigger,主 workflow 接通故意打 invalid signature,DLQ 有紀錄、Slack 收到 alert
D+21切兩段架構:主流程入 queue / worker 拉 queue模擬 100 event/sec,主流程 P95 < 500ms
D+30retry budget + circuit breaker,DLQ 自動 replay cron過去 7 天 retry 自救率 > 70%、DLQ 進場率 < 1%

收斂三個量化指標:webhook P95 回應時間 < 1 秒、event 去重命中率 < 0.5%(命中率太高代表上游瘋狂重送,要查上游)、DLQ 30 天累積 < 100 筆。三個指標任何一個飆高都是訊號,照前面對應段落回頭補。

常見問題

Q:n8n Cloud 跟自架在 webhook 上有什麼差別? Cloud 預設不開 Queue Mode,event 量大就會卡住。自架可以開 Queue Mode + 獨立 worker,但要自己處理 HTTPS、TLS 憑證、防火牆。流量 < 50 event/min 用 Cloud,> 50 event/min 直接自架。

Q:Stripe 的 webhook 一定要走 n8n 嗎? 不一定。如果你的 fulfillment 全部在 Stripe 生態系內(subscription、invoice、refund),用 Stripe Workflows 也許更簡單。要串外部系統(自家 CRM、LINE 通知、Slack)才有理由走 n8n。

Q:LINE 的 replyToken 用完 30 秒了怎麼辦? 切換 Push Message API。push 算配額,每個 channel plan 不同,台灣標準方案大約 1000 通/月。超過用量要升 plan 或改 LIFF 內部訊息。

Q:要不要把 webhook 直接打到 sub-workflow? 不要。webhook trigger 必須是「主入口」,從入口分流到 sub-workflow 才能集中做驗簽 / 去重 / 200 回應這三件事。每個 sub-workflow 各開 webhook 等於每條都要重做這三件事,維護成本爆炸。

接 webhook 之前先把這四件事都規劃好:簽章 / 去重 / 200 race / DLQ。剩下的 LINE、Slack、Stripe 都只是 payload 結構差異,骨架完全一樣。