# WhatsApp 快捷回复按钮

快捷回复按钮在 WhatsApp 消息下方放置最多三个可点击选项，让收件人通过点击而非自由输入来回复。适用于快速决策场景，例如确认或取消预订。如果选项超过三个，请改用[列表菜单](/docs/guides/whatsapp/message-types/interactive/list-menus)。

## 发送快捷回复按钮

将 `interactive.type` 设置为 `button`，包含一个 `body_text` 和一到三个 `buttons`，每个都是一个 `quick_reply`：

**TypeScript**

```typescript
const msg = await bird.whatsapp.send({
  to: "+16505551234",
  from: "+13124495648",
  interactive: {
    type: "button",
    body_text: "Your gardening workshop is scheduled for 9am tomorrow.",
    buttons: [{ type: "quick_reply", quick_reply: { slug: "change-booking", text: "Change" } }],
  },
});
console.log(msg.id, msg.status);
```

Examples: [TypeScript](/zh-sg/wendang/guides/whatsapp/message-types/interactive/reply-buttons.ts.md) · [Python](/zh-sg/wendang/guides/whatsapp/message-types/interactive/reply-buttons.py.md) · [Go](/zh-sg/wendang/guides/whatsapp/message-types/interactive/reply-buttons.go.md) · [PHP](/zh-sg/wendang/guides/whatsapp/message-types/interactive/reply-buttons.php.md) · [CLI](/zh-sg/wendang/guides/whatsapp/message-types/interactive/reply-buttons.cli.md) · [MCP](/zh-sg/wendang/guides/whatsapp/message-types/interactive/reply-buttons.mcp.md) · [cURL](/zh-sg/wendang/guides/whatsapp/message-types/interactive/reply-buttons.curl.md)

`from` 在每条服务消息中都是必填项：必须是您的工作区拥有的号码，而不是 Bird 托管的号码。完整结构还可以添加可选的标题、页脚、对早前消息的引用，以及第二个按钮：

```json
{
  "to": "+16505551234",
  "from": "+13124495648",
  "in_reply_to_message_id": "wam_01kya19eknftrs2s6p82asmvnh",
  "interactive": {
    "type": "button",
    "header": {
      "type": "image",
      "url": "https://cdn.example.com/banners/workshop.png"
    },
    "body_text": "Your gardening workshop is scheduled for 9am tomorrow.",
    "footer_text": "Lucky Shrub, your gateway to succulents",
    "buttons": [
      { "type": "quick_reply", "quick_reply": { "slug": "change-booking", "text": "Change" } },
      { "type": "quick_reply", "quick_reply": { "slug": "cancel-booking", "text": "Cancel" } }
    ]
  },
  "tags": [{ "name": "category", "value": "booking" }],
  "metadata": { "order_id": "A-1" }
}
```

