WhatsApp 电话号码
WhatsApp 消息从两种号码之一发出:一种是 Bird 代你运营的号码,另一种是你自己的工作区拥有的号码。你使用哪种号码决定了你能发送什么内容,以及发送时是否会显示发送方信息。

Bird 托管号码
Bird 自有号码无需设置,并携带 slug 以 bird_ 开头的预审批模板。Bird 根据模板类别和你的地区选择号码:authentication 模板使用专用的身份验证号码,utility 模板使用通知号码。因此,托管模板的发送没有 from 字段,设置该字段会被拒绝。
这些号码使用 Bird 托管的发送基础设施,因此收件人看到的发送方是 Bird 而非你自己,且无法通过它们发送自由格式内容。它们在 WABA 列中标记为 Bird-managed。
你的自有号码
你从 Numbers 页面通过 Meta 的 Embedded Signup 弹窗连接号码。有两种方式,区别在于谁来读取 Meta 发送给该号码的验证码:
- 我有自己的号码。 你通过 SMS 或语音电话接收 Meta 的验证码,然后自行输入到 Embedded Signup 窗口中。在更改现有注册之前,请选择支持的迁移路径或符合条件的 Business app 共存路径,并且仅在号码已在 WhatsApp 上设置过 Phone registration PIN 时才设置该 PIN。
- 你的工作区在 Bird 持有的号码。 改为从 Number 列表中选择。Bird 会接收验证码并为你完成 Meta 的验证,因此该号码到达时已处于 pre-verified 状态,你只需在 Embedded Signup 窗口中选择它。
对 Bird 持有的号码进行验证
选择一个持有的号码会在 Embedded Signup 弹窗打开之前启动验证。Bird 请求 Meta 向该号码发送短信,然后代你回读验证码。

这通常不到一分钟。你无需在对话框中等待:Continue in background 会关闭对话框,Numbers 页面上的行会跟踪相同的进度。
验证码读取完成后,号码已通过 Meta 验证,等待你在 Embedded Signup 中完成设置。Finish setting up 会打开 Meta 的弹窗,你在其中选择号码及其应加入的商业账户。

号码状态的含义
号码在可以发送之前会经历多个状态,Status 列显示其当前所处的状态:
| 状态 | 含义 |
|---|---|
| Preparing | Bird 正在为你的工作区持有的号码完成 Meta 验证。 |
| Pre-verified | Bird 已完成 Meta 验证。请在 Embedded Signup 中完成号码设置。 |
| Pending | Embedded Signup 已完成,Bird 正在向 Meta 注册该号码。 |
| Connected | 号码可以发送。 |
| Failed | 设置已停止。该行显示原因。 |
两种路径都可能在中途失败,可能发生在 Meta 验证环节,也可能发生在弹窗中。恢复方式取决于该行显示的原因。
如果该行显示 verification_code_not_received 或 verification_rate_limited,打开该号码并选择 Try again,而不是断开连接。预验证失败的原因及何时重试说明了该按钮何时可用,以及重试仍然失败时该怎么做。
对于所有其他原因,从该行的操作中断开号码连接,然后重新连接:失败的行会保持号码的占用状态,因此不先移除就进行第二次尝试会被拒绝。
不购买电话号码可以发送 WhatsApp 吗?详细介绍了这个选择。
已连接号码显示的内容
号码的详情页面显示 WhatsApp 当前允许它执行的操作,以及一个涵盖其发送历史的 Activity 部分。

Quality rating、Messaging limit 和 Send rate 是 WhatsApp 的数值,而非 Bird 的。消息发送限额是 WhatsApp 允许在 24 小时内发起的商业主动会话数量,随着号码发送表现良好而提升。Quality rating 在 WhatsApp 积累足够的投递历史来评分之前显示为 Not rated。
Business profile 标签页包含收件人在 WhatsApp 中看到的关于你的信息:显示名称、描述、地址和头像。
号码背后的商业账户
每个已连接的号码都属于一个 WhatsApp Business Account,WABA 列链接到它。其详情页报告的是 Meta 对该商业主体本身的审核结果,而非对号码的审核。

