設定 OpenClaw 語音通話插件:整合 Twilio、Telnyx 與 Plivo
想要讓你的 AI 機器人直接打電話給使用者,或是接聽客戶的詢問嗎?處理語音通話通常很麻煩,要搞定各種 Webhook、串流協議還有不同供應商的 API 差異。OpenClaw 的 Voice Call 插件就是為了簡化這一切而設計的,讓你透過簡單的設定就能賦予機器人說話與聽取語音的能力。
這個插件支援主動撥打通知,也支援帶有入境策略的多輪對話。目前支援的供應商包括:
twilio(Programmable Voice + Media Streams)telnyx(Call Control v2)plivo(Voice API + XML transfer + GetInput speech)mock(開發專用,不需網路)
執行位置 (本地 vs 遠端)
Section titled “執行位置 (本地 vs 遠端)”Voice Call 插件是執行在 Gateway 程序內部的。
如果你使用的是遠端 Gateway,請在執行 Gateway 的那台機器上安裝並設定插件,然後重啟 Gateway 來載入它。
選項 A:從 npm 安裝(推薦)
Section titled “選項 A:從 npm 安裝(推薦)”openclaw plugins install @openclaw/voice-call安裝完成後請重啟 Gateway。
選項 B:從本地資料夾安裝(開發用,無需複製)
Section titled “選項 B:從本地資料夾安裝(開發用,無需複製)”PLUGIN_SRC=./path/to/local/voice-call-pluginopenclaw plugins install "$PLUGIN_SRC"cd "$PLUGIN_SRC" && pnpm install安裝完成後請重啟 Gateway。
在 plugins.entries.voice-call.config 下進行設定:
{ plugins: { entries: { "voice-call": { enabled: true, config: { provider: "twilio", // or "telnyx" | "plivo" | "mock" fromNumber: "+15550001234", toNumber: "+15550005678",
twilio: { accountSid: "ACxxxxxxxx", authToken: "...", },
telnyx: { apiKey: "...", connectionId: "...", // Telnyx webhook public key from the Telnyx Mission Control Portal // (Base64 string; can also be set via TELNYX_PUBLIC_KEY). publicKey: "...", },
plivo: { authId: "MAxxxxxxxxxxxxxxxxxxxx", authToken: "...", },
// Webhook server serve: { port: 3334, path: "/voice/webhook", },
// Webhook security (recommended for tunnels/proxies) webhookSecurity: { allowedHosts: ["voice.example.com"], trustedProxyIPs: ["100.64.0.1"], },
// Public exposure (pick one) // publicUrl: "https://example.ngrok.app/voice/webhook", // tunnel: { provider: "ngrok" }, // tailscale: { mode: "funnel", path: "/voice/webhook" }
outbound: { defaultMode: "notify", // notify | conversation },
streaming: { enabled: true, streamPath: "/voice/stream", preStartTimeoutMs: 5000, maxPendingConnections: 32, maxPendingConnectionsPerIp: 4, maxConnections: 128, }, }, }, }, },}注意事項:
- Twilio/Telnyx 需要一個外部可存取的 Webhook URL。
- Plivo 同樣需要一個外部可存取的 Webhook URL。
mock是本地開發用的供應商(不會發出網路請求)。- 除非
skipSignatureVerification為 true,否則 Telnyx 需要telnyx.publicKey(或TELNYX_PUBLIC_KEY)。 skipSignatureVerification僅供本地測試使用。- 如果你使用 ngrok 免費版,請將
publicUrl設定為正確的 ngrok URL;簽名驗證會強制執行。 tunnel.allowNgrokFreeTierLoopbackBypass: true僅在tunnel.provider="ngrok"且serve.bind為 loopback(ngrok 本地代理)時,允許 Twilio Webhook 使用無效簽名。這僅限本地開發使用。- Ngrok 免費版 URL 可能會變動或加入中間頁面;如果
publicUrl跑掉了,Twilio 簽名驗證會失敗。生產環境建議使用固定域名或 Tailscale funnel。 - 串流安全預設值:
streaming.preStartTimeoutMs會關閉那些從未發送有效start幀的 socket。streaming.maxPendingConnections限制未經身份驗證的預啟動 socket 總數。streaming.maxPendingConnectionsPerIp限制每個來源 IP 的未經身份驗證預啟動 socket 數量。streaming.maxConnections限制總共開啟的媒體串流 socket 數量(包含待處理與活動中)。
過期通話清理器 (Stale call reaper)
Section titled “過期通話清理器 (Stale call reaper)”使用 staleCallReaperSeconds 來結束那些從未收到終端 Webhook 的通話(例如,從未完成的通知模式通話)。預設值為 0(禁用)。
推薦範圍:
- 生產環境: 通知型流程建議設定為
120–300秒。 - 確保這個值高於
maxDurationSeconds,這樣正常的通話才能完成。一個好的起點是maxDurationSeconds + 30–60秒。
範例:
{ plugins: { entries: { "voice-call": { config: { maxDurationSeconds: 300, staleCallReaperSeconds: 360, }, }, }, },}Webhook 安全性
Section titled “Webhook 安全性”當 Gateway 前方有代理伺服器或隧道時,插件會重建公開 URL 以進行簽名驗證。以下選項控制哪些轉發標頭 (forwarded headers) 是可信的。
webhookSecurity.allowedHosts 允許來自轉發標頭的特定主機白名單。
webhookSecurity.trustForwardingHeaders 在沒有白名單的情況下信任轉發標頭。
webhookSecurity.trustedProxyIPs 僅在請求的遠端 IP 符合列表時才信任轉發標頭。
Twilio 和 Plivo 已啟用 Webhook 重放攻擊保護。重複的有效 Webhook 請求會被確認,但會跳過副作用處理。
Twilio 對話輪次在 <Gather> 回呼中包含每輪 token,因此過期或重放的語音回呼無法滿足較新的待處理轉錄輪次。
如果缺少供應商要求的簽名標頭,未經身份驗證的 Webhook 請求會在讀取 body 之前被拒絕。
Voice Call Webhook 使用共享的預認證 body 設定(64 KB / 5 秒),並在簽名驗證前設有每 IP 的在途請求限制。
使用固定公開主機的範例:
{ plugins: { entries: { "voice-call": { config: { publicUrl: "https://voice.example.com/voice/webhook", webhookSecurity: { allowedHosts: ["voice.example.com"], }, }, }, }, },}通話專用的 TTS
Section titled “通話專用的 TTS”Voice Call 使用核心的 messages.tts 設定來處理通話中的串流語音。你可以在插件設定下使用相同的結構來覆寫它 —— 它會與 messages.tts 進行深度合併 (deep-merge)。
{ tts: { provider: "elevenlabs", providers: { elevenlabs: { voiceId: "pMsXgVXv3BLzUgSXRplE", modelId: "eleven_multilingual_v2", }, }, },}注意事項:
- 插件設定中舊版的
tts.<provider>鍵(如openai,elevenlabs,microsoft,edge)在載入時會自動遷移到tts.providers.<provider>。建議在設定檔中使用providers結構。 - 語音通話會忽略 Microsoft 語音(電話音訊需要 PCM,而目前的 Microsoft 傳輸方式不支援電話 PCM 輸出)。
- 當啟用 Twilio 媒體串流時會使用核心 TTS;否則通話會回退到供應商的原生語音。
- 如果 Twilio 媒體串流已經處於活動狀態,Voice Call 不會回退到 TwiML
<Say>。在這種狀態下如果電話 TTS 不可用,播放請求會失敗,而不是混合兩種播放路徑。 - 當電話 TTS 回退到備用供應商時,Voice Call 會記錄一條包含供應商鏈(
from,to,attempts)的警告,方便除錯。
僅使用核心 TTS(不覆寫):
{ messages: { tts: { provider: "openai", providers: { openai: { voice: "alloy" }, }, }, },}僅針對通話覆寫為 ElevenLabs(其他地方保留核心預設值):
{ plugins: { entries: { "voice-call": { config: { tts: { provider: "elevenlabs", providers: { elevenlabs: { apiKey: "elevenlabs_key", voiceId: "pMsXgVXv3BLzUgSXRplE", modelId: "eleven_multilingual_v2", }, }, }, }, }, }, },}僅針對通話覆寫 OpenAI 模型(深度合併範例):
{ plugins: { entries: { "voice-call": { config: { tts: { providers: { openai: { model: "gpt-4o-mini-tts", voice: "marin", }, }, }, }, }, }, },}入境通話 (Inbound calls)
Section titled “入境通話 (Inbound calls)”入境策略預設為 disabled。要啟用入境通話,請設定:
{ inboundPolicy: "allowlist", allowFrom: ["+15550001234"], inboundGreeting: "Hello! How can I help?",}inboundPolicy: "allowlist" 是一種低強度的來電顯示篩選。插件會將供應商提供的 From 值標準化,並與 allowFrom 進行比較。Webhook 驗證可以確保供應商的傳遞與資料完整性,但無法證明 PSTN/VoIP 來電號碼的所有權。請將 allowFrom 視為來電過濾,而非強大的身份認證。
自動回覆使用 Agent 系統。你可以透過以下參數進行微調:
responseModelresponseSystemPromptresponseTimeoutMs
語音輸出規範 (Spoken output contract)
Section titled “語音輸出規範 (Spoken output contract)”對於自動回覆,Voice Call 會在系統提示詞中附加一個嚴格的語音輸出規範:
{"spoken":"..."}
隨後 Voice Call 會防禦性地提取語音文本:
- 忽略標記為推理或錯誤內容的資料。
- 解析直接的 JSON、fenced JSON 或行內的
"spoken"鍵。 - 回退到純文本,並移除可能的規劃或元數據引導段落。
這能確保語音播放集中在面向來電者的文本,避免將規劃過程的文字洩漏到音訊中。
對話啟動行為
Section titled “對話啟動行為”對於撥出的 conversation 通話,首條訊息的處理與即時播放狀態掛鉤:
- 僅在初始問候語正在播放時,才會抑制插嘴 (barge-in) 隊列清理與自動回覆。
- 如果初始播放失敗,通話會回到
listening狀態,且初始訊息會保留在隊列中等待重試。 - Twilio 串流的初始播放會在串流連接後立即開始,沒有額外延遲。
Twilio 串流斷線寬限期
Section titled “Twilio 串流斷線寬限期”當 Twilio 媒體串流斷開時,Voice Call 會等待 2000ms 才自動結束通話:
- 如果串流在該視窗內重新連接,自動結束會被取消。
- 如果寬限期後沒有重新註冊串流,通話將結束,以防止通話卡在活動狀態。
openclaw voicecall call --to "+15555550123" --message "Hello from OpenClaw"openclaw voicecall start --to "+15555550123" # alias for callopenclaw voicecall continue --call-id <id> --message "Any questions?"openclaw voicecall speak --call-id <id> --message "One moment"openclaw voicecall end --call-id <id>openclaw voicecall status --call-id <id>openclaw voicecall tailopenclaw voicecall latency # summarize turn latency from logsopenclaw voicecall expose --mode funnellatency 會從預設的 voice-call 儲存路徑讀取 calls.jsonl。使用 --file <path> 指向不同的日誌,並使用 --last <n> 限制分析最後 N 筆記錄(預設 200)。輸出包含輪次延遲與等待聽取時間的 p50/p90/p99。
Agent 工具
Section titled “Agent 工具”工具名稱:voice_call
操作動作:
initiate_call(message, to?, mode?)continue_call(callId, message)speak_to_user(callId, message)end_call(callId)get_status(callId)
此倉庫在 skills/voice-call/SKILL.md 提供了一份匹配的技能文件。
Gateway RPC
Section titled “Gateway RPC”voicecall.initiate(to?,message,mode?)voicecall.continue(callId,message)voicecall.speak(callId,message)voicecall.end(callId)voicecall.status(callId)
下一步:
有任何設定上的問題嗎?試試我們的 AI Setup Assistant!
OpenClaw Expert
還是卡住了?
如果這篇文件沒有解決你的情境,直接問 OpenClaw Expert,拿到可執行步驟。