WhatsApp 回应事件
表情回应是对已有消息的标注,而非创建新消息,因此它不会作为独立消息出现,也不会出现在消息的消息状态事件中。Bird 为此保留两个视图:当前附在消息上的回应,以及记录所有变更的日志。两者都会记录联系人和您的商业号码所做的变更。
要在联系人做出回应时收到通知,请订阅 whatsapp.reacted。要添加或移除你自己的回应,请参阅发送回应。
前提条件
一个具有 WhatsApp 读取权限的 API 密钥,以及被回应消息的 ID(wam_…)。
1. 读取当前回应
如果你的应用需要显示消息上当前附加的回应,请检索该消息并读取其 reactions。该列表包含每个发送者的一个当前回应,没有回应时该字段会被省略。
对于 GET /v1/whatsapp/messages/wam_01ky8b3xq4gd7pmzn2ka51f7te,回应相关字段的结构如下(其他消息字段已省略):
{
"id": "wam_01ky8b3xq4gd7pmzn2ka51f7te",
"reactions": [
{
"emoji": "👍",
"from": { "phone_number": "+14155550100" }
}
]
}消息保留其原始内容、方向和投递状态。reactions[].from 标识做出回应的人。
这是应该展示的状态。回应 webhook 的时间戳可能相同且到达顺序不确定,因此应将其作为重新读取消息的触发器,而非当作当前状态使用。
2. 读取回应日志
使用 GET /v1/whatsapp/messages/{message_id}/reaction-events 列出回应事件,查看被引用消息的所有变更(最新优先):添加、替换和移除。每条记录包含一个回应 ID(war_…)、emoji、在 from 中做出变更的人、一个 occurred_at 时间戳,以及一个 status:
received:联系人的变更。sent:WhatsApp 接受了你的商业号码的变更。failed:WhatsApp 拒绝了你的变更。rejected:Bird 在发送前拒绝了你的变更。
failed 或 rejected 条目在 error 上携带原因。移除操作携带 emoji: null。你的变更如果仍在等待中,则在结果确定之前不会有条目。回应不会产生费用,因此此处的失败都不涉及计费。
回应事件 API 返回分页响应。以下示例展示了一个被拒绝的商业回应和一个更早收到的联系人回应:
{
"data": [
{
"id": "war_01krdgeqcxet5s7t44vh8rt9mh",
"emoji": "🎉",
"status": "rejected",
"from": {
"phone_number": "+13124495569"
},
"error": {
"code": "internal_error",
"description": "the receiving number is no longer connected",
"occurred_at": "2026-08-28T19:04:22Z"
},
"occurred_at": "2026-08-28T19:04:22Z"
},
{
"id": "war_01krdgeqcxet5s7t44vh8rt9mg",
"emoji": "👍",
"status": "received",
"from": {
"phone_number": "+14155550100",
"bsuid": "US.13491208655302741918"
},
"occurred_at": "2026-08-28T19:01:10Z"
}
],
"next_cursor": null,
"prev_cursor": null,
"refresh_cursor": "eyJ2IjoxLCJzIjoiMjAyNi0wOC0yOFQxOTowNDoyMloiLCJpIjoiMDE5ZTFiMDctNWQ5ZC03NjhiLTkzZTgtODRkYzUxOGQyNjkxIn0"
}回应历史与消息的投递事件是分开的。消息状态事件端点不包含 whatsapp.reacted 变更。有关保留期限和分页,请参阅回应日志参考。
故障排除
- 回应未出现在消息列表中:查找原始消息。回应附加在该消息上,没有单独的消息行。
- 回应状态异常变化:读取消息的
reactions,而不是按到达时间或时间戳对 webhook 事件排序。
后续步骤
- 回应 webhook:在联系人做出回应时收到通知
- 发送或移除回应
- 消息状态事件:消息的投递时间线