Plugins
Plugin voor spraakoproepen
Spraakoproepen voor OpenClaw via een Plugin. Ondersteunt uitgaande meldingen, gesprekken met meerdere beurten, full-duplex realtime spraak, streaming transcriptie en inkomende oproepen met allowlist-beleid.
Huidige providers: twilio (Programmable Voice + Media Streams),
telnyx (Call Control v2), plivo (Voice API + XML transfer + GetInput
speech), mock (dev/geen netwerk).
Snelstart
Installeer de Plugin
Van npm
openclaw plugins install @openclaw/voice-call
Van een lokale map (dev)
PLUGIN_SRC=./path/to/local/voice-call-plugin
openclaw plugins install "$PLUGIN_SRC"
cd "$PLUGIN_SRC" && pnpm install
Gebruik het kale pakket om de huidige officiële release-tag te volgen. Pin een exacte versie alleen wanneer je een reproduceerbare installatie nodig hebt.
Herstart daarna de Gateway zodat de Plugin wordt geladen.
Configureer provider en Webhook
Stel de configuratie in onder plugins.entries.voice-call.config (zie
Configuratie hieronder voor de volledige vorm). Minimaal:
provider, providerreferenties, fromNumber en een publiek
bereikbare Webhook-URL.
Controleer de installatie
openclaw voicecall setup
De standaarduitvoer is leesbaar in chatlogs en terminals. Deze controleert
of de Plugin is ingeschakeld, providerreferenties, Webhook-toegang en dat
slechts één audiomodus (streaming of realtime) actief is. Gebruik
--json voor scripts.
Smoke-test
openclaw voicecall smoke
openclaw voicecall smoke --to "+15555550123"
Beide zijn standaard dry-runs. Voeg --yes toe om daadwerkelijk een korte
uitgaande meldingsoproep te plaatsen:
openclaw voicecall smoke --to "+15555550123" --yes
Configuratie
Als enabled: true is ingesteld maar de geselecteerde provider referenties mist,
logt het opstarten van de Gateway een setup-incomplete-waarschuwing met de ontbrekende sleutels en
wordt het starten van de runtime overgeslagen. Commando's, RPC-aanroepen en agenttools
geven bij gebruik nog steeds de exacte ontbrekende providerconfiguratie terug.
{
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: { voice: "alloy" },
},
},
},
},
twilio: {
accountSid: "ACxxxxxxxx",
authToken: "...",
},
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 /* see Streaming transcription */ },
realtime: { enabled: false /* see Realtime voice */ },
},
},
},
},
}
Providerblootstelling en beveiligingsnotities
- Twilio, Telnyx en Plivo vereisen allemaal een publiek bereikbare Webhook-URL.
mockis een lokale dev-provider (geen netwerkoproepen).- Telnyx vereist
telnyx.publicKey(ofTELNYX_PUBLIC_KEY), tenzijskipSignatureVerificationtrue is. skipSignatureVerificationis alleen bedoeld voor lokale tests.- Stel op de gratis ngrok-laag
publicUrlin op de exacte ngrok-URL; handtekeningverificatie wordt altijd afgedwongen. tunnel.allowNgrokFreeTierLoopbackBypass: truestaat Twilio-webhooks met ongeldige handtekeningen alleen toe wanneertunnel.provider="ngrok"enserve.bindloopback is (lokale ngrok-agent). Alleen lokale dev.- URL's op de gratis ngrok-laag kunnen wijzigen of tussenschermgedrag toevoegen; als
publicUrlafwijkt, mislukken Twilio-handtekeningen. Productie: geef de voorkeur aan een stabiel domein of een Tailscale-funnel.
Limieten voor streamingverbindingen
streaming.preStartTimeoutMssluit sockets die nooit een geldigstart-frame verzenden.streaming.maxPendingConnectionsbegrenst het totale aantal niet-geverifieerde pre-start-sockets.streaming.maxPendingConnectionsPerIpbegrenst niet-geverifieerde pre-start-sockets per bron-IP.streaming.maxConnectionsbegrenst het totale aantal open mediastream-sockets (in behandeling + actief).
Migraties van legacy-configuratie
Oudere configuraties die provider: "log", twilio.from of legacy
streaming.* OpenAI-sleutels gebruiken, worden herschreven door openclaw doctor --fix.
Runtime-fallback accepteert de oude voice-call-sleutels voorlopig nog, maar
het herschrijfpad is openclaw doctor --fix en de compat-shim is
tijdelijk.
Automatisch gemigreerde streaming-sleutels:
streaming.sttProvider→streaming.providerstreaming.openaiApiKey→streaming.providers.openai.apiKeystreaming.sttModel→streaming.providers.openai.modelstreaming.silenceDurationMs→streaming.providers.openai.silenceDurationMsstreaming.vadThreshold→streaming.providers.openai.vadThreshold
Sessiebereik
Standaard gebruikt Voice Call sessionScope: "per-phone", zodat herhaalde oproepen van
dezelfde beller gespreksgeheugen behouden. Stel sessionScope: "per-call" in wanneer
elke carrier-oproep met nieuwe context moet beginnen, bijvoorbeeld voor receptie,
boekingen, IVR of Google Meet-bridgeflows waarbij hetzelfde telefoonnummer
verschillende vergaderingen kan vertegenwoordigen.
Realtime spraakgesprekken
realtime selecteert een full-duplex realtime-spraakprovider voor live oproepaudio.
Dit staat los van streaming, dat audio alleen doorstuurt naar
realtime-transcriptieproviders.
Huidig runtimegedrag:
realtime.enabledwordt ondersteund voor Twilio Media Streams.realtime.provideris optioneel. Als dit niet is ingesteld, gebruikt Voice Call de eerste geregistreerde realtime-spraakprovider.- Gebundelde realtime-spraakproviders: Google Gemini Live (
google) en OpenAI (openai), geregistreerd door hun provider-Plugins. - Provider-eigen ruwe configuratie staat onder
realtime.providers.<providerId>. - Voice Call stelt standaard de gedeelde realtime-tool
openclaw_agent_consultbeschikbaar. Het realtime-model kan deze aanroepen wanneer de beller om diepere redenering, actuele informatie of normale OpenClaw-tools vraagt. realtime.consultPolicyvoegt optioneel richtlijnen toe voor wanneer het realtime-modelopenclaw_agent_consultmoet aanroepen.realtime.agentContext.enabledstaat standaard uit. Wanneer dit is ingeschakeld, injecteert Voice Call bij het instellen van de sessie een begrensde agentidentiteit, overschrijving van de systeemprompt en geselecteerde workspace-bestandscapsule in de instructies voor de realtime-provider.realtime.fastContext.enabledstaat standaard uit. Wanneer dit is ingeschakeld, doorzoekt Voice Call eerst geïndexeerd geheugen/sessiecontext voor de consultvraag en geeft die fragmenten binnenrealtime.fastContext.timeoutMsterug aan het realtime-model, voordat alleen wordt teruggevallen op de volledige consultagent alsrealtime.fastContext.fallbackToConsulttrue is.- Als
realtime.providernaar een niet-geregistreerde provider verwijst, of als er helemaal geen realtime-spraakprovider is geregistreerd, logt Voice Call een waarschuwing en slaat het realtime-media over in plaats van de hele Plugin te laten mislukken. - Consult-sessiesleutels hergebruiken de opgeslagen oproepsessie wanneer beschikbaar en vallen daarna terug op de geconfigureerde
sessionScope(standaardper-phone, ofper-callvoor geïsoleerde oproepen).
Toolbeleid
realtime.toolPolicy beheert de consult-run:
| Beleid | Gedrag |
|---|---|
safe-read-only |
Stel de consulttool beschikbaar en beperk de reguliere agent tot read, web_search, web_fetch, x_search, memory_search en memory_get. |
owner |
Stel de consulttool beschikbaar en laat de reguliere agent het normale agenttoolbeleid gebruiken. |
none |
Stel de consulttool niet beschikbaar. Aangepaste realtime.tools worden nog steeds doorgegeven aan de realtime-provider. |
realtime.consultPolicy beheert alleen de instructies voor het realtime-model:
| Beleid | Richtlijn |
|---|---|
auto |
Behoud de standaardprompt en laat de provider bepalen wanneer de consulttool wordt aangeroepen. |
substantive |
Beantwoord eenvoudige conversationele overgangen direct en raadpleeg voor feiten, geheugen, tools of context. |
always |
Raadpleeg voor elk inhoudelijk antwoord. |
Agentspraakcontext
Schakel realtime.agentContext in wanneer de spraakbridge moet klinken als de
geconfigureerde OpenClaw-agent zonder een volledige agent-consult-rondreis te betalen bij
gewone beurten. De contextcapsule wordt één keer toegevoegd wanneer de realtime-sessie wordt
gemaakt, dus dit voegt geen latency per beurt toe. Aanroepen naar
openclaw_agent_consult draaien nog steeds de volledige OpenClaw-agent en moeten worden gebruikt
voor toolwerk, actuele informatie, geheugenzoekopdrachten of workspacestatus.
{
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,
includeSystemPrompt: true,
includeWorkspaceFiles: true,
files: ["SOUL.md", "IDENTITY.md", "USER.md"],
},
},
},
},
},
},
}
Voorbeelden van realtime providers
Google Gemini Live
Standaarden: API-sleutel uit realtime.providers.google.apiKey,
GEMINI_API_KEY of GOOGLE_GENERATIVE_AI_API_KEY; model
gemini-2.5-flash-native-audio-preview-12-2025; stem Kore.
sessionResumption en contextWindowCompression staan standaard aan voor langere,
opnieuw te verbinden gesprekken. Gebruik silenceDurationMs, startSensitivity en
endSensitivity om sneller beurtwisselen op telefonie-audio af te stemmen.
{
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",
agentContext: { enabled: true },
providers: {
google: {
apiKey: "${GEMINI_API_KEY}",
model: "gemini-2.5-flash-native-audio-preview-12-2025",
voice: "Kore",
silenceDurationMs: 500,
startSensitivity: "high",
},
},
},
},
},
},
},
}
OpenAI
{
plugins: {
entries: {
"voice-call": {
config: {
realtime: {
enabled: true,
provider: "openai",
providers: {
openai: { apiKey: "${OPENAI_API_KEY}" },
},
},
},
},
},
},
}
Zie Google provider en OpenAI provider voor provider-specifieke realtime spraakopties.
Streaming transcriptie
streaming selecteert een realtime transcriptieprovider voor live gespreksaudio.
Huidig runtimegedrag:
streaming.provideris optioneel. Als deze niet is ingesteld, gebruikt Voice Call de eerste geregistreerde realtime transcriptieprovider.- Meegeleverde realtime transcriptieproviders: Deepgram (
deepgram), ElevenLabs (elevenlabs), Mistral (mistral), OpenAI (openai) en xAI (xai), geregistreerd door hun provider-plugins. - Ruwe configuratie die eigendom is van de provider staat onder
streaming.providers.<providerId>. - Nadat Twilio een geaccepteerd stream-
start-bericht verstuurt, registreert Voice Call de stream direct, zet inkomende media in de wachtrij via de transcriptieprovider terwijl de provider verbinding maakt, en start de eerste begroeting pas nadat realtime transcriptie klaar is. - Als
streaming.providerverwijst naar een niet-geregistreerde provider, of als er geen is geregistreerd, logt Voice Call een waarschuwing en slaat het mediastreaming over in plaats van de hele Plugin te laten mislukken.
Voorbeelden van streamingproviders
OpenAI
Standaarden: API-sleutel streaming.providers.openai.apiKey of
OPENAI_API_KEY; model gpt-4o-transcribe; silenceDurationMs: 800;
vadThreshold: 0.5.
{
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,
},
},
},
},
},
},
},
}
xAI
Standaarden: API-sleutel streaming.providers.xai.apiKey of XAI_API_KEY;
endpoint wss://api.x.ai/v1/stt; codering mulaw; samplefrequentie 8000;
endpointingMs: 800; interimResults: true.
{
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 voor gesprekken
Voice Call gebruikt de kernconfiguratie messages.tts voor streaming spraak tijdens gesprekken. Je kunt deze overschrijven onder de pluginconfiguratie met
dezelfde vorm — deze wordt diep samengevoegd met messages.tts.
{
tts: {
provider: "elevenlabs",
providers: {
elevenlabs: {
voiceId: "pMsXgVXv3BLzUgSXRplE",
modelId: "eleven_multilingual_v2",
},
},
},
}
Gedragsnotities:
- Verouderde
tts.<provider>-sleutels binnen pluginconfiguratie (openai,elevenlabs,microsoft,edge) worden gerepareerd dooropenclaw doctor --fix; vastgelegde configuratie moettts.providers.<provider>gebruiken. - Core TTS wordt gebruikt wanneer Twilio-mediastreaming is ingeschakeld; anders vallen gesprekken terug op provider-native stemmen.
- Als een Twilio-mediastream al actief is, valt Voice Call niet terug op TwiML
OPENCLAW_DOCS_MARKER:calloutOpen:U2F5. Als telefonie-TTS in die toestand niet beschikbaar is, mislukt de afspeelaanvraag in plaats van twee afspeelpaden te mengen. - Wanneer telefonie-TTS terugvalt op een secundaire provider, logt Voice Call een waarschuwing met de providerketen (
from,to,attempts) voor foutopsporing. - Wanneer Twilio barge-in of stream-teardown de wachtende TTS-wachtrij wist, worden in de wachtrij geplaatste afspeelaanvragen afgehandeld in plaats van bellers te laten wachten op voltooiing van het afspelen.
TTS-voorbeelden
Core TTS only
{
messages: {
tts: {
provider: "openai",
providers: {
openai: { voice: "alloy" },
},
},
},
}
Override to ElevenLabs (calls only)
{
plugins: {
entries: {
"voice-call": {
config: {
tts: {
provider: "elevenlabs",
providers: {
elevenlabs: {
apiKey: "elevenlabs_key",
voiceId: "pMsXgVXv3BLzUgSXRplE",
modelId: "eleven_multilingual_v2",
},
},
},
},
},
},
},
}
OpenAI model override (deep-merge)
{
plugins: {
entries: {
"voice-call": {
config: {
tts: {
providers: {
openai: {
model: "gpt-4o-mini-tts",
voice: "marin",
},
},
},
},
},
},
},
}
Inkomende gesprekken
Het beleid voor inkomende oproepen staat standaard op disabled. Stel het volgende in om inkomende oproepen in te schakelen:
{
inboundPolicy: "allowlist",
allowFrom: ["+15550001234"],
inboundGreeting: "Hello! How can I help?",
}
Automatische antwoorden gebruiken het agentsysteem. Stem dit af met responseModel,
responseSystemPrompt en responseTimeoutMs.
Routering per nummer
Gebruik numbers wanneer één Voice Call-Plugin oproepen ontvangt voor meerdere telefoon-
nummers en elk nummer zich als een andere lijn moet gedragen. Zo kan één
nummer een informele persoonlijke assistent gebruiken, terwijl een ander een zakelijke
persona, een andere antwoordagent en een andere TTS-stem gebruikt.
Routes worden geselecteerd op basis van het door de provider geleverde gebelde To-nummer. Sleutels moeten
E.164-nummers zijn. Wanneer een oproep binnenkomt, lost Voice Call de overeenkomende route één keer op,
slaat de overeenkomende route op in de oproeprecord en hergebruikt die effectieve configuratie
voor de begroeting, het klassieke automatische-antwoordpad, het realtime consultpad en TTS-
afspelen. Als geen route overeenkomt, wordt de globale Voice Call-configuratie gebruikt.
Uitgaande oproepen gebruiken numbers niet; geef het uitgaande doel, het bericht en de
sessie expliciet door bij het starten van de oproep.
Route-overschrijvingen ondersteunen momenteel:
inboundGreetingttsagentIdresponseModelresponseSystemPromptresponseTimeoutMs
De routewaarde tts wordt diep samengevoegd over de globale Voice Call-tts-configuratie, dus
je kunt meestal alleen de providerstem overschrijven:
{
inboundGreeting: "Hello from the main line.",
responseSystemPrompt: "You are the default voice assistant.",
tts: {
provider: "openai",
providers: {
openai: { voice: "coral" },
},
},
numbers: {
"+15550001111": {
inboundGreeting: "Silver Fox Cards, how can I help?",
responseSystemPrompt: "You are a concise baseball card specialist.",
tts: {
providers: {
openai: { voice: "alloy" },
},
},
},
},
}
Contract voor gesproken uitvoer
Voor automatische antwoorden voegt Voice Call een strikt contract voor gesproken uitvoer toe aan de systeemprompt:
{"spoken":"..."}
Voice Call extraheert spraaktekst defensief:
- Negeert payloads die zijn gemarkeerd als redeneer-/foutinhoud.
- Parset directe JSON, afgeschermde JSON of inline
"spoken"-sleutels. - Valt terug op platte tekst en verwijdert waarschijnlijke inleidende alinea's voor planning/meta-inhoud.
Zo blijft gesproken afspelen gericht op tekst voor de beller en wordt voorkomen dat planningstekst in audio lekt.
Opstartgedrag van gesprekken
Voor uitgaande conversation-oproepen is de afhandeling van het eerste bericht gekoppeld aan de live
afspeelstatus:
- Het leegmaken van de barge-in-wachtrij en automatische antwoorden worden alleen onderdrukt terwijl de eerste begroeting actief wordt uitgesproken.
- Als het eerste afspelen mislukt, keert de oproep terug naar
listeningen blijft het eerste bericht in de wachtrij staan voor een nieuwe poging. - Eerste afspelen voor Twilio-streaming start zodra de stream verbinding maakt, zonder extra vertraging.
- Barge-in breekt actief afspelen af en wist Twilio TTS-vermeldingen die in de wachtrij staan maar nog niet worden afgespeeld. Gewiste vermeldingen worden afgehandeld als overgeslagen, zodat vervolglogica voor antwoorden kan doorgaan zonder te wachten op audio die nooit zal worden afgespeeld.
- Realtime spraakgesprekken gebruiken de eigen openingsturn van de realtime stream. Voice Call plaatst geen verouderde
OPENCLAW_DOCS_MARKER:calloutOpen:U2F5TwiML-update voor dat eerste bericht, zodat uitgaande<Connect><Stream>-sessies gekoppeld blijven.
Respijt bij verbroken Twilio-streamverbinding
Wanneer een Twilio-mediastream de verbinding verbreekt, wacht Voice Call 2000 ms voordat de oproep automatisch wordt beëindigd:
- Als de stream binnen dat venster opnieuw verbinding maakt, wordt automatisch beëindigen geannuleerd.
- Als geen stream zich na de respijtperiode opnieuw registreert, wordt de oproep beëindigd om vastgelopen actieve oproepen te voorkomen.
Opruimer voor verouderde oproepen
Gebruik staleCallReaperSeconds om oproepen te beëindigen die nooit een terminale
Webhook ontvangen (bijvoorbeeld oproepen in meldingsmodus die nooit worden voltooid). De standaardwaarde
is 0 (uitgeschakeld).
Aanbevolen bereiken:
- Productie:
120–300seconden voor notify-achtige flows. - Houd deze waarde hoger dan
maxDurationSeconds, zodat normale oproepen kunnen worden afgerond. Een goed startpunt ismaxDurationSeconds + 30–60seconden.
{
plugins: {
entries: {
"voice-call": {
config: {
maxDurationSeconds: 300,
staleCallReaperSeconds: 360,
},
},
},
},
}
Webhook-beveiliging
Wanneer een proxy of tunnel vóór de Gateway staat, reconstrueert de Plugin de openbare URL voor handtekeningverificatie. Deze opties bepalen welke doorgestuurde headers worden vertrouwd:
webhookSecurity.allowedHostsstring[]Sta hosts uit forwarding-headers toe.
webhookSecurity.trustForwardingHeadersbooleanVertrouw doorgestuurde headers zonder allowlist.
webhookSecurity.trustedProxyIPsstring[]Vertrouw doorgestuurde headers alleen wanneer het externe IP-adres van de aanvraag overeenkomt met de lijst.
Aanvullende beschermingen:
- Webhook-replaybescherming is ingeschakeld voor Twilio en Plivo. Herhaalde geldige Webhook-aanvragen worden bevestigd, maar overgeslagen voor neveneffecten.
- Twilio-gespreksbeurten bevatten een token per beurt in
<Gather>-callbacks, zodat verouderde/herhaalde spraakcallbacks geen nieuwere wachtende transcriptiebeurt kunnen voltooien. - Niet-geverifieerde Webhook-aanvragen worden vóór het lezen van de body geweigerd wanneer de vereiste handtekeningheaders van de provider ontbreken.
- De Voice Call-Webhook gebruikt het gedeelde pre-auth-bodyprofiel (64 KB / 5 seconden) plus een limiet per IP voor gelijktijdige aanvragen vóór handtekeningverificatie.
Voorbeeld met een stabiele openbare host:
{
plugins: {
entries: {
"voice-call": {
config: {
publicUrl: "https://voice.example.com/voice/webhook",
webhookSecurity: {
allowedHosts: ["voice.example.com"],
},
},
},
},
},
}
CLI
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
Wanneer de Gateway al draait, delegeren operationele voicecall-opdrachten
naar de door de Gateway beheerde voice-call-runtime, zodat de CLI geen tweede
Webhook-server bindt. Als er geen Gateway bereikbaar is, vallen de opdrachten terug op een
zelfstandige CLI-runtime.
latency leest calls.jsonl uit het standaardopslagpad voor voice-call.
Gebruik --file <path> om naar een ander log te verwijzen en --last <n> om
de analyse te beperken tot de laatste N records (standaard 200). De uitvoer bevat p50/p90/p99
voor beurtlatentie en luisterwachttijden.
Agent-tool
Toolnaam: voice_call.
| Actie | Argumenten |
|---|---|
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 |
Deze repo levert een bijbehorend Skill-document mee op skills/voice-call/SKILL.md.
Gateway RPC
| Methode | Argumenten |
|---|---|
voicecall.initiate |
to?, message, mode?, dtmfSequence? |
voicecall.continue |
callId, message |
voicecall.speak |
callId, message |
voicecall.dtmf |
callId, digits |
voicecall.end |
callId |
voicecall.status |
callId |
dtmfSequence is alleen geldig met mode: "conversation". Oproepen in notify-modus
moeten voicecall.dtmf gebruiken nadat de oproep bestaat als ze cijfers na het verbinden
nodig hebben.
Probleemoplossing
Setup mislukt bij Webhook-blootstelling
Voer setup uit vanuit dezelfde omgeving waarin de Gateway draait:
openclaw voicecall setup
openclaw voicecall setup --json
Voor twilio, telnyx en plivo moet webhook-exposure groen zijn. Een
geconfigureerde publicUrl mislukt nog steeds wanneer deze naar lokale of privénetwerkruimte
wijst, omdat de carrier niet naar die adressen kan terugbellen. Gebruik
localhost, 127.0.0.1, 0.0.0.0, 10.x, 172.16.x-172.31.x,
192.168.x, 169.254.x, fc00::/7 of fd00::/8 niet als publicUrl.
Uitgaande Twilio-oproepen in notify-modus sturen hun initiële OPENCLAW_DOCS_MARKER:calloutOpen:U2F5-TwiML rechtstreeks in
de create-call-aanvraag, zodat het eerste uitgesproken bericht niet afhankelijk is van Twilio
die Webhook-TwiML ophaalt. Een openbare Webhook is nog steeds vereist voor statuscallbacks,
gespreksoproepen, DTMF vóór verbinding, realtime streams en oproepbesturing na verbinding.
Gebruik één openbaar blootstellingspad:
{
plugins: {
entries: {
"voice-call": {
config: {
publicUrl: "https://voice.example.com/voice/webhook",
// or
tunnel: { provider: "ngrok" },
// or
tailscale: { mode: "funnel", path: "/voice/webhook" },
},
},
},
},
}
Herstart of herlaad de Gateway na het wijzigen van de configuratie en voer daarna uit:
openclaw voicecall setup
openclaw voicecall smoke
voicecall smoke is een dry run tenzij je --yes meegeeft.
Providerreferenties mislukken
Controleer de geselecteerde provider en de vereiste referentievelden:
- Twilio:
twilio.accountSid,twilio.authTokenenfromNumber, ofTWILIO_ACCOUNT_SID,TWILIO_AUTH_TOKENenTWILIO_FROM_NUMBER. - Telnyx:
telnyx.apiKey,telnyx.connectionId,telnyx.publicKeyenfromNumber. - Plivo:
plivo.authId,plivo.authTokenenfromNumber.
Referenties moeten op de Gateway-host bestaan. Het bewerken van een lokaal shellprofiel heeft geen effect op een al draaiende Gateway totdat deze herstart of zijn omgeving opnieuw laadt.
Oproepen starten, maar provider-Webhooks komen niet binnen
Controleer of de providerconsole naar de exacte openbare Webhook-URL wijst:
https://voice.example.com/voice/webhook
Inspecteer daarna de runtimestatus:
openclaw voicecall status --call-id <id>
openclaw voicecall tail
openclaw logs --follow
Veelvoorkomende oorzaken:
publicUrlwijst naar een ander pad danserve.path.- De tunnel-URL is gewijzigd nadat de Gateway is gestart.
- Een proxy stuurt de aanvraag door, maar verwijdert of herschrijft host/proto-headers.
- Firewall of DNS routeert de openbare hostnaam naar iets anders dan de Gateway.
- De Gateway is herstart zonder dat de Voice Call-Plugin is ingeschakeld.
Wanneer een reverse proxy of tunnel vóór de Gateway staat, stel
webhookSecurity.allowedHosts in op de openbare hostnaam, of gebruik
webhookSecurity.trustedProxyIPs voor een bekend proxyadres. Gebruik
webhookSecurity.trustForwardingHeaders alleen wanneer de proxygrens onder
jouw controle staat.
Handtekeningverificatie mislukt
Providerhandtekeningen worden gecontroleerd tegen de openbare URL die OpenClaw reconstrueert uit de inkomende aanvraag. Als handtekeningen mislukken:
- Controleer of de provider-Webhook-URL exact overeenkomt met
publicUrl, inclusief schema, host en pad. - Werk voor gratis ngrok-URL's
publicUrlbij wanneer de tunnelhostnaam verandert. - Zorg dat de proxy de oorspronkelijke host- en proto-headers behoudt, of configureer
webhookSecurity.allowedHosts. - Schakel
skipSignatureVerificationniet in buiten lokale tests.
Google Meet-Twilio-deelnames mislukken
Google Meet gebruikt deze Plugin voor Twilio-inbeldeelnames. Verifieer eerst Voice Call:
openclaw voicecall setup
openclaw voicecall smoke --to "+15555550123"
Verifieer daarna expliciet het Google Meet-transport:
openclaw googlemeet setup --transport twilio
Als Voice Call groen is, maar de Meet-deelnemer nooit deelneemt, controleer dan het Meet-
inbelnummer, de PIN en --dtmf-sequence. Het telefoongesprek kan gezond zijn terwijl
de vergadering een onjuiste DTMF-reeks weigert of negeert.
Google Meet start de Twilio-telefoonleg via voicecall.start met een
DTMF-reeks vóór verbinding. Van PIN afgeleide reeksen bevatten de
voiceCall.dtmfDelayMs van de Google Meet-Plugin als voorafgaande Twilio-wachtcijfers. De standaardwaarde is 12 seconden
omdat Meet-inbelprompts laat kunnen verschijnen. Voice Call leidt daarna terug naar
realtime afhandeling voordat de introductiebegroeting wordt aangevraagd.
Gebruik openclaw logs --follow voor de live fasetrace. Een gezonde Twilio Meet-
deelname logt deze volgorde:
- Google Meet delegeert de Twilio-deelname aan Voice Call.
- Voice Call slaat DTMF-TwiML vóór verbinding op.
- Initiële Twilio-TwiML wordt geconsumeerd en geserveerd vóór realtime afhandeling.
- Voice Call serveert realtime TwiML voor de Twilio-oproep.
- Google Meet vraagt introductiespraak aan met
voicecall.speakna de post-DTMF-vertraging.
openclaw voicecall tail toont nog steeds blijvend opgeslagen oproeprecords; het is nuttig voor
oproepstatus en transcripties, maar niet elke Webhook-/realtime-overgang verschijnt
daar.
Realtime oproep heeft geen spraak
Controleer of slechts één audiomodus is ingeschakeld. realtime.enabled en
streaming.enabled kunnen niet allebei true zijn.
Controleer voor realtime Twilio-oproepen ook:
- Een realtime provider-Plugin is geladen en geregistreerd.
realtime.provideris niet ingesteld of noemt een geregistreerde provider.- De provider-API-sleutel is beschikbaar voor het Gateway-proces.
openclaw logs --followtoont dat realtime TwiML is geserveerd, de realtime bridge is gestart en de initiële begroeting in de wachtrij is geplaatst.