跳至主要內容

如何使用 Wati webhooks 追蹤範本訊息的傳送與訊息狀態

摘要

當您使用 Wati API 發送模板訊息時,可以透過 Webhook 即時追蹤訊息狀態(已發送、已送達、已讀、已回覆或失敗),而不僅僅是依賴 Wati 內建的行銷活動分析。

透過 API 發送行銷活動後,您可以在 Wati 的行銷活動概覽 (Campaign Overview) 中查看其績效。Webhook 可讓您在訊息狀態和送達事件發生時,透過您自己的系統進行追蹤。

注意:如需完整的 Webhook 參考文件,請參閱 Wati 開發者文件。

說明

發送模板訊息

請使用 v3 端點發送模板訊息。v3 是所有新整合的建議版本。

端點: POST https://live-mt-server.wati.io/api/ext/v3/messageTemplates/send

v3 路徑不包含 /{tenantId}/。請在 Connector > API > Create API Token 處建立一個具有 messagetemplatev3:write 權限範圍的 API Token。

cURL 請求範例:

curl --location 'https://live-mt-server.wati.io/api/ext/v3/messageTemplates/send' \
--header 'Authorization: Bearer <Token>' \
--header 'Content-Type: application/json' \
--data '{
"template_name": "update_for_you",
"broadcast_name": "JPTestBroadcast",
"channel_number": "85264318722",
"target": "<whatsappNumber>",
"parameters": []
}'

channel_number 為必填項目。請使用包含國家代碼的數字,且不帶 "+" 號(例如 85264318722)。target 欄位接受電話號碼、ContactId、BSUID 或 Channel:PhoneNumber。

API 回應範例:

{
"result": true,
"error": null,
"templateName": "update_for_you",
"receivers": [
{
"localMessageId": "d38f0c3a-e833-4725-a894-53a2b1dc1af6",
"waId": "<whatsappNumber>",
"isValidWhatsAppNumber": true,
"errors": []
}
],
"parameters": []
}

重要: 200 回應僅代表請求已受理,並不代表訊息已送達。送達狀態由 sentMessageDELIVERED_v2 Webhook 確認;失敗訊息則由 templateMessageFailed 回報。

關鍵欄位:

  • localMessageId — 訊息的唯一識別碼。請儲存此數值,它能將所有外發訊息的狀態 Webhook 事件連結回原始訊息。

使用 Webhook 追蹤訊息狀態

訊息發送後,Wati 會針對每個狀態更新觸發 Webhook 事件。請使用 localMessageId 將事件與原始訊息進行匹配。

1. 模板訊息已發送

  • 觸發條件: 訊息已被 Wati 受理並發送

  • 事件: templateMessageSent_v2

  • 狀態: SENT

SENT 意指訊息已離開 Wati 系統,並不代表已送達至收件人的裝置。

負載 (Payload) 範例:

{
"eventType": "templateMessageSent_v2",
"localMessageId": "84689938-5e2-877821d672c2",
"id": "693fd8ee21f81",
"whatsappMessageId": "wamid.HBgNODEYEjQ3RDMzQzM2QjM3QjU1ODQ4RQA=",
"templateId": "6929b",
"templateName": "test_jm4",
"created": "2025-12-15T09:46:23.4083984Z",
"conversationId": "68b68470e93cc",
"ticketId": "693fd6ab545f82",
"text": "Make your messages personal using variables like name and get more replies!",
"operatorEmail": "[email protected]",
"waId": "86151285",
"type": "template",
"statusString": "SENT",
"sourceType": "WEB",
"channelId": null,
"channelPhoneNumber": "174742",
"bsuid": "HK.xxxxxxxxxxxxx",
"parentBsuid": "HK.ENT.xxxxxxxxxxxxx",
"username": "@bob",
"templateContent": {
"header": { "type": "text", "text": "Hello" },
"footer": "Footer text",
"buttons": [
{ "type": "QUICK_REPLY", "text": "Yes" },
{ "type": "URL", "text": "Visit us", "url": "https://example.com" },
{ "type": "CALL", "text": "Call us", "phoneNumber": "+1234567890" }
]
}
}

templateContent 欄位:

欄位

描述

header

標題類型與內容(文字、圖片、影片或文件)

footer

頁尾文字

buttons

按鈕陣列 — 包含 QUICK_REPLY、URL 與 CALL 類型

模板發送 Webhook 現已包含按鈕資訊

模板發送 Webhook 現在包含 WhatsApp 模板中設定的按鈕資訊。這讓您可以辨識與發送的模板訊息相關聯的按鈕文字。

此功能適用於訂閱 Pro、Business 與 Enterprise 方案的客戶。

包含哪些按鈕資訊?

Webhook 負載可包含來自 WhatsApp 模板的下列按鈕資訊:

  • 快速回覆 (Quick reply) 按鈕文字

  • 連結 (Link) 按鈕文字

當您透過 API 檢索模板資訊時,回應也會包含為該模板設定的按鈕文字。

BSUID 變體

templateMessageSent_v2_bsuid 會觸發相同的事件,並包含 bsuid、parentBsuid 與 username 欄位,以便使用 BSUID 而非電話號碼來識別聯絡人。

2. 訊息已送達

  • 觸發條件: 訊息已送達至收件人的裝置

  • 事件: sentMessageDELIVERED_v2

  • 狀態: Delivered

負載 (Payload) 範例:

{
"eventType": "sentMessageDELIVERED_v2",
"statusString": "Delivered",
"localMessageId": "16bf77ae-79e8-691eb4b",
"id": "693fd65f99391640",
"whatsappMessageId": "wamid.HBgNODYxMzEzMzg4Nzg2MDU0OEM0NTYxRTlBMwA=",
"conversationId": "68cba32b3349e",
"ticketId": "693f7a0a8545f54",
"text": "hello",
"type": "text",
"timestamp": "1765791326",
"assigneeId": "65a105b5cf65262",
"operatorEmail": "derre.ai",
"channelId": null,
"channelPhoneNumber": "17742"
}

