在 Corsair 中使用 Twilio 插件:短信、语音呼叫与 Webhook 的完整接入指南

📅 发布时间:2026/9/16 11:21:21
在 Corsair 中使用 Twilio 插件:短信、语音呼叫与 Webhook 的完整接入指南
在 Corsair 中使用 Twilio 插件短信、语音呼叫与 Webhook 的完整接入指南【免费下载链接】corsairConnect your users to their apps项目地址: https://gitcode.com/GitHub_Trending/corsa/corsaircorsair-dev/twilio是 Corsair 生态中的官方 Twilio 通信插件它以一套类型安全的客户端 API 把 Twilio 的 SMS/MMS 消息与语音呼叫能力封装进你的 Agent 应用同时提供本地数据库同步与三类入站 Webhook。读完本文你将掌握如何安装并注册该插件、如何为多租户配置 API Key 认证、如何调用全部 6 个twilio.api.*端点、如何利用本地同步数据做离线检索以及如何用webhookHooks处理短信与呼叫状态事件。插件概览Corsair 如何承载 TwilioCorsair 是一个把用户连接到他们的应用的集成框架见仓库根目录 README.md其核心思路是以一个统一的客户端、一套类型安全的调用、本地数据库同步和入站 Webhook来承载第三方 SaaS 能力。Twilio 插件正是这一模式的标准范例位于 packages/twilio文档说明位于 docs/plugins/twilio/overview.mdx。接入后你立即获得三样东西6 个类型化的 API 操作消息send/get/list与呼叫create/get/list2 个本地同步实体calls、messages支持不经过 Twilio 的快速.search()/.list()3 类入站 Webhook 事件短信接收、消息状态回执、呼叫状态回执。插件的运行时形态在 packages/twilio/index.ts 中由twilio()工厂函数构造它声明了插件id: twilio、端点树、Webhook 树、认证配置twilioAuthConfig、错误处理器与 KeyBuilder 逻辑并导出完整类型供 TS 编译器校验。安装与注册安装依赖按 packages/twilio/README.md 的说明使用 pnpm 安装pnpm add corsair-dev/twilio该包同时把corsair0.1.0与zod^4.1.13声明为 peerDependencies见 packages/twilio/package.json因此请确保你的项目已安装 Corsair 核心包例如npm install corsair corsair-dev/twilio。文档站点docs/plugins/twilio/overview.mdx还给出了 yarn、bun 的等价安装方式。创建 Corsair 实例并注册插件在corsair.ts中创建客户端并传入插件import Database from better-sqlite3; import { createCorsair } from corsair; import { twilio } from corsair-dev/twilio; export const corsair createCorsair({ plugins: [ twilio(), ], database: new Database(corsair.db), kek: process.env.CORSAIR_KEK!, hub: { projectApiKey: process.env.CORSAIR_API_KEY!, signingSecret: process.env.CORSAIR_SIGNING_SECRET!, }, });要点说明databaseCorsair 需要一块数据库示例用better-sqlite3来存放插件同步的实体与密钥kekKey Encryption Key用于加密租户凭据首次使用前需要配置详见 docs/getting-started/set-up-with-your-agent.mdx 与 docs/quick-start.mdxhub提供 projectApiKey 与 signingSecret用于托管 Connect 页面和凭据的加密传递见 docs/concepts/api-key.mdx 与 docs/management/connect.mdx多租户是默认行为任何租户作用域调用都通过corsair.withTenant(id)发起账户间数据隔离的细节见 docs/concepts/multi-tenancy.mdx。认证API Key 与凭据管理Twilio 插件采用API Key 认证。twilioAuthConfigpackages/twilio/index.ts定义了需要用户提供accountSid这一项凭据而实际请求时还需要 Auth Token。凭据来源与 KeyBuilder 优先级插件的 KeyBuilderpackages/twilio/index.ts按以下优先级解析密钥Webhook 来源优先使用options.webhookSecret→options.key→ 密钥库中的 webhook signature → API KeyEndpoint 来源优先使用options.key→ 密钥库中的 API Key。因此你可以在创建插件时静态传入全局凭据适合单一账户场景也可以完全不传让 Corsair 在租户首次发起请求时提示租户填写凭据——这是推荐的多租户做法。你不需要预先做任何配置// 无需配置首次请求时 Corsair 会提示租户输入 API Key twilio()从端点实现可以看到凭据的实际组合方式以 packages/twilio/endpoints/calls.ts 为例accountSid依次从ctx.options.accountSid、密钥库的accountSid、以及ctx.key.split(:)[0]解析Auth Token 则取ctx.key中冒号后的部分支持accountSid:authToken复合格式。随后 packages/twilio/client.ts 用Buffer.from(${accountSid}:${authToken}).toString(base64)构造 HTTP Basic 认证头并向https://api.twilio.com/2010-04-01发起请求。连接租户多租户场景下为租户签发 Connect 链接并引导其浏览器访问Hub 托管页面并在完成凭据填写后把结果送回你的应用const { connectUrl } await corsair.manage.connect.createLink({ plugin: twilio, tenantId: acme, }); // 将用户浏览器重定向到 connectUrl完整的 Connect / OAuth 流程见 docs/management/connect.mdx。端点全景6 个类型化 API 操作端点树定义于 packages/twilio/index.ts输入/输出 Schema 在 packages/twilio/endpoints/types.ts 中用 Zod 声明元信息风险等级与描述在twilioEndpointMetapackages/twilio/index.ts中。下表是插件 README 与源码共同确认的完整清单OperationOperation IDRiskDescriptioncalls.createtwilio.api.calls.createwriteInitiate an outbound phone callcalls.gettwilio.api.calls.getreadRetrieve a call record by SIDcalls.listtwilio.api.calls.listreadList call records with optional filtersmessages.gettwilio.api.messages.getreadRetrieve a message by SIDmessages.listtwilio.api.messages.listreadList messages with optional filtersmessages.sendtwilio.api.messages.sendwriteSend an SMS or MMS message调用方式统一为corsair.withTenant(id).twilio.api.资源.操作(input)所有输入与输出均有严格类型。消息端点发送短信/彩信messages.send输入字段packages/twilio/endpoints/types.ts字段类型必填说明Tostring是收件人号码E.164 格式Fromstring是发件人号码或 Messaging Service 中的号码Bodystring否消息正文MediaUrlstring[]否MMS 媒体附件 URL 数组StatusCallbackstring否投递状态回调 URLMessagingServiceSidstring否Messaging Service SID获取消息messages.get入参messageSid: stringpackages/twilio/endpoints/types.ts返回完整消息对象sid、status、direction、body、price、price_unit等。列出消息messages.list入参支持可选过滤packages/twilio/endpoints/types.tsTo、From、DateSent、PageSize响应为{ messages: [...] }分页结构。呼叫端点发起外呼calls.createpackages/twilio/endpoints/types.ts字段类型必填说明Tostring是被叫号码Fromstring是主叫号码Urlstring否TwiML 指令 URL与Twiml二选一Twimlstring否内联 TwiML 指令StatusCallbackstring否状态回调 URLStatusCallbackMethodGET \| POST否回调方法StatusCallbackEventstring[]否需要回调的状态事件Timeoutnumber否接通超时秒Recordboolean否是否录音获取呼叫calls.get入参callSid: string列出呼叫calls.list可选过滤To、From、Status、StartTime、EndTime、PageSizepackages/twilio/endpoints/types.ts。调用示例来自 docs/plugins/twilio/overview.mdx 的实战片段// 以 acme 租户身份列出消息 const tenant corsair.withTenant(acme); await tenant.twilio.api.messages.list({}); // 发送一条短信 await tenant.twilio.api.messages.send({ To: 15555550100, From: 15555550101, Body: Hello from Corsair, });plugin-docs.yamlpackages/twilio/plugin-docs.yaml为插件文档站提供了示例参数与默认示例如写操作使用messages.send、参数To: 15555550100、Body: Hello from Corsair说明这些都是可直接运行的示例形态。底层调用链统一 HTTP 客户端所有端点共用makeTwilioRequestpackages/twilio/client.ts请求路径为Accounts/${accountSid}/${Resource}.json如Accounts/ACxxx/Messages.jsonPOST/PUT 使用application/x-www-form-urlencoded编码Twilio 的标准格式GET 查询参数透传网络错误统一包装为TwilioAPIError并保留ApiError的透传。错误处理与重试策略packages/twilio/error-handlers.ts 内置了四类错误处理规则并可在twilio({ errorHandlers })中覆盖合并RATE_LIMIT_ERROR匹配 HTTP 429 或含rate/429/too many requests的报错重试最多 5 次优先采用服务端Retry-After头AUTH_ERROR匹配 401 或认证类错误不重试BAD_REQUEST_ERROR匹配 400 或is not a valid phone number/invalid类错误不重试DEFAULT兜底不重试。本地数据库同步离线检索同步数据每个端点在被调用后除了返回 Twilio 响应还会把结果写入本地数据库通过upsertByEntityId以sid为主键。例如messages.sendpackages/twilio/endpoints/messages.ts与calls.listpackages/twilio/endpoints/calls.ts都会在成功后落库并在失败时仅打印告警而不中断主流程。同步实体 Schema 定义于 packages/twilio/schema/database.tsmessagessid、to、from、body、status、direction、date_sent、price、price_unit与callssid、to、from、status、direction、duration、start_time、end_time、price、price_unit并由 packages/twilio/schema/index.ts 聚合成version: 1.0.0的插件 Schema。这意味着你可以不访问 Twilio 就能检索历史数据const tenant corsair.withTenant(acme); const rows await tenant.twilio.db.messages.search({ data: {}, limit: 50, });同步实体calls、messages。更丰富的过滤器与操作符可参考 docs/plugins/twilio/api.mdx 与数据库相关文档docs/plugins/twilio/database.mdx。plugin-docs.yaml也确认了这一用法dbExample描述为Search synced messages without hitting Twiliolimit 为 50。Webhook三类入站事件与签名校验插件共处理 3 个 Webhook 事件事件树与 Schema 定义在 packages/twilio/index.ts事件匹配与验签逻辑在 packages/twilio/webhooks。事件映射如下事件路径触发场景匹配依据message.received收到入站短信/彩信存在MessageSid且存在Body且无MessageStatusmessage.statusUpdate消息投递状态变化存在MessageSid与MessageStatuscall.statusUpdate呼叫状态变化存在CallSid与CallStatus每个事件的匹配器由createTwilioMatchpackages/twilio/webhooks/types.ts生成可同时解析 JSON 与x-www-form-urlencoded两种载荷。事件的具体处理器实现见 packages/twilio/webhooks/messages.ts 与 packages/twilio/webhooks/calls.ts。Webhook 路由与 HTTP 处理器Corsair 用pluginWebhookMatcher校验x-twilio-signature请求头是否存在与pluginTenantWebhookMatcher定位插件与租户。租户匹配器matchTwilioTenantWebhookpackages/twilio/webhooks/tenant-matcher.ts从 Webhook 载荷的AccountSid字段解析出linkType: accountSid的外部 ID——这意味着同一个 Twilio 账号下不同租户的 Webhook 可以被自动路由到正确的租户基于 Multi-tenancy 文档 docs/concepts/multi-tenancy.mdx 的账户隔离模型。在你的框架中只需挂载一次 HTTP 处理器以 Next.js App Router 为例来自 docs/plugins/twilio/webhooks.mdx// app/api/webhook/route.ts import { processWebhook } from corsair; import { corsair } from /server/corsair; export async function POST(request: Request) { const headers Object.fromEntries(request.headers); const body await request.json(); const result await processWebhook(corsair, headers, body); return result.response; }然后把 Twilio 侧的回调 URL 指向该地址即可。其他框架的挂载方式见 docs/frameworks。签名校验HMAC-SHA1 与时序安全比较每个 Webhook handler 都会先调用verifyTwilioWebhookSignaturepackages/twilio/webhooks/types.ts做验签失败则返回401Twilio 的签名算法取完整 Webhook URL → 对 POST 参数按键名字母序排序→ 将keyvalue依次拼接到 URL 之后 → 以Auth Token 作为密钥计算HMAC-SHA1→ Base64 编码比较环节使用timingSafeEqual进行时序安全比较防止时序侧信道攻击缺签名头或缺 Auth Token 都会返回明确的错误信息。需要说明的是Twilio Webhook 载荷以x-www-form-urlencoded全部为字符串值到达处理器在验签时将其转换为Recordstring, string再参与签名计算见 packages/twilio/webhooks/messages.ts。三个事件的载荷与响应以下载荷定义直接取自 Zod Schemapackages/twilio/webhooks/types.ts与 docs/plugins/twilio/webhooks.mdx。call.statusUpdate呼叫状态变化ringing、in-progress、completed 等。NameTypeRequiredCallSidstringYesAccountSidstringYesFromstringYesTostringYesCallStatusqueued \| ringing \| in-progress \| completed \| busy \| no-answer \| canceled \| failedYesDirectionstringNoDuration/CallDurationstringNoApiVersion/Timestamp/SequenceNumberstringNomessage.received收到入站短信/彩信。NameTypeRequiredMessageSidstringYesSmsSid/MessagingServiceSidstringNoAccountSidstringYesFrom/TostringYesBodystringYesNumMediastringYesNumSegments/SmsStatus/ApiVersionstringNoFromCity/FromState/FromCountry/FromZipstringNoToCity/ToState/ToCountry/ToZipstringNomessage.statusUpdate消息投递状态变化sent、delivered、failed 等。NameTypeRequiredMessageSid/AccountSid/From/TostringYesMessageStatusaccepted \| queued \| sending \| sent \| delivered \| undelivered \| failed \| receiving \| received \| readYesErrorCode/ErrorMessage/ApiVersionstringNo用 webhookHooks 订阅事件在插件选项中配置webhookHooks即可在每个事件处理的前后注入逻辑。例如收到入站短信时打印消息来自 docs/plugins/twilio/overview.mdxtwilio({ webhookHooks: { message: { received: { after: async (ctx, result) { console.log(Twilio message:, result.data); } }, }, }, })before/after钩子的完整能力如修改参数、改写响应可参考 docs/concepts/hooks.mdx 与 docs/concepts/webhooks.mdx。验证与测试集成测试如何覆盖全链路仓库自带集成测试 packages/twilio/integration.test.ts它通过 mockcorsair/http的request函数完整覆盖了本文描述的端到端链路messages.send发送短信并校验sid随后从数据库中findByEntityId查到已同步的记录状态为queuedmessages.get/messages.list读取与分页calls.create创建呼叫并校验数据库同步calls.get/calls.list查询呼叫手工构造createHmac(sha1, authToken)签名模拟 Twilio 发送message.receivedWebhook验证签名校验通过且 handler 返回success: true。这段测试是理解插件行为的极佳参考它证实了端点调用 → 本地落库 → Webhook 验签处理这条完整调用链。此外 packages/twilio/webhooks/types.test.ts 与 packages/twilio/error-handlers.test.ts 分别覆盖了事件 Schema 与错误处理规则的单元测试。在 Agent 与 MCP 中暴露 Twilio 能力插件安装后其全部twilio.api.*操作与 Webhook 也可以作为 MCP 工具暴露给 Agent 使用。相关接入方式见 docs/mcp-adapters/mcp-adapters.mdx如果你使用 LangChain、LlamaIndex 或 MastraCorsair 还提供了对应的适配器adapters/langchain、adapters/llamaindex、adapters/mastra。小结corsair-dev/twilio用约 300 行核心源码packages/twilio为 Corsair 应用交付了完整的 Twilio 集成能力6 个类型安全端点、2 个本地同步实体、3 类带 HMAC 验签的入站 Webhook以及可配置的重试错误处理。无论你的场景是 Agent 代发短信、语音外呼还是根据投递回执驱动业务流程都可以按本文步骤在几分钟内完成接入。【免费下载链接】corsairConnect your users to their apps项目地址: https://gitcode.com/GitHub_Trending/corsa/corsair创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考