ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

OpenClaw 官方语音通话插件 @openclaw/voice-call 实战指南:Twilio / Telnyx / Plivo 接入与 AI 语音对话

OpenClaw 官方语音通话插件 @openclaw/voice-call 实战指南:Twilio / Telnyx / Plivo 接入与 AI 语音对话
  • 人工智能
  • 大模型
  • LLM 网关
  • AI Agent
  • 即时通讯

【免费下载链接】openclaw-zero-token

OpenClaw: Use All Major AI Models NO API Token! Claude/ChatGPT/Gemini/DeepSeek/Doubao/Grok/Qwen/Manus/Kimi

项目地址:https://gitcode.com/gh_mirrors/op/openclaw-zero-token
点击查看免费下载

本文是一份围绕 OpenClaw 官方语音通话插件@openclaw/voice-call的完整技术指南。该插件让 OpenClaw 能够通过 Twilio(Programmable Voice + Media Streams)、Telnyx(Call Control v2)、Plivo(Voice API + XML transfer + GetInput speech)三家电信运营商发起真实电话通话,也内置了零网络的mockProvider 用于本地开发。读完本文,你将掌握该插件的安装方式、完整配置项、CLI 与 AI 工具调用方法、Webhook 签名验证与重放防护原理,以及如何配置基于 OpenAI Realtime 的双向音频流式对话。

插件定位:让 AI 真正"打一通电话"

@openclaw/voice-call是 OpenClaw 的官方语音通话插件,仓库入口位于 voice-call/README.md,插件元数据(依赖、主机版本要求、扩展入口)定义在 voice-call/package.json 与 voice-call/openclaw.plugin.json。它把"发起外呼 → 播放 TTS 语音 → 听取对方回复 → 多轮对话 → 挂断"这一完整闭环封装成:

  • 一组 CLI 命令(openclaw voicecall ...);
  • 一个名为voice_call的 Agent 工具(Tool);
  • 一组 Gateway RPC 方法(voicecall.*)。

底层由CallManager(voice-call/src/manager.ts)统一管理通话状态机,通过 Provider 抽象(voice-call/src/providers/base.ts)屏蔽三家运营商 API 差异。通话记录以 JSONL 形式持久化,重启后还会向 Provider 核验存活通话并自动恢复,实现断电续接。

支持的 Provider 与选型建议

Provider协议/能力适用场景
twilioProgrammable Voice + Media Streams生产环境,支持实时双向音频流(配合 OpenAI Realtime)
telnyxCall Control v2生产环境,需要 Telnyx 账号与 Call Control 应用
plivoVoice API + XML transfer + GetInput speech生产环境,需要 Plivo 账号
mock本地模拟,零网络调用开发调试、单元测试、无真实号码场景

选型建议:调试阶段先用mock跑通整体链路;生产环境优先 Twilio(其对 Media Streams WebSocket 的支持最完整,插件内针对 Twilio 的流式特性也最丰富);若已有 Telnyx 或 Plivo 账号则直接选用对应 Provider。

安装与启用

Option A:通过 OpenClaw 插件系统安装(推荐)

openclaw plugins install @openclaw/voice-call

安装完成后需要重启 Gateway 使插件生效。@openclaw/voice-call的peerDependencies声明openclaw >= 2026.3.28,即要求宿主 OpenClaw 版本不低于该版本(见 voice-call/package.json)。

Option B:复制到全局扩展目录(本地开发)

mkdir -p ~/.openclaw/extensions cp -R extensions/voice-call ~/.openclaw/extensions/voice-call cd ~/.openclaw/extensions/voice-call && pnpm install

注意:仓库中extensions/目录下也有 voice-call 的副本用于打包分发;两种方式任选其一,不要同时安装导致重复注册。

配置详解

插件配置整体放在 OpenClaw 配置的plugins.entries.voice-call.config下。配置的解析、校验逻辑定义在 voice-call/src/config.ts,并在 voice-call/index.ts 的插件入口中被resolveVoiceCallConfig/validateProviderConfig处理。