BSUID 變體:sentMessageDELIVERED_v2_bsuid

3. 訊息已讀

  • 觸發條件: 收件人已讀取訊息

  • 事件: sentMessageREAD_v2

  • 狀態: Read

負載 (Payload) 範例:

{
"eventType": "sentMessageREAD_v2",
"statusString": "Read",
"localMessageId": "16bf77ae-79e691eb4b",
"id": "693fd65f961dc81779391640",
"whatsappMessageId": "wamid.HBgNODYxMzEABEYEjVCNzg2MDU0OEM0NTYxRTlBMwA=",
"conversationId": "68cba3db12b3349e",
"ticketId": "693fd64d1d45f54",
"text": "hello",
"type": "text",
"timestamp": "17651326",
"assigneeId": "65a10905cf65262",
"operatorEmail": "[email protected]",
"channelId": null,
"channelPhoneNumber": "174742"
}

BSUID 變體:sentMessageREAD_v2_bsuid

4. 訊息已回覆

  • 觸發條件: 收件人已回覆訊息

  • 事件: sentMessageREPLIED_v2

  • 狀態: Replied

負載 (Payload) 範例:

{
"eventType": "sentMessageREPLIED_v2",
"statusString": "Replied",
"localMessageId": "16bf77ae-79e691eb4b",
"id": "693fd65f961dc81779391640",
"whatsappMessageId": "wamid.HBgNODYxMzEABEYEjVCNzg2MDU0OEM0NTYxRTlBMwA=",
"conversationId": "68cba3db12b3349e",
"ticketId": "693fd64d1d45f54",
"text": "hello",
"type": "text",
"timestamp": "17651326",
"assigneeId": "65a10905cf65262",
"operatorEmail": "[email protected]",
"channelId": null,
"channelPhoneNumber": "174742"
}

BSUID 變體:sentMessageREPLIED_v2_bsuid

5. 訊息已接收

  • 觸發條件: 使用者向您的 Wati 號碼發送訊息

  • 事件: message

  • 狀態: Received

使用案例:

  • 追蹤使用者傳入的訊息

  • 捕捉模板訊息中的快速回覆按鈕點擊

  • 使用 replyContextId 偵測針對特定外發訊息的回覆

傳入的訊息不帶有 localMessageId。若要將回覆連結至原始模板訊息,請使用 replyContextId — 它包含了原始外發訊息的 whatsappMessageId。

文字訊息負載範例:

{
"eventType": "message",
"statusString": "Received",
"whatsappMessageId": "wamid.HBgMOAE4NjY4NDkzNjAxFAIAERgSOTEENzFCNjEwMkNDNENGQUJGAA==",
"replyContextId": "wamid.HBgNODEYEjQ3RDMzQzM2QjM3QjU1ODQ4RQA=",
"text": "Hello, I need help!",
"timestamp": "1665645642",
"operatorEmail": "[email protected]"
}

快速回覆按鈕點擊負載範例:

{
"eventType": "message",
"statusString": "Received",
"whatsappMessageId": "wamid.HBgMOAE4NjY4NDkzNjAxFAIAERgSOTEENzFCNjEwMkNDNENGQUJGAA==",
"buttonReply": {
"id": "btn_yes",
"title": "Yes"
},
"timestamp": "1665645642",
"operatorEmail": "[email protected]"
}

6. 模板訊息發送失敗

  • 觸發條件: 訊息發送失敗

  • 事件: templateMessageFailed

  • 狀態: Failed

負載 (Payload) 範例:

{
"eventType": "templateMessageFailed",
"statusString": "Failed",
"localMessageId": "fd29c1f-9033-59b2-7d72-5ac964c4c8a7",
"failedCode": "131026",
"failedDetail": "Message undeliverable",
"id": "66b2531d4931581381944612",
"whatsappMessageId": "wamid.HBgMOAE4NjY4NDkzNjAxFAIAERgSOTEENzFCNjEwMkNDNENGQUJGAA==",
"conversationId": "66b1fb044045cedb1f19538e",
"ticketId": "66bdfba190194752bb7326d7",
"text": null,
"type": "template",
"timestamp": "1665645642",
"assigneeId": null,
"operatorEmail": "[email protected]"
}

僅當 Webhook 綁定至特定號碼時,此負載中才會包含 channelPhoneNumber。

如何在 Wati 中設定 Webhook

透過 Wati UI:

  • 前往 Connector > Webhooks。

  • 點擊 Add Webhook。

  • 輸入您的 Webhook URL 並將狀態設定為 Enabled。

  • 選擇要訂閱的事件:

    • 模板訊息已發送 (Template Message Sent)

    • 已送達 (Delivered)

    • 已讀 (Read)

    • 已回覆 (Replied)

    • 失敗 (Failed)

透過 API:

建立 Webhook (v2):

POST https://live-mt-server.wati.io/{tenantId}/api/v2/webhookEndpoints

列出、取得、更新與刪除 Webhook (v3 — 建議使用):

https://live-mt-server.wati.io/api/ext/v3/webhooks

v3 Webhook 端點的路徑中不包含 /{tenantId}/。

最後說明

  • 請務必儲存來自發送回應的 localMessageId — 它能將所有外發狀態事件連結回原始訊息。

  • 針對傳入訊息,請使用 replyContextId 將回覆連結回原始外發訊息。

  • 使用 buttonReply 來偵測快速回覆按鈕的互動。

  • 結合多個 Webhook 事件,以建立完整的訊息生命週期視圖。

是否回答了您的問題?