Voice call plugin
기준일: 2026-07-26
공식 기준: Voice call plugin
Voice call plugin 문서는 OpenClaw 공식 문서(plugins/voice-call)를 한국어로 정리한 가이드입니다. Place outbound and accept inbound voice calls via Twilio, Telnyx, or Plivo, with optional realtime voice and streaming transcription 명령·설정 키·코드 예시는 공식 문서를 그대로 보존하며, 해석과 절차 안내는 한국어로 제공합니다. 최종 동작은 설치된 CLI 버전과 공식 원문을 확인하세요.
핵심 요약
Place outbound and accept inbound voice calls via Twilio, Telnyx, or Plivo, with optional realtime voice and streaming transcription
한국어 가이드 범위: plugins/voice-call 경로의 설정·명령·제약·예시를 학습용으로 재구성합니다.
문서 구성
공식 문서의 주요 섹션은 다음과 같습니다.
- 빠른 시작
- 구성
- Config reference
- Session scope
- Realtime voice conversations
- Tool policy
- Agent voice context
- Realtime provider examples
- Streaming transcription
- Streaming provider examples
- TTS for calls
- TTS examples
- Inbound calls
- Per-number routing
- Spoken output contract
- Conversation startup behavior
- Twilio stream disconnect grace
- Stale call reaper
- Webhook security
- CLI
- Agent tool
- Gateway RPC
- 트러블슈팅
- Setup fails webhook exposure
- Provider credentials fail
- Calls start but provider webhooks do not arrive
- Signature verification fails
- Google Meet Twilio joins fail
- Realtime call has no speech
- 관련 문서
상세 내용
본문
Voice calls for OpenClaw via a plugin: outbound notifications, multi-turn conversations, full-duplex realtime voice, streaming transcription, and inbound calls with allowlist policies.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
빠른 시작
Use the bare package to follow the current release tag. Pin an exact version only when you need a reproducible install. Restart the Gateway afterwards so the plugin loads.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
openclaw plugins install @openclaw/voice-call
PLUGIN_SRC=./path/to/local/voice-call-plugin
openclaw plugins install "$PLUGIN_SRC"
cd "$PLUGIN_SRC" && pnpm install
openclaw voicecall setup
openclaw voicecall setup --json
openclaw voicecall smoke
openclaw voicecall smoke --to "+15555550123"
구성
If enabled: true but the selected provider is missing credentials, Gateway startup logs a setup-incomplete warning with the missing keys and skips starting the runtime. Commands, RPC calls, and agent tools still return the exact missing configuration when used.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
{
plugins: {
entries: {
"voice-call": {
enabled: true,
config: {
provider: "twilio", // or "telnyx" | "plivo" | "mock"
fromNumber: "+15550001234", // or TWILIO_FROM_NUMBER for Twilio
toNumber: "+15550005678",
sessionScope: "per-phone", // per-phone | per-call
numbers: {
"+15550009999": {
inboundGreeting: "Silver Fox Cards, how can I help?",
responseSystemPrompt: "You are a concise baseball card specialist.",
tts: {
providers: {
openai: { speakerVoice: "alloy" },
},
},
},
},
twilio: {
accountSid: "ACxxxxxxxx",
authToken: "...",
// region: "ie1", // optional: us1 | ie1 | au1; defaults to us1
},
telnyx: {
apiKey: "...",
connectionId: "...",
// Telnyx webhook public key from the Mission Control Portal
// (Base64; can also be set via TELNYX_PUBLIC_KEY).
publicKey: "...",
},
plivo: {
authId: "MAxxxxxxxxxxxxxxxxxxxx",
authToken: "...",
},
// Webhook server
serve: {
port: 3334,
path: "/voice/webhook",
},
// Webhook security (recommended for tunnels/proxies)
webhookSecurity: {
allowedHosts: ["voice.example.com"],
trustedProxyIPs: ["100.64.0.1"],
},
// Public exposure (pick one)
// publicUrl: "https://example.ngrok.app/voice/webhook",
// tunnel: { provider: "ngrok" },
// tailscale: { mode: "funnel", path: "/voice/webhook" },
outbound: {
defaultMode: "notify", // notify | conversation
},
streaming: { enabled: true /* Twilio only; see Streaming transcription */ },
realtime: { enabled: false /* see Realtime voice conversations */ },
},
},
},
},
}
Config reference
Top-level keys under plugins.entries.voice-call.config not shown above:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
- Twilio, Telnyx, and Plivo all require a publicly reachable webhook URL.
mockis a local dev provider (no network calls).- Telnyx requires
telnyx.publicKey(orTELNYX_PUBLIC_KEY) unlessskipSignatureVerificationis true. skipSignatureVerificationis for local testing only.- On ngrok free tier, set
publicUrlto the exact ngrok URL; signature verification is always enforced. tunnel.allowNgrokFreeTierLoopbackBypass: trueallows Twilio webhooks with invalid signatures only whentunnel.provider="ngrok"andserve.bindis loopback (ngrok local agent). Local dev only.- Ngrok free-tier URLs can change or add interstitial behavior; if
publicUrldrifts, Twilio signatures fail. Production: prefer a stable domain or a Tailscale funnel. streaming.preStartTimeoutMs(default5000) closes sockets that never send a validstartframe.streaming.maxPendingConnections(default32) caps total unauthenticated pre-start sockets.streaming.maxPendingConnectionsPerIp(default4) caps unauthenticated pre-start sockets per source IP.streaming.maxConnections(default128) caps all open media stream sockets (pending + active).provider: "log"→provider: "mock"twilio.from→fromNumberstreaming.sttProvider→streaming.providerstreaming.openaiApiKey→streaming.providers.openai.apiKeystreaming.sttModel→streaming.providers.openai.modelstreaming.silenceDurationMs→streaming.providers.openai.silenceDurationMsstreaming.vadThreshold→streaming.providers.openai.vadThresholdrealtime.agentContext.includeSystemPromptis removed (realtime context now uses the generated agent prompt)
| Key | Default | Notes |
|---|---|---|
enabled |
false |
Master on/off switch. |
inboundPolicy |
"disabled" |
disabled | allowlist | pairing | open. See Inbound calls. |
allowFrom |
[] |
E.164 allowlist for inboundPolicy: "allowlist". |
maxDurationSeconds |
300 |
Hard per-call duration cap, enforced regardless of answered state. |
staleCallReaperSeconds |
120 |
See Stale call reaper. 0 disables it. |
silenceTimeoutMs |
800 |
End-of-speech silence detection for the classic (non-realtime) flow. |
transcriptTimeoutMs |
180000 |
Max wait for a caller transcript before giving up on a turn. |
ringTimeoutMs |
30000 |
Ring timeout for outbound calls. |
maxConcurrentCalls |
1 |
Outbound calls beyond this limit are rejected. |
outbound.notifyHangupDelaySec |
3 |
Seconds to wait after TTS before auto-hangup in notify mode. |
skipSignatureVerification |
false |
Local testing only; never enable in production. |
store |
unset | Overrides the default $OPENCLAW_STATE_DIR/voice-calls path (normally ~/.openclaw/voice-calls). |
agentId |
"main" |
Agent used for response generation and session storage. |
responseModel |
unset | Overrides the default model for classic (non-realtime) responses. |
responseSystemPrompt |
generated | Custom system prompt for classic responses. |
responseTimeoutMs |
30000 |
Timeout for classic response generation (ms). |
Session scope
By default, Voice Call uses sessionScope: "per-phone" so repeat calls from the same caller keep conversation memory. Set sessionScope: "per-call" when each carrier call should start with fresh context, for example reception, booking, IVR, or Google Meet bridge flows where the same phone number may represent different meetings.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
Realtime voice conversations
realtime selects a full-duplex realtime voice provider for live call audio. It is separate from streaming, which only forwards audio to realtime transcription providers.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
realtime.enabledis supported for Twilio and Telnyx.realtime.provideris optional. If unset, Voice Call uses the first registered realtime voice provider.- Bundled realtime voice providers: Google Gemini Live (
google) and OpenAI (openai), registered by their provider plugins. - Provider-owned raw config lives under
realtime.providers.<providerId>. - Voice Call exposes the shared
openclaw_agent_consultrealtime tool by default. The realtime model can call it when the caller asks for deeper reasoning, current information, or normal OpenClaw tools. realtime.consultPolicyoptionally adds guidance for when the realtime model should callopenclaw_agent_consult.realtime.agentContext.enabledis default-off. When enabled, Voice Call injects a bounded agent identity and selected workspace-file capsule into the realtime provider instructions at session setup.realtime.fastContext.enabledis default-off. When enabled, Voice Call first searches indexed memory/session context for the consult question and returns those snippets to the realtime model withinrealtime.fastContext.timeoutMsbefore falling back to the full consult agent only ifrealtime.fastContext.fallbackToConsultis true.- If
realtime.providerpoints at an unregistered provider, or no realtime voice provider is registered at all, Voice Call logs a warning and skips realtime media instead of failing the whole plugin. inboundPolicymust not be"disabled"whenrealtime.enabledis true;validateProviderConfigrejects that combination.- Consult session keys reuse the stored call session when available, then fall back to the configured
sessionScope(per-phoneby default, orper-callfor isolated calls).
Tool policy
realtime.toolPolicy controls the consult run:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
| Policy | Behavior |
|---|---|
safe-read-only |
Expose the consult tool and limit the regular agent to read, web_search, web_fetch, x_search, memory_search, and memory_get. |
owner |
Expose the consult tool and let the regular agent use the normal agent tool policy. |
none |
Do not expose the consult tool. Custom realtime.tools are still passed through to the realtime provider. |
| Policy | Guidance |
|---|---|
auto |
Keep the default prompt and let the provider decide when to call the consult tool. |
substantive |
Answer simple conversational glue directly and consult before facts, memory, tools, or context. |
always |
Consult before every substantive answer. |
Agent voice context
Enable realtime.agentContext when the voice bridge should sound like the configured OpenClaw agent without paying a full agent-consult round trip on ordinary turns. The context capsule is added once when the realtime session is created, so it does not add per-turn latency. Calls to openclaw_agent_consult still run the full OpenClaw agent and should be used for tool work, current information, memory lookups, or workspace state.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
{
plugins: {
entries: {
"voice-call": {
config: {
agentId: "main",
realtime: {
enabled: true,
provider: "google",
toolPolicy: "safe-read-only",
consultPolicy: "substantive",
agentContext: {
enabled: true,
maxChars: 6000,
includeIdentity: true,
includeWorkspaceFiles: true,
files: ["SOUL.md", "IDENTITY.md", "USER.md"],
},
},
},
},
},
},
}
Realtime provider examples
Defaults: API key from realtime.providers.google.apiKey, GEMINI_API_KEY, or GOOGLE_API_KEY; model gemini-3.1-flash-live-preview; voice Kore. sessionResumption and contextWindowCompression default on for longer, reconnectable calls. Use silenceDurationMs, startSensitivity, and endSensitivity to tune faster turn-taking on telephony audio.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
{
plugins: {
entries: {
"voice-call": {
config: {
provider: "twilio",
inboundPolicy: "allowlist",
allowFrom: ["+15550005678"],
realtime: {
enabled: true,
provider: "google",
instructions: "Speak briefly. Call openclaw_agent_consult before using deeper tools.",
toolPolicy: "safe-read-only",
consultPolicy: "substantive",
consultThinkingLevel: "low",
consultFastMode: true,
agentContext: { enabled: true },
providers: {
google: {
apiKey: "${GEMINI_API_KEY}",
model: "gemini-3.1-flash-live-preview",
speakerVoice: "Kore",
silenceDurationMs: 500,
startSensitivity: "high",
},
},
},
},
},
},
},
}
{
plugins: {
entries: {
"voice-call": {
config: {
realtime: {
enabled: true,
provider: "openai",
providers: {
openai: { apiKey: "${OPENAI_API_KEY}" },
},
},
},
},
},
},
}
Streaming transcription
streaming connects Twilio Media Streams to a realtime transcription provider. The classic streaming path requires provider: "twilio"; configuration with Telnyx, Plivo, or mock is rejected. Telnyx live audio uses the separately authenticated realtime.enabled path instead.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
streaming.provideris optional. If unset, Voice Call uses the first registered realtime transcription provider.- Bundled realtime transcription providers: Deepgram (
deepgram), ElevenLabs (elevenlabs), Mistral (mistral), OpenAI (openai), and xAI (xai), registered by their provider plugins. - Provider-owned raw config lives under
streaming.providers.<providerId>. - After Twilio sends an accepted stream
startmessage, Voice Call registers the stream immediately, queues inbound media through the transcription provider while the provider connects, and starts the initial greeting only after realtime transcription is ready. - If
streaming.providerpoints at an unregistered provider, or none is registered, Voice Call logs a warning and skips media streaming instead of failing the whole plugin.
Streaming provider examples
Defaults: API key streaming.providers.openai.apiKey or OPENAI_API_KEY; model gpt-4o-transcribe; silenceDurationMs: 800; vadThreshold: 0.5.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
{
plugins: {
entries: {
"voice-call": {
config: {
streaming: {
enabled: true,
provider: "openai",
streamPath: "/voice/stream",
providers: {
openai: {
apiKey: "sk-...", // optional if OPENAI_API_KEY is set
model: "gpt-4o-transcribe",
silenceDurationMs: 800,
vadThreshold: 0.5,
},
},
},
},
},
},
},
}
{
plugins: {
entries: {
"voice-call": {
config: {
streaming: {
enabled: true,
provider: "xai",
streamPath: "/voice/stream",
providers: {
xai: {
apiKey: "${XAI_API_KEY}", // optional if XAI_API_KEY is set
endpointingMs: 800,
language: "en",
},
},
},
},
},
},
},
}
TTS for calls
Voice Call uses the core tts configuration for streaming speech on calls. You can override it under the plugin config with the same shape — it deep-merges with tts.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
- Legacy
tts.<provider>keys inside plugin config (openai,elevenlabs,microsoft,edge) are repaired byopenclaw doctor --fix; committed config should usetts.providers.<provider>. - Core TTS is used when Twilio media streaming is enabled; otherwise calls fall back to provider-native voices.
- If a Twilio media stream is already active, Voice Call does not fall back to TwiML
<Say>. If telephony TTS is unavailable in that state, the playback request fails instead of mixing two playback paths. - When telephony TTS falls back to a secondary provider, Voice Call logs a warning with the provider chain (
from,to,attempts) for debugging. - When Twilio barge-in or stream teardown clears the pending TTS queue, queued playback requests settle instead of hanging callers awaiting playback completion.
{
tts: {
provider: "elevenlabs",
providers: {
elevenlabs: {
speakerVoiceId: "pMsXgVXv3BLzUgSXRplE",
modelId: "eleven_multilingual_v2",
},
},
},
}
TTS examples
{
tts: {
provider: "openai",
providers: {
openai: { speakerVoice: "alloy" },
},
},
}
{
plugins: {
entries: {
"voice-call": {
config: {
tts: {
provider: "elevenlabs",
providers: {
elevenlabs: {
apiKey: "elevenlabs_key",
speakerVoiceId: "pMsXgVXv3BLzUgSXRplE",
modelId: "eleven_multilingual_v2",
},
},
},
},
},
},
},
}
{
plugins: {
entries: {
"voice-call": {
config: {
tts: {
providers: {
openai: {
model: "gpt-4o-mini-tts",
speakerVoice: "marin",
},
},
},
},
},
},
},
}
Inbound calls
Inbound policy defaults to disabled. To enable inbound calls, set:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
{
inboundPolicy: "allowlist",
allowFrom: ["+15550001234"],
inboundGreeting: "Hello! How can I help?",
}
Per-number routing
Use numbers when one Voice Call plugin receives calls for multiple phone numbers and each number should behave like a different line. 예를 들어, one number can use a casual personal assistant while another uses a business persona, a different response agent, and a different TTS voice.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
inboundGreetingttsagentIdresponseModelresponseSystemPromptresponseTimeoutMs
{
inboundGreeting: "Hello from the main line.",
responseSystemPrompt: "You are the default voice assistant.",
tts: {
provider: "openai",
providers: {
openai: { speakerVoice: "coral" },
},
},
numbers: {
"+15550001111": {
inboundGreeting: "Silver Fox Cards, how can I help?",
responseSystemPrompt: "You are a concise baseball card specialist.",
tts: {
providers: {
openai: { speakerVoice: "alloy" },
},
},
},
},
}
Spoken output contract
For auto-responses, Voice Call appends a strict spoken-output contract to the system prompt requiring a {"spoken":"..."} JSON reply. Voice Call extracts speech text defensively:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
- Ignores payloads marked as reasoning/error content.
- Parses direct JSON, fenced JSON, or inline
"spoken"keys. - Falls back to plain text and removes likely planning/meta lead-in paragraphs.
Conversation startup behavior
For outbound conversation calls, first-message handling is tied to live playback state:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
- Barge-in queue clear and auto-response are suppressed only while the initial greeting is actively speaking.
- If initial playback fails, the call returns to
listeningand the initial message remains queued for retry. - Initial playback for Twilio streaming starts on stream connect without extra delay.
- Barge-in aborts active playback and clears queued-but-not-yet-playing Twilio TTS entries. Cleared entries resolve as skipped, so follow-up response logic can continue without waiting on audio that will never play.
- Realtime voice conversations use the realtime stream's own opening turn. Voice Call does not post a legacy
<Say>TwiML update for that initial message, so outbound<Connect><Stream>sessions stay attached.
Twilio stream disconnect grace
When a Twilio media stream disconnects, Voice Call waits 2000 ms before auto-ending the call:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
- If the stream reconnects during that window, auto-end is canceled.
- If no stream re-registers after the grace period, the call is ended to prevent stuck active calls.
Stale call reaper
Use staleCallReaperSeconds (default 120) to end calls that are never answered and never reach a live conversation state, for example notify-mode calls where the provider never delivers a terminal webhook. Set it to 0 to disable.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
{
plugins: {
entries: {
"voice-call": {
config: {
maxDurationSeconds: 300,
staleCallReaperSeconds: 120,
},
},
},
},
}
Webhook security
When a proxy or tunnel sits in front of the Gateway, the plugin reconstructs the public URL for signature verification. These options control which forwarded headers are trusted:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
- Webhook replay protection is enabled for Twilio, Telnyx, and Plivo. Replayed valid webhook requests are acknowledged but skipped for side effects.
- Twilio conversation turns include a per-turn token in
<Gather>callbacks, so stale/replayed speech callbacks cannot satisfy a newer pending transcript turn. - Unauthenticated webhook requests are rejected before body reads when the provider's required signature headers are missing.
- The voice-call webhook uses the shared pre-auth body-read profile (64 KB max body, 5-second read timeout) plus a per-key in-flight cap (8 concurrent requests per key by default) before signature verification.
{
plugins: {
entries: {
"voice-call": {
config: {
publicUrl: "https://voice.example.com/voice/webhook",
webhookSecurity: {
allowedHosts: ["voice.example.com"],
},
},
},
},
},
}
CLI
When the Gateway is already running, operational voicecall commands delegate to the Gateway-owned voice-call runtime so the CLI does not bind a second webhook server. If no Gateway is reachable, the commands fall back to a standalone CLI runtime.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
openclaw voicecall call --to "+15555550123" --message "Hello from OpenClaw"
openclaw voicecall start --to "+15555550123" # alias for call
openclaw voicecall continue --call-id <id> --message "Any questions?"
openclaw voicecall speak --call-id <id> --message "One moment"
openclaw voicecall dtmf --call-id <id> --digits "ww123456#"
openclaw voicecall end --call-id <id>
openclaw voicecall status --call-id <id>
openclaw voicecall tail
openclaw voicecall latency # summarize turn latency from logs
openclaw voicecall expose --mode funnel
Agent tool
The voice-call plugin ships a matching agent skill.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
| Action | Args |
|---|---|
initiate_call |
message, to?, mode?, dtmfSequence? |
continue_call |
callId, message |
speak_to_user |
callId, message |
send_dtmf |
callId, digits |
end_call |
callId |
get_status |
callId |
Gateway RPC
dtmfSequence is only valid with mode: "conversation"; notify-mode calls should use voicecall.dtmf after the call exists if they need post-connect digits.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
| Method | Args | Notes |
|---|---|---|
voicecall.initiate |
to?, message, mode?, sessionKey?, requesterSessionKey? |
Falls back to toNumber config when to is omitted. |
voicecall.start |
to, message?, mode?, dtmfSequence?, sessionKey? |
Same as initiate but also accepts pre-connect dtmfSequence. |
voicecall.continue |
callId, message |
Blocks until the turn resolves; returns the transcript. |
voicecall.continue.start |
callId, message |
Async variant: returns an operationId immediately. |
voicecall.continue.result |
operationId |
Polls a pending voicecall.continue.start operation for its result. |
voicecall.speak |
callId, message |
Speaks without waiting; uses the realtime bridge when realtime.enabled. |
voicecall.dtmf |
callId, digits |
|
voicecall.end |
callId |
|
voicecall.status |
callId? |
Omit callId to list all active calls. |
트러블슈팅
이 섹션의 세부 항목은 공식 문서 트러블슈팅를 참고하세요.
Setup fails webhook exposure
Run setup from the same environment that runs the Gateway:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
openclaw voicecall setup
openclaw voicecall setup --json
{
plugins: {
entries: {
"voice-call": {
config: {
publicUrl: "https://voice.example.com/voice/webhook",
// or
tunnel: { provider: "ngrok" },
// or
tailscale: { mode: "funnel", path: "/voice/webhook" },
},
},
},
},
}
openclaw voicecall setup
openclaw voicecall smoke
Provider credentials fail
Check the selected provider and the required credential fields:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
- Twilio:
twilio.accountSid,twilio.authToken, andfromNumber, or - Telnyx:
telnyx.apiKey,telnyx.connectionId,telnyx.publicKey, and - Plivo:
plivo.authId,plivo.authToken, andfromNumber, or
Calls start but provider webhooks do not arrive
Confirm the provider console points at the exact public webhook URL:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
publicUrlpoints at a different path thanserve.path.- The tunnel URL changed after the Gateway started.
- A proxy forwards the request but strips or rewrites host/proto headers.
- Firewall or DNS routes the public hostname somewhere other than the Gateway.
- The Gateway was restarted without the Voice Call plugin enabled.
https://voice.example.com/voice/webhook
openclaw voicecall status --call-id <id>
openclaw voicecall tail
openclaw logs --follow
Signature verification fails
Provider signatures are checked against the public URL OpenClaw reconstructs from the incoming request. If signatures fail:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
- Confirm the provider webhook URL exactly matches
publicUrl, including scheme, host, and path. - For ngrok free-tier URLs, update
publicUrlwhen the tunnel hostname changes. - Ensure the proxy preserves the original host and proto headers, or configure
webhookSecurity.allowedHosts. - Do not enable
skipSignatureVerificationoutside local testing.
Google Meet Twilio joins fail
Google Meet uses this plugin for Twilio dial-in joins. First verify Voice Call:
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
- Google Meet delegates the Twilio join to Voice Call.
- Voice Call stores pre-connect DTMF TwiML.
- Twilio initial TwiML is consumed and served before realtime handling.
- Voice Call serves realtime TwiML for the Twilio call.
- Google Meet requests intro speech with
voicecall.speakafter the post-DTMF delay.
openclaw voicecall setup
openclaw voicecall smoke --to "+15555550123"
openclaw googlemeet setup --transport twilio
Realtime call has no speech
Confirm only one audio mode is enabled: realtime.enabled and streaming.enabled cannot both be true.
위 내용은 공식 문서의 해당 섹션 요지입니다. 세부 플래그·기본값은 원문과
--help를 확인하세요.
주요 항목:
- A realtime provider plugin is loaded and registered.
realtime.provideris unset or names a registered provider.- The provider API key is available to the Gateway process.
openclaw logs --followshows realtime TwiML served, the realtime bridge started, and the initial greeting queued.
관련 문서
주요 항목:
- Talk mode
- Text-to-speech
- Voice wake
실습 체크리스트
- 공식 문서와 로컬 버전을 대조합니다:
https://docs.openclaw.ai/plugins/voice-call - 관련 CLI는
openclaw --help및 하위 명령--help로 옵션을 확인합니다. - 설정 변경 시
openclaw config/openclaw doctor로 유효성을 검사합니다. - Gateway·채널·플러그인 변경 후에는 필요 시 Gateway를 재시작합니다.
자주 쓰는 명령·설정 예시
openclaw plugins install @openclaw/voice-call
PLUGIN_SRC=./path/to/local/voice-call-plugin
openclaw plugins install "$PLUGIN_SRC"
cd "$PLUGIN_SRC" && pnpm install
openclaw voicecall setup
openclaw voicecall setup --json
openclaw voicecall smoke
openclaw voicecall smoke --to "+15555550123"
openclaw voicecall smoke --to "+15555550123" --yes
{
plugins: {
entries: {
"voice-call": {
enabled: true,
config: {
provider: "twilio", // or "telnyx" | "plivo" | "mock"
fromNumber: "+15550001234", // or TWILIO_FROM_NUMBER for Twilio
toNumber: "+15550005678",
sessionScope: "per-phone", // per-phone | per-call
numbers: {
"+15550009999": {
inboundGreeting: "Silver Fox Cards, how can I help?",
responseSystemPrompt: "You are a concise baseball card specialist.",
tts: {
providers: {
openai: { speakerVoice: "alloy" },
},
},
},
},
twilio: {
accountSid: "ACxxxxxxxx",
authToken: "...",
// region: "ie1", // optional: us1 | ie1 | au1; defaults to us1
},
telnyx: {
apiKey: "...",
connectionId: "...",
// Telnyx webhook public key from the Mission Control Portal
// (Base64; can also be set via TELNYX_PUBLIC_KEY).
publicKey: "...",
},
plivo: {
authId: "MAxxxxxxxxxxxxxxxxxxxx",
authToken: "...",
},
// Webhook server
serve: {
port: 3334,
path: "/voice/webhook",
},
// Webhook security (recommended for tunnels/proxies)
webhookSecurity: {
allowedHosts: ["voice.example.com"],
trustedProxyIPs: ["100.64.0.1"],
},
// Public exposure (pick one)
// publicUrl: "https://example.ngrok.app/voice/webhook",
// tunnel: { provider: "ngrok" },
// tailscale: { mode: "funnel", path: "/voice/webhook" },
outbound: {
defaultMode: "notify", // notify | conversation
},
streaming: { enabled: true /* Twilio only; see Streaming transcription */ },
realtime: { enabled: false /* see Realtime voice conversations */ },
},
},
},
},
}
관련 링크
- 공식 원문: plugins/voice-call
- OpenClaw 문서 홈
이 가이드는 공식 문서를 한국어 학습용으로 재구성한 것입니다. 옵션 기본값·플래그 이름은 설치 버전에 따라 달라질 수 있습니다.