`in_reply_to_message_id` 引用同一会话中的早前消息。请参阅中心的[引用消息以关联回复](/docs/guides/whatsapp/message-types/interactive#quoting-a-message-to-correlate-a-reply)，了解解析方式及其可能遗漏的情况。

此类型仅发送 `quick_reply` 按钮。`cta_url` 按钮属于单独的 `interactive.type`，不能与 `buttons` 一起出现；请参阅中心的[按钮](/docs/guides/whatsapp/message-types/interactive#buttons)部分了解共享的按钮结构。

## 标题和页脚

标题是可选的，有以下四种形式之一：

```text
"header": { "type": "text",     "text": "New workshop dates" }
"header": { "type": "image",    "url": "https://cdn.example.com/a.png" }
"header": { "type": "video",    "url": "https://cdn.example.com/a.mp4" }
"header": { "type": "document", "url": "https://cdn.example.com/a.pdf" }
```

媒体标题（`image`、`video` 或 `document`）通过公开的 `https` URL 携带文件，由 WhatsApp 在发送时获取，而不是使用已上传的媒体句柄。`footer_text` 是可选的，会在按钮下方添加一行文字。

## 限制

| 字段                       | 约束                                  |
| -------------------------- | ------------------------------------- |
| `buttons`                  | 1 到 3 个条目，每个都是 `quick_reply` |
| `quick_reply.slug`         | 必填，1 到 256 个字符                 |
| `quick_reply.text`（标签） | 必填，1 到 20 个字符，在消息内唯一    |
| `body_text`                | 必填，1 到 1024 个字符                |
| `footer_text`              | 可选，1 到 60 个字符                  |
| `header.text`              | 1 到 60 个字符                        |

Bird 会检查按钮标签（`quick_reply.text`）是否唯一，但不会检查 `slug` 值是否唯一，尽管每个 slug 本应标识一个按钮。两个共享同一 slug 的按钮都能发送和投递，但它们的回复无法区分。

## 读取回复

按下按钮会作为一条独立的入站消息到达，携带 `interactive_reply`：

```json
{
  "id": "wam_01kyb2m4xq7whs0d8n3prv6tez",
  "direction": "inbound",
  "from": { "phone_number": "+16505551234" },
  "to": { "phone_number": "+13124495648" },
  "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"
}
```

您在发送时设置的 `slug` 会原样返回，因此可以直接用它进行分支判断，无需查找表。您可以通过消息列表或 `GET /v1/whatsapp/messages/{id}` 查看此回复；请参阅中心的[读取回复](/docs/guides/whatsapp/message-types/interactive#reading-a-reply)了解完整流程。

## 限制和边界情况

- **客户服务窗口必须处于打开状态。** 快捷回复按钮是服务消息，仅在窗口打开时可投递；请参阅中心的[客户服务窗口](/docs/guides/whatsapp/message-types#the-customer-service-window)。窗口检查采用开放失败策略，因此 `202` 并不能证明发送时窗口确实处于打开状态。
- **`from` 必须是您的工作区拥有的号码。** 省略该字段或指定一个未连接的发送号码，请求会在创建发送之前被拒绝。
- **标签必须唯一，否则发送会被拒绝。** 两个具有相同 `quick_reply.text` 的按钮会以 `422` [`E15056`](/docs/api/errors/E15056) `WhatsAppInteractiveDuplicateLabel` 失败，因为 Meta 会在发送已被接受并计费后拒绝重复标签。
- **标签是收件人看到的内容；slug 永远不会显示。** 将面向用户的文案放在 `slug` 中不会产生任何效果，因为只有 `text` 会在聊天中渲染。
- **WhatsApp 无法获取的媒体请求头 URL 会在发送被接受后失败。** Bird 不会像验证媒体消息 URL 那样验证请求头 `url`，因此 `http://` URL 或返回错误的 URL 会通过请求，然后异步失败，`media_rejected` 会出现在消息的 `last_error` 上。
- **发送 Meta 自有的字段名会导致请求失败。** 此类型会直接拒绝未知属性，因此从 Meta Cloud API 参考文档复制的 JSON（例如 `body` 对象或 `action.buttons` 包装器）需要先重新整理为 Bird 的扁平字段。

无法解析的引用会在创建或计费之前导致请求失败：当 id 指定的消息不属于此工作区时返回 `404` [`E15071`](/docs/api/errors/E15071)，当指定的消息无法被引用时返回 `422` [`E15072`](/docs/api/errors/E15072)。对于任何 WhatsApp 发送可能遇到的错误（窗口关闭、发送方缺失或无效、收件人无效），请参阅中心的[错误](/docs/guides/whatsapp/message-types/interactive#errors)和[发送 WhatsApp 消息](/docs/guides/whatsapp/sending-whatsapp)。

## 后续步骤

- [WhatsApp 互动消息](/docs/guides/whatsapp/message-types/interactive)：六种互动类型的共同要素
- [列表菜单](/docs/guides/whatsapp/message-types/interactive/list-menus)：适用于超过三个选项的场景
- [发送 WhatsApp 消息](/docs/guides/whatsapp/sending-whatsapp)：请求信封、`202` 模型和安全重试

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