# 接收 WhatsApp 互动回复

联系人点击回复按钮、列表行或模板的快捷回复按钮后，会产生一条独立的入站消息，携带 `interactive_reply`。该分支会返回你在发送时设置的句柄，因此流程根据你自己的标识符进行分支，而非联系人看到的标签。

## 入站互动回复携带的内容

`type` 标明点击的类型，同名字段携带该类型的数据：

```json
{
  "id": "wam_01kyb2m4xq7whs0d8n3prv6tez",
  "direction": "inbound",
  "from": { "phone_number": "+14155550100" },
  "to": { "phone_number": "+13124495569" },
  "status": "received",
  "in_reply_to_message_id": "wam_01kya19eknftrs2s6p82asmvnh",
  "interactive_reply": {
    "type": "button",
    "button": { "slug": "cancel-booking", "text": "Cancel" }
  },
  "created_at": "2026-08-25T09:04:11Z"
}
```

| `type`   | 字段     | 携带内容                                                                |
| -------- | -------- | ----------------------------------------------------------------------- |
| `button` | `button` | 回复按钮或模板快捷回复按钮的 `slug` 和 `text`                           |
| `list`   | `list`   | 联系人所选行的 `slug` 和 `text`，以及该行的 `description`（如果有的话） |

列表行将 `button` 替换为 `list`，并添加该行显示的第二行文本：

```json
{
  "interactive_reply": {
    "type": "list",
    "list": {
      "slug": "priority_express",
      "text": "Priority Mail Express",
      "description": "Next day to 2 days"
    }
  }
}
```

`slug` 是你声明的、联系人从未看到的句柄；`text` 是他们看到的标签。请根据 `slug` 进行分支。标签可能被改写和翻译，而点击模板快捷回复按钮时，`slug` 是该模板声明的载荷，WhatsApp 默认将其设为按钮自身的标签。

类型列表是开放的：WhatsApp 会随时间添加新的互动类型，因此遇到不认识的 `type` 时应将其视为未来类型而非错误，回退到记录该消息而不是中断读取。

## 将点击关联到你发送的消息

`in_reply_to_message_id` 标明承载按钮或菜单的那条消息，让你知道这个回答属于哪个问题。WhatsApp 并非在每次点击时都会报告它，解析也可能失败，此时该字段会被省略而非报告为空。Hub 的[引用回复](/docs/guides/whatsapp/receiving-whatsapp#quoted-replies)说明了缺失意味着什么，以及被引用消息可解析的持续时间。

如果关联必须可靠，请将你自己的引用放在 `slug` 本身中，或放在发送时的 `metadata` 中，而不是依赖该字段。发送端的做法参见[引用消息](/docs/guides/whatsapp/sending-whatsapp#quoting-a-message)。

## 通过其他途径到达的两种点击

两种互动类型的回答完全不带 `interactive_reply`：

- [位置请求](/docs/guides/whatsapp/message-types/interactive/location-requests)会作为普通入站[位置](/docs/guides/whatsapp/receiving-whatsapp/location)返回。
- [联系信息请求](/docs/guides/whatsapp/message-types/interactive/contact-info-requests)会作为[联系人名片](/docs/guides/whatsapp/receiving-whatsapp/contact-cards)返回，其中 `origin` 设为 `contact_request`。

[链接按钮](/docs/guides/whatsapp/message-types/interactive/cta-url-buttons)不会返回任何内容：联系人跳转到 URL，没有入站消息记录该点击。仅监听 `interactive_reply` 的集成会漏掉以上三种情况。

## Webhook 载荷

`whatsapp.received` 在事件信封上携带 `interactive_reply` 分支，因此机器人无需回读消息即可响应点击：

```json
{
  "type": "whatsapp.received",
  "timestamp": "2026-08-25T09:04:11.118Z",
  "data": {
    "whatsapp_id": "wam_01kyb2m4xq7whs0d8n3prv6tez",
    "workspace_id": "ws_01ky7m235keycbnwyajabe1a6b",
    "direction": "inbound",
    "from": { "phone_number": "+14155550100", "display_name": "Alex Rivera" },
    "to": { "phone_number": "+13124495569" },
    "in_reply_to_message_id": "wam_01kya19eknftrs2s6p82asmvnh",
    "interactive_reply": {
      "type": "button",
      "button": { "slug": "cancel-booking", "text": "Cancel" }
    },
    "tags": null,
    "metadata": null
  }
}
```

## 注意事项

- **`interactive` 和 `interactive_reply` 是相反的方向。** `interactive` 是你发送的内容，不会出现在入站消息中；`interactive_reply` 是联系人点击的内容，不会出现在出站消息中。
- **点击会重置服务窗口。** 它是一条入站消息，因此和文本消息一样，会重新开启 24 小时的自由回复窗口。
- **联系人可以点击同一个按钮两次。** 不会对点击进行去重，每次点击都是一条有独立 ID 的消息。请确保你在 `slug` 上执行的操作是幂等的。
- **旧菜单上的点击仍然会到达。** 联系人可以向上滚动并点击几天前的按钮，因此请验证流程是否仍然有效，而不要假设该点击是对你最新消息的回答。

## 后续步骤

- [接收消息的工作原理](/docs/guides/whatsapp/receiving-whatsapp)：入站信封、媒体获取和 `whatsapp.received` webhook
- [WhatsApp 互动消息](/docs/guides/whatsapp/message-types/interactive)：收件人可点击的六种类型
- [WhatsApp 回复按钮](/docs/guides/whatsapp/message-types/interactive/reply-buttons)：按钮点击的发送端
- [WhatsApp 列表菜单](/docs/guides/whatsapp/message-types/interactive/list-menus)：行选择的发送端

## 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)
