SDK 概念
TypeScript、Go、Python 和 PHP SDK 遵循同一设计。每个 SDK 都有一个由 Bird 的 OpenAPI 规范生成的类型基础和底层客户端。手写层管理请求生命周期并暴露精选的接口表面。本页介绍它们的共享行为。各语言页面介绍各自的惯用细节。
自动幂等
每个变更操作(POST、PUT、PATCH、DELETE)都会自动生成一个 Idempotency-Key 请求头。该密钥在每次逻辑调用中只生成一次,并在所有重试尝试中复用。这可防止重试的写操作被重复应用。如果一次发送在服务器处理后超时,重试会收到已存储的响应。当逻辑操作跨越多次 SDK 调用时(例如应用层围绕 SDK 的重试循环),请传入自定义密钥(按调用的 idempotencyKey / option.WithIdempotencyKey / idempotency_key)。有关服务端协议,请参阅幂等性。
安全重试
重试默认开启(每个 SDK 中的 maxRetries: 2)。客户端会重试瞬态故障,包括网络错误、单次尝试超时、429 响应和可重试的 5xx 响应。它使用带抖动的指数退避,并遵循服务器的 Retry-After 请求头。确定性失败(401、404、422 及其他 4xx 响应)不会被重试。复用幂等密钥使变更操作的重试安全。超时适用于每次尝试(默认 60 秒),因此带重试的调用可能耗时更长。PHP 使用注入的 HTTP 客户端所强制的超时,因为 PSR-18 没有可移植的按请求超时。
分页
列表端点使用游标分页。每个 SDK 都支持原生迭代,自动获取后续页面。如需手动控制游标,请使用单页访问器。每页包含 data 和 next_cursor;将游标作为 starting_after 传回以前进到下一页。
for await (const message of bird.email.list({ status: "bounced" })) {
console.log(message.id);
}
const page = await bird.email.list({ limit: 50 }); // page.data, page.next_cursorfor message in client.email.list(status="delivered"):
print(message.id)
page = client.email.list(status="delivered") # page.data, page.next_cursor
print(len(page.data), page.next_cursor)for msg, err := range client.Email.List(context.Background(), bird.EmailListParams{Status: bird.EmailStatusBounced}) {
if err != nil {
log.Fatal(err)
}
fmt.Println(msg.Id)
}
page, err := client.Email.ListPage(context.Background(), bird.EmailListParams{}, "")
if err != nil {
log.Fatal(err)
}
fmt.Println(len(page.Data)) // page.NextCursor carries the next starting_after$page = $bird->email->list(['status' => 'delivered'])->fetch();
foreach ($page->data as $message) {
echo $message->getId(), "\n";
}
$next = $page->nextCursor; // pass back as starting_after to fetch the next page区域推断
Bird API 密钥编码了所属区域:bk_{region}_{token}。SDK 读取前缀并自动路由到 https://{region}.platform.bird.com。region 选项可覆盖推断的区域。显式的 baseUrl(option.WithBaseURL / base_url)优先于二者,并支持本地开发或自托管部署。当密钥不匹配 bk_{region}_ 格式且未设置覆盖时,构造会失败。
按调用选项与仅构造时配置
配置分为两层。身份和传输设置仅在构造时指定:API 密钥、基础 URL 或区域,以及 HTTP 客户端或 fetch 实现。生命周期设置可作为构造默认值,并按调用覆盖:timeout、maxRetries、幂等密钥和额外请求头。TypeScript、Python 和 PHP 使用尾部选项对象;Go 使用可变参数 option.With… 选项。SDK 拥有的请求头(Authorization、User-Agent、Idempotency-Key)优先于调用方提供的请求头。渠道默认值(例如默认的邮件 from)遵循相同模式。
Webhook 验证
每个 SDK 提供一个验证入口:webhooks.unwrap(rawBody, headers)。它实现了 Standard Webhooks,使用 HMAC-SHA256 对原始载荷和端点签名密钥进行签名。它接受 v1 标记的签名条目,拒绝超出 5 分钟容差窗口的时间戳,并以恒定时间比较签名。请传入接收到的原始请求体字节。解析并重新序列化 JSON 会改变字节内容,导致签名失效。
成功时,unwrap 返回一个根据 type 区分的类型化事件,例如 email.delivered 或 email.bounced。未知事件类型仍会通过验证和解码,因此请在 default 分支中处理它们。验证失败是一个独立的错误(BirdWebhookVerificationError / *WebhookVerificationError / WebhookVerificationError);请返回 400。有关端点设置和事件目录,请参阅 Webhooks。
后续步骤
- 快速入门:用您的语言和框架发送第一封邮件。
- Webhooks 和事件:设置端点并探索 unwrap 背后的事件目录。
- API 参考:查看每个 SDK 使用的 HTTP 契约。