4 minute read

一、插件概述

Voice Call 是 OpenClaw 的一个核心插件,允许用户通过 AI 助手发起和接收语音通话。它支持多种电话服务提供商(Twilio、Telnyx、Plivo),并提供两种主要通话模式:通知模式(Notify)和对话模式(Conversation)。

二、插件安装和配置

1. 安装方式

# 从 npm 安装(推荐)
openclaw plugins install @openclaw/voice-call

# 从本地开发(开发模式)
openclaw plugins install ./extensions/voice-call
cd ./extensions/voice-call && pnpm install

安装后需要重启 Gateway 网关。

2. 配置

~/.openclaw/config.json 文件中配置插件:

{
  plugins: {
    entries: {
      "voice-call": {
        enabled: true,
        config: {
          provider: "twilio", //  "telnyx" | "plivo" | "mock"
          fromNumber: "+15550001234",
          toNumber: "+15550005678",
          
          // 提供商特定配置
          twilio: {
            accountSid: "ACxxxxxxxx",
            authToken: "...",
          },
          
          // Webhook 服务器配置
          serve: {
            port: 3334,
            path: "/voice/webhook",
          },
          
          // 公开访问配置(选择一种)
          publicUrl: "https://example.ngrok.app/voice/webhook",
          // 或使用隧道
          // tunnel: { provider: "ngrok" },
          // 或使用 Tailscale
          // tailscale: { mode: "funnel", path: "/voice/webhook" }
          
          // 通话模式配置
          outbound: {
            defaultMode: "notify", // notify | conversation
          },
          
          // TTS 配置(可选,覆盖全局配置)
          tts: {
            provider: "elevenlabs",
            elevenlabs: {
              voiceId: "pMsXgVXv3BLzUgSXRplE",
              modelId: "eleven_multilingual_v2",
            },
          },
        },
      },
    },
  },
}

三、通话工作流程

1. 插件初始化流程(Runtime Creation)

createVoiceCallRuntime() [runtime.ts]
├─ 解析和验证配置
├─ 选择并创建提供商实例(TwilioProvider/TelnyxProvider/PlivoProvider/MockProvider)
├─ 创建 CallManager(呼叫管理器)
├─ 创建 VoiceCallWebhookServer(Webhook 服务器)
├─ 启动 Webhook 服务器
├─ 设置隧道/公开访问(如果需要)
├─ 配置 TTS 提供商
├─ 初始化 CallManager 与提供商
└─ 返回运行时实例

2. 发起呼叫流程(Initiate Call)

CallManager.initiateCall() [manager.ts]
├─ 验证配置和状态
├─ 创建 CallRecord(呼叫记录)并保存到存储
├─ 调用提供商的 initiateCall() 方法
│  ├─ Twilio:使用 Twilio API 发起呼叫,可能包含内联 TwiML
│  ├─ Telnyx:使用 Telnyx API 发起呼叫
│  ├─ Plivo:使用 Plivo API 发起呼叫
│  └─ Mock:模拟呼叫(用于开发)
├─ 保存提供商返回的呼叫 ID
└─ 返回 CallId 给用户

[manager/outbound.ts]
├─ 生成 CallRecord
├─ 为通知模式生成 TwiML(如果有初始消息)
├─ 调用 provider.initiateCall()
├─ 保存呼叫状态
└─ 持久化到存储

3. 通知模式流程(Notify Mode)

通知模式用于向用户发送简短的语音通知,不需要用户回应。

发起呼叫(通知模式)
├─ 生成包含 <Say> 标签的 TwiML
├─ 提供商执行 TwiML(播放文本到语音)
├─ 等待配置的延迟时间(默认 2 秒)
├─ 自动挂断
└─ 结束呼叫

[manager/outbound.ts:161-274]
├─ 识别模式为通知模式
├─ 生成 TwiML 包含消息
├─ 使用 Twilio 的 <Say> 或 Plivo 的类似功能
├─ 通话结束后自动挂断

4. 对话模式流程(Conversation Mode)

对话模式允许用户与 AI 助手进行多轮对话,支持语音识别和合成。

发起呼叫(对话模式)
├─ 等待用户接听
├─ 播放初始消息(如果有)
├─ 切换到监听状态
├─ 识别用户语音(STT)
├─ 处理用户输入(AI 响应)
├─ 播放 AI 响应(TTS)
├─ 循环:监听 → 识别 → 处理 → 响应
└─ 结束呼叫

[manager/outbound.ts:229-380]
├─ speakInitialMessage():播放初始消息
├─ continueCall():继续对话
│  ├─ speak():播放消息
│  ├─ startListening():开始监听
│  ├─ waitForFinalTranscript():等待最终转录
│  └─ stopListening():停止监听
└─ endCall():结束呼叫

5. 入站呼叫流程(Inbound Calls)

