Mainstream messaging
SMS
OpenClaw 透過 Twilio 電話號碼或 Messaging Service 接收與傳送 SMS。閘道會註冊輸入網路鉤子路由(預設為 /webhooks/sms)、預設驗證 Twilio 請求簽章,並透過 Twilio 的 Messages API 傳回回覆。
狀態:官方外掛,需另行安裝。僅支援文字:不支援 MMS/媒體,且僅支援私人訊息。
開始之前
你需要:
- 使用
openclaw plugins install @openclaw/sms安裝官方 SMS 外掛。 - 具備支援 SMS 的電話號碼或 Twilio Messaging Service 的 Twilio 帳號。
- Twilio Account SID 與 Auth Token。
- 可連線至 OpenClaw 閘道的公開 HTTPS URL。
- 傳送者政策選項:私人使用請選擇
pairing(預設)、預先核准的電話號碼請選擇allowlist,只有刻意開放公開 SMS 存取時才選擇open。
如果具備這兩種功能,一個 Twilio 號碼可以同時用於 SMS 和語音通話。SMS 網路鉤子與語音網路鉤子在 Twilio 中分別設定,並使用不同的閘道路徑;本頁僅說明 SMS 網路鉤子。
快速設定
安裝外掛
openclaw plugins install @openclaw/sms建立或選擇 Twilio 傳送者
在 Twilio 中開啟 Phone Numbers > Manage > Active numbers,然後選擇支援 SMS 的號碼。儲存:
- Account SID,例如
ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx - Auth Token
- 傳送者電話號碼,例如
+15551234567
如果使用 Messaging Service 而非固定傳送者號碼,請儲存 Messaging Service SID,例如 MGxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx。
設定 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",},},}套用設定:
openclaw config patch --file ./sms.patch.json5 --dry-runopenclaw config patch --file ./sms.patch.json5將 Twilio 指向閘道網路鉤子
在 Twilio 電話號碼設定中開啟 Messaging,並將 A message comes in 設為:
https://gateway.example.com/webhooks/sms使用 HTTP POST。預設本機路徑為 /webhooks/sms;如需其他路由,請變更 channels.sms.webhookPath。
公開確切的 SMS 網路鉤子路徑
你的公開 URL 必須將 SMS 路徑路由至閘道程序(預設連接埠為 18789)。如果使用 Tailscale Funnel 進行本機測試,請明確公開 /webhooks/sms:
tailscale funnel --bg --set-path /webhooks/sms http://127.0.0.1:<gateway-port>/webhooks/smstailscale funnel status語音通話與 SMS 使用不同的網路鉤子路徑。如果同一個 Twilio 號碼同時處理兩者,請在 Twilio 和通道中保留這兩條路由的設定。
啟動閘道並核准第一位傳送者
openclaw gateway傳送簡訊至 Twilio 號碼。第一則訊息會建立配對請求。核准該請求:
openclaw pairing list smsopenclaw pairing approve sms <CODE>配對碼會在 1 小時後到期。
設定範例
所有鍵都位於 channels.sms 之下(每個帳號的設定則位於 channels.sms.accounts.<id> 之下):
| 鍵 | 預設值 | 用途 |
|---|---|---|
enabled |
true |
啟用或停用頻道/帳號。 |
accountSid |
— | Twilio Account SID(AC...)。 |
authToken |
— | Twilio Auth Token;純文字字串或 SecretRef。 |
fromNumber |
— | E.164 傳送者號碼。 |
messagingServiceSid |
— | 未解析出 fromNumber 時使用的 Messaging Service SID(MG...)。 |
defaultTo |
— | 傳送流程省略明確目標時的預設目的地。 |
webhookPath |
/webhooks/sms |
Twilio 輸入網路鉤子的閘道 HTTP 路徑。 |
publicWebhookUrl |
— | 在 Twilio 中設定的公開 URL;簽章驗證需要此項。 |
dangerouslyDisableSignatureValidation |
false |
略過 X-Twilio-Signature 檢查;僅供本機通道測試使用。 |
dmPolicy |
"pairing" |
pairing、allowlist、open 或 disabled。 |
allowFrom |
[] |
允許的 E.164 傳送者號碼,或搭配 dmPolicy: "open" 使用 "*"。 |
textChunkLimit |
1500 |
每個輸出 SMS 分段的字元數上限。 |
accounts、defaultAccount |
— | 多帳號對應表與預設帳號 ID。 |
設定檔
如果你希望頻道定義隨閘道設定一同移轉,請使用設定檔進行設定:
{ channels: { sms: { enabled: true, accountSid: "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", authToken: "twilio-auth-token", fromNumber: "+15551234567", publicWebhookUrl: "https://gateway.example.com/webhooks/sms", dmPolicy: "pairing", }, },}環境變數
環境變數僅套用於預設帳號;設定值的優先順序高於環境變數值。
| 變數 | 對應至 |
|---|---|
TWILIO_ACCOUNT_SID |
accountSid |
TWILIO_AUTH_TOKEN |
authToken |
TWILIO_PHONE_NUMBER(別名 TWILIO_SMS_FROM) |
fromNumber |
TWILIO_MESSAGING_SERVICE_SID |
messagingServiceSid |
SMS_PUBLIC_WEBHOOK_URL |
publicWebhookUrl |
SMS_WEBHOOK_PATH |
webhookPath |
SMS_ALLOWED_USERS |
allowFrom(以逗號分隔) |
SMS_TEXT_CHUNK_LIMIT |
textChunkLimit |
SMS_DANGEROUSLY_DISABLE_SIGNATURE_VALIDATION |
dangerouslyDisableSignatureValidation("true") |
export TWILIO_ACCOUNT_SID="ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"export TWILIO_AUTH_TOKEN="<twilio-auth-token>"export TWILIO_PHONE_NUMBER="+15551234567"export SMS_PUBLIC_WEBHOOK_URL="https://gateway.example.com/webhooks/sms"然後在設定中啟用頻道:
{ channels: { sms: { enabled: true, dmPolicy: "pairing", }, },}SecretRef Auth Token
authToken 可以是 SecretRef(source: "env" | "file" | "exec")。如果閘道應從 OpenClaw 密鑰執行階段解析 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", }, },}閘道執行階段必須能夠存取所參照的環境變數或密鑰提供者。變更主機環境變數後,請重新啟動受管理的閘道程序。
Messaging Service 傳送者
如果應由 Twilio 透過 Messaging Service 選擇傳送者,請使用 messagingServiceSid,而非 fromNumber:
{ channels: { sms: { enabled: true, accountSid: "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", authToken: "twilio-auth-token", messagingServiceSid: "MGxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", publicWebhookUrl: "https://gateway.example.com/webhooks/sms", dmPolicy: "pairing", }, },}如果設定與環境變數解析後同時存在 fromNumber 和 messagingServiceSid,則會使用 fromNumber。
預設輸出目標
如果傳送流程省略明確目標時,自動化或代理程式發起的傳遞應使用預設目的地,請設定 defaultTo:
{ channels: { sms: { enabled: true, accountSid: "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", authToken: "twilio-auth-token", fromNumber: "+15551234567", defaultTo: "+15557654321", publicWebhookUrl: "https://gateway.example.com/webhooks/sms", }, },}存取控制
channels.sms.dmPolicy 控制 SMS 私人訊息的直接存取:
pairing(預設):未知傳送者會收到配對碼;使用openclaw pairing approve sms <CODE>核准。allowlist:僅處理allowFrom中的傳送者。空白的allowFrom會拒絕所有傳送者(閘道會記錄啟動警告)。open:設定驗證要求allowFrom必須包含"*"。若未使用萬用字元,則只有列出的號碼可以聊天。disabled:捨棄所有輸入私人訊息。
allowFrom 項目應為 E.164 電話號碼,例如 +15551234567。系統接受並正規化 sms: 和 twilio-sms: 前綴。對於私人助理,建議搭配明確的電話號碼使用 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"], }, },}傳送 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 "hello"命令列介面要求明確指定 --target。defaultTo 適用於可從頻道設定解析目標的自動化和代理程式發起傳遞路徑。
來自傳入 SMS 對話的代理程式回覆,會自動透過已設定的 Twilio 傳送端回傳給傳送者。
SMS 輸出為純文字。OpenClaw 會移除 Markdown、攤平圍欄程式碼區塊、將連結改寫為 label (url),並將較長的回覆分割成每段最多 textChunkLimit 個字元(預設為 1500),再透過 Twilio 傳送。
驗證設定
閘道啟動後:
- 確認閘道記錄顯示 SMS 網路鉤子路由。
- 執行 Twilio 端探測(檢查已設定的 Twilio 網路鉤子 URL/方法,以及近期的傳入錯誤):
openclaw channels capabilities --channel smsopenclaw channels status --channel sms --probe --json- 使用手機向 Twilio 號碼傳送 SMS。
- 執行
openclaw pairing list sms。 - 使用
openclaw pairing approve sms <CODE>核准配對碼。 - 再傳送一則 SMS,並確認代理程式有回覆。
若只測試傳出功能,請使用:
openclaw message send --channel sms --target sms:+15557654321 --message "OpenClaw SMS test"從 macOS iMessage/SMS 進行端對端測試
在可透過「訊息」傳送電信業者 SMS 的 Mac 上,你可以使用 imsg 驅動傳送端,而不必操作手機:
imsg send --to "+15551234567" --service sms --text "OpenClaw SMS E2E $(date -u +%Y%m%dT%H%M%SZ)" --jsonopenclaw pairing list smsopenclaw pairing approve sms <CODE>imsg send --to "+15551234567" --service sms --text "reply exactly SMS pong" --json第一則訊息應建立配對請求。第二則訊息應透過 Twilio 收到代理程式回覆。
網路鉤子安全性
OpenClaw 預設會使用 publicWebhookUrl 和 authToken 驗證 X-Twilio-Signature。請確保 publicWebhookUrl 的端點部分與 Twilio 中設定的 URL 逐位元組完全一致,包括通訊協定、主機、路徑和查詢字串。依 Twilio 的要求,OpenClaw 會在簽章計算中排除 Twilio 連線覆寫片段(#...)。
網路鉤子路由也會獨立於簽章驗證,強制執行下列規則:
- 僅限
POST。 - 每個 SMS 帳號、網路鉤子路由及解析出的用戶端位址,每分鐘的失敗請求額度為 300 個請求。所有請求都會計入此額度,但只有當請求無法剖析本文、Twilio 驗證失敗或 AccountSid 不相符後,才會套用 HTTP 429。
- 通過上述檢查後,每個 SMS 帳號、網路鉤子路由及解析出的用戶端位址,每分鐘可分派的回呼速率上限為 30 個已接受的回呼(超過時回傳 HTTP 429)。若停用簽章驗證,此每分鐘 30 個的限制即為未經驗證的分派上限。
- 用戶端位址會透過共用的閘道受信任 Proxy 規則解析。若
gateway.trustedProxies包含轉送 Twilio 回呼的反向 Proxy,OpenClaw 會依據轉送的用戶端位址套用這些限制;否則會退回使用直接 Socket 位址。 - 承載內容中的
AccountSid必須與已設定的accountSid相符(否則回傳 HTTP 403)。 - 重播的
MessageSid值會在 10 分鐘內去除重複。 - 每個 SMS 帳號的重播快取最多保留 10,000 個有效訊息 SID。當所有欄位都處於有效狀態時,該帳號的新網路鉤子會採取封閉式失敗,回傳 HTTP 429 和
Retry-After標頭,直到最舊的欄位到期。 - 超過 32 KB 的請求本文會遭到拒絕。
Twilio 預設不會重試 HTTP 429,也沒有記載支援 Retry-After。#rp=4xx 和 #rp=all 連線覆寫可選擇啟用 4xx 重試,但 Twilio 會將完整重試交易限制在 15 秒內,因此重試仍可能在重播快取欄位到期前結束。若其他處理常式必須接收傳送失敗的內容,請設定備援 URL;應將 429 視為封閉式失敗的拒絕,而不是可靠的背壓機制。
僅限本機通道測試,你可以設定:
{ channels: { sms: { dangerouslyDisableSignatureValidation: true, }, },}請勿在公開閘道上停用簽章驗證。
多帳號設定
操作多個 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"], }, }, }, },}每個帳號都必須使用不同的 webhookPath;閘道會拒絕註冊路徑已由其他帳號擁有的網路鉤子路由。TWILIO_*/SMS_* 環境變數備援值僅適用於預設帳號;設定 defaultAccount 可變更預設帳號。
疑難排解
Twilio 回傳 403,或 OpenClaw 拒絕網路鉤子
請檢查 publicWebhookUrl 是否與 Twilio 中設定的 URL 完全一致,包括通訊協定、主機、路徑和查詢字串。Twilio 會對公開 URL 字串進行簽署,因此 Proxy 改寫和替代主機名稱可能會破壞簽章驗證。
若 403 伴隨 Invalid account,表示傳入承載內容的 AccountSid 與已設定的 accountSid 不相符;請檢查網路鉤子是否指向擁有該號碼的帳號。
未出現配對請求
請檢查 Twilio 號碼的 Messaging 網路鉤子 URL 和方法。它必須指向 SMS 網路鉤子 URL,並使用 POST。另請確認可從公用網際網路或透過你的通道連線至閘道。
若 Twilio 訊息記錄顯示錯誤 11200,表示 Twilio 已接受傳入 SMS,但無法連線至你的網路鉤子。請檢查:
- Twilio Messaging > A message comes in 指向
publicWebhookUrl。 - 方法為
POST。 - 通道或反向 Proxy 公開了完全一致的
webhookPath;若使用 Tailscale Funnel,請執行tailscale funnel status,並確認其中列出/webhooks/sms。 publicWebhookUrl使用與 Twilio 傳送內容相同的通訊協定、主機、路徑和查詢字串,以便簽章驗證能重現已簽署的 URL。
openclaw channels status --channel sms --probe 會同時顯示不相符的 Twilio 網路鉤子設定和近期的 11200 錯誤。
傳出訊息失敗
請確認已解析 accountSid、authToken,以及 fromNumber 或 messagingServiceSid。若使用 Twilio 試用帳號,可能必須先在 Twilio 中驗證目的地號碼,才能傳送 SMS。
訊息已送達,但代理程式沒有回覆
請檢查 dmPolicy 和 allowFrom。使用預設的 pairing 政策時,必須先核准傳送者,才會處理一般代理程式回合。