Sign inGet started

WhatsApp 联系人卡片

联系人卡片消息可分享一个或多个联系人:收件人在卡片上看到的姓名,以及从卡片打开的个人资料视图,其中包含电话号码、电子邮件、网站、地址、雇主和生日。用它把同事的号码、快递员的号码或您自己的号码递给客户,无需将数字粘贴到文本中让对方重新手动输入。

发送联系人卡片

contact_cards 是一个数组。每张卡片需要一个 name,且该名称需要 formatted_name 加上至少一个其他部分:
const msg = await bird.whatsapp.send({
  to: "+16505551234",
  from: "+13124495648",
  contact_cards: [
    {
      name: {
        formatted_name: "Barbara J. Johnson",
        first_name: "Barbara",
        last_name: "Johnson",
      },
      phone_numbers: [{ phone_number: "+16505559999", type: "Mobile" }],
    },
  ],
});
console.log(msg.id, msg.status);
from 在每条服务消息中都是必填项:一个您的工作区拥有的号码,而非 Bird 托管的号码。
完整结构还包含雇主、生日以及其他联系方式详情数组:
代码示例
{
  "to": "+16505551234",
  "from": "+13124495648",
  "contact_cards": [
    {
      "name": {
        "formatted_name": "Dr. Barbara J. Johnson Esq.",
        "prefix": "Dr.",
        "first_name": "Barbara",
        "middle_name": "Joana",
        "last_name": "Johnson",
        "suffix": "Esq."
      },
      "org": { "company": "Lucky Shrub", "department": "Legal", "title": "Lead Counsel" },
      "birthday": "1999-01-23",
      "phone_numbers": [
        { "phone_number": "+16505559999", "type": "Landline" },
        { "phone_number": "+19175559999", "type": "Mobile" }
      ],
      "emails": [{ "email": "bjohnson@example.com", "type": "Work" }],
      "urls": [{ "url": "https://example.com", "type": "Company" }],
      "addresses": [
        {
          "street": "1 Lucky Shrub Way",
          "city": "Menlo Park",
          "state": "CA",
          "zip": "94025",
          "country": "United States",
          "country_code": "US",
          "type": "Office"
        }
      ]
    }
  ]
}
每个 type 标签,无论用在电话、电子邮件、网站还是地址上,都是您自行填写的自由文本,按原样发送,并在收件人的个人资料视图中显示在值的旁边。WhatsApp 未定义这些标签的词汇表,因此 MobileLandlinePop-UpWork (old) 都同样有效。

卡片获得按钮的条件

以 E.164 格式书写的电话号码(包含国家代码和前导 +)会为该卡片赢得一个按钮,点击即可与该号码打开 WhatsApp 聊天。Bird 无法识别为 E.164 的号码仍会按原样显示在卡片上,只是不会获得按钮。
这包括没有前导 + 的号码。Bird 不会为您补上:一个国内格式的号码在加上 + 后,可能被解析为另一个国家的有效号码,从而将按钮指向一个陌生人。放弃猜测只是少一个按钮;猜错则让收件人与错误的人聊天。
完全不包含电话号码的卡片不会显示聊天按钮,只能被保存到通讯录。

限制

字段约束执行方
contact_cards每条消息 1 到 5 张卡片Bird,在接受时(422
name必填;formatted_name 加上至少一个其他名称部分Bird,在接受时(422
formatted_namefirst_namemiddle_namelast_name最多 256 个字符Bird,在接受时(422
prefixsuffix最多 64 个字符Bird,在接受时(422
birthday可选,YYYY-MM-DD,且为日历中存在的日期Bird,在接受时(422
phone_numbersemailsurlsaddresses各最多 10 个条目Bird,在接受时(422
phone_number最多 32 个字符Bird,在接受时(422
email最多 254 个字符Bird,在接受时(422
url最多 2048 个字符,不校验是否为 URLBird,在接受时(422
任意电话、电子邮件、网站或地址上的 type最多 64 个字符的自由文本Bird,在接受时(422
companydepartmenttitle最多 128 个字符Bird,在接受时(422
streetcitystatezipcountrycountry_code最多 128 个字符Bird,在接受时(422
五张卡片的上限是 Bird 设定的,且远低于 WhatsApp 所接受的数量。 WhatsApp 自己发布的 API 描述声明上限为五,其文档建议出于可用性和负面反馈原因发送更少,而一打开就是 "Contact 1 and 256 other contacts" 的消息在成为功能之前先是垃圾信息载体。日后提高上限属于增量变更,因此如果五张不够用,请提出需求。
上面的所有长度限制也是 Bird 设定的。WhatsApp 没有施加任何有意义的限制,其客户端也不会补偿:500 个字符的 type 会渲染成十行重复字母,4000 个字符的 url 会被静默丢弃,使个人资料视图留白。一个指出问题字段的 422 胜过一张收件人无法阅读的卡片。

Schema 无法表达的两条规则

姓名需要第二个部分。 仅有 formatted_name 会被拒绝,返回 422 E15061 WhatsAppContactNameIncomplete,指明 contact_cards.<n>.nameprefixfirst_namemiddle_namelast_namesuffix 中的任意一个即可满足要求,但空白或仅含空格的值不算,org 也无法弥补。这是 WhatsApp 自身的要求,其参考文档中未有记载;Bird 会在接受时捕获此错误,让您获得可操作的错误而非异步失败。
生日必须是真实日期。 birthday 的格式为 YYYY-MM-DD;任何其他格式以及日历中不存在的日期(例如 2026-02-30)都会被拒绝,返回 422 E15062 WhatsAppContactBirthdayInvalid。WhatsApp 本身接受 2026-02-30 并将其展示给收件人,看起来像是您数据中的 bug。

回读卡片

您发送的卡片通过消息列表或 GET /v1/whatsapp/messages/{id} 在入站卡片使用的同一个 contact_cards 字段上回读:
代码示例
{
  "id": "wam_01kyb2m4xq7whs0d8n3prv6tez",
  "direction": "outbound",
  "status": "delivered",
  "contact_cards": [
    {
      "name": { "formatted_name": "Barbara J. Johnson", "first_name": "Barbara" },
      "phone_numbers": [{ "phone_number": "+16505559999", "type": "Mobile" }]
    }
  ]
}
您发送的卡片上不存在 originvcard:WhatsApp 在联系人分享的卡片上设置这两个字段。您发送的 type 标签回读时与原文完全一致,而收到的卡片上的标签会被转为小写。入站侧详见接收 WhatsApp 联系人卡片

边界情况

  • 客服窗口必须处于打开状态。 联系人卡片发送属于服务消息,仅在打开的窗口内可投递;请参阅 Hub 的客服窗口
  • 没有可发送的 wa_id WhatsApp 通过帐户 ID 标识卡片的联系人;Bird 从每个 E.164 phone_number 中推导该 ID,而非接受一个现成的 ID,因此卡片上的按钮永远只会指向卡片上印刷的号码。
  • vcard 是只读的。 WhatsApp 在联系人分享的卡片上生成该字段。无法以原始 vCard 文本的形式发送卡片。
  • 卡片不是联系人记录。 发送卡片只是在消息中分享详情;它不会在您的工作区中创建任何内容,收件人是否保存完全是他们自己的操作,对您不可见。

后续步骤