# 接收 WhatsApp 回应

订阅回应变更，以便了解联系人何时对您的消息添加表情符号、更改表情符号或撤回表情符号。回应附加在现有消息上，通过 `whatsapp.reacted` 送达。

## 前提条件

为您的工作区设置一个 [webhook 端点](/docs/guides/webhooks)。要检索当前回应或其历史记录，请使用具有 WhatsApp 读取权限的 API 密钥。

## 1. 订阅回应变更

将 `whatsapp.reacted` 添加到您的 webhook 订阅中。订阅 `whatsapp.received` 不包含回应。请参照 [webhook 指南](/docs/guides/webhooks) 完成签名验证、投递重试和端点配置。

回应不会在消息列表中创建新消息，也不会打开客服会话窗口。如果您需要回复，请在发送自由格式消息之前查看[服务窗口规则](/docs/guides/whatsapp/sending-whatsapp)。

## 2. 识别消息和变更

读取事件的 `data.whatsapp_id`，找到联系人所回应的消息。这是原始 Bird 消息 ID (`wam_…`)，而非单独的回应 ID。

使用 `data.from` 识别联系人，使用 `data.to` 识别您的 WhatsApp 发送方。它们是 WhatsApp 地址对象；当联系人的地址没有电话号码时，请处理[业务范围用户 ID](/docs/guides/whatsapp/business-scoped-user-ids)。

联系人添加一个竖起大拇指的回应会产生以下 webhook：

```json
{
  "data": {
    "emoji": "👍",
    "from": { "phone_number": "+14155550100" },
    "to": { "phone_number": "+13124495569" },
    "whatsapp_id": "wam_01ky8b3xq4gd7pmzn2ka51f7te",
    "workspace_id": "ws_01ky7m235keycbnwyajabe1a6b"
  },
  "timestamp": "2026-08-28T19:01:10.000Z",
  "type": "whatsapp.reacted"
}
```

按以下方式解读 `data.emoji`：

- 非空的表情符号表示在被引用的消息上添加或替换该联系人的回应。
- `null` 表情符号表示移除该联系人的回应。此字段在移除事件中存在。

替换以一个携带新表情符号的事件送达；旧表情符号没有单独的移除事件。请保留精确字符串：`❤` 和 `❤️` 在载荷中是不同的值。

## 3. 检索当前回应

如果您的应用需要显示当前附加在消息上的回应，请[检索该消息](/docs/api/reference/get-whatsapp-message)并读取其 `reactions`。该列表包含每个发送方的一个有效回应，当没有回应存在时会被省略。

对于 `GET /v1/whatsapp/messages/wam_01ky8b3xq4gd7pmzn2ka51f7te`，回应相关字段的结构如下（省略了其他消息字段）：

```json
{
  "id": "wam_01ky8b3xq4gd7pmzn2ka51f7te",
  "reactions": [
    {
      "emoji": "👍",
      "from": { "phone_number": "+14155550100" }
    }
  ]
}
```

消息保留其原始内容、方向和投递状态。`reactions[].from` 标识做出回应的人。

不要将收到的最后一个 webhook 视为当前状态。WhatsApp 以秒为精度报告回应时间，因此变更可能共享同一时间戳，webhook 重试也可能改变到达顺序。请使用 webhook 触发对消息当前回应的刷新。

## 4. 查看回应历史

[列出回应事件](/docs/api/reference/list-whatsapp-message-reaction-events)以查看被引用消息的变更。传入的联系人变更状态为 `received`；移除操作携带 `emoji: null`。该列表还包含[您的工作区发送的回应](/docs/guides/whatsapp/reactions)的结果。

回应事件 API 返回分页响应。以下示例展示了一个被拒绝的业务回应和一个更早收到的联系人回应：

```json
{
  "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` 变更。关于保留期和分页方式，请参照[回应日志参考](/docs/api/reference/list-whatsapp-message-reaction-events)。

## 故障排查

- **没有收到回应 webhook**：检查订阅是否包含 `whatsapp.reacted`。对较旧消息的回应，如果其提供商引用已无法解析，则不会产生匹配的回应、日志条目或 webhook。
- **消息列表中缺少回应**：查找原始消息。回应附加在该消息上，没有单独的消息行。
- **回应状态意外变化**：刷新原始消息的 `reactions`，而不是按到达时间或时间戳对 webhook 事件排序。

## 后续步骤

- [发送或移除回应](/docs/guides/whatsapp/reactions)
- [阅读 WhatsApp 事件载荷](/docs/guides/whatsapp/events)
- [接收 WhatsApp 消息](/docs/guides/whatsapp/receiving-whatsapp)

## Related resources

- [Connecting WhatsApp to Bird: from buying a number to a live channel](/learn/whatsapp/connecting-whatsapp-to-bird) (video)
- [What is the 24-hour customer service window on WhatsApp?](/explained/whatsapp/what-is-the-24-hour-customer-service-window) (answer)
- [WhatsApp message builder](/tools/whatsapp-message-builder) (tool)
- [WhatsApp](/products/whatsapp) (product)

[Get an implementation brief](/learn/workspace?topic=whatsapp)
