Voice Call (plugin)

Plugin gọi điện thoại cho OpenClaw. Hỗ trợ thông báo qua cuộc gọi đi và hội thoại nhiều lượt với chính sách cuộc gọi đến.

Các provider hiện tại:

  • twilio (Programmable Voice + Media Streams)
  • telnyx (Call Control v2)
  • plivo (Voice API + XML transfer + GetInput speech)
  • mock (dev/không cần mạng)

Cách hoạt động nhanh:

  • Cài đặt plugin
  • Khởi động lại Gateway
  • Cấu hình trong plugins.entries.voice-call.config
  • Dùng lệnh openclaw voicecall ... hoặc tool voice_call

Chạy ở đâu (local hay remote)

Plugin Voice Call chạy bên trong tiến trình Gateway.

Nếu các bạn dùng Gateway từ xa, hãy cài đặt/cấu hình plugin trên máy đang chạy Gateway, sau đó khởi động lại Gateway để load plugin nhé.

Cài đặt

Cách A: cài từ npm (khuyên dùng)

openclaw plugins install @openclaw/voice-call

Khởi động lại Gateway sau khi cài xong.

Cách B: cài từ thư mục local (dev, không copy)

openclaw plugins install ./extensions/voice-call
cd ./extensions/voice-call && pnpm install

Khởi động lại Gateway sau khi cài xong.

Cấu hình

Đặt config trong plugins.entries.voice-call.config:

{
  plugins: {
    entries: {
      "voice-call": {
        enabled: true,
        config: {
          provider: "twilio", // hoặc "telnyx" | "plivo" | "mock"
          fromNumber: "+15550001234",
          toNumber: "+15550005678",

          twilio: {
            accountSid: "ACxxxxxxxx",
            authToken: "...",
          },

          plivo: {
            authId: "MAxxxxxxxxxxxxxxxxxxxx",
            authToken: "...",
          },

          // Webhook server
          serve: {
            port: 3334,
            path: "/voice/webhook",
          },

          // Public exposure (chọn một)
          // 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",
          },
        },
      },
    },
  },
}

Lưu ý:

  • Twilio/Telnyx cần một webhook URL có thể truy cập công khai.
  • Plivo cần một webhook URL có thể truy cập công khai.
  • mock là provider dev local (không gọi mạng).
  • skipSignatureVerification chỉ dùng để test local thôi.
  • Nếu dùng ngrok free tier, đặt publicUrl thành URL ngrok chính xác; signature verification luôn được bật.
  • tunnel.allowNgrokFreeTierLoopbackBypass: true cho phép Twilio webhook với signature không hợp lệ chỉ khi tunnel.provider="ngrok"serve.bind là loopback (ngrok local agent). Chỉ dùng cho dev local.
  • URL ngrok free tier có thể thay đổi hoặc thêm hành vi interstitial; nếu publicUrl thay đổi, Twilio signature sẽ fail. Với production, mình khuyên dùng domain ổn định hoặc Tailscale funnel.

TTS cho cuộc gọi

Voice Call sử dụng cấu hình messages.tts cốt lõi (OpenAI hoặc ElevenLabs) để streaming giọng nói trong cuộc gọi. Các bạn có thể override nó trong config plugin với cùng cấu trúc — nó sẽ deep-merge với messages.tts.

{
  tts: {
    provider: "elevenlabs",
    elevenlabs: {
      voiceId: "pMsXgVXv3BLzUgSXRplE",
      modelId: "eleven_multilingual_v2",
    },
  },
}

Lưu ý:

  • Edge TTS bị bỏ qua cho cuộc gọi thoại (audio điện thoại cần PCM; output của Edge không ổn định).
  • TTS cốt lõi được dùng khi Twilio media streaming được bật; nếu không cuộc gọi sẽ fallback về giọng nói native của provider.

Thêm ví dụ

Chỉ dùng TTS cốt lõi (không override):

{
  messages: {
    tts: {
      provider: "openai",
      openai: { voice: "alloy" },
    },
  },
}

Override sang ElevenLabs chỉ cho cuộc gọi (giữ default cốt lõi cho chỗ khác):

{
  plugins: {
    entries: {
      "voice-call": {
        config: {
          tts: {
            provider: "elevenlabs",
            elevenlabs: {
              apiKey: "elevenlabs_key",
              voiceId: "pMsXgVXv3BLzUgSXRplE",
              modelId: "eleven_multilingual_v2",
            },
          },
        },
      },
    },
  },
}

Override chỉ model OpenAI cho cuộc gọi (ví dụ deep-merge):

{
  plugins: {
    entries: {
      "voice-call": {
        config: {
          tts: {
            openai: {
              model: "gpt-4o-mini-tts",
              voice: "marin",
            },
          },
        },
      },
    },
  },
}

Cuộc gọi đến

Inbound policy mặc định là disabled. Để bật cuộc gọi đến, đặt:

{
  inboundPolicy: "allowlist",
  allowFrom: ["+15550001234"],
  inboundGreeting: "Hello! How can I help?",
}

Auto-response sử dụng hệ thống agent. Điều chỉnh với:

  • responseModel
  • responseSystemPrompt
  • responseTimeoutMs

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
openclaw voicecall expose --mode funnel

Agent tool

Tên tool: voice_call

Các action:

  • initiate_call (message, to?, mode?)
  • continue_call (callId, message)
  • speak_to_user (callId, message)
  • end_call (callId)
  • get_status (callId)

Repo này có kèm skill doc tương ứng tại skills/voice-call/SKILL.md.

Gateway RPC

  • voicecall.initiate (to?, message, mode?)
  • voicecall.continue (callId, message)
  • voicecall.speak (callId, message)
  • voicecall.end (callId)
  • voicecall.status (callId)