这些状态决定了账户能做什么。Business verification 尤其决定了身份验证模板的使用:未验证的商业主体无法创建此类模板。Marketing Messages API 在 Meta 接受账户后显示为 Onboarded。营销发送不需要等待它。Onboarding 决定了 Meta 的投递优化功能,以及一个 gif 请求头,该请求头在未完成 onboarding 的账户上会在 WhatsApp 处失败。一个工作区可以包含多个商业账户,每个账户可以有多个号码。请查看拥有目标发送号码的账户的审核结果;已连接的账户有特定的工作区和地区归属。
Bird 按计划而非持续地从 Meta 读取这些信息,因此 Last read from WhatsApp 标注了其上方审核结果的读取日期。
通过 API 读取你的号码
仪表板上显示的所有内容都可以通过 API 和 SDK 读取。读取需要具有 whatsapp_management 读取权限的 API 密钥。
GET /v1/whatsapp/numbers 以游标分页形式返回你的发送号码。每个号码携带 WhatsApp 为其报告的状态,因此这是告诉你发送可以使用哪些 from 值的调用。
GET /v1/whatsapp/numbers/{id} 读取单个号码,包含与详情页面呈现的相同的质量评分、消息发送限额和吞吐量级别。GET /v1/whatsapp/numbers/{id}/profile 读取 Business profile 标签页背后的商业资料,包括 description、address 和 websites。
GET /v1/whatsapp/numbers/{id}/events 返回号码如何到达当前状态的历史记录,最新的在前:添加时间、每次状态变更,以及每次消息发送限额、质量评分和显示名称的决定。每个事件携带 type、summary 和 created_at。type 是一个开放枚举,因此将你不认识的值视为未来的事件类型而非错误。
GET /v1/whatsapp/business-accounts 和 GET /v1/whatsapp/business-accounts/{id} 读取本页上述的账户状态:account_review_status、business_verification_status 和 marketing_messages_onboarding_status。号码在其自身的 waba 字段中报告其所属账户,该字段持有 Meta 的账户 ID 而非 Bird ID。
在基于这些读取构建之前,有两个细节值得了解。meta_synced_at 标注了 WhatsApp 报告字段的日期,对应仪表板中的 Last read from WhatsApp,在 Bird 代你运营的号码上该字段不存在。注册中的号码是可读取的:status 报告 preparing 和 awaiting_signup,next 说明该状态下应采取的操作,finish_setup_url 携带完成设置的链接,因此你可以轮询设置进度并将最后一步交给用户。唯一保留的字段是 meta_preverified_id,即 WhatsApp 为正在准备的号码分配的内部 ID,该字段仅在仪表板中可见。
连接、重命名和断开号码不属于公共 API 或 SDK 的功能。它们可在仪表板和 CLI(bird whatsapp numbers create|update|delete 和 bird whatsapp numbers profile update)中使用。只有一个步骤必须在浏览器中完成:新连接需在 Meta 自己的授权页面上完成,这就是 create 返回给你一个 finish_setup_url 而非自行完成的原因。
入站消息
入站消息仅通过你的自有号码到达你的工作区。Bird 将其记录在 WhatsApp 日志中,Metrics 页面的 Inbound 标签页按号码报告接收量。每条入站消息还会打开自由格式内容所需的 24 小时窗口。Bird 托管号码不会为你的工作区接收消息。
后续步骤
- 发送 WhatsApp 消息:这些号码承载的发送调用,以及何时需要 from
- WhatsApp 模板:托管目录和你的自有模板
- WhatsApp 客服窗口:自由格式内容何时可以投递
- WhatsApp 日志:查看消息从哪个号码发出
- 将 WhatsApp 连接到 Bird:从购买号码到上线频道:一段在仪表板中演示相同流程的视频
for await (const number of bird.whatsapp.numbers.list({ limit: 25 })) {
console.log(number.id, number.phone_number, number.status);
}for number in client.whatsapp.numbers.list(limit=25):
print(number.id, number.phone_number, number.status)for number, err := range client.Whatsapp.Numbers.List(ctx, bird.WhatsappNumbersListParams{Limit: 25}) {
if err != nil {
log.Fatal(err)
}
fmt.Println(number.Id, number.PhoneNumber, number.Status)
}foreach ($bird->whatsapp->numbers->list() as $number) {
echo $number->getId(), ' ', $number->getPhoneNumber(), ' ', $number->getStatus(), PHP_EOL;
}curl -sS "https://us1.platform.bird.com/v1/whatsapp/numbers?limit=25" \
-H "Authorization: Bearer $BIRD_API_KEY"