OpenClaw SMS/MMS 频道接入指南:基于 Twilio 的短信收发、Webhook 安全与多账户配置

OpenClaw SMS/MMS 频道接入指南:基于 Twilio 的短信收发、Webhook 安全与多账户配置 OpenClaw SMS/MMS 频道接入指南基于 Twilio 的短信收发、Webhook 安全与多账户配置【免费下载链接】openclawThe AI that really does things. Any OS. Any Platform. The lobster way. 项目地址: https://gitcode.com/GitHub_Trending/cl/openclawOpenClaw 通过官方 SMS 频道插件接入 Twilio将任意具备短信/彩信能力的 Twilio 号码或 Messaging Service 变成 AI Agent 的收发通道Gateway 注册/webhooks/sms入站路由、默认校验 Twilio 请求签名、经 Twilio Messages API 回复并记录出站投递回调。读完本文你将掌握从安装插件、配置channels.sms、选择发送策略到验证签名、排查11200/30034等典型故障的完整实战闭环。频道定位与能力边界SMS 频道是官方插件需要单独安装openclaw plugins install openclaw/sms并非 Gateway 内置。从 extensions/sms/src/channel.ts 声明的能力清单看它只支持direct点对点私聊会话支持短信文本与 MMS 附件media: true不支持群聊线程、表情回应、消息编辑/撤回、回复引用等threads/reactions/edit/unsend/reply均为false频道元数据selectionLabel为 SMS (Twilio)文档路径docsPath: /channels/sms对应 docs/channels/sms.md。在 extensions/sms/openclaw.plugin.json 中可以看到插件id为sms归类于channels且activation.onStartup为false——即插件按需激活配置了channels.sms后才会启动。一条 Twilio 号码可同时承载短信与语音如果号码同时具备 SMS 与 Voice 能力可与 Voice Call 插件 共用但两者的 webhook 在 Twilio 控制台分别配置、在 Gateway 使用独立路径本文只覆盖 SMS webhook。前置准备开始配置前你需要准备官方 SMS 插件openclaw plugins install openclaw/sms。Twilio 账号一个具备 SMS 能力的电话号码或一个 Twilio Messaging Service。发送 MMS 还需要 MMS 能力的号码原生 MMS 投递还取决于目的地国家和运营商。Twilio Account SID 与 Auth Token。一个能到达 OpenClaw Gateway 的公网 HTTPS URL。发送方策略选择pairing默认适合私人使用、allowlist预批准号码或open仅用于有意公开的短信访问。US A2P / 10DLC 投递合规美国本地号码必读如果从美国本地 10DLC 号码向美国用户发送应用类 SMS/MMS需要完成US A2P 10DLC 注册。免费电话号码与短码走各自的验证流程。这与 OpenClaw 频道配置相互独立——即使 webhook 签名校验、配对、出站凭据全部正确运营商仍可能拦截或过滤投递。在依赖美国 10DLC 发送方之前请在 Twilio 确认账号为付费账号Twilio 试用账号无法注册 A2P 10DLCTrust Hub 中已批准 Primary 或 Secondary Compliance ProfileBrand 与 Campaign 已注册并获批Twilio 号码的 A2P 状态为REGISTERED且位于与获批 Campaign 关联的 Messaging Service 的 Sender Pool 中或者你配置的messagingServiceSid就是那个获批服务Campaign 描述了真实的 OpenClaw 消息使用场景并附上匹配的示例消息每个网站、关键词、线下、纸质或二维码 opt-in 路径都被完整描述若流程非公开可见需提供可公开访问的截图或其他证据消息同意是自愿的且与必需的服务条款、账号创建或购买分离并包含 Twilio 要求的隐私政策、条款、频率、资费与 opt-out 披露你保留同意证据、能标识发送方、遵守标准一步 opt-out 关键词且不购买、出租、出售或转让同意。用户 opt-out 后除非其再次 opt-in否则只能发送一条确认消息。以 Twilio 官方要求为准本文为配置指引而非法律意见。若注册审核被拒请先在 Twilio 修正再用于 OpenClaw常见错误码含义30909消息流程或行动号召不完整或无法验证30923消息同意被设定为服务、账号创建或购买的条件或与服务条款捆绑30893示例消息与声明的使用场景不匹配。快速安装与配置第 1 步安装插件openclaw plugins install openclaw/sms第 2 步创建或选择 Twilio 发送方在 Twilio 中打开Phone Numbers Manage Active numbers选择具备 SMS 能力的号码要发附件则选择同时具备 MMS 能力的号码。保存Account SID例如ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxAuth Token发送方号码例如15551234567如果使用 Messaging Service 而非固定发送号码保存 Messaging Service SID例如MGxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx。第 3 步配置 SMS 频道保存为sms.patch.json5并替换占位符{ channels: { sms: { enabled: true, accountSid: ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, authToken: twilio-auth-token, fromNumber: 15551234567, publicWebhookUrl: https://gateway.example.com/webhooks/sms, dmPolicy: pairing, }, }, }应用配置先 dry-run 预览再正式应用openclaw config patch --file ./sms.patch.json5 --dry-run openclaw config patch --file ./sms.patch.json5第 4 步在 Twilio 侧指向 Gateway webhook在 Twilio 号码设置的Messaging中将A message comes in设为https://gateway.example.com/webhooks/sms使用 HTTPPOST。默认本地路径为/webhooks/sms如需不同路由可改channels.sms.webhookPath。第 5 步暴露精确的 SMS webhook 路径公网 URL 必须将 SMS 路径路由到 Gateway 进程默认端口18789。同一路径同时服务入站 Twilio webhook 与 OpenClaw 发送 MMS 时的短期令牌化附件。若用 Tailscale Funnel 做本地测试需显式暴露/webhooks/smstailscale funnel --bg --set-path /webhooks/sms http://127.0.0.1:gateway-port/webhooks/sms tailscale funnel status语音与短信使用不同 webhook 路径。若同一号码同时处理两者Twilio 与隧道中都要保留两条路由。第 6 步启动 Gateway 并批准首个发送方openclaw gateway向 Twilio 号码发送一条短信首条消息会创建配对请求然后批准openclaw pairing list sms openclaw pairing approve sms CODE配对码 1 小时后过期。配对行为由 extensions/sms/src/channel.ts 中的pairing配置驱动idLabel为phoneNumber批准后向该号码发送 OpenClaw: your SMS access has been approved. 的通知消息。配置参考所有键位于channels.sms下多账户时位于channels.sms.accounts.id下KeyDefaultPurposeenabledtrue启用或禁用频道/账户。accountSid—Twilio Account SIDAC...。authToken—Twilio Auth Token明文或 SecretRef。fromNumber—E.164 发送方号码。messagingServiceSid—Messaging Service SIDMG...当无fromNumber解析时使用。defaultTo—发送流程未给出显式目标时的默认目的地。webhookPath/webhooks/smsGateway 接收 Twilio 入站 webhook 的 HTTP 路径。publicWebhookUrl—公开 Twilio webhook URL签名校验与出站 MMS 托管必需。dangerouslyDisableSignatureValidationfalse跳过X-Twilio-Signature校验仅限本地隧道测试。dmPolicypairingpairing、allowlist、open或disabled。allowFrom[]允许的发送方 E.164 号码dmPolicy: open时可设为*。textChunkLimit1500每条出站 SMS 分块的最大字符数。accounts、defaultAccount—多账户映射与默认账户 id。这些键在 extensions/sms/src/config-schema.ts 中有完整的 Zod schema 定义dmPolicy默认pairingtextChunkLimit要求正整数mediaMaxMb要求正数schema 还通过requireChannelOpenAllowFrom校验open策略必须配合allowFrom含*。dmPolicy的合法取值集合与 channel.ts 中 setup contract 的choices一致pairing/allowlist/open/disabled。配置文件方式让频道定义随 Gateway 配置一起分发{ channels: { sms: { enabled: true, accountSid: ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, authToken: twilio-auth-token, fromNumber: 15551234567, publicWebhookUrl: https://gateway.example.com/webhooks/sms, dmPolicy: pairing, }, }, }环境变量方式环境变量只作用于默认账户配置值优先于环境变量值。VariableMaps toTWILIO_ACCOUNT_SIDaccountSidTWILIO_AUTH_TOKENauthTokenTWILIO_PHONE_NUMBER(别名TWILIO_SMS_FROM)fromNumberTWILIO_MESSAGING_SERVICE_SIDmessagingServiceSidSMS_PUBLIC_WEBHOOK_URLpublicWebhookUrlSMS_WEBHOOK_PATHwebhookPathSMS_ALLOWED_USERSallowFrom逗号分隔SMS_TEXT_CHUNK_LIMITtextChunkLimitSMS_DANGEROUSLY_DISABLE_SIGNATURE_VALIDATIONdangerouslyDisableSignatureValidationtrueexport TWILIO_ACCOUNT_SIDACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx export TWILIO_AUTH_TOKENtwilio-auth-token export TWILIO_PHONE_NUMBER15551234567 export SMS_PUBLIC_WEBHOOK_URLhttps://gateway.example.com/webhooks/sms然后在配置中启用频道{ channels: { sms: { enabled: true, dmPolicy: pairing, }, }, }SecretRef 认证令牌authToken可以是 SecretRefsource: env | file | exec | store。当希望 Gateway 从 OpenClaw secrets 运行时解析 Twilio Auth Token、而不是在配置中存明文时使用{ channels: { sms: { enabled: true, accountSid: ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, authToken: { source: env, provider: default, id: TWILIO_AUTH_TOKEN }, fromNumber: 15551234567, publicWebhookUrl: https://gateway.example.com/webhooks/sms, dmPolicy: pairing, }, }, }被引用的环境变量或 secret provider 必须对 Gateway 运行时可见。修改宿主机环境变量后需重启受管 Gateway 进程。Messaging Service 发送方用messagingServiceSid代替fromNumber让 Twilio 通过 Messaging Service 选择发送方{ channels: { sms: { enabled: true, accountSid: ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, authToken: twilio-auth-token, messagingServiceSid: MGxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, publicWebhookUrl: https://gateway.example.com/webhooks/sms, dmPolicy: pairing, }, }, }若配置与环境变量解析后fromNumber与messagingServiceSid同时存在优先使用fromNumber。默认出站目标自动化或 Agent 发起的投递若发送流程省略显式目标可设置defaultTo{ channels: { sms: { enabled: true, accountSid: ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, authToken: twilio-auth-token, fromNumber: 15551234567, defaultTo: 15557654321, publicWebhookUrl: https://gateway.example.com/webhooks/sms, }, }, }CLI 要求显式--targetdefaultTo服务于自动化与 Agent 发起、可从频道配置解析目标的投递路径。访问控制dmPolicy 与 allowFromchannels.sms.dmPolicy控制短信直连访问pairing默认未知发送方获得配对码用openclaw pairing approve sms CODE批准allowlist只处理allowFrom中的发送方。空allowFrom会拒绝所有发送方Gateway 记录启动警告open配置校验要求allowFrom包含*。没有通配符时只有列出的号码能聊天disabled丢弃所有入站私聊。allowFrom条目应为 E.164 号码如15551234567。sms:与twilio-sms:前缀会被接受并规范化——这一行为在 extensions/sms/src/phone.ts 的normalizeSmsPhoneNumber中实现剥离前缀、自动补、过滤非数字字符looksLikeSmsPhoneNumber用/^\[1-9]\d{6,14}$/校验 E.164 形态。normalizeSmsAllowFrom则对allowFrom条目做同样的规范化通配符*除外。对私人助手推荐dmPolicy: allowlist搭配显式号码{ channels: { sms: { enabled: true, accountSid: ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, authToken: twilio-auth-token, fromNumber: 15551234567, publicWebhookUrl: https://gateway.example.com/webhooks/sms, dmPolicy: allowlist, allowFrom: [15557654321], }, }, }从源码看channel.ts 会对dmPolicy: open且allowFrom含*的配置产生critical级别的安全告警allows any phone number to message the bot并在禁用签名校验时输出 Only use this for local testing 警告。发送 SMS选中 SMS 频道后目标接受裸 E.164 号码或sms:前缀openclaw message send --channel sms --target sms:15551234567 --message hello当频道选择是隐式时twilio-sms:前缀会选中本频道而不会占用sms:服务前缀后者被 iMessage 用来为自己的目标选择运营商 SMS 投递openclaw message send --target twilio-sms:15551234567 --message helloCLI 要求显式--target。defaultTo面向自动化与 Agent 发起、可从频道配置解析目标的投递路径。Agent 对入站短信会话的回复会自动通过已配置的 Twilio 发送方返回给发信人。文本处理与分块SMS 输出是纯文本。OpenClaw 会剥离 Markdown、展平围栏代码块、将链接改写为label (url)形式并在发送前把长回复拆分为至多textChunkLimit默认 1500字符的分块。这些逻辑位于 extensions/sms/src/send.tstoSmsPlainText调用sanitizeAssistantVisibleTextstripMarkdownlinkStyle: label-and-url并压缩多余空行chunkSmsPlainText在textChunkLimit与 Twilio 单条消息体上限TWILIO_MESSAGE_BODY_MAX_LENGTH之间取较小值切分多条分块会逐条经 Twilio 发送中途失败时抛出ChannelPartialDeliveryError携带已成功消息的 SID 回执避免把部分成功误报为全量失败。resolveSmsTextChunkLimit见 channel.ts的解析链是账户级textChunkLimit→ fallback 1500。发送 MMS使用常规结构化媒体字段或 CLI--media选项openclaw message send \ --channel sms \ --target sms:15551234567 \ --message photo \ --media ./photo.jpgOpenClaw 通过共享的出站媒体策略加载附件临时存储到插件作用域的 SQLite 状态中并在配置的publicWebhookUrl路径上给 Twilio 一个令牌化的 HTTPS URL。纯媒体发送受支持。channels.sms.mediaMaxMb限制每个入站与出站附件的 MiB 大小。所选账户的mediaMaxMb覆盖频道根级值然后是agents.defaults.mediaMaxMb兜底。此单附件设置不替代 Twilio 的总消息或媒体类型上限。出站图片发送前可能被优化。生成的媒体 URL 是 bearer 能力凭证10 分钟后过期。应把完整查询串视为机密配置反向代理与访问日志省略查询串或脱敏每个查询值。OpenClaw Gateway 路由诊断只记录 pathname但无法控制上游代理日志。出站投递每次附带一个媒体项。OpenClaw 将 JPEG、JPG、PNG、GIF 附件上限设为 5,000,000 字节其他受支持媒体类型上限为 500,000 字节。application/vcard附件必须是纯媒体发送Twilio 不接受带标题的 vCard。目的地运营商可能执行更小的限制或拒绝不支持的格式。Twilio 必须能在无需 HTTP 认证的情况下获取生成的 URL因此publicWebhookUrl不能包含内嵌 userinfo基于查询串的反向代理令牌可保留。入站 MMS 最多处理 10 个附件、最多下载 5 MiB 总量。任何额外或不可用的附件会产生可见的媒体不可用通知而不会丢弃已签名的消息或静默投递空轮次。下载仅在发送方授权之后进行并限制使用 Twilio 认证与api.twilio.com主机。投递状态每次出站发送成功后若 Twilio API 响应包含初始状态OpenClaw 会记录该状态。publicWebhookUrl有效时每条出站消息还会给 Twilio 一个派生的StatusCallbackURL——保留基础 URL 与连接覆盖connection overrides同时附加必需的投递回调重试设置。无效或超长的派生 URL 会被省略。后续投递回调更新同一条插件作用域 SQLite 记录。语义重试会去重旧状态转换不能回退终态冲突的终态观察被报告为conflicted而不是挑选一个虚假的胜者。记录包含消息 SID、状态/错误元数据与时间戳但不包含消息正文或电话号码地址。每条记录在最近一次观察后保留至多 30 天受插件级 5,000 条消息上限与最旧记录淘汰约束。验证配置Gateway 启动后确认 Gateway 日志显示 SMS webhook 路由运行 Twilio 侧探测检查已配置的 Twilio webhook URL/方法、近期入站错误与最近存储的出站投递状态openclaw channels capabilities --channel sms openclaw channels status --channel sms --probe --json用手机向 Twilio 号码发送一条短信运行openclaw pairing list sms用openclaw pairing approve sms CODE批准配对码再发一条短信确认 Agent 回复。仅做纯出站测试openclaw message send --channel sms --target sms:15557654321 --message OpenClaw SMS test从 macOS iMessage/SMS 做端到端测试在可通过信息发送运营商短信的 Mac 上可用imsg驱动发送侧而无需手机imsg send --to 15551234567 --service sms --text OpenClaw SMS E2E $(date -u %Y%m%dT%H%M%SZ) --json openclaw pairing list sms openclaw pairing approve sms CODE imsg send --to 15551234567 --service sms --text reply exactly SMS pong --json第一条消息应创建配对请求第二条消息应通过 Twilio 收到 Agent 回复。Webhook 安全默认情况下OpenClaw 使用publicWebhookUrl与authToken校验X-Twilio-Signature。publicWebhookUrl的端点部分必须与 Twilio 中配置的 URL 逐字节一致含 scheme、host、path 与 query string。OpenClaw 会从签名计算中排除 Twilio connection-override 片段#...符合 Twilio 的要求。除签名校验外webhook 路由还独立强制以下规则仅接受POST失败请求预算每 SMS 账户、webhook 路由、解析出的客户端地址 300 次/分钟。所有请求都计入预算但 HTTP 429 仅在 body 解析或 Twilio 签名校验失败后应用签名投递回调分类先于入站发送方配额进行分类并在返回 HTTP 200 前提交到有界、插件作用域的 SQLite 状态。它们不消耗入站分发配额该配额保护原始入站消息准入与下游 Agent 分发。投递持久化另有每 SMS 账户路由 3,000 回调/分钟的安全熔断超出时返回 HTTP 503 且不带持久化接受标记——这是 fail-closed 过载保护而非无损背压。禁用签名校验时投递回调先用更严格的 30 次/分钟解析客户端地址上限可分发的回调限流body 解析与签名校验通过后每 SMS 账户、webhook 路由、已校验发送方 30 次/分钟超出返回 HTTP 429。发送方键是规范化、被签名覆盖的From值因此等效的 SMS/RCS 地址形式共享同一预算、单个泛滥发送方只能耗尽自己的预算、Twilio 共享出口地址背后的其他发送方回调仍可分发。无效或缺失的发送方值共享独立的空发送方预算聚合校验回调上限每 SMS 账户、webhook 路由 300 次/分钟。这约束了大量不同已签名发送方的持久化入口压力。禁用签名校验时From未经认证改用更严格的 30 次/分钟解析客户端地址分发上限客户端地址解析遵循共享 Gateway 可信代理规则。若 gateway.trustedProxies 包含转发 Twilio 回调的反向代理地址类限制基于转发客户端地址否则回退到直接 socket 地址载荷身份校验入站载荷必须携带非空AccountSid且与配置的accountSid完全一致。直拨号码回调必须指向配置的fromNumberMessaging Service 回调必须携带配置的MessagingServiceSid。原始回调先提交到持久化入口队列并确认身份不匹配在 drain 阶段被标记为永久无效载荷失败绝不会被分发或允许下载媒体缺失或不同的AccountSid确认、记录、有意不存储重放去重重放的MessageSid由持久化入口队列去重。完成消息 tombstone 保留 24 小时每账户至多 20,000 条永久失败 tombstone 保留 30 天至多 1,000 条非 PII 指纹投递观察使用来源、消息 SID、规范化状态、错误码与运营商完成日期的语义化非 PII 指纹。同一条出站消息的多个状态保持独立。记录在最近观察后 30 天过期5,000 条上限可更早淘汰旧记录载荷上限超过 32 KB 的请求体被拒绝。OpenClaw 会给生成的投递StatusCallbackURL 附加5xx重试策略与重试次数以便 Twilio 在 SQLite 提交失败或投递状态路由过载时重试。Twilio 默认不重试 HTTP 429。#rp4xx与#rpallconnection override 可启用 4xx 重试但 Twilio 将完整重试事务限制在 15 秒内。429 或投递状态 503 都不保证后续恢复需要最终状态完整性时应使用对账。对完整性敏感的工作流持久化 Message SID并轮询 Twilio 的 Message resource 对账陈旧的非终态记录。Twilio 建议当消息在 12 小时内未达到delivered或undelivered时轮询因为状态回调可能未到达。SMS fallback URL 不是替代品它只处理检索或执行入站 SMS TwiML webhook 的失败。仅限本地隧道测试时可设置{ channels: { sms: { dangerouslyDisableSignatureValidation: true, }, }, }切勿在公网 Gateway 上禁用签名校验。多账户配置运营多个 Twilio 号码时使用accounts{ channels: { sms: { accounts: { support: { enabled: true, accountSid: ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, authToken: twilio-auth-token, fromNumber: 15551234567, publicWebhookUrl: https://gateway.example.com/webhooks/sms/support, webhookPath: /webhooks/sms/support, dmPolicy: allowlist, allowFrom: [15557654321], }, }, }, }, }每个账户必须使用不同的webhookPathGateway 拒绝注册已被其他账户占用的路由。TWILIO_*/SMS_*环境变量回退只作用于默认账户可用defaultAccount更改默认账户。多账户结构与解析逻辑见 extensions/sms/src/accounts.ts 及 config-schema.ts 中的buildMultiAccountChannelSchema。故障排查Twilio 返回 403 或 OpenClaw 拒绝 webhook检查publicWebhookUrl与 Twilio 中配置的 URL 完全一致含 scheme、host、path 与 query string。Twilio 对公网 URL 字符串签名代理重写与备用主机名会破坏签名校验。如果 Twilio 收到持久化确认但没有出现配对请求检查 Gateway 日志中的永久无效载荷失败确认回调的AccountSid与To匹配配置的账户与fromNumber或其MessagingServiceSid匹配配置的 Messaging Service。没有出现配对请求检查 Twilio 号码的Messagingwebhook URL 与方法必须指向 SMS webhook URL 且使用POST同时确认 Gateway 对公网或隧道可达。若 Twilio 消息日志显示错误11200Twilio 已接受入站短信但无法到达你的 webhook检查TwilioMessaging A message comes in指向publicWebhookUrl方法为POST隧道或反向代理暴露了精确的webhookPathTailscale Funnel 可运行tailscale funnel status确认/webhooks/sms在列表中publicWebhookUrl使用与 Twilio 发送相同的 scheme、host、path 与 query string使签名校验能复现被签名的 URL。openclaw channels status --channel sms --probe能同时暴露 Twilio webhook 设置不匹配与近期11200错误。出站发送失败确认accountSid、authToken、以及fromNumber或messagingServiceSid已解析。Twilio 试用账号只能发送给账号注册国家的已验证接收方且必须使用 Twilio 预定义内容——自定义短信正文不受支持。试用账号也无法注册 A2P 10DLC注册美国 10DLC 发送方前请先升级。Twilio 接受发送但随后投递失败先从 OpenClaw 存储的投递观察开始openclaw channels status --channel sms --probe --json若最近出站状态为failed或undelivered用其messageSid在 Twilio 中检查最终消息状态与错误码30034发送方未注册或不在与获批 Campaign 关联的 Messaging Service 的 Sender Pool 中30035Twilio 仍在注册、注销或重新分配该号码等其状态为REGISTERED再发送。消息到达但 Agent 不回复检查dmPolicy与allowFrom。默认pairing策略下发送方必须先被批准才能处理常规 Agent 轮次。相关资源Channels 总览Secrets 管理 — 通过 SecretRef 解析 Twilio Auth TokenGateway 配置 —gateway.trustedProxies及其余本文用到的 Gateway 设置Channel 故障排查 — 跨频道诊断与修复手册频道配对 — 短信默认 DM 策略说明Voice Call 插件 — 与短信共用号码时的语音 webhook 配置【免费下载链接】openclawThe AI that really does things. Any OS. Any Platform. The lobster way. 项目地址: https://gitcode.com/GitHub_Trending/cl/openclaw创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考