Sign inGet started

WhatsApp 快捷回复按钮

快捷回复按钮在 WhatsApp 消息下方放置最多三个可点击选项,让收件人通过点击而非自由输入来回复。适用于快速决策场景,例如确认或取消预订。如果选项超过三个,请改用列表菜单

发送快捷回复按钮

interactive.type 设置为 button,包含一个 body_text 和一到三个 buttons,每个都是一个 quick_reply
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);
from 在每条服务消息中都是必填项:必须是您的工作区拥有的号码,而不是 Bird 托管的号码。完整结构还可以添加可选的标题、页脚、对早前消息的引用,以及第二个按钮:
代码示例
{
  "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 引用同一会话中的早前消息。请参阅中心的引用消息以关联回复,了解解析方式及其可能遗漏的情况。
此类型仅发送 quick_reply 按钮。cta_url 按钮属于单独的 interactive.type,不能与 buttons 一起出现;请参阅中心的按钮部分了解共享的按钮结构。

标题和页脚

标题是可选的,有以下四种形式之一:
代码示例
"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" }
媒体标题(imagevideodocument)通过公开的 https URL 携带文件,由 WhatsApp 在发送时获取,而不是使用已上传的媒体句柄。footer_text 是可选的,会在按钮下方添加一行文字。

限制

字段约束
buttons1 到 3 个条目,每个都是 quick_reply
quick_reply.slug必填,1 到 256 个字符
quick_reply.text(标签)必填,1 到 20 个字符,在消息内唯一
body_text必填,1 到 1024 个字符
footer_text可选,1 到 60 个字符
header.text1 到 60 个字符
Bird 会检查按钮标签(quick_reply.text)是否唯一,但不会检查 slug 值是否唯一,尽管每个 slug 本应标识一个按钮。两个共享同一 slug 的按钮都能发送和投递,但它们的回复无法区分。

读取回复

按下按钮会作为一条独立的入站消息到达,携带 interactive_reply
代码示例
{
  "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} 查看此回复;请参阅中心的读取回复了解完整流程。

限制和边界情况

  • 客户服务窗口必须处于打开状态。 快捷回复按钮是服务消息,仅在窗口打开时可投递;请参阅中心的客户服务窗口。窗口检查采用开放失败策略,因此 202 并不能证明发送时窗口确实处于打开状态。
  • from 必须是您的工作区拥有的号码。 省略该字段或指定一个未连接的发送号码,请求会在创建发送之前被拒绝。
  • 标签必须唯一,否则发送会被拒绝。 两个具有相同 quick_reply.text 的按钮会以 422 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,当指定的消息无法被引用时返回 422 E15072。对于任何 WhatsApp 发送可能遇到的错误(窗口关闭、发送方缺失或无效、收件人无效),请参阅中心的错误发送 WhatsApp 消息

后续步骤