跳转到主要内容

如何使用 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 (Template Sent webhook) 现在包含 WhatsApp 模板中配置的按钮信息。这允许您识别与已发送模板消息关联的按钮文本。

此功能适用于使用 Pro、Business 和 Enterprise 计划的客户。

包含哪些按钮信息?

Webhook Payload 可包含以下来自 WhatsApp 模板的按钮信息:

  • 快速回复按钮文本 (Quick reply button text)

  • 链接按钮文本 (Link button text)

当您通过 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。

Payload 示例 — 文本消息:

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

Payload 示例 — 快速回复按钮点击:

{
"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 绑定到特定号码时,此 Payload 中才会包含 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 事件以构建完整的消息生命周期视图。

这是否解答了您的问题?