上一篇文章我們學了 Webhook 的基本概念:
當某個事件發生時,一個伺服器主動用 HTTP POST 把資料送到你登記的網址。
但當你實際去串接第三方服務時,你可能會在後台看到這樣的設定:
- Incoming Webhook
- Outgoing Webhook
或是有些平台會寫成:
- Inbound Webhook
- Outbound Webhook
這是什麼意思?有什麼差別?
其實很簡單,關鍵在於:你站在誰的角度看。
Webhook 的三個角色
在一個完整的 Webhook 流程中,通常有三個角色:
flowchart LR
Client[Client<br/>使用者/App/瀏覽器] --> Service[Service<br/>第三方服務平台]
Service --> Handler[Handler<br/>你寫的程式]
Handler --> Service| 角色 | 說明 | 範例 |
|---|---|---|
| Client | 使用者端,發起操作的人 | 手機 App、瀏覽器、使用者 |
| Service | 第三方服務平台 | Slack、LINE、GitHub、金流公司 |
| Handler | 你寫的程式,處理 Webhook 的接收端 | 你的伺服器、你的機器人 |
Incoming vs Outgoing:關鍵是「誰的視角」
Incoming 和 Outgoing 的差別,取決於你站在哪個角色的角度來看。
從 Handler(你的程式)的角度
flowchart LR
Service -->|Incoming<br/>資料進來| Handler
Handler -->|Outgoing<br/>資料出去| Service| 方向 | 意思 | 你要做什麼 |
|---|---|---|
| Incoming | 資料「進來」你的程式 | 接收 Webhook,處理資料 |
| Outgoing | 資料「出去」到別的服務 | 發送資料給其他服務 |
從 Service(第三方平台)的角度
flowchart LR
Service -->|Outgoing<br/>資料出去| Handler
Handler -->|Incoming<br/>資料進來| Service| 方向 | 意思 | 平台做什麼 |
|---|---|---|
| Outgoing | 平台把資料「送出去」給你 | 事件發生時通知你 |
| Incoming | 平台「收到」你送來的資料 | 接收你發送的訊息 |
重點:角度相反,方向就相反!
⚠️ 注意:大部分第三方服務(如 Slack、Discord)在後台設定時,都是以他們自己為主角。
所以當他們說「Outgoing Webhook」,意思是「我們把資料送出去給你」。
當他們說「Incoming Webhook」,意思是「我們接收你送來的資料」。
實際案例:Slack 機器人
讓我們用 Slack 機器人來說明這兩種 Webhook。
場景:做一個查天氣的 Slack 機器人
使用者在 Slack 輸入 /weather 台北,機器人回覆台北的天氣。
完整流程
sequenceDiagram
participant User as 使用者
participant Slack as Slack 平台
participant Bot as 你的機器人
participant Weather as 天氣 API
User->>Slack: 輸入 /weather 台北
Slack->>Slack: 儲存指令記錄
Slack->>Bot: Outgoing Webhook:有人輸入指令
Bot->>Weather: 查詢台北天氣
Weather-->>Bot: 回傳天氣資料
Bot->>Slack: Incoming Webhook:回傳天氣結果
Slack->>User: 顯示天氣資訊從 Slack 的角度看
| Webhook 類型 | 方向 | 說明 |
|---|---|---|
| Outgoing Webhook | Slack → 你的機器人 | 使用者輸入指令時,Slack 把指令「送出去」給你 |
| Incoming Webhook | 你的機器人 → Slack | 你的機器人把回覆「送進來」給 Slack |
從你的機器人的角度看
| Webhook 類型 | 方向 | 說明 |
|---|---|---|
| Incoming | Slack → 你的機器人 | 你「收到」Slack 送來的指令 |
| Outgoing | 你的機器人 → Slack | 你把回覆「送出去」給 Slack |
看到了嗎?同一個箭頭,從不同角度看,名字是相反的!
常見平台的 Webhook 設定
Slack
| 設定名稱 | 從 Slack 角度 | 實際用途 |
|---|---|---|
| Incoming Webhooks | 接收你送來的訊息 | 讓你的程式發訊息到 Slack 頻道 |
| Outgoing Webhooks | 送出事件給你 | 當有人在頻道發言時通知你 |
Discord
| 設定名稱 | 從 Discord 角度 | 實際用途 |
|---|---|---|
| Webhooks | 接收你送來的訊息 | 讓你的程式發訊息到 Discord 頻道 |
LINE Bot
| 設定名稱 | 從 LINE 角度 | 實際用途 |
|---|---|---|
| Webhook URL | 送出事件給你 | 當使用者發訊息時通知你的伺服器 |
GitHub
| 設定名稱 | 從 GitHub 角度 | 實際用途 |
|---|---|---|
| Webhooks | 送出事件給你 | 當有 push、PR 等事件時通知你 |
如何判斷 In 還是 Out?
當你在設定第三方服務的 Webhook 時,記住這個口訣:
先搞清楚「誰是主角」,再判斷方向。
步驟
- 看文件或後台是誰寫的 → 通常是以平台為主角
- Incoming = 進來平台 → 你要發資料給平台
- Outgoing = 離開平台 → 平台會發資料給你
快速對照表
| 你想做的事 | 從平台角度 | 你需要設定 |
|---|---|---|
| 讓程式發訊息到 Slack | 資料進來 Slack | Incoming Webhook |
| 當 Slack 有訊息時通知我 | 資料離開 Slack | Outgoing Webhook |
| 讓程式發訊息到 Discord | 資料進來 Discord | Webhook |
| 當 GitHub 有 push 時通知我 | 資料離開 GitHub | Webhook |
| 當 LINE 收到訊息時通知我 | 資料離開 LINE | Webhook URL |
實作範例
範例一:發訊息到 Slack(Incoming Webhook)
你想讓程式自動發訊息到 Slack 頻道。
從 Slack 角度:資料「進來」Slack → Incoming Webhook
// 發送訊息到 Slack
const webhookUrl = 'https://hooks.slack.com/services/xxx/yyy/zzz';
fetch(webhookUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
text: '伺服器部署完成!🚀'
})
});範例二:接收 Slack 指令(Outgoing Webhook)
你想在使用者輸入指令時,讓 Slack 通知你的伺服器。
從 Slack 角度:資料「離開」Slack → Outgoing Webhook
// 你的伺服器接收 Slack 送來的資料
app.post('/slack/commands', (req, res) => {
const { text, user_name } = req.body;
console.log(`${user_name} 輸入了:${text}`);
// 處理指令,回傳結果
res.json({
text: `收到!你查詢的是:${text}`
});
});常見錯誤
錯誤一:搞混 In 和 Out
症狀:設定完 Webhook 後,資料收不到或發不出去。
原因:你設定了錯誤的 Webhook 類型。
解法:先確認你要「發送」還是「接收」,再對照平台文件。
錯誤二:沒注意主角是誰
症狀:看了教學文章照做,但結果跟預期相反。
原因:教學文章的角度(你的程式)和平台文件的角度(平台本身)不同。
解法:永遠以平台官方文件的定義為準。
總結
核心觀念
| 名詞 | 意思 |
|---|---|
| Incoming Webhook | 資料「進來」某個服務 |
| Outgoing Webhook | 資料「離開」某個服務 |
| 主角很重要 | 同一個 Webhook,從不同角度看,方向是相反的 |
三個重點
- Incoming / Outgoing 是相對的:取決於你站在誰的角度
- 平台文件以平台為主角:他們說的 Incoming 是「進來他們」
- 設定前先確認方向:你要「發送」還是「接收」?
快速記憶
你想發訊息到平台 → 找 Incoming Webhook(進來平台)
你想收到平台通知 → 找 Outgoing Webhook(離開平台)💡 小提醒:每個平台的命名習慣可能不同,有些只叫「Webhook」不分 In/Out。設定前一定要看清楚官方文件!