入站呼叫
├─ 提供商 Webhook 接收呼叫事件
├─ 验证呼叫来源(白名单检查)
├─ 播放欢迎消息
├─ 进入对话模式
├─ 处理用户输入和 AI 响应
└─ 结束呼叫

[webhook.ts]
├─ 接收 POST 请求
├─ 验证签名
├─ 规范化事件
├─ CallManager.processEvent()
├─ 路由到相应的事件处理逻辑
└─ 生成 TwiML 响应

[manager/events.ts]
├─ 处理 call.ringing 事件
├─ 处理 call.answered 事件
├─ 处理 call.hangup 事件
└─ 其他事件处理

6. 核心组件交互

┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│   User/CLI      │────▶│  CallManager    │────▶│  Voice Provider │
└─────────────────┘     └─────────────────┘     └─────────────────┘
         ▲                      ▲                       ▲
         │                      │                       │
         │                      │                       │
         ▼                      ▼                       ▼
┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│  Gateway RPC    │     │  Webhook Server │     │   TTS/STT       │
└─────────────────┘     └─────────────────┘     └─────────────────┘
         ▲                      ▲                       ▲
         │                      │                       │
         │                      │                       │
         ▼                      ▼                       ▼
┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│   AI Agent      │     │  Call Store     │     │  Media Stream   │
└─────────────────┘     └─────────────────┘     └─────────────────┘

四、使用方式

1. CLI 命令

# 发起呼叫
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

2. AI 助手工具

在 OpenClaw 的 AI 助手中,您可以使用 voice_call 工具:

{
  "tool": "voice_call",
  "action": "initiate_call",
  "message": "Hello, this is a test call",
  "to": "+15555550123",
  "mode": "conversation"
}

五、关键技术细节

1. 媒体流处理

对于 Twilio 提供商,支持实时媒体流(Media Streaming),允许更高级的音频处理:

// [runtime.ts:163-190]
if (provider.name === "twilio" && config.streaming?.enabled) {
  const ttsProvider = createTelephonyTtsProvider({...});
  twilioProvider.setTTSProvider(ttsProvider);
  
  const mediaHandler = webhookServer.getMediaStreamHandler();
  twilioProvider.setMediaStreamHandler(mediaHandler);
}

2. 状态管理

CallManager 负责管理所有呼叫状态:

// [manager.ts]
export class CallManager {
  private activeCalls = new Map<CallId, CallRecord>();
  private providerCallIdMap = new Map<string, CallId>();
  private processedEventIds = new Set<string>();
  // ...
}

3. 事件处理

Webhook 服务器接收并处理提供商的事件:

// [webhook.ts]
export class VoiceCallWebhookServer {
  async handlePost(request: Request): Promise<Response> {
    // 验证签名
    // 规范化事件
    // 处理事件
    this.manager.processEvent(event);
    // 生成响应
  }
}

六、总结

Voice Call 插件为 OpenClaw 提供了强大的语音通话功能,支持多种提供商和通话模式。它的设计遵循了 OpenClaw 的插件架构,运行在 Gateway 进程内部,并通过 Webhook 与电话服务提供商通信。核心组件包括 CallManager(呼叫管理)、VoiceCallWebhookServer(事件处理)和各种 Provider(提供商实现),它们协同工作以实现完整的语音通话流程。 让我检查一下是否还有其他相关的文档或代码需要查看,以确保我的回答是完整和准确的。

Twilio Telnyx Plivo

这三家都是全球领先的云通信服务提供商(CPaaS - Communications Platform as a Service)。

简单来说,它们为开发者提供 API(接口),让企业能够通过代码实现拨打电话、发送短信、语音验证码等功能。

它们的关系与区别:

服务商 特点
Twilio 行业老大。功能最全、文档最完善,是很多公司的首选,但价格通常也是最贵的。
Plivo 性价比之选。直接竞争对手,通常提供比 Twilio 更便宜的语音和短信资费。
Telnyx 自建网络。它们拥有自己的全球私有 IP 网络,延迟更低,在号码资源和通话质量稳定性上很有优势。

云通信商(CPaaS)是如何和电话系统连接的?

要理解 CPaaS(如 Twilio)是如何把你的网页/代码和全球几十亿部电话连在一起的,我们需要看一看它们在背后搭建的“数字桥梁”。

简单来说,CPaaS 充当了一个翻译官路由枢纽的角色。


1. 技术层面的“三层架构”

CPaaS 的连接过程通常分为三个层级,每一层都在做不同的转换:

第一层:应用接口层 (REST API / Webhooks)

  • 你的动作: 你的 AI 程序发出一个指令(比如:POST /Calls)。
  • CPaaS 的工作: 它接收你的 HTTP 请求(互联网协议),验证身份,并理解你的意图(拨给谁、播放什么语音)。

