如需查看基于 Schema 派生的完整目录,请参阅所有示例。
功能概述
处理 WhatsApp、Messenger、Email、SMS 和 Voice 消息的状态更新。准备工作
- 在您的应用程序中创建一个公开的 HTTPS 端点。
- 为您所需的事件类型配置 YCloud Webhook 端点。
- 安全存储端点签名密钥。
- 确保事件处理具备幂等性。
工作原理
事件发生时,YCloud 会发送一个 HTTPPOST 请求。验证签名,持久化记录该事件,返回 2xx 响应,并异步处理耗时任务。
请求
以下场景展示了发送至您的 Webhook URL 的请求。请将事件id 视为投递标识符,并使用 type 路由有效载荷。
响应
接收事件后返回2xx 状态。
有关端点设置、签名验证和重试机制,请参阅配置 Webhook。
accepted。消息状态更新将触发 whatsapp.message.updated Webhook。
通常情况下,消息状态:
- 如果我们无法投递此消息,则变更为
failed。 - 如果此消息有可能被投递,则变更为
sent,随后可能变更为failed、delivered或read。 - 如果此消息已投递到接收者的设备,则变更为
delivered或read。
delivered 事件可能会在 failed 之后发生,反之亦然,尤其是当最终用户使用多个设备时。
消息已发送
在此情况下,您的 Webhook 端点接收到了消息sent 事件:
- 消息
status为sent,表示消息正在 WhatsApp 系统中传输。 - 包含有关会话的信息,包括会话过期时间以及来源类型。
- 包含我们可能会向您收取的 预估
pricingCategory和totalPrice。 - 包含
wamid,即 WhatsApp 平台上的原始消息 ID,以wamid.开头。
请求
响应
在持久化接收事件后确认投递。说明
-
totalPrice在第一条消息送达前仅为预估价格,当status为delivered或read时,它将成为最终价格。已发送但尚未送达的消息所占用的余额,在消息被丢弃之前将无法使用(发送但 30 天内未送达的消息会被丢弃)。 -
通常,状态为
sent的消息很快会变更为delivered或read,除非发生以下情况:- 接收者的 WhatsApp 账户处于离线状态,您发送的 WhatsApp 消息将在接收者拥有可用或活跃的网络连接后才会送达。
- 发送给已将您拉黑的联系人的任何消息,将始终显示消息
sent,且永远不会变更为delivered。 - 接收者关闭了已读回执,您将不会收到消息
read回执。 - 消息随后变更为
failed,错误码为131026,表示“消息无法送达”或“接收方无法接收此消息”。这很可能是因为接收者未注册,或使用的是较旧的 WhatsApp 版本。 - 为了提供高质量的用户体验,该消息未予送达。请参阅单用户营销模板消息频次限制。
消息已送达
在此情况下,您的 Webhook 端点接收到了消息delivered 事件:
- 消息
status为delivered,表示消息已送达至接收者的设备。
请求
响应
在持久化接收事件后确认投递。说明
- 该事件表示您的企业发送的消息已送达至用户的设备。
- 状态要变为
read,必须先经历delivered。在某些场景中,例如当用户正处于聊天界面时新消息到达,消息几乎同时处于delivered和read状态。在这一类或类似的场景下,delivered通知将不会回传,因为消息已读便隐含了已送达。出现这种行为的原因是内部优化。 - 我们可能会针对同一条消息生成超过 1 个
deliveredWebhook 事件,尤其是当最终用户使用多个设备时。 - pricingModel:“PMP”——表示适用按消息计费(per-message pricing)。另请参阅 whatsapp-message-pricing-updates
- pricingType
- regular — 表示该消息计费。
- free_customer_service — 表示该消息免费,因为它是公用模板消息,或者是在客服窗口内发送的非模板消息。
- free_entry_point — 表示该消息免费,因为它是免费切入点对话的一部分。
消息已读
在这种情况下,您的 Webhook 端点收到了一条消息read 事件:
- 消息
status为read,表示消息已被收件人阅读。
请求
响应
持久接收该事件后确认投递。说明
- 如果收件人关闭了已读回执,您将不会收到消息
read回执。
消息发送失败
在这种情况下,您的 Webhook 端点收到了一条消息failed 事件:
- 消息
status为failed。 - 包含
errroCode、errorMessage和whatsappApiError。
请求
响应
持久接收该事件后确认投递。说明
- 这些事件旨在通知您之前向客户发送的出站消息的状态变化。
- 消息失败的原因通常是消息请求参数无效、客户电话号码未注册等。有关错误处理,请参阅 WhatsApp Errors。
- 如果我们曾尝试将此消息提交至 Meta 的 WhatsApp 平台,则会提供
whatsappApiError以帮助您了解错误详情。另请参阅 Cloud API Error Codes。 - 对于失败的消息,我们不收取费用。
邮件投递更新
当邮件投递状态变更为delivered 或 failed 时使用 email.delivery.updated。
请求
响应
持久接收该事件后确认投递。说明
使用emailId 和 recipientAddress 关联投递:该状态适用于此收件人。提供 externalId 时,可使用它来匹配您自己的记录。当投递失败时,检查 errorCode 和 errorMessage。载荷属性为 emailDelivery,而非 whatsappMessage。
SMS 投递更新
当 SMS 投递状态变更为delivered 或 undelivered 时使用 sms.message.updated。
请求
响应
持久接收该事件后确认投递。说明
使用sms.id 标识 SMS 并读取 sms.status。投递失败时检查 errorCode。SMS 使用 undelivered 表示投递失败回执;请勿将 WhatsApp 的 read 状态模型应用于此事件。
语音投递更新
当语音消息状态变更为delivered 或 undelivered 时使用 voice.message.updated。
请求
响应
持久接收该事件后确认投递。说明
使用voice.id 标识语音消息并读取 voice.status。如有提供,请检查 errorCode。此投递事件属于语音消息 API;它与 WhatsApp 通话生命周期事件相互独立。
Messenger 出站已读快照
订阅messenger.message.updated 以获取已保存的普通一对一出站快照。投递重试会保留 Event.id;从相同的源事实重新创建事件可能会生成新的 Event.id。通过 messengerMessage.id 关联更新。
提交与回执状态
accepted 表示 Meta 已接受提交,并不意味着消息已 sent 或 delivered。rejected 是明确的提交拒绝;unknown 是未确认的结果,绝不能视为失败。发生超时或收到 unknown 结果后,请勿自动重新提交消息。如有返回的消息 ID,请使用它来检查已保存的状态,或联系支持人员。
快照保留当前已保存的事实,其中 read 优先于 delivered、sent 和提交结果。较晚的回执不会降级该状态。您可能会收到重复的快照或遗漏中间状态。使用 GET /v2/messenger/messages/{id} 搭配 from,或通过已确认的 Meta 消息 ID 进行检索,以核对您当前保存的状态。
提交结果通知遵循尽力而为原则。不要依赖于每个同步发送结果都能收到 Webhook。不可用时将省略可选 ID、errorCode 以及回执时间。在后续回执事实确立了更确定的状态之后,已存储的提交错误可能仍然存在。
请求
响应
说明
Facebook 页面 ID 为from,客户 PSID 为 to。此示例展示了已保存的 read 状态,且没有编造缺失的 sendTime 或 deliverTime。id 是 YCloud 消息 ID,而 metaMessageId 是提供商身份标识。
Messenger 消息反应
请求
响应
说明
使用pageId 和 psid 来标识对话,使用 metaMessageId 来标识目标消息。回应(reaction)属于互动,不会更改送达状态。目标消息可能没有本地 YCloud 消息记录。请保留来源 createTime;可能会发生重复投递。在返回成功响应之前,请根据原始请求体验证 YCloud-Signature。
Messenger 消息回应已撤回
请求
响应
说明
移除与此公共主页、客户 PSID 以及目标 Meta 消息关联的回应。unreact 可以省略 reaction 和 emoji。请勿要求本地消息 ID 或推断消息状态变更。HTTP 投递重试会保留相同的事件 ID 和请求体;重复的源回调可能会创建新的事件 ID。在返回成功响应之前,请根据原始请求体验证 YCloud-Signature。
