关于 sent-integration-starter
sent-integration-starter 是面向开发者的 Sent 集成实施技能,涵盖凭据、幂等发送、Webhook 验证和运行保障,并按阶段提供实现与上线检查指导。
主要功能
- 01凭据与客户端生命周期指导
- 02幂等发送模式
- 03Webhook 签名验证指导
- 04重试与速率限制处理
- 05日志与上线检查清单
适用场景
- 01设计应用的 Sent API 身份验证
- 02避免超时重试造成重复发送
- 03构建经过验证的 Webhook 接收端
- 04准备 Sent 集成上线
MCP 相关
该技能说明 Sent MCP 服务使用客户端管理的 OAuth,并将其与 REST API 密钥身份验证区分开来。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ sentdm/ sent-plugin --skill sent-integration-starter安装后在 Claude Code 中输入/sent-integration-starter确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlreferences/errors-and-limits.mdsdk-and-frameworks.mdscripts/preflight.py详细介绍
Sent 集成入门
分四个阶段接入 Sent 集成:身份验证、幂等发送、接收已验证事件,然后加固。不要混为一谈——大多数有问题的集成都通过了第一阶段,却跳过了第三阶段。
阶段 1:客户端和凭据
直接发送 Sent v3 REST 请求时,使用 x-api-key 标头进行身份验证。应用代理可能会接受来自其调用方的 Authorization: Bearer,Sent MCP 服务则使用由客户端管理的 OAuth,但这两者都不会改变发送到 api.sent.dm 的 REST 标头。组织密钥可以通过添加 x-profile-id 代表子档案执行操作;使用该标头的档案级密钥会收到 403。
| 语言 | 包 | 客户端 |
|---|---|---|
| TypeScript | @sentdm/sentdm | new SentDm({ apiKey }) |
| Python | sentdm(导入 sent_dm) | Sent(api_key=api_key) 或 AsyncSent(api_key=api_key) |
| Go | github.com/sentdm/sent-dm-go | sentdm.NewClient(option.WithAPIKey(apiKey)) |
| Java | dm.sent:sent-java | SentOkHttpClient.builder().apiKey(apiKey).build() |
| C# | Sentdm | new SentClient { ApiKey = apiKey } |
| PHP | sentdm/sent-dm-php | new SentDm\Client($apiKey) |
| Ruby | sentdm | Sentdm::Client.new(api_key: api_key) |
生成应用代码时,要求由应用所有者提供明确且非空的 API 密钥,并通过 SDK 的凭据选项传入。将为每个 webhook id 解析出的签名密钥注入接收器辅助函数。切勿检查插件安装程序的环境、凭据存储或 MCP 令牌;插件本身通过由客户端管理的 OAuth 进行身份验证。多租户生产接收器需要一个以 webhook id 为键的密钥注册表。
根据凭据模型选择客户端生命周期。使用单个服务器管理密钥的单账户服务应复用长期运行的客户端及其连接池。对于每个请求都要解析调用方或档案凭据的多租户代理,应为该请求创建客户端并在用后丢弃,以免租户凭据通过共享状态泄漏。特定框架的接线方式、Ruby 中 messages.send_ 的命名特殊情况,以及各生态系统的后台任务方案,见 references/sdk-and-frameworks.md。
在启动时验证配置;如果密钥缺失,应立即失败,而不是等到首次向客户发送消息时才暴露身份验证错误。
阶段 2:幂等发送
{
"to": ["+14155551234"],
"template": {
"name": "order_confirmation",
"parameters": { "order_id": "12345" }
},
"sandbox": true
}
to 是唯一必填字段。提供 template 或 text,并省略 channel,以便自动路由选择。切勿设置包含多个值的 channel 数组并期待系统回退——这会广播消息并增加多笔费用。渠道选择应交由 sent-routing-strategist 处理。
每次 POST、PUT 和 PATCH 请求都要发送 Idempotency-Key,并根据你自己的领域对象确定性地生成该值(例如订单 id 加通知类型),这样超时后重试就不会重复发送。密钥长度为 1–255 个字符,且只能包含 [A-Za-z0-9_-];每个客户的每个密钥会缓存 24 小时。重放请求会返回缓存的响应正文,并带有 Idempotent-Replayed: true 和 X-Original-Request-Id。如果原始请求仍在处理中时收到重复请求,系统会等待最多五秒,然后返回错误 409 CONFLICT_001;503 SERVICE_001 表示幂等性存储不可用,且请求已被有意跳过执行。
202 表示请求已接受,而非已送达。立即将返回的 message_id 值与自己的租户、档案和逻辑发送标识符一并持久化。Webhook 事件会携带 Sent 消息 id 和账户数据,但不会携带应用的租户标识符。
阶段 3:经过验证的 Webhook 接收器
没有接收器的集成无法确认消息是否送达。注册一个端点,然后验证每次投递:对 {x-webhook-id}.{x-webhook-timestamp}.{raw_body} 计算 HMAC-SHA256,以去除 whsec_ 前缀后经 Base64 解码的密钥作为密钥,并以恒定时间进行比较;拒绝时间戳超出 300 秒范围的请求。没有任何语言的 SDK 内置验证器。
先用 200 确认收到,再执行后续工作;对出站事件按 {message_id}:{message_status} 去重,对入站事件按 message_id 去重。连续 10 次投递失败会停用端点。具体机制请参阅 sent-webhook-engineer;此处应将经过验证、快速确认且支持去重的接收器视为上线要求。
阶段 4:强化
按响应类别制定重试策略
| 响应 | 重试 | 方式 |
|---|---|---|
2xx | 否 | 成功 |
400、422 VALIDATION_* | 否 | 修正请求 |
401、403 AUTH_* | 否 | 立即停止;连续 10 次认证失败会锁定凭据,且锁定时间逐次延长 |
404 RESOURCE_* | 否 | 引用的对象不存在 |
409 CONFLICT_001 | 是,暂停后重试一次 | 并发的重复请求正在处理中 |
429 | 是 | 遵循 Retry-After;使用带抖动的退避策略 |
5xx、503 SERVICE_001 | 是 | 使用带抖动和上限的指数退避 |
| 超时且未收到响应 | 仅在有依据时安全重试 | 重用相同的 Idempotency-Key;没有该键时,无法通过键或收件人可靠地查询 API,因此不要自动重新发送 |
标准限制为滑动窗口内每分钟 200 个请求。POST /v3/webhooks/{id}/rotate-secret 和 POST /v3/webhooks/{id}/test 的限制为每分钟 10 个请求。速率限制标头仅出现在 429 响应中,因此必须预先设计请求节奏,而不能依靠测量来调整——每个请求最多批量处理 1,000 位收件人,批量操作时将请求频率控制在每秒约 1 次。
错误处理
错误以 {success, data, error: {code, message, details, doc_url}, meta: {request_id, timestamp, version}} 的形式返回。根据 error.code 的前缀类别(AUTH_、VALIDATION_、RESOURCE_、BUSINESS_、CONFLICT_、SERVICE_、INTERNAL_)进行分支处理,而不要依赖错误消息文本或单个错误代码。包含重试分类的完整 46 个错误代码目录见 references/errors-and-limits.md。
有两个代码的含义不太直观:文档将 BUSINESS_003 和 BUSINESS_004 定义为请求级错误,但对于 POST /v3/messages,请求会以 202 被接受,受影响的消息最终状态为 BLOCKED 和 FILTERED。因此,余额不足不会导致发送调用失败。
可观测性
记录每个响应(无论成功还是失败)中的 meta.request_id——它是联系支持团队时用于关联请求的标识。记录逻辑发送与返回的 message_id 值之间的映射,并保留仅追加的事件历史,以便审计重新路由时的事件顺序。切勿记录 API 密钥、Webhook 签名密钥、payment_details,也不要记录超出保留策略允许范围的原始收件人消息内容。
上线检查清单
- 凭据由应用自有配置显式提供;不提交任何凭据,并且每个环境使用独立密钥。
- 客户端生命周期与凭据作用域匹配:使用一个由服务端管理的密钥时共享客户端,使用租户提供的凭据时按请求创建客户端。
- 每次变更调用都携带
Idempotency-Key,并以确定性方式生成。 - 重试策略根据错误类别区分可重试错误与终止错误。
- 批量操作路径将请求速率控制在每分钟 200 次,并将每批收件人数量限制为最多 1,000 人。
- Webhook 接收器验证签名和时间戳,快速返回
200,并进行去重。 - 发生真实故障时,接收器返回非 2xx 响应,以便 Sent 重试。
- 发送前持久化
message_id与租户的映射关系。 - 记录
request_id;不记录密钥和卡片数据。 - Sandbox 冒烟测试通过,然后实际发送的状态达到
DELIVERED。 - 告警覆盖 Webhook
consecutive_failures、429数量,以及过滤或拦截率。
验证
运行本地预检,无需凭据或网络:
python3 scripts/preflight.py --self-test
然后使用 "sandbox": true 验证真实调用路径,此操作会进行身份验证和校验,但不会执行发送;最后执行一次实际发送,并通过接收器确认状态达到 DELIVERED。
适用范围
需要深入了解接收器时使用 sent-webhook-engineer,选择通道时使用 sent-routing-strategist,确认一次性发送时使用 sent-messaging,处理入站消息和用户同意时使用 sent-two-way-messaging,进行多租户配置时使用 sent-profile-provisioning,替换其他 CPaaS 提供商时使用 migrate-to-sent。