尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

OpenClaw Voice Call 插件实战:从 Twilio/Telnyx/Plivo 电话呼叫到实时语音对话的完整接入指南

OpenClaw Voice Call 插件实战:从 Twilio/Telnyx/Plivo 电话呼叫到实时语音对话的完整接入指南 OpenClaw Voice Call 插件实战从 Twilio/Telnyx/Plivo 电话呼叫到实时语音对话的完整接入指南【免费下载链接】openclawThe AI that really does things. Any OS. Any Platform. The lobster way. 项目地址: https://gitcode.com/GitHub_Trending/cl/openclawopenclaw/voice-call是 OpenClaw 官方的语音通话插件让 Agent 可以通过真实电信网络拨打、接听并参与电话对话。本文以 extensions/voice-call/README.md 为主线结合仓库内源码配置 Schema、Provider 实现、CLI 注册、Webhook 安全校验与响应生成深入讲解如何安装启用、如何为 Twilio/Telnyx/Plivo/Mock 四种 Provider 编写完整配置、如何通过 CLI / Agent 工具 / Gateway RPC 发起并管理呼叫、如何打通实时语音Realtime Voice与流式转写Media Streams以及背后的签名验证、重放防护与语音输出约束等安全设计。读完本文你将掌握把 OpenClaw Agent 接入真实电话网络并驱动其开口说话、听懂来电的完整实战方案。插件概览四种 Provider 与统一抽象Voice Call 插件把电信能力抽象为一组 Provider覆盖主流电信语音 API 与本地开发场景TwilioProgrammable Voice Media Streams实时音频流式转写TelnyxCall Control v2原生支持流式转写与 DTMFPlivoVoice API XML 转接 GetInput 语音识别Mock本地开发 / 无网络环境模拟。插件内部通过统一的VoiceCallProvider接口定义于 src/providers/base.ts屏蔽各厂商差异每个 Provider 必须实现verifyWebhookWebhook 签名校验、parseWebhookEvent把厂商事件归一化为统一事件、initiateCall/hangupCall/playTts/startListening/stopListening/getCallStatus等能力。调用管理器src/manager只面向这套抽象接口编程因此切换厂商只需改配置无需改业务逻辑。以 Telnyx 为例src/providers/telnyx.ts 将call.initiated、call.answered、call.bridged、call.transcription、call.hangup、call.dtmf.received等事件归一化为call.initiated/call.active/call.speech/call.ended/call.dtmf等内部事件类型并将 Telnyx 的hangup_cause如originator_cancel、call_rejected、machine_detected映射为统一的结束原因。安装与启用在 OpenClaw 中安装插件并重启 Gatewayopenclaw plugins install openclaw/voice-call安装后必须重启 Gateway插件才会在启动时加载插件的激活方式定义在 openclaw.plugin.jsononStartup: true、onCommands: [voicecall]并注册了voicecall命令与voice_call工具契约。本地开发安装从源码检出目录进行本地安装调试PLUGIN_HOME~/.openclaw/extensions mkdir -p $PLUGIN_HOME cp -R local-plugin-checkout $PLUGIN_HOME/voice-call cd $PLUGIN_HOME/voice-call pnpm install本地开发时建议使用provider: mock不产生任何网络调用配合后文的 Mock Webhook 驱动方式验证完整呼叫生命周期。配置详解插件配置放在plugins.entries.voice-call.config下同时还需设置plugins.entries.voice-call.enabled: true启用插件。完整配置示例JSON5{ enabled: true, provider: twilio, // or telnyx | plivo | mock fromNumber: 15550001234, toNumber: 15550005678, sessionScope: per-phone, // or per-call | main twilio: { accountSid: ACxxxxxxxx, authToken: your_token, // 非 US 区域可选region: ie1 | au1 }, telnyx: { apiKey: KEYxxxx, connectionId: CONNxxxx, // Telnyx webhook public key来自 Telnyx Mission Control PortalBase64 字符串 // 也可通过环境变量 TELNYX_PUBLIC_KEY 设置 publicKey: ..., }, plivo: { authId: MAxxxxxxxxxxxxxxxxxxxx, authToken: your_token, }, // Webhook 服务 serve: { port: 3334, bind: 127.0.0.1, path: /voice/webhook, }, // 公网暴露三选一 // publicUrl: https://example.ngrok.app/voice/webhook, // tunnel: { provider: ngrok }, // tailscale: { mode: funnel, port: 8443, path: /voice/webhook } outbound: { defaultMode: notify, // or conversation notifyHangupDelaySec: 3, }, // 可选响应 Agent workspace默认 main agentId: main, // 实时语音Realtime Voice realtime: { enabled: false, // 可选缺省时使用 autoSelectOrder 注册顺序第一个实时语音 Provider provider: realtime-voice-provider-id, streamPath: /voice/stream/realtime, instructions: ..., // 缺省使用内置实时指令 toolPolicy: safe-read-only, // or owner | none consultPolicy: auto, // or substantive | always providers: { realtime-voice-provider-id: { // provider-owned options }, }, }, // 经典流式转写仅 Twilio与 realtime 互斥 streaming: { enabled: true, provider: realtime-transcription-provider-id, streamPath: /voice/stream, providers: { realtime-transcription-provider-id: { // provider-owned options }, }, preStartTimeoutMs: 5000, maxPendingConnections: 32, maxPendingConnectionsPerIp: 4, maxConnections: 128, }, }核心参数说明以下参数及默认值均由 src/config.ts 中的 Zod Schema 定义并校验参数说明默认值provider活动 Providertwilio/telnyx/plivo/mock无必填fromNumber/toNumber呼出号码 / 默认被叫号码E.164 格式^\[1-9]\d{1,14}$见 config.ts无inboundPolicy来电策略disabled拒绝全部来电/allowlist仅白名单/pairing配对/open放行全部危险disabledconfig.tsallowFrom来电白名单号码数组E.164[]inboundGreeting来电问候语无numbers按被叫号码E.164 键路由的入站覆盖配置可覆盖inboundGreeting、tts、agentId、responseModel、responseSystemPrompt、responseTimeoutMs{}outbound.defaultMode外呼模式notify播报后自动挂断/conversation保持通话notifyconfig.tsoutbound.notifyHangupDelaySecnotify 模式下 TTS 播报后等待几秒再挂断3config.tsmaxDurationSeconds单次呼叫最大时长秒300config.tsstaleCallReaperSeconds呼叫最大存活时长超过后由清理器回收0 表示关闭用于兜底未接通的悬挂呼叫120config.tssilenceTimeoutMs静音检测判定说话结束超时800config.tstranscriptTimeoutMs用户语音转写超时180000config.tsringTimeoutMs外呼振铃超时30000config.tsmaxConcurrentCalls最大并发呼叫数1config.tsserve.port/serve.bind/serve.pathWebhook 服务监听端口 / 绑定地址 / 路径3334/127.0.0.1//voice/webhookconfig.tsagentId语音响应与会话存储归属的 Agent多 Agent 场景下显式指定缺省取唯一配置的 AgentsessionScope会话作用域per-phone/per-call/mainper-phoneconfig.tsresponseModel可选语音回复使用的模型覆盖缺省使用运行时默认模型responseSystemPrompt可选语音回复 System Prompt 覆盖无responseTimeoutMs语音回复生成超时ms30000config.tsskipSignatureVerification跳过 Webhook 签名校验仅限开发生产环境切勿开启falsepublicUrl公网 Webhook URL 覆盖设置后绕过 tunnel 自动探测无store呼叫记录存储路径默认存储目录下的calls.jsonl环境变量兜底resolveVoiceCallConfigconfig.ts在配置缺失时会自动读取环境变量敏感凭据优先走环境变量更安全TelnyxTELNYX_API_KEY、TELNYX_CONNECTION_ID、TELNYX_PUBLIC_KEYTwilioTWILIO_FROM_NUMBER、TWILIO_ACCOUNT_SID、TWILIO_AUTH_TOKENPlivoPLIVO_AUTH_ID、PLIVO_AUTH_TOKENTunnelNGROK_AUTHTOKEN、NGROK_DOMAIN各 Provider 的最低配置要求validateProviderConfigconfig.ts会在启动与 CLI 检查时校验配置完整性TwiliofromNumbertwilio.accountSidtwilio.authToken凭据也可来自环境变量TelnyxfromNumbertelnyx.apiKeytelnyx.connectionId且除非skipSignatureVerification为 true否则必须提供telnyx.publicKey或TELNYX_PUBLIC_KEYPlivofromNumberplivo.authIdplivo.authTokenMock无需任何凭据本地无网络开发。组合约束与旧配置迁移streaming.enabled: true时 Provider 必须是twilio经典流式转写依赖 Twilio Media Streamsrealtime.enabled: true时 Provider 必须是twilio/telnyx/mockrealtime.enabled与streaming.enabled不能同时为 truerealtime.enabled: true时inboundPolicy不能是disabled实时对话需要能接听来电。运行时会话仅接受规范配置。若旧配置文件仍使用provider: log、twilio.from或旧版streaming.*OpenAI 密钥字段执行openclaw doctor --fix即可自动改写为规范配置。插件的doctorContract见 openclaw.plugin.json还声明了stateMigrations可将旧的voice-call-calls-jsonl状态迁移到插件状态存储。Webhook 公网暴露Twilio / Telnyx / Plivo 都要求 Webhook公网可达。插件内置了三级暴露方案三选一即可publicUrl直接声明公网地址例如https://example.ngrok.app/voice/webhooktunnel.provider: ngrok由插件拉起 ngrok 隧道可选ngrokAuthToken、ngrokDomaintailscaletailscale.mode: serve仅 tailnet 内网可达或funnel公网 HTTPS配合tailscale.port与tailscale.path。关于 Tailscale 端口的限制tailscale.port默认443同时承载旧版tailscale.mode与统一 Tunnel Provider 对外的 HTTPS 端口Funnel 仅支持443、8443、10000Serve 支持任意合法 TCP 端口该约束同时以 Zodrefine强制在 config.ts 中。反向代理与 Webhook 安全配置webhookSecurity控制反向代理场景下的 URL 重建与请求信任webhookSecurity: { allowedHosts: [example.ngrok.app], // 仅接受这些主机名防 Host 头注入 trustForwardingHeaders: false, // 是否显式信任 X-Forwarded-* 头 trustedProxyIPs: [10.0.0.1], // 仅在来源 IP 命中时信任转发头 }底层实现src/webhook-security.ts按优先级从X-Forwarded-Proto/Host、X-Original-Host、Ngrok-Forwarded-Host、Host头重建 Twilio 实际用于签名的公网 URL除非配置了allowedHosts白名单或显式trustForwardingHeaders: true否则转发头一律不被信任从而阻断 Host 头注入攻击。用 CLI 管理 Tailscale 暴露openclaw voicecall expose命令src/cli.ts可动态开启 / 关闭 Tailscale serve/funnel并自动把实时语音 / 流式转写的 WebSocket 路径一并暴露openclaw voicecall expose --mode funnel # 开启公网 funnel openclaw voicecall expose --mode serve # 仅 tailnet 内网 openclaw voicecall expose --mode off # 关闭全部暴露路由会话作用域per-phone / per-call / mainsessionScope决定语音对话的会话记忆归属config.tsper-phone默认以agent:agentId:voice:phone为会话键同一来电号码跨呼叫保留上下文记忆适合客服、个人助理等需要记住老客户的场景per-call以agent:agentId:voice:call:callId为键每次呼叫独立起止适合前台接待、预订、IVR、电话转接bridge等要求每通电话全新开始的流程main共享配置 Agent 的主会话agent:agentId:main当核心配置session.scope为global时则为global。注意自定义的核心session.mainKey会被忽略。呼叫模式notify 与 conversation外呼有两种模式CallModeSchema见 config.tsnotify单向通知。接通后播报消息等待notifyHangupDelaySec默认 3 秒后自动挂断conversation保持通话Agent 与来电者你来我往直到显式挂断或超时。行为细节摘自 extensions/voice-call/README.md Notes外呼 conversation 模式仅在初始问候语正在播报期间抑制 barge-in抢话打断播报结束后立即恢复正常的打断能力Twilio 媒体流Media Streams激活期间播放不会回退到 TwiMLSay流式 TTS 失败会直接导致本次播放请求失败而不是静默降级保证音频时序一致。实时语音与流式转写插件支持两种实时形态配置互斥Realtime Voice实时语音对话realtime.enabled: true启用端到端实时语音语音进、语音出适用于低延迟自然对话。关键子配置config.tsrealtime.provider实时语音 Provider ID缺省时按注册顺序自动选择第一个realtime.streamPath本地 WebSocket 路由缺省按serve.path推导为serve-path/stream/realtimeconfig.tsrealtime.instructions传给实时 Provider 的系统指令缺省使用内置默认实时指令realtime.toolPolicy共享的openclaw_agent_consult工具策略safe-read-only/owner/none默认safe-read-onlyrealtime.consultPolicy何时应触发 Agent 咨询auto/substantive/always默认autorealtime.consultThinkingLevel可选覆盖实时openclaw_agent_consult调用背后常规 Agent 运行的思考级别off/minimal/low/medium/high/xhigh/adaptive/max/ultrarealtime.consultFastMode可选为实时 consult 调用切换快速模式realtime.fastContext在完整 consult Agent 之前先做有界的记忆 / 会话检索enabled默认 falsetimeoutMs默认 800maxResults默认 3sources默认[memory, sessions]fallbackToConsult默认 falserealtime.agentContext把紧凑的 Agent 身份与 workspace 上下文胶囊注入实时语音指令默认注入SOUL.md、IDENTITY.md、USER.md受maxChars上限约束realtime.providers.id按 Provider ID 存放厂商自有选项。经典流式转写Media Streamsstreaming.enabled: true仅限 Twilio启用 Twilio Media Streams 实时转写把来电语音流送入注册的实时转写 Provider。并发与抗滥用参数config.tsstreaming.preStartTimeoutMs默认5000未认证的媒体流 Socket 若未在期限内收到合法start帧即关闭防止认证前空闲连接占用攻击streaming.maxPendingConnections默认32并发 pendingpre-start媒体流 Socket 上限streaming.maxPendingConnectionsPerIp默认4单来源 IP 的 pending 连接上限streaming.maxConnections默认128全部开放媒体流 Socket 硬上限。两种形态都遵循通用的实时 Provider 选择机制配置streaming.provider/realtime.provider厂商自有选项放在providers.id下。TTS通话中的语音合成通话中的流式语音播报复用核心tts配置voice-call下可用tts字段做深合并覆盖Microsoft TTS 在通话场景会被忽略见 openclaw.plugin.json 的提示。tts子配置支持 OpenAI / ElevenLabs / Microsoft / Edge 等 Provider 的参数音色、语速、音量、模型、文本归一化等完整 Schema 见 openclaw.plugin.json。例如 ElevenLabs 的speakerVoiceId、voiceSettings.stability、similarityBoost、applyTextNormalization或 OpenAI 的speakerVoice、speed、instructions。若responseModel未设置语音回复使用运行时默认模型。Stale Call Reaper悬挂呼叫回收staleCallReaperSeconds默认 1200 关闭用于兜底那些永远等不到 Provider 回调的悬挂呼叫例如本地 Mock 呼叫发起后没有任何 Webhook 驱动。当呼叫存活超过该阈值时清理器自动将其回收结束。底层实现与测试见 src/webhook/stale-call-reaper.ts 及其传输层测试stale-call-reaper.transport.test.ts生产环境的推荐区间可参考插件文档对应章节。CLI 命令插件注册了voicecall命令族注册入口见 src/cli.ts。常用命令# 拨打电话conversation 模式保持通话 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 # 查询状态全部或指定呼叫支持 --json openclaw voicecall status --json openclaw voicecall status --call-id id # 跟随/查看呼叫日志 openclaw voicecall tail # 开启 Tailscale funnel 公网暴露 openclaw voicecall expose --mode funnel除上述之外还有几个实用子命令openclaw voicecall setup一键体检输出插件启用、Provider 选择、凭据完整性、Webhook 暴露、实时/流式模式互斥、响应 Agent 归属等检查项--json输出机器可读结果实现见 src/cli.tsopenclaw voicecall startcall的别名openclaw voicecall smoke就绪性检查加--to phone --yes可真正拨打一通测试电话默认消息 OpenClaw voice call smoke test.openclaw voicecall dtmf --call-id id --digits digits向活动呼叫发送 DTMF 按键用于 IVR 菜单导航。Agent 工具voice_call插件向 Agent 暴露工具voice_call契约声明于 openclaw.plugin.json支持以下 ActionAction参数说明initiate_callmessage,to?,mode?发起外呼并播报消息continue_callcallId,message播报并等待用户回复speak_to_usercallId,message播报消息不等待回复end_callcallId结束呼叫get_statuscallId查询呼叫状态配套的 Agent 技能定义在 skills/voice-call/SKILL.mdAgent 在需要拨打电话时会被引导使用该工具。Gateway RPC集成方或同一 Gateway 上的其他组件可通过 Gateway RPC 远程驱动语音通话voicecall.initiateto?,message,mode?voicecall.continuecallId,messagevoicecall.speakcallId,messagevoicecall.endcallIdvoicecall.statuscallIdCLI 子命令在 Gateway 可用时优先走 RPC并在方法不可用时回退到进程内 Manager见 src/cli-gateway-call.ts 与 src/cli.ts 的双通道降级逻辑。安全机制插件在 Webhook 与语音输出两个层面内置了安全防护详见 src/webhook-security.ts1. 三方签名验证TwilioHMAC-SHA1 校验。把请求 URL 与排序后的 POST 参数拼接后以 Auth Token 计算 HMAC-SHA1 并与X-Twilio-Signature做常量时间比较webhook-security.ts针对 ngrok / 反代导致的端口与 Host 差异会尝试一组确定性的 URL 变体再校验TelnyxEd25519 验签。校验telnyx-signature-ed25519与telnyx-timestamptimestamp|payload签名默认容忍 5 分钟时钟偏差webhook-security.tstelnyx.publicKey支持 PEM、原始 32 字节 Base64 或 Base64 DER 三种编码导入Plivo优先 V3HMAC-SHA256 nonce回退 V2HMAC-SHA256base URL noncewebhook-security.ts。2. 重放保护Twilio 与 Plivo 的 Webhook 具备重放保护合法的重复回调会被安全忽略Telnyx 通过timestamp|signature|body组合键去重Twilio 每轮语音speech turn携带独立的每轮 token过期的 / 被重放的旧回调无法完成更新的语音轮次。3. 语音输出约束spoken JSON 合约语音自动回复强制遵循 spoken JSON 合约src/response-generator.ts模型只返回形如{spoken:...}的 JSON播放前会过滤掉 reasoning / 思维链等元输出tryParseSpokenJson与isLikelyMetaReasoningParagraph见 response-generator.ts保证打给用户的永远是干净、可朗读的话术。同时通话开场上下文被标记为不可信对话数据绝不作为系统 / 开发者指令注入。4. 其他行为保障Twilio 流式断连自动结束呼叫带有一个短宽限窗口grace window快速重连不会误杀通话实现见 src/webhook/stream-disconnect-grace.ts语音响应复用与消息通道相同的 Agent 基础设施具备完整工具调用能力response-generator.ts并支持会话记忆持久化。Mock Provider无网络的本地闭环开发provider: mock是本地开发利器initiateCall直接返回mock-callId而不发起任何网络请求src/providers/mock.ts。开发者通过向 Webhook 端点 POST JSON 来驱动事件# 驱动单事件 curl -X POST http://127.0.0.1:3334/voice/webhook \ -H Content-Type: application/json \ -d {event: {type: call.answered, callId: ...}} # 或批量驱动事件 curl -X POST http://127.0.0.1:3334/voice/webhook \ -H Content-Type: application/json \ -d {events: [{type: call.initiated, callId: ...}, {type: call.answered, callId: ...}]}支持的事件类型包括call.initiated/call.ringing/call.answered/call.active/call.speaking/call.assistant-speech/call.speech/call.silence/call.dtmf/call.ended/call.errormock.ts足以在不消耗任何电信资费的前提下完整验证从拨号、接听、语音、挂断到清理器的全链路。结语openclaw/voice-call将电信语音能力与 OpenClaw Agent 运行时深度整合统一的 Provider 抽象让 Twilio / Telnyx / Plivo 无缝切换notify/conversation两种模式覆盖通知与对话两类场景Realtime Voice 与 Media Streams 提供从流式转写到端到端实时对话的演进路径而签名验证、重放防护、spoken JSON 合约与悬挂呼叫回收则保证了生产环境的可靠与安全。无论你是要搭建一个会打电话的提醒 Agent、一个带记忆的客服热线还是一个能实时对话的语音助理都可以从本文的安装、配置与命令入手结合 extensions/voice-call 目录下的源码与测试用例逐步打磨出适合自己业务的电话能力。【免费下载链接】openclawThe AI that really does things. Any OS. Any Platform. The lobster way. 项目地址: https://gitcode.com/GitHub_Trending/cl/openclaw创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表