Voice Call(plugin)
plugin経由でOpenClawに音声通話機能を追加します。着信ポリシーを備えた 発信通知とマルチターン会話に対応しています。 現在のprovider:twilio(Programmable Voice + Media Streams)telnyx(Call Control v2)plivo(Voice API + XML transfer + GetInput speech)mock(開発用 / ネットワークなし)
- pluginをインストールする
- Gatewayを再起動する
plugins.entries.voice-call.config配下で設定するopenclaw voicecall ...またはvoice_calltoolを使う
実行場所(local vs remote)
Voice Call pluginはGateway process内で動作します。 remote Gatewayを使う場合は、Gatewayを実行しているマシンにpluginをインストール/設定し、 その後pluginを読み込むためにGatewayを再起動してください。インストール
オプションA: npmからインストールする(推奨)
オプションB: ローカルフォルダーからインストールする(開発用、コピーなし)
設定
設定はplugins.entries.voice-call.config 配下に置きます:
- Twilio/Telnyxでは公開到達可能な webhook URLが必要です。
- Plivoでも公開到達可能な webhook URLが必要です。
mockはローカル開発用providerです(ネットワーク呼び出しなし)。- 古い設定で
provider: "log"、twilio.from、またはlegacyなstreaming.*OpenAI keysを使っている場合は、openclaw doctor --fixを実行して書き換えてください。 - Telnyxでは、
skipSignatureVerificationがtrueでない限りtelnyx.publicKey(またはTELNYX_PUBLIC_KEY)が必要です。 skipSignatureVerificationはローカルテスト専用です。- ngrokの無料tierを使う場合は、
publicUrlに正確なngrok URLを設定してください。署名検証は常に強制されます。 tunnel.allowNgrokFreeTierLoopbackBypass: trueは、tunnel.provider="ngrok"かつserve.bindがloopback (ngrok local agent)の場合にのみ、無効な署名を持つTwilio webhooksを許可します。ローカル開発専用です。- ngrok無料tierのURLは変わったり、中間画面の挙動が加わったりすることがあります。
publicUrlがずれると、Twilio署名は失敗します。本番では、安定したドメインまたはTailscale funnelを推奨します。 - ストリーミングのセキュリティデフォルト:
streaming.preStartTimeoutMsは、有効なstartフレームを送らないソケットを閉じます。
streaming.maxPendingConnectionsは、未認証のpre-startソケット総数を制限します。streaming.maxPendingConnectionsPerIpは、送信元IPごとの未認証pre-startソケット数を制限します。streaming.maxConnectionsは、開いているmedia streamソケット総数(pending + active)を制限します。- ランタイムのフォールバックは、今のところそれらの古いvoice-call keysも引き続き受け付けますが、
書き換え経路は
openclaw doctor --fixであり、この互換shimは一時的なものです。
ストリーミング音声文字起こし
streaming は、通話中のライブ音声向けにrealtime transcription providerを選択します。
現在のランタイム挙動:
streaming.providerは任意です。未設定の場合、Voice Callは最初に 登録されたrealtime transcription providerを使います。- 現在のbundled providerはOpenAIで、bundled
openaipluginによって登録されます。 - provider所有のraw configは
streaming.providers.<providerId>配下に置きます。 streaming.providerが未登録providerを指している場合、またはrealtime transcription providerがまったく登録されていない場合、Voice Callは警告を記録し、 plugin全体を失敗させる代わりにmedia streamingをスキップします。
- API key:
streaming.providers.openai.apiKeyまたはOPENAI_API_KEY - model:
gpt-4o-transcribe silenceDurationMs:800vadThreshold:0.5
openclaw doctor --fix によって自動移行されます:
streaming.sttProvider→streaming.providerstreaming.openaiApiKey→streaming.providers.openai.apiKeystreaming.sttModel→streaming.providers.openai.modelstreaming.silenceDurationMs→streaming.providers.openai.silenceDurationMsstreaming.vadThreshold→streaming.providers.openai.vadThreshold
古い通話のreaper
終端webhookを受け取らないまま残る通話を終了するには、staleCallReaperSeconds を使います
(たとえば、完了しないnotify-mode通話)。デフォルトは 0
(無効)です。
推奨範囲:
- 本番: notifyスタイルフローでは
120〜300秒。 - 通常の通話が完了できるよう、この値は
maxDurationSecondsより大きく してください。 良い初期値はmaxDurationSeconds + 30〜60秒です。
Webhook Security
proxyまたはtunnelがGatewayの前段にある場合、pluginは署名検証のために 公開URLを再構築します。これらのオプションは、どのforwarded headersを信頼するかを制御します。webhookSecurity.allowedHosts は、forwarding headers内のhostをallowlist化します。
webhookSecurity.trustForwardingHeaders は、allowlistなしでforwarded headersを信頼します。
webhookSecurity.trustedProxyIPs は、リクエストの
remote IPがこの一覧に一致する場合にのみforwarded headersを信頼します。
Webhook replay protectionはTwilioとPlivoで有効です。再送された有効なwebhook
requestsは受理されますが、副作用はスキップされます。
Twilio conversation turnsには、<Gather> callbacksにturnごとのtokenが含まれるため、
古い / 再送されたspeech callbacksが新しいpending transcript turnを満たしてしまうことはありません。
未認証のwebhook requestsは、provider必須の署名headersが欠けていると、
bodyを読む前に拒否されます。
voice-call webhookは、共有のpre-auth body profile(64 KB / 5秒)と、
署名検証前のIPごとのin-flight上限を使います。
安定した公開hostを使う例:
通話用TTS
Voice Callは、通話上のストリーミング音声に対してコアのmessages.tts 設定を使用します。
plugin config配下で同じ形のまま上書きでき、
messages.tts とdeep-mergeされます。
- plugin config内のlegacyな
tts.<provider>keys(openai,elevenlabs,microsoft,edge)は、読み込み時に自動でtts.providers.<provider>へ移行されます。コミットするconfigではproviders形式を推奨します。 - Microsoft speechはvoice callsでは無視されます(電話音声にはPCMが必要ですが、現在のMicrosoft transportは電話向けPCM出力を公開していません)。
- Twilio media streamingが有効な場合はコアTTSが使われ、それ以外では通話はproviderネイティブ音声へフォールバックします。
- Twilio media streamがすでに有効な場合、Voice CallはTwiML
<Say>へフォールバックしません。その状態でtelephony TTSが使えない場合、2つの再生経路を混在させる代わりに再生リクエストは失敗します。 - telephony TTSが二次providerへフォールバックした場合、Voice Callはデバッグ用に
provider chain(
from,to,attempts)付きの警告を記録します。
さらに例
コアTTSだけを使う(上書きなし):着信通話
着信ポリシーのデフォルトはdisabled です。着信通話を有効にするには、次を設定します:
inboundPolicy: "allowlist" は、低保証のcaller-IDチェックです。pluginは
providerから渡された From 値を正規化し、allowFrom と比較します。
Webhook verificationはproviderによる配送とpayload整合性を認証しますが、
PSTN/VoIPの発信番号所有権を証明するものではありません。allowFrom は
強い発信者本人確認ではなく、caller-IDフィルタリングとして扱ってください。
自動応答はagent systemを使います。次で調整できます:
responseModelresponseSystemPromptresponseTimeoutMs
音声出力契約
自動応答では、Voice Callは厳格な音声出力契約をsystem promptへ追加します:{"spoken":"..."}
- reasoning/error contentとしてマークされたpayloadは無視します。
- 直接JSON、fenced JSON、またはインラインの
"spoken"keysを解析します。 - プレーンテキストへフォールバックし、計画/メタ説明らしい先頭段落を除去します。
会話開始時の挙動
発信conversation 通話では、最初のメッセージ処理はライブ再生状態に結び付いています。
- Barge-inのキュークリアと自動応答の抑制は、最初の挨拶が実際に話されている間だけ行われます。
- 最初の再生に失敗した場合、通話は
listeningに戻り、最初のメッセージは再試行用にキューに残ります。 - Twilio streamingの最初の再生は、追加遅延なしでstream接続時に開始されます。
Twilio stream切断時の猶予
Twilio media streamが切断されると、Voice Callは通話を自動終了する前に2000ms 待機します:
- その間にstreamが再接続した場合、自動終了はキャンセルされます。
- 猶予期間後もstreamが再登録されない場合、activeなまま固まった通話を防ぐために通話は終了されます。
CLI
latency は、デフォルトのvoice-call保存パスにある calls.jsonl を読みます。
別のlogを指定するには --file <path> を使い、分析対象を直近N件
(デフォルト200件)に制限するには --last <n> を使います。出力には、
turn latencyとlisten-wait時間のp50/p90/p99が含まれます。
Agent tool
Tool名:voice_call
アクション:
initiate_call(message,to?,mode?)continue_call(callId,message)speak_to_user(callId,message)end_call(callId)get_status(callId)
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)