完整配置示例(继承自官方 README,含注释)

{ provider: "twilio", // or "telnyx" | "plivo" | "mock" fromNumber: "+15550001234", toNumber: "+15550005678", twilio: { accountSid: "ACxxxxxxxx", authToken: "your_token", }, telnyx: { apiKey: "KEYxxxx", connectionId: "CONNxxxx", // 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: "your_token", }, // Webhook server serve: { port: 3334, path: "/voice/webhook", }, // Public exposure (pick one): // publicUrl: "https://example.ngrok.app/voice/webhook", // tunnel: { provider: "ngrok" }, // tailscale: { mode: "funnel", path: "/voice/webhook" } outbound: { defaultMode: "notify", // or "conversation" }, streaming: { enabled: true, streamPath: "/voice/stream", preStartTimeoutMs: 5000, maxPendingConnections: 32, maxPendingConnectionsPerIp: 4, maxConnections: 128, }, }

核心参数速查表(含源码确认的默认值)

以下默认值、取值范围均来自 voice-call/src/config.ts 的 Zod Schema:

参数默认值说明
enabledfalse总开关,必须显式打开插件才会加载运行时
provider无telnyx/twilio/plivo/mock,启用时必填
fromNumber/toNumber无E.164 格式(正则^\+[1-9]\d{1,14}$),非 mock 时fromNumber必填
inboundPolicydisabled入站策略:disabled(仅外呼)/allowlist(仅白名单)/pairing(预留配对流程)/open(全放行,危险)
allowFrom[]入站来电白名单(E.164 数组),匹配时先做纯数字归一化(见 voice-call/src/allowlist.ts)
inboundGreeting无接听入站来电时播放的问候语
outbound.defaultModenotify外呼默认模式:notify(播完自动挂断)/conversation(保持通话多轮对话)
outbound.notifyHangupDelaySec3notify 模式下播完语音后延迟多少秒自动挂断
maxDurationSeconds300单通电话最大时长(秒),超时自动挂断
staleCallReaperSeconds0(禁用)卡死通话自动清理上限,官方建议生产环境设为120–300
silenceTimeoutMs800语音停顿多久视为对方说完(结束语音识别)
transcriptTimeoutMs180000等待对方最终转写文本的超时(180 秒)
ringTimeoutMs30000外呼振铃超时(30 秒)
maxConcurrentCalls1最大并发通话数,超出时initiate_call直接报错
serve.port/serve.bind/serve.path3334/127.0.0.1//voice/webhookWebhook 服务器监听端口、绑定地址、路径
tailscale.mode/tailscale.pathoff//voice/webhook旧式 Tailscale 暴露:off/serve(仅 tailnet)/funnel(公网 HTTPS)
tunnel.providernone统一隧道配置:none/ngrok/tailscale-serve/tailscale-funnel
tunnel.ngrokAuthToken/ngrokDomain无ngrok 鉴权令牌与自定义域名(付费功能)
tunnel.allowNgrokFreeTierLoopbackBypassfalsengrok 免费版兼容开关,仅当 loopback 绑定且 provider 为 ngrok 时生效;不绕过签名验证
webhookSecurity.allowedHosts[]允许的 Host 白名单,防止 Host 头注入
webhookSecurity.trustForwardingHeadersfalse是否信任X-Forwarded-*头(仅在你信任代理时开启)
webhookSecurity.trustedProxyIPs[]可信代理 IP 列表,转发头只在来源 IP 命中时被信任
publicUrl无公网 Webhook URL 显式覆盖(优先级最高,高于隧道自动探测)
skipSignatureVerificationfalse跳过 Webhook 签名验证(仅开发,严禁生产使用)
stt.provider/stt.modelopenai/whisper-1非流式转写配置(当前仅支持 OpenAI)
responseModelopenai/gpt-4o-mini生成语音应答所用模型,格式如anthropic/claude-sonnet-4
responseSystemPrompt无语音应答的自定义系统提示词
responseTimeoutMs30000应答生成超时(毫秒)

敏感信息的三种注入方式

Provider 凭据既可以直接写在配置里,也可以通过环境变量注入。resolveVoiceCallConfig(voice-call/src/config.ts)在缺省时会自动回退到以下环境变量:

  • Twilio:TWILIO_ACCOUNT_SID、TWILIO_AUTH_TOKEN
  • Telnyx:TELNYX_API_KEY、TELNYX_CONNECTION_ID、TELNYX_PUBLIC_KEY
  • Plivo:PLIVO_AUTH_ID、PLIVO_AUTH_TOKEN
  • ngrok:NGROK_AUTHTOKEN、NGROK_DOMAIN

配置校验规则

validateProviderConfig(voice-call/src/config.ts)会在运行时给出明确错误,常见必填项:

  • provider必填(enabled为 true 时);
  • fromNumber必填(mock除外);
  • Twilio:accountSid+authToken;
  • Telnyx:apiKey+connectionId+publicKey(除非skipSignatureVerification为 true);
  • Plivo:authId+authToken。

另外 voice-call/index.ts 做了兼容处理:旧配置provider: "log"会被映射为mock并告警;twilio.from已废弃,应改用顶层fromNumber。

通话模式:notify 与 conversation

外呼有notify与conversation两种模式(CallModeSchema,见 voice-call/src/config.ts):

  • notify(通知模式):单向播报。拨通后播放初始消息,播完等待notifyHangupDelaySec秒自动挂断。在 Twilio 上,notify 模式直接以内联 TwiML<Say>执行(见 voice-call/src/manager/twiml.ts 的generateNotifyTwiml),不依赖额外回调;
  • conversation(对话模式):保持通话,先播报问候,再进入聆听,支持通过continue反复进行多轮"说一句 → 听一句"(continueCall的实现见 voice-call/src/manager/outbound.ts),直到显式end或达到maxDurationSeconds。

通话状态机定义在 voice-call/src/types.ts:非终止态initiated / ringing / answered / active / speaking / listening,终止态completed / hangup-user / hangup-bot / timeout / error / failed / no-answer / busy / voicemail。

Stale Call Reaper:清理卡死通话

由于 notify 模式可能因终端回调丢失等原因停留在非终止状态,插件提供"卡死通话清理器"(Stale Call Reaper)。源码位于 voice-call/src/webhook/stale-call-reaper.ts:每 30 秒扫描一次活动通话,凡startedAt距今超过staleCallReaperSeconds的一律执行endCall收尾。

  • 默认0表示禁用;
  • 官方推荐生产环境设为120–300(秒);
  • 它与maxDurationSeconds互补:后者针对已接通通话的时长上限,Reaper 兜底覆盖从未收到终端回调的异常态。

通话 TTS:复用核心 messages.tts

Voice Call 的语音合成统一复用 OpenClaw 核心的messages.tts配置(voice-call/README.md 明确说明)。插件配置中的tts字段会与核心配置做"深合并"(normalizeVoiceCallTtsConfig+deepMergeDefined,见 voice-call/src/config.ts),即插件只覆盖你指定的字段,其余继承核心配置。

实现层面(voice-call/src/telephony-tts.ts):createTelephonyTtsProvider把核心 TTS 产出的 PCM 音频转换为电话网所需的mu-law 8kHz 单声道格式(convertPcmToMulaw8k)。需要特别注意的是:

  • 通话 TTS 支持 OpenAI 与 ElevenLabs 两家 Provider;
  • Edge TTS 在通话场景被忽略(CHANGELOG 0.1.0 明确记录);
  • 旧的tts.model/tts.voice/tts.instructions插件字段已移除,统一走核心配置。

CLI 实战

CLI 由registerVoiceCallCli注册(实现见 voice-call/src/cli.ts),全部挂在openclaw voicecall下。官方 README 给出的命令全集如下:

openclaw voicecall call --to "+15555550123" --message "Hello from OpenClaw" openclaw 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 tail openclaw voicecall expose --mode funnel

补充说明(来自 CLI 源码):

  • call的-m/--message为必填;-t/--to缺省时回退到配置的toNumber;--mode支持notify | conversation,CLI 默认conversation(注意与配置默认notify的区别,见 voice-call/src/cli.ts);
  • call命令成功后会以 JSON 输出{ callId },后续continue / speak / end / status都要用该 ID;
  • tail用于实时跟踪calls.jsonl通话日志(默认路径~/.openclaw/voice-calls/calls.jsonl),支持--file、--since(先打印最近 N 行,默认 25)、--poll(轮询间隔,默认 250ms);
  • 额外的latency命令可对 JSONL 日志做延迟分析,输出turnLatency与listenWait的 count / min / max / avg / p50 / p95 统计;
  • expose --mode funnel用于配置 Tailscale funnel/serve 公网暴露,关闭时用--mode off。

AI 工具集成:voice_call

插件向 Agent 注册名为voice_call的工具(定义见 voice-call/index.ts),Tool Schema 支持以下 Actions:

  • initiate_call(参数:message必填、to?、mode?)——发起外呼;
  • continue_call(callId、message)——说话并等待对方回复,返回transcript;
  • speak_to_user(callId、message)——只说一句话,不等待回复;
  • end_call(callId)——挂断;
  • get_status(callId)——查询通话状态(同时支持按 Provider 侧 ID 查询)。

另外兼容一种无action的旧式调用:传mode: "call"或mode: "status"分别映射为发起外呼与按sid查询。

AI 自动应答由responseModel/responseSystemPrompt控制(voice-call/README.md)。实现上,generateVoiceResponse(voice-call/src/response-generator.ts)复用嵌入式 Pi Agent 基础设施,与消息通道共用 Agent、会话与工具能力:

  • 会话键为voice:{纯数字手机号},同一来电号码跨通话保持记忆;
  • 默认系统提示要求"1-2 句话、简短自然、可调用工具";
  • 输出强制遵循 spoken JSON 契约{"spoken":"..."},并对 reasoning/meta 段落与代码块做过滤,确保真正播报的内容干净可读。

Gateway RPC

插件向 Gateway 注册的 RPC 方法(实现见 voice-call/index.ts):

  • voicecall.initiate(to?、message、mode?)——message必填,to缺省回退toNumber;
  • voicecall.continue(callId、message)——成功时返回transcript;
  • voicecall.speak(callId、message);
  • voicecall.end(callId);
  • voicecall.status(callId或sid)——支持内部 Call ID 与 Provider 侧 Call SID 双查询;
  • 兼容旧方法voicecall.start(to、message?)。

CLI、Tool 与 RPC 三套入口最终都汇聚到CallManager.initiateCall / continueCall / speak / endCall / getCall同一套调用链,行为一致。

安全与健壮性机制

Webhook 签名验证

Twilio / Telnyx / Plivo 的 Webhook 全部要求公网可达 URL,且默认强制签名验证(实现集中在 voice-call/src/webhook-security.ts):

  • Twilio:X-Twilio-Signature,以 Auth Token 对"完整 URL + 排序后的 POST 参数"做 HMAC-SHA1,Base64 后通过crypto.timingSafeEqual常量时间比较;签名校验失败时还会尝试去掉端口、补端口等若干 URL 变体再验,规避代理导致的 URL 差异;
  • Telnyx:telnyx-signature-ed25519+telnyx-timestamp,对timestamp|payload做 Ed25519 验签,并校验时间戳偏差不超过 5 分钟;公钥支持 PEM / Base64 原始 Ed25519 / DER SPKI 三种形态;
  • Plivo:优先 V3 签名(X-Plivo-Signature-V3+ nonce),缺失时回退 V2。

skipSignatureVerification仅供开发调试,运行时若开启会打印明显的 SECURITY WARNING(见 voice-call/src/runtime.ts)。

重放保护与 turn token

  • 三个 Provider 各自维护独立的重放缓存:签名合法的重复回调在10 分钟窗口内会被识别为isReplay并安全忽略(见 voice-call/src/webhook-security.ts);
  • Twilio 语音回合还带per-turn token:continueCall时生成turnToken(voice-call/src/manager/outbound.ts),使过期的/重放的语音回调无法"完成"新一轮对话。

其他设计细节(官方 README Notes)

  • 流式通话激活期间,播放不回退到 TwiML<Say>:流式 TTS 失败即视为播放请求失败;
  • 外呼对话模式只在"初始问候语正在播放"期间抑制打断(barge-in),播完立即恢复正常的随时插话能力(对应 voice-call/src/webhook.ts 的shouldSuppressBargeInForInitialMessage);
  • Twilio 流断开后的自动挂断带有 2 秒宽限窗口(STREAM_DISCONNECT_HANGUP_GRACE_MS = 2000,见 voice-call/src/webhook.ts),避免快速重连导致误挂;
  • 媒体流(Media Streaming)依赖ws库与 OpenAI Realtime API Key(对应streaming.openaiApiKey)。

媒体流:Twilio Media Streams × OpenAI Realtime

启用streaming.enabled后,插件在streamPath(默认/voice/stream)提供 WebSocket 双向音频(实现见 voice-call/src/media-stream.ts):

  • 上行:接收 Twilio 的 mu-law 音频帧,转发给 OpenAI Realtime STT 做实时转写,产出 partial/final 转录与语音开始(barge-in)信号;
  • 下行:TTS 音频按"每条流串行队列"逐段播放,支持clear事件实现打断;
  • 连接治理:未发送有效start帧的连接在preStartTimeoutMs(默认 5000ms)后关闭;maxPendingConnections(32)/maxPendingConnectionsPerIp(4)/maxConnections(128)三档并发上限,并对超过 1MB 的 WebSocket 发送缓冲做背压关闭;
  • 流令牌(token)用于校验该流确实属于某个已知通话,避免未授权连接占用资源。

从源码结构看,只有当 Provider 为 Twilio 且开启 streaming 时,运行时才会把 TTS Provider 与媒体流处理器接线到 Twilio Provider(见 voice-call/src/runtime.ts)。

源码导读

想深入原理的读者可按如下路径继续阅读仓库:

  • 配置 Schema 与校验:voice-call/src/config.ts
  • 插件入口(Tool / RPC / 服务注册):voice-call/index.ts
  • 通话管理器与状态机:voice-call/src/manager.ts、voice-call/src/manager/outbound.ts、voice-call/src/types.ts
  • 安全核心:voice-call/src/webhook-security.ts
  • 媒体流:voice-call/src/media-stream.ts
  • 运行时装配与资源生命周期:voice-call/src/runtime.ts
  • 测试用例:voice-call/src/下大量*.test.ts(如webhook-security.test.ts、manager.closed-loop.test.ts、media-stream.test.ts)覆盖了签名验证、状态流转、流控等关键路径,是理解边界行为的第一手材料。

快速上手建议

  1. 先用mockProvider + 本地 Webhook 起一个最小配置,跑通voicecall call到voicecall status的完整生命周期;
  2. 接入真实 Provider(以 Twilio 为例)时补齐accountSid/authToken与 E.164 号码,并确保 Webhook 公网可达(publicUrl、ngrok 或 Tailscale funnel 三选一);
  3. 生产环境务必保持签名验证开启,设置staleCallReaperSeconds(如 180)与合理的maxDurationSeconds,并把maxConcurrentCalls调到你真正需要的并发量;
  4. 需要真机实时对话时再开启streaming.enabled,并配置 OpenAI Realtime API Key。
  • 人工智能
  • 大模型
  • LLM 网关
  • AI Agent
  • 即时通讯

【免费下载链接】openclaw-zero-token

OpenClaw: Use All Major AI Models NO API Token! Claude/ChatGPT/Gemini/DeepSeek/Doubao/Grok/Qwen/Manus/Kimi

项目地址:https://gitcode.com/gh_mirrors/op/openclaw-zero-token
点击查看免费下载

相关推荐

上一篇:如何用深度学习加速流体力学模拟:DeepCFD完整指南
下一篇:Mermaid在线编辑器完整指南:写文字就能出图,免费在线作图

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进