WhatsApp 模板
由企业发起的 WhatsApp 消息使用预先审批的模板。模板包含固定文本和变量,因此发送时只需提供值,例如 OTP 验证码或订单号。
Bird 提供托管模板目录,将其内容注册到 WhatsApp,并通过 Bird 自有号码发送;其 slug 以 bird_ 开头。已连接自有号码的工作区也可以在其自己的 WhatsApp Business Account 上创建模板。Templates 页面显示该工作区可发送的所有模板及每个模板的渲染效果。

在仪表盘中浏览模板
打开 WhatsApp > Templates 下的模板。Your templates 包含此工作区创建的模板;All templates 还包含 Bird 托管目录。按名称搜索或按状态和类别筛选,使用筛选器旁的切换按钮在卡片网格和列表视图之间切换。
在列表视图中,每行显示选择和发送模板所需的字段:
- Status:模板整体是否可发送。托管目录模板显示
active;自有模板显示其审批状态。检查语言列表以确认所需语言可用。 - Name:显示标签,其下方为模板的
slug。发送时使用slug。 - Languages:模板已注册的语言,例如英语和荷兰语。
- Category:
authentication、utility或marketing。类别决定 WhatsApp 如何处理消息、托管模板从哪个 Bird 号码发送,以及结合目的地国家的价格。 - WABA:目录模板显示 Bird-managed。自有模板显示持有它的 WhatsApp Business Account,且仅从该账户上的号码发送。
- Updated:模板的最后更改时间。
点击一行打开模板详情。
模板包含什么
详情视图以 WhatsApp 风格的预览渲染消息正文、变量和按钮。
详情还提供用于 POST /v1/whatsapp/messages 的 cURL 示例,使用区域主机和模板的示例值。发送前请替换 API 密钥、收件人和变量值。
该示例是查看发送所需结构的最快方式。通过 API,相同内容来自模板的版本(读取模板内容)。
从 API 列出模板
GET /v1/whatsapp/templates 返回游标分页的目录。请求需要 whatsapp_management 读取权限。使用 HTTP 或 SDK 的原始请求方法。
type Templates = { data: Array<{ slug: string; status: string }> };
const templates = await bird.request<Templates>({
method: "GET",
path: "/v1/whatsapp/templates",
});templates = client.get("/v1/whatsapp/templates")var out struct {
Data []struct {
Slug string `json:"slug"`
Status string `json:"status"`
} `json:"data"`
}
if err := client.Get(context.Background(), "/v1/whatsapp/templates", &out); err != nil {
log.Fatal(err)
}$templates = $bird->get('/v1/whatsapp/templates');curl https://us1.platform.bird.com/v1/whatsapp/templates \
-H "Authorization: Bearer $BIRD_API_KEY"每条记录标识模板、其类别和可用语言。消息内容需单独读取实时版本。
{
"available_languages": ["en", "es", "pt-BR", "..."],
"category": "authentication",
"default_language": "en",
"description": "One-time passcode",
"id": "wat_01ky4x8e4genzb7way45txfkm1",
"languages": {
"en": { "status": "approved" },
"es": { "status": "approved" },
"pt-BR": { "status": "approved" },
"...": "..."
},
"name": "bird_otp",
"on_missing_language": "fail",
"scope": "system",
"slug": "bird_otp",
"status": "active"
}示例响应对 bird_otp 语言列表进行了缩略。
发送依赖的字段:
slug:发送时使用的标识。托管模板的 slug 以bird_开头,该前缀为其保留。waba:在 Meta 持有模板语言的 WhatsApp Business Account,也是发送号码必须归属的账户。托管模板上不存在此字段,因为 Bird 管理其账户。available_languages:可发送的语言。已暂停、已禁用、已归档或受限的语言不在此列表中。on_missing_language:请求的语言不可用时的处理方式。Bird 托管的 WhatsApp 模板使用fail,即拒绝发送而非替换为其他语言。
状态和语言状态
Bird 托管的模板显示 status: active。languages.<tag>.status 报告单个语言的 WhatsApp 状态,例如 approved、paused 或 disabled。
活跃的模板仍可能有不可用的语言。使用 available_languages 判断某语言是否可发送。
读取模板内容
消息内容属于实时版本中的某个语言。从模板读取 live_version_id,然后请求所需语言:
const language = await bird.request({
method: "GET",
path: "/v1/whatsapp/templates/bird_order_confirmation/versions/{version_id}/languages/en",
});language = client.get(
"/v1/whatsapp/templates/bird_order_confirmation/versions/{version_id}/languages/en"
)var language map[string]any
if err := client.Get(context.Background(),
"/v1/whatsapp/templates/bird_order_confirmation/versions/{version_id}/languages/en",
&language); err != nil {
log.Fatal(err)
}$language = $bird->get('/v1/whatsapp/templates/bird_order_confirmation/versions/{version_id}/languages/en');curl https://us1.platform.bird.com/v1/whatsapp/templates/bird_order_confirmation/versions/{version_id}/languages/en \
-H "Authorization: Bearer $BIRD_API_KEY"模板引用接受 slug 或 wat_ ID。GET …/versions/{version_id}/languages 列出版本的语言但不包含其内容。
{
"category": "utility",
"components": [
{
"example_parameters": [
{ "name": "ref", "text": "A1B2C3D4", "type": "text" },
{ "name": "amount", "text": "USD 49.99", "type": "text" }
],
"text": "Your order {{ref}} has been confirmed for a total of {{amount}}. Thanks for shopping with us.",
"type": "body"
}
],
"language": "en",
"status": "approved"
}发送的 components 必须与模板匹配。example_parameters 标识每个占位符。在此示例中,正文参数使用 name: "ref" 和 name: "amount"。位置型模板省略 name,按 {{n}} 顺序取值。参数化按钮有自己的 example_parameters。
语言 category 是 Meta 用于定价的类别。如果 Meta 重新分类该语言,它可能与模板的注册类别不同。
版本的 variables 列表汇总每个占位符的键、类型、必填标志和约束。命名占位符使用其名称作为键,位置占位符使用其编号。
使用模板发送
在发送的 template 对象中指定模板,并通过 components 填充变量;完整载荷请参阅发送 WhatsApp 消息:
const msg = await bird.whatsapp.send({
to: "+15551234567",
template: {
slug: "bird_otp",
components: [{ type: "body", parameters: [{ type: "text", text: "123456" }] }],
},
});
console.log(msg.id, msg.status);msg = client.whatsapp.send(
to="+31612345678",
template="bird_otp",
language="en",
components=[{"type": "body", "parameters": [{"type": "text", "text": "123456"}]}],
)
print(msg.id, msg.status)code := "123456"
msg, err := client.Whatsapp.Send(context.Background(), bird.WhatsappSendParams{
To: "+15551234567",
Template: "bird_otp",
Language: "en",
Components: []bird.WhatsAppMessageTemplateComponent{{
Type: "body",
Parameters: &[]bird.WhatsAppMessageTemplateComponentParameter{{Type: "text", Text: &code}},
}},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(msg.Id, *msg.Status)$message = $bird->whatsapp->send(
to: '+15551234567',
template: 'bird_otp',
language: 'en',
components: [
(new WhatsAppMessageTemplateComponent())
->setType('body')
->setParameters([
(new WhatsAppMessageTemplateComponentParameter())->setType('text')->setText('123456'),
]),
],
);
echo $message->getId(), ' ', $message->getStatus();bird whatsapp send \
--components '[{"parameters":[{"text":"1234","type":"text"}],"type":"body"},{"parameters":[{"text":"1234","type":"text"}],"type":"button"}]' \
--language en \
--template bird_otp \
--to +31612345678curl -X POST https://us1.platform.bird.com/v1/whatsapp/messages \
-H "Authorization: Bearer $BIRD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+14155550100",
"template": {
"slug": "bird_otp",
"language": "en",
"components": [
{ "type": "body", "parameters": [{ "type": "text", "text": "481920" }] },
{ "type": "button", "parameters": [{ "type": "text", "text": "481920" }] }
]
}
}'按类别发送
每个模板属于 Meta 的三个类别之一,类别影响发送成功前需要满足的条件以及费用。创建或复制自有的身份验证模板需要经过企业验证,但发送不需要:Bird 的托管 bird_otp 位于 Bird 自己的 WhatsApp Business Account 上,无需您的验证即可发送。营销模板始终从您自己的 WhatsApp Business Account 发送,通过 Bird 自动路由到的第二个 Meta API。实用模板在三者中所需前提条件最少。
后续步骤
- 发送 WhatsApp 消息:
template对象所嵌入的完整发送载荷 - WhatsApp 模板指南:Meta 审核模板时依据的规则
- 身份验证模板:一次性验证码以及创建时的企业验证门槛
- WhatsApp 定价:类别和目的地如何决定价格