第二层:信令与媒体控制层 (SIP 协议)

  • 核心转换: 这是最关键的一步。CPaaS 会把你的互联网指令转换成 SIP (Session Initiation Protocol)
  • 作用: SIP 是现代 VoIP(网络电话)的标准语言。它负责“呼叫”动作——让对方的电话响铃、建立连接、挂断。
  • 媒体流: 你的语音(或 AI 生成的音频)被切成无数个小数据包(RTP 包),通过网络实时传输。

第三层:物理互联层 (PSTN 网关)

  • 落地: CPaaS 在全球各地的机房里,通过数字中继线物理光纤直接连接到传统运营商(如中国联通、AT&T、沃达丰)的交换机上。
  • 进入 PSTN: 这一步将数字信号转回传统电话网(PSTN)。这样,远在千里之外一部没联网的老式座机也能收到信号并响铃。

2. 核心组件:它是靠什么“接通”的?

为了保证通话不卡顿、能拨通,CPaaS 背后有几样核心武器:

  1. VoIP 网关 (Gateways): 就像翻译机,把互联网的 0 和 1 转换成电话线的电信号。
  2. 软交换 (Softswitches): 智能导航员。如果你拨打一个英国号码,CPaaS 会自动寻找离英国最近的节点出局,以降低延迟。
  3. 号码池 (DID): CPaaS 拥有数以百万计的真实电话号码(DID),当你拨号时,它会给你的呼叫分配一个“主叫号码”,让对方手机上显示出具体的数字。

3. 一个通话的完整生命周期(以 AI 拨号为例)

  1. 发起: 你的 AI 系统通过 API 告诉 Twilio:“拨打 138xxxx,并朗读这段文本”。
  2. 转换: Twilio 的服务器把文本转成语音文件,并启动 SIP 邀请
  3. 路由: Twilio 发现这是中国号码,通过私有光纤将信号传给中国当地的合作伙伴(运营商)。
  4. 振铃: 目标手机收到基站信号,开始响铃。
  5. 通话: 对方接听后,语音通过 WebRTCRTP 协议在你的服务器和手机之间实时双向传输。

4. 为什么不直接连运营商,而非要用 CPaaS?

如果没有 CPaaS,你想做个自动拨号系统,你得:

  • 跑去移动/电信机房拉线。
  • 自己买几十万的硬件交换机。
  • 自己写极其复杂的底层通信协议(C++ / C 语言级别)。

CPaaS 的价值在于: 它把这些脏活累活都干了,只给你留了一个简单的网址 (API Endpoint)

云通信服务提供商和传统通信服务提供商的区别

简单来说,“云通信” (CPaaS)“传统通信” 的区别,就像是“刷卡消费”“开一家银行”的区别。

以下是它们核心差异的深度对比:

1. 接入方式:代码 vs. 硬件

  • 云通信 (Twilio/Plivo/Telnyx): 它是基于 API 的。开发者只需要写几行代码(调用接口),就能实现拨打电话的功能。不需要买交换机,不需要拉电话线,一切都在云端完成。
  • 传统通信 (中国电信/AT&T/移动): 传统方式通常需要物理接入。比如企业需要购买大量的网关设备、交换机(PBX),并与运营商签署复杂的物理链路协议。

2. 灵活性与扩展性

  • 云通信: 极其灵活。你今天想拨 1 个电话,明天想拨 10,000 个,云平台会自动帮你扩容。按需付费,用多少花多少。
  • 传统通信: 扩展缓慢。如果你发现线路不够用了,可能需要增加物理板卡或申请新的中继线(E1/数字电路),流程长且有固定成本。

3. 功能集成度

  • 云通信: 它是“乐高式”的。你可以轻松地把电话功能和你的 CRM(如 Salesforce)AI 机器人数据库 串联起来。
  • 传统通信: 往往是闭环的。如果你想在传统电话线基础上加一个“AI 自动语音转文字”功能,通常需要额外购买极其昂贵的第三方软件和硬件集成包。

4. 核心差异对比表

特性 云通信 (CPaaS) 传统通信 (Telco/Carrier)
主要客户 软件开发者、互联网企业 传统大企业、呼叫中心
部署时间 几分钟(拿到 API Key 即可) 几周甚至几个月
收费模式 按分钟/按条计费 (Pay-as-you-go) 月租 + 固定套餐 + 硬件维护费
技术门槛 需要懂编程 (Python/JS/Java) 需要懂通信工程 (硬件维护)
全球覆盖 一个账号即可全球拨号 通常受地域限制,跨国业务极难

总结

  • 传统通信商是“基建狂魔”,他们负责在地底下埋光缆、盖基站。
  • 云通信商(如你图中的三家)是“超级中间商”,他们把底层复杂的通信能力包装成简单的软件接口卖给你。

如果你是想开发一个 AI 自动拨号系统,选择“云通信”是唯一的方案,因为 AI 必须通过代码来控制电话的接听与挂断。

参考资料

Updated: