语音通话(插件)
OpenClaw 的语音通话插件。支持外拨通知和带入站策略的多轮对话。 当前支持的服务提供商:twilio(可编程语音 + 媒体流)telnyx(呼叫控制 v2)plivo(语音 API + XML 转接 + GetInput 语音识别)mock(开发用/无网络)
- 安装插件
- 重启网关
- 在
plugins.entries.voice-call.config下配置 - 使用
openclaw voicecall ...或voice_call工具
运行位置(本地 vs 远程)
语音通话插件运行在网关进程内部。 如果使用远程网关,请在运行网关的机器上安装/配置插件,然后重启网关以加载插件。安装
选项 A:通过 npm 安装(推荐)
选项 B:从本地文件夹安装(开发用,无需复制)
配置
在plugins.entries.voice-call.config 下设置配置项:
- Twilio/Telnyx 需要公开可访问的 webhook URL。
- Plivo 也需要公开可访问的 webhook URL。
mock是本地开发用提供商(无网络调用)。- Telnyx 需要
telnyx.publicKey(或环境变量TELNYX_PUBLIC_KEY),除非设置了skipSignatureVerification为 true。 skipSignatureVerification仅用于本地测试。- 使用 ngrok 免费版时,请将
publicUrl设置为准确的 ngrok URL;签名验证始终强制启用。 - 设置
tunnel.allowNgrokFreeTierLoopbackBypass: true可允许 Twilio webhook 带无效签名,仅当tunnel.provider="ngrok"且serve.bind为回环地址(ngrok 本地代理)时有效,仅限本地开发使用。 - ngrok 免费版 URL 可能变化或加入中间页;若
publicUrl发生变化,Twilio 签名会验证失败。生产环境建议使用稳定域名或 Tailscale 漏斗。 - 流媒体安全默认:
streaming.preStartTimeoutMs会关闭从未发送有效start帧的连接套接字。streaming.maxPendingConnections限制总未认证的预启动套接字数。streaming.maxPendingConnectionsPerIp限制每个源 IP 的未认证预启动套接字。streaming.maxConnections限制总媒体流套接字(预启动 + 活跃)。
过期通话清理器
使用staleCallReaperSeconds 结束从未收到终止 webhook 的通话(例如,通知模式中未完成的通话)。默认值为 0(禁用)。
推荐范围:
- 生产环境:通知型流程建议设置为
120–300秒。 - 保持此值高于
maxDurationSeconds,以便正常通话能完成。推荐起始值为maxDurationSeconds + 30–60秒。
Webhook 安全
当代理或隧道位于网关之前时,插件会重建用于签名验证的公共 URL。以下选项控制信任哪些转发头。webhookSecurity.allowedHosts 允许通过头中的主机名白名单。
webhookSecurity.trustForwardingHeaders 在无白名单时信任转发头。
webhookSecurity.trustedProxyIPs 仅当请求远程 IP 位于列表时信任转发头。
Twilio 和 Plivo 已启用 webhook 重放保护。重放的有效 webhook 请求会被确认但跳过副作用执行。
Twilio 会话转轮在 <Gather> 回调中包含每轮的令牌,因此过期或重放的语音回调无法满足较新的待处理转录。
使用稳定公网主机的示例:
通话的 TTS
语音通话使用核心的messages.tts 配置(OpenAI 或 ElevenLabs)执行流式语音合成。您可以在插件配置下覆盖,且配置结构相同 — 会与 messages.tts 深度合并。
- Edge TTS 被忽略,因为语音电话音频需 PCM 格式;Edge 输出不稳定。
- 启用 Twilio 媒体流时使用核心 TTS,否则通话回退至服务提供商原生语音。
更多示例
仅使用核心 TTS(无覆盖):入站调用
入站策略默认禁用。启用入站通话,设置:responseModelresponseSystemPromptresponseTimeoutMs
命令行界面(CLI)
代理工具
工具名称: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。
网关 RPC
voicecall.initiate(to?,message,mode?)voicecall.continue(callId,message)voicecall.speak(callId,message)voicecall.end(callId)voicecall.status(callId)