发送 SMS
用一套 API 发送 你的每一条短信。
通过 Bird 发送事务性消息和通知。提供文本和发送方,或使用模板;在响应中查看编码和分段计数。添加幂等键以安全重试,并通过签名 webhook 跟踪投递状态。
一条消息,一个可见结果。
发送示例
了解接受状态与随后的运营商回执。此示例不会实际发送短信;送达并不代表收件人已阅读。
深受构建世界级软件团队的日常信赖
查看更多客户故事测试你的首个 SMS 集成。
用你已经在使用的语言。
发送是 Bird SMS API 的核心。以下示例展示了请求结构。若需受控测试,请将收件人替换为文档中的沙盒号码 +15005550006。先设置合适的美国发送方并启用目标号码,然后在向客户发送前验证接收和投递事件。
const msg = await bird.sms.send({
from: "+15557654321",
to: "+14155550100",
text: "Your verification code is 123456.",
category: "authentication",
});
console.log(msg.id, msg.status);SMS 发送会投递你提供的文本。若用于登录和账户验证,请使用 Bird Verify 在验证流程中生成、过期和校验验证码。
基于清晰的发送契约构建。
准备请求并跟踪结果。
- 01
发送前计算段数。
Bird 在响应中返回计算出的编码和分段计数。使用分段计算器在提交前检查草稿。
- 02
GSM-7 和 Unicode,替你决定。
字符决定编码。GSM-7 在单个分段中容纳 160 个单元;Unicode 容纳 70 个。多段消息会为重组预留空间,emoji 可能占用多个单元。
- 03
在一次调用中批量发送。
在一次批量请求中提交最多 100 条独立消息。验证在入队前完成;每条被接受的消息随后有各自的处理结果。
- 04
使用幂等键重试。
每个逻辑请求使用一个幂等键,并在相同的重试中复用它。已保留的 API 响应可被重放;这不保证运营商仅投递一次。
- 05
面向你的应用的投递事件。
订阅已接受、已发送和最终结果事件。验证签名,对 webhook 重试去重,并使用消息已读状态排查缺失或延迟的观测。
通过受控测试推进集成。
将你当前的请求字段、发送方注册和事件处理映射到 Bird。在迁移流量前核对退订列表,然后在更改生产路由前进行受控测试对比。
import twilio from "twilio";
const client = twilio(accountSid, authToken);
await client.messages.create({
from: "+14155550172",
to: "+15005550006",
body: "Your code is 123456.",
});import { BirdClient } from "@messagebird/sdk";
const bird = new BirdClient({ apiKey: process.env.BIRD_API_KEY! });
await bird.sms.send({
from: "+14155550172",
to: "+15005550006",
text: "Your code is 123456.",
category: "authentication",
});提交前了解分段计数。
GSM-7 在单个分段中容纳 160 个 septet;UCS-2 容纳 70 个码元。多段容量分别为 153 和 67。扩展 GSM-7 字符占用两个 septet,emoji 可能占用两个码元。Bird 在接受时返回编码和分段数;适用的费率和运营商费用单独计价。
const { data, error } = await bird.sms.send({
from: "Bird",
to: "+31612345678",
text: "Your code is 123456.",
category: "authentication",
}).safe();
if (error) throw error;
console.log(data.segments);
// → { characters: 20, count: 1, encoding: "GSM_7BIT" }
一条消息或一百条,一次调用。
批量提交最多 100 条独立消息,每条有各自的收件人和文本。无效输入会在入队前拒绝请求。成功返回 202 响应后,每条 SMS 的处理和投递可能分别成功或失败。在文档规定的保留窗口内重试时,复用相同的请求和幂等键。
const { data: batch, error } = await bird.sms
.sendBatch(
users.map((u) => ({
from: "Bird",
to: u.phone,
text: `Hi ${u.name}, your appointment is tomorrow at ${u.time}.`,
})),
{ idempotencyKey: `reminders-${runId}` },
)
.safe();
if (error) throw error;
console.log(`queued ${batch.data.length} messages`);从接受到最终结果全程跟踪。
成功的请求返回 202 Accepted。计费和运营商提交在之后发生,仍可能失败。消费签名的投递事件,并在排查结果时检查消息记录。
import { bird } from "@/lib/bird";
export async function POST(req: Request) {
const event = bird.webhooks.unwrap(
await req.text(),
Object.fromEntries(req.headers),
);
switch (event.type) {
case "sms.delivered":
await markDelivered(event.data.sms_id);
break;
case "sms.failed":
await flag(event.data.to, event.data.error?.description);
break;
}
return new Response(null, { status: 204 });
}按报告的原因检查失败。支持的 STOP 关键词和运营商退订会创建抑制记录;其他投递失败不会自动变为退订。
sms.accepted已被 API 接受并排队等待交付给运营商。sms.sent已提交给目的地运营商的 SMSC。sms.delivered已从运营商收到投递回执(DLR)。sms.failed此 SMS 尝试的最终失败。检查报告的错误和消息时间线。
付诸实践。
继续查阅此主题的文档、指南和示例。资源为英文。