Plugin guides

Plugin voor spraakoproepen

Spraakoproepen voor OpenClaw via een Plugin: uitgaande meldingen, gesprekken met meerdere beurten, full-duplex realtime spraak, streaming transcriptie en inkomende oproepen met beleid op basis van een toelatingslijst.

Providers: mock (ontwikkeling, geen netwerk), plivo (Voice API + XML-overdracht + GetInput-spraak), telnyx (Call Control v2), twilio (Programmable Voice + Media Streams).

Snel aan de slag

  • De Plugin installeren

    Van npm

    bash
    openclaw plugins install @openclaw/voice-call

    Uit een lokale map (ontwikkeling)

    bash
    PLUGIN_SRC=./path/to/local/voice-call-pluginopenclaw plugins install "$PLUGIN_SRC"cd "$PLUGIN_SRC" && pnpm install

    Gebruik het pakket zonder versienummer om de huidige releasetag te volgen. Zet alleen een exacte versie vast wanneer u een reproduceerbare installatie nodig hebt. Start de Gateway daarna opnieuw zodat de Plugin wordt geladen.

  • Provider en Webhook configureren

    Stel de configuratie in onder plugins.entries.voice-call.config (zie Configuratie hieronder). Minimaal vereist: provider, de aanmeldgegevens van de provider, fromNumber en een openbaar bereikbare Webhook-URL.

  • Configuratie verifiëren

    bash
    openclaw voicecall setupopenclaw voicecall setup --json

    Controleert of de Plugin is ingeschakeld, de aanmeldgegevens van de provider, de bereikbaarheid van de Webhook en of slechts één audiomodus (streaming of realtime) actief is.

  • Rooktest

    bash
    openclaw voicecall smokeopenclaw voicecall smoke --to "+15555550123"

    Beide zijn standaard proefuitvoeringen. Voeg --yes toe om een korte uitgaande meldingsoproep te plaatsen:

    bash
    openclaw voicecall smoke --to "+15555550123" --yes
  • Configuratie

    Als enabled: true is ingesteld maar de geselecteerde provider geen aanmeldgegevens heeft, registreert het opstarten van de Gateway een waarschuwing dat de configuratie onvolledig is, met de ontbrekende sleutels, en wordt de runtime niet gestart. Opdrachten, RPC-aanroepen en agenthulpmiddelen geven bij gebruik nog steeds exact aan welke configuratie ontbreekt.

    json5
    {  plugins: {    entries: {      "voice-call": {        enabled: true,        config: {          provider: "twilio", // of "telnyx" | "plivo" | "mock"          fromNumber: "+15550001234", // of TWILIO_FROM_NUMBER voor Twilio          toNumber: "+15550005678",          sessionScope: "per-phone", // per-phone | per-call          numbers: {            "+15550009999": {              inboundGreeting: "Silver Fox Cards, waarmee kan ik u helpen?",              responseSystemPrompt: "U bent een beknopte specialist in honkbalkaarten.",              tts: {                providers: {                  openai: { speakerVoice: "alloy" },                },              },            },          },           twilio: {            accountSid: "ACxxxxxxxx",            authToken: "...",            // region: "ie1", // optioneel: us1 | ie1 | au1; standaard us1          },          telnyx: {            apiKey: "...",            connectionId: "...",            // Openbare sleutel voor de Telnyx-Webhook uit het Mission Control Portal            // (Base64; kan ook worden ingesteld via TELNYX_PUBLIC_KEY).            publicKey: "...",          },          plivo: {            authId: "MAxxxxxxxxxxxxxxxxxxxx",            authToken: "...",          },           // Webhookserver          serve: {            port: 3334,            path: "/voice/webhook",          },           // Webhookbeveiliging (aanbevolen voor tunnels/proxy's)          webhookSecurity: {            allowedHosts: ["voice.example.com"],            trustedProxyIPs: ["100.64.0.1"],          },           // Openbare bereikbaarheid (kies er één)          // publicUrl: "https://example.ngrok.app/voice/webhook",          // tunnel: { provider: "ngrok" },          // tailscale: { mode: "funnel", path: "/voice/webhook" },           outbound: {            defaultMode: "notify", // notify | conversation          },           streaming: { enabled: true /* zie Streaming transcriptie */ },          realtime: { enabled: false /* zie Realtime spraakgesprekken */ },        },      },    },  },}

    Configuratiereferentie

    Sleutels op het hoogste niveau onder plugins.entries.voice-call.config die hierboven niet worden weergegeven:

    Sleutel Standaard Opmerkingen
    enabled false Hoofdschakelaar voor aan/uit.
    inboundPolicy "disabled" disabled | allowlist | pairing | open. Zie Inkomende oproepen.
    allowFrom [] E.164-toelatingslijst voor inboundPolicy: "allowlist".
    maxDurationSeconds 300 Harde maximale duur per oproep, ongeacht of de oproep is beantwoord.
    staleCallReaperSeconds 120 Zie Opschoner voor verouderde oproepen. 0 schakelt deze uit.
    silenceTimeoutMs 800 Stiltedetectie aan het einde van spraak voor de klassieke (niet-realtime) stroom.
    transcriptTimeoutMs 180000 Maximale wachttijd op een transcript van de beller voordat een beurt wordt opgegeven.
    ringTimeoutMs 30000 Beltime-out voor uitgaande oproepen.
    maxConcurrentCalls 1 Uitgaande oproepen boven deze limiet worden geweigerd.
    outbound.notifyHangupDelaySec 3 Aantal seconden wachten na TTS voordat automatisch wordt opgehangen in meldingsmodus.
    skipSignatureVerification false Alleen voor lokaal testen; nooit inschakelen in productie.
    store niet ingesteld Overschrijft het standaardpad ~/.openclaw/voice-calls voor oproeplogboeken.
    agentId "main" Agent die wordt gebruikt voor het genereren van antwoorden en de opslag van sessies.
    responseModel niet ingesteld Overschrijft het standaardmodel voor klassieke (niet-realtime) antwoorden.
    responseSystemPrompt gegenereerd Aangepaste systeemprompt voor klassieke antwoorden.
    responseTimeoutMs 30000 Time-out voor het genereren van klassieke antwoorden (ms).

    Twilio gebruikt standaard het US1 REST-eindpunt. Om oproepen in een ondersteunde regio buiten de VS te verwerken, stelt u twilio.region in op ie1 of au1 en gebruikt u aanmeldgegevens uit die regio. Zie Twilio's handleiding voor de REST API in een regio buiten de VS.

    Opmerkingen over bereikbaarheid en beveiliging van providers
    • Twilio, Telnyx en Plivo vereisen allemaal een openbaar bereikbare Webhook-URL.
    • mock is een lokale ontwikkelprovider (geen netwerkaanroepen).
    • Telnyx vereist telnyx.publicKey (of TELNYX_PUBLIC_KEY), tenzij skipSignatureVerification waar is.
    • skipSignatureVerification is alleen bedoeld voor lokaal testen.
    • Stel bij het gratis ngrok-abonnement publicUrl in op de exacte ngrok-URL; handtekeningverificatie wordt altijd afgedwongen.
    • tunnel.allowNgrokFreeTierLoopbackBypass: true staat Twilio-Webhooks met ongeldige handtekeningen alleen toe wanneer tunnel.provider="ngrok" en serve.bind local loopback is (lokale ngrok-agent). Alleen voor lokale ontwikkeling.
    • URL's van het gratis ngrok-abonnement kunnen veranderen of tussenschermen toevoegen; als publicUrl afwijkt, mislukt de Twilio-handtekeningverificatie. Voor productie: geef de voorkeur aan een stabiel domein of een Tailscale-funnel.
    Limieten voor streamingverbindingen
    • streaming.preStartTimeoutMs (standaard 5000) sluit sockets die nooit een geldig start-frame verzenden.
    • streaming.maxPendingConnections (standaard 32) begrenst het totale aantal niet-geverifieerde sockets vóór de start.
    • streaming.maxPendingConnectionsPerIp (standaard 4) begrenst niet-geverifieerde sockets vóór de start per bron-IP.
    • streaming.maxConnections (standaard 128) begrenst alle open sockets voor mediastreams (in afwachting + actief).
    Migraties van verouderde configuratie

    Bij het parseren van de configuratie worden deze verouderde sleutels automatisch genormaliseerd en wordt een waarschuwing geregistreerd waarin het vervangende pad wordt genoemd; de compatibiliteitslaag wordt in een toekomstige release (2026.6.0) verwijderd. Voer daarom openclaw doctor --fix uit om vastgelegde configuratie naar de canonieke vorm te herschrijven:

    • provider: "log"provider: "mock"
    • twilio.fromfromNumber
    • streaming.sttProviderstreaming.provider
    • streaming.openaiApiKeystreaming.providers.openai.apiKey
    • streaming.sttModelstreaming.providers.openai.model
    • streaming.silenceDurationMsstreaming.providers.openai.silenceDurationMs
    • streaming.vadThresholdstreaming.providers.openai.vadThreshold
    • realtime.agentContext.includeSystemPrompt is verwijderd (realtime-context gebruikt nu de gegenereerde agentprompt)

    Sessiebereik

    Voice Call gebruikt standaard sessionScope: "per-phone", zodat herhaalde oproepen van dezelfde beller het gespreksgeheugen behouden. Stel sessionScope: "per-call" in wanneer elke oproep via de telecomprovider met nieuwe context moet beginnen, bijvoorbeeld voor receptie-, boekings-, IVR- of Google Meet-bridge-stromen waarbij hetzelfde telefoonnummer verschillende vergaderingen kan vertegenwoordigen.

    Voice Call slaat gegenereerde sessiesleutels op onder de geconfigureerde agentnaamruimte (agent:<agentId>:voice:*). Expliciete onbewerkte integratiesleutels worden naar dezelfde naamruimte omgezet: een canonieke sleutel agent:<configuredAgentId>:* behoudt die eigenaar en respecteert aliasing via session.mainKey/globaal bereik in de kern; invoer van vreemde of onjuist gevormde agent:* wordt als een ondoorzichtige sleutel onder de geconfigureerde agent geplaatst; global en unknown blijven globale sentinelwaarden.

    Realtime spraakgesprekken

    realtime selecteert een full-duplex realtime spraakprovider voor live oproepaudio. Dit staat los van streaming, dat audio alleen doorstuurt naar providers voor realtime transcriptie.

    Huidig runtimegedrag:

    • realtime.enabled wordt ondersteund voor Twilio en Telnyx.
    • realtime.provider is optioneel. Als deze niet is ingesteld, gebruikt Voice Call de eerste geregistreerde realtime-spraakprovider.
    • Meegeleverde realtime-spraakproviders: Google Gemini Live (google) en OpenAI (openai), geregistreerd door hun providerplugins.
    • De onbewerkte configuratie die eigendom is van de provider, bevindt zich onder realtime.providers.<providerId>.
    • Voice Call stelt standaard de gedeelde realtime-tool openclaw_agent_consult beschikbaar. Het realtimemodel kan deze aanroepen wanneer de beller om diepgaandere redenering, actuele informatie of normale OpenClaw-tools vraagt.
    • realtime.consultPolicy voegt optioneel richtlijnen toe voor wanneer het realtimemodel openclaw_agent_consult moet aanroepen.
    • realtime.agentContext.enabled is standaard uitgeschakeld. Wanneer deze optie is ingeschakeld, voegt Voice Call bij het instellen van de sessie een begrensde agentidentiteit en een capsule met geselecteerde werkruimtebestanden toe aan de instructies voor de realtimeprovider.
    • realtime.fastContext.enabled is standaard uitgeschakeld. Wanneer deze optie is ingeschakeld, doorzoekt Voice Call eerst de geïndexeerde geheugen-/sessiecontext voor de consultatievraag en retourneert het die fragmenten binnen realtime.fastContext.timeoutMs aan het realtimemodel, voordat het alleen op de volledige consultatieagent terugvalt als realtime.fastContext.fallbackToConsult waar is.
    • Als realtime.provider naar een niet-geregistreerde provider verwijst, of als er helemaal geen realtime-spraakprovider is geregistreerd, registreert Voice Call een waarschuwing en slaat het realtime-media over in plaats van de volledige plugin te laten mislukken.
    • inboundPolicy mag niet "disabled" zijn wanneer realtime.enabled waar is; validateProviderConfig wijst die combinatie af.
    • Consultatiesessiesleutels hergebruiken de opgeslagen oproepsessie wanneer die beschikbaar is en vallen vervolgens terug op het geconfigureerde sessionScope (standaard per-phone, of per-call voor geïsoleerde oproepen).

    Toolbeleid

    realtime.toolPolicy beheert de consultatie-uitvoering:

    Beleid Gedrag
    safe-read-only Stelt de consultatietool beschikbaar en beperkt de normale agent tot read, web_search, web_fetch, x_search, memory_search en memory_get.
    owner Stelt de consultatietool beschikbaar en laat de normale agent het normale agenttoolbeleid gebruiken.
    none Stelt de consultatietool niet beschikbaar. Aangepaste realtime.tools worden nog steeds doorgegeven aan de realtimeprovider.

    realtime.consultPolicy beheert alleen de instructies voor het realtimemodel:

    Beleid Richtlijn
    auto Behoud de standaardprompt en laat de provider bepalen wanneer de consultatietool wordt aangeroepen.
    substantive Beantwoord eenvoudige verbindende gesprekszinnen rechtstreeks en consulteer vóór feiten, geheugen, tools of context.
    always Consulteer vóór elk inhoudelijk antwoord.

    Spraakcontext van de agent

    Schakel realtime.agentContext in wanneer de spraakbrug moet klinken als de geconfigureerde OpenClaw-agent zonder voor gewone beurten de volledige heen-en-terugreis van een agentconsultatie te doorlopen. De contextcapsule wordt eenmaal toegevoegd wanneer de realtimesessie wordt aangemaakt en voegt dus geen latentie per beurt toe. Aanroepen van openclaw_agent_consult voeren nog steeds de volledige OpenClaw-agent uit en moeten worden gebruikt voor toolwerk, actuele informatie, geheugenzoekacties of de toestand van de werkruimte.

    json5
    {  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"],            },          },        },      },    },  },}

    Voorbeelden van realtimeproviders

    Google Gemini Live

    Standaardwaarden: API-sleutel uit realtime.providers.google.apiKey, GEMINI_API_KEY of GOOGLE_API_KEY; model gemini-3.1-flash-live-preview; stem Kore. sessionResumption en contextWindowCompression zijn standaard ingeschakeld voor langere oproepen waarbij opnieuw verbinding kan worden gemaakt. Gebruik silenceDurationMs, startSensitivity en endSensitivity om snellere beurtwisseling voor telefonieaudio af te stellen.

    json5
    {  plugins: {    entries: {      "voice-call": {        config: {          provider: "twilio",          inboundPolicy: "allowlist",          allowFrom: ["+15550005678"],          realtime: {            enabled: true,            provider: "google",            instructions: "Spreek beknopt. Roep openclaw_agent_consult aan voordat je diepgaandere tools gebruikt.",            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",              },            },          },        },      },    },  },}

    OpenAI

    json5
    {  plugins: {    entries: {      "voice-call": {        config: {          realtime: {            enabled: true,            provider: "openai",            providers: {              openai: { apiKey: "${OPENAI_API_KEY}" },            },          },        },      },    },  },}

    Zie Google-provider en OpenAI-provider voor providerspecifieke opties voor realtime-spraak.

    Streamingtranscriptie

    streaming selecteert een realtime-transcriptieprovider voor live-oproepaudio.

    Huidig runtimegedrag:

    • streaming.provider is 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 providerplugins.
    • De onbewerkte configuratie die eigendom is van de provider, bevindt zich onder streaming.providers.<providerId>.
    • Nadat Twilio een geaccepteerd start-bericht voor een stream heeft verzonden, registreert Voice Call de stream onmiddellijk, plaatst het binnenkomende media via de transcriptieprovider in de wachtrij terwijl de provider verbinding maakt en start het de eerste begroeting pas wanneer realtime-transcriptie gereed is.
    • Als streaming.provider naar een niet-geregistreerde provider verwijst, of als er geen provider is geregistreerd, registreert Voice Call een waarschuwing en slaat het mediastreaming over in plaats van de volledige plugin te laten mislukken.

    Voorbeelden van streamingproviders

    OpenAI

    Standaardwaarden: API-sleutel streaming.providers.openai.apiKey of OPENAI_API_KEY; model gpt-4o-transcribe; silenceDurationMs: 800; vadThreshold: 0.5.

    json5
    {  plugins: {    entries: {      "voice-call": {        config: {          streaming: {            enabled: true,            provider: "openai",            streamPath: "/voice/stream",            providers: {              openai: {                apiKey: "sk-...", // optioneel als OPENAI_API_KEY is ingesteld                model: "gpt-4o-transcribe",                silenceDurationMs: 800,                vadThreshold: 0.5,              },            },          },        },      },    },  },}

    xAI

    Standaardwaarden: API-sleutel streaming.providers.xai.apiKey of XAI_API_KEY (valt terug op een xAI OAuth-authenticatieprofiel als geen van beide is ingesteld); eindpunt wss://api.x.ai/v1/stt; codering mulaw; samplefrequentie 8000; endpointingMs: 800; interimResults: true.

    json5
    {  plugins: {    entries: {      "voice-call": {        config: {          streaming: {            enabled: true,            provider: "xai",            streamPath: "/voice/stream",            providers: {              xai: {                apiKey: "${XAI_API_KEY}", // optioneel als XAI_API_KEY is ingesteld                endpointingMs: 800,                language: "en",              },            },          },        },      },    },  },}

    TTS voor oproepen

    Voice Call gebruikt de kernconfiguratie messages.tts voor gestreamde spraak tijdens oproepen. Je kunt deze onder de pluginconfiguratie overschrijven met dezelfde structuur — deze wordt diep samengevoegd met messages.tts.

    json5
    {  tts: {    provider: "elevenlabs",    providers: {      elevenlabs: {        speakerVoiceId: "pMsXgVXv3BLzUgSXRplE",        modelId: "eleven_multilingual_v2",      },    },  },}

    Gedragsnotities:

    • Verouderde sleutels tts.<provider> binnen de pluginconfiguratie (openai, elevenlabs, microsoft, edge) worden door openclaw doctor --fix hersteld; vastgelegde configuratie moet tts.providers.<provider> gebruiken.
    • Kern-TTS wordt gebruikt wanneer Twilio-mediastreaming is ingeschakeld; anders vallen oproepen terug op de ingebouwde stemmen van de provider.
    • 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 het afspeelverzoek in plaats van twee afspeelpaden te combineren.
    • Wanneer telefonie-TTS terugvalt op een secundaire provider, registreert Voice Call voor foutopsporing een waarschuwing met de providerketen (from, to, attempts).
    • Wanneer Twilio-onderbreking door de beller of het beëindigen van de stream de wachtende TTS-wachtrij wist, worden afspeelverzoeken in de wachtrij afgehandeld in plaats van bellers die op voltooiing van het afspelen wachten te laten vastlopen.

    TTS-voorbeelden

    Alleen kern-TTS

    json5
    {messages: {tts: {provider: "openai",providers: {  openai: { speakerVoice: "alloy" },},},},}

    Overschrijven met ElevenLabs (alleen oproepen)

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

    OpenAI-modeloverschrijving (diepe samenvoeging)

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

    Inkomende oproepen

    Het beleid voor inkomende oproepen is standaard disabled. Stel het volgende in om inkomende oproepen in te schakelen:

    json5
    {inboundPolicy: "allowlist",allowFrom: ["+15550001234"],inboundGreeting: "Hallo! Hoe kan ik helpen?",}

    Automatische antwoorden gebruiken het agentsysteem. Stem dit af met responseModel, responseSystemPrompt en responseTimeoutMs.

    Routering per nummer

    Gebruik numbers wanneer één Voice Call-plugin oproepen voor meerdere telefoon- nummers ontvangt en elk nummer zich als een afzonderlijke lijn moet gedragen. Zo kan het ene nummer bijvoorbeeld 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 aangeleverde gebelde To-nummer. Sleutels moeten E.164-nummers zijn. Wanneer een oproep binnenkomt, bepaalt Voice Call eenmaal de overeenkomende route, slaat de gevonden route op in de oproeprecord en hergebruikt die effectieve configuratie voor de begroeting, het klassieke pad voor automatische antwoorden, het realtime consultatiepad en TTS-weergave. Als geen route overeenkomt, wordt de algemene Voice Call- configuratie gebruikt. Uitgaande oproepen gebruiken numbers niet; geef bij het starten van de oproep expliciet het uitgaande doel, het bericht en de sessie door.

    Route-overschrijvingen ondersteunen momenteel:

    • inboundGreeting
    • tts
    • agentId
    • responseModel
    • responseSystemPrompt
    • responseTimeoutMs

    De routewaarde tts wordt diep samengevoegd met de algemene tts-configuratie van Voice Call, zodat je doorgaans alleen de providerstem hoeft te overschrijven:

    json5
    {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" },      },    },  },},}

    Contract voor gesproken uitvoer

    Voor automatische antwoorden voegt Voice Call een strikt contract voor gesproken uitvoer toe aan de systeemprompt, dat een JSON-antwoord in de vorm {"spoken":"..."} vereist. Voice Call extraheert de spraaktekst defensief:

    • Negeert payloads die als redeneer- of foutinhoud zijn gemarkeerd.
    • Parseert rechtstreekse JSON, JSON in een codeblok of inline "spoken"-sleutels.
    • Valt terug op platte tekst en verwijdert vermoedelijke inleidende alinea's met planning of metatekst.

    Hierdoor blijft de gesproken weergave gericht op tekst voor de beller en wordt voorkomen dat planningstekst in de audio terechtkomt.

    Gedrag bij het starten van een gesprek

    Voor uitgaande conversation-oproepen is de verwerking van het eerste bericht gekoppeld aan de actieve weergavestatus:

    • Het wissen van de wachtrij bij onderbreking en automatische antwoorden worden alleen onderdrukt zolang de eerste begroeting actief wordt uitgesproken.
    • Als de eerste weergave mislukt, keert de oproep terug naar listening en blijft het eerste bericht in de wachtrij staan voor een nieuwe poging.
    • De eerste weergave voor Twilio-streaming begint bij het verbinden van de stream, zonder extra vertraging.
    • Een onderbreking breekt de actieve weergave af en wist Twilio TTS-items die in de wachtrij staan maar nog niet worden afgespeeld. Gewiste items worden als overgeslagen afgehandeld, zodat de vervolglogica voor antwoorden kan doorgaan zonder te wachten op audio die nooit zal worden afgespeeld.
    • Realtime spraakgesprekken gebruiken de eigen openingsbeurt van de realtime stream. Voice Call plaatst voor dat eerste bericht geen verouderde OPENCLAW_DOCS_MARKER:calloutOpen:U2F5-TwiML-update, zodat uitgaande &lt;Connect&gt;&lt;Stream&gt;-sessies verbonden blijven.

    Respijtperiode bij verbreking van een Twilio-stream

    Wanneer een Twilio-mediastream wordt verbroken, wacht Voice Call 2000 ms voordat de oproep automatisch wordt beëindigd:

    • Als de stream binnen dat tijdsvenster opnieuw verbinding maakt, wordt de automatische beëindiging geannuleerd.
    • Als na de respijtperiode geen stream opnieuw wordt geregistreerd, wordt de oproep beëindigd om vastgelopen actieve oproepen te voorkomen.

    Opruimer voor verouderde oproepen

    Gebruik staleCallReaperSeconds (standaard 120) om oproepen te beëindigen die nooit worden beantwoord en nooit een actieve gespreksstatus bereiken, bijvoorbeeld oproepen in de meldingsmodus waarbij de provider nooit een afsluitende Webhook levert. Stel dit in op 0 om de functie uit te schakelen.

    De opruimer wordt elke 30 seconden uitgevoerd en beëindigt alleen oproepen zonder answeredAt-tijdstempel die nog niet in een afsluitende of actieve status (speaking/listening) verkeren. Beantwoorde gesprekken worden dus nooit door deze timer opgeruimd; maxDurationSeconds (standaard 300) is de afzonderlijke limiet die beantwoorde oproepen beëindigt wanneer ze te lang duren.

    Verhoog voor meldingsstromen waarbij providers bel-/antwoord- webhooks mogelijk langzaam leveren staleCallReaperSeconds tot boven de standaardwaarde, zodat trage maar normale oproepen niet voortijdig worden opgeruimd; 120-300 seconden is een redelijk bereik voor productieomgevingen.

    json5
    {plugins: {entries: {  "voice-call": {    config: {      maxDurationSeconds: 300,      staleCallReaperSeconds: 120,    },  },},},}

    Webhookbeveiliging

    Wanneer er 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[]

    Hosts uit doorgestuurde headers die zijn toegestaan.

    webhookSecurity.trustForwardingHeadersboolean

    Vertrouw doorgestuurde headers zonder een lijst met toegestane waarden.

    webhookSecurity.trustedProxyIPsstring[]

    Vertrouw doorgestuurde headers alleen wanneer het externe IP-adres van het verzoek in de lijst voorkomt.

    Aanvullende beveiligingen:

    • Webhook-beveiliging tegen herhaling is ingeschakeld voor Twilio, Telnyx en Plivo. Herhaalde geldige Webhookverzoeken worden bevestigd, maar de neveneffecten worden overgeslagen.
    • Twilio-gespreksbeurten bevatten een token per beurt in &lt;Gather&gt;-callbacks, zodat verouderde of herhaalde spraakcallbacks niet kunnen voldoen aan een nieuwere openstaande transcriptiebeurt.
    • Niet-geverifieerde Webhookverzoeken worden afgewezen voordat de body wordt gelezen wanneer de vereiste handtekeningheaders van de provider ontbreken.
    • De Webhook van voice-call gebruikt het gedeelde profiel voor het lezen van de body vóór verificatie (maximale bodygrootte van 64 KB en een leestime-out van 5 seconden), plus een limiet per sleutel voor gelijktijdige lopende verzoeken (standaard 8 gelijktijdige verzoeken per sleutel) vóór handtekeningverificatie.

    Voorbeeld met een stabiele openbare host:

    json5
    {plugins: {entries: {  "voice-call": {    config: {      publicUrl: "https://voice.example.com/voice/webhook",      webhookSecurity: {        allowedHosts: ["voice.example.com"],      },    },  },},},}

    CLI

    bash
    openclaw voicecall call --to "+15555550123" --message "Hello from OpenClaw"openclaw voicecall start --to "+15555550123"   # alias for callopenclaw 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 tailopenclaw voicecall latency                      # summarize turn latency from logsopenclaw voicecall expose --mode funnel

    Wanneer de Gateway al actief is, delegeren operationele voicecall-opdrachten naar de door de Gateway beheerde voice-call-runtime, zodat de CLI geen tweede Webhookserver bindt. Als 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 een ander logbestand aan te wijzen en --last <n> om de analyse te beperken tot de laatste N records (standaard 200). De uitvoer bevat minimum/maximum/gemiddelde, p50 en p95 voor de latentie per beurt en de wachttijden voor luisteren.

    Agenttool

    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

    De voice-call-plugin wordt geleverd met een bijbehorende agentskill.

    Gateway-RPC

    Methode Argumenten Opmerkingen
    voicecall.initiate to?, message, mode?, sessionKey?, requesterSessionKey? Valt terug op de configuratie toNumber wanneer to is weggelaten.
    voicecall.start to, message?, mode?, dtmfSequence?, sessionKey? Hetzelfde als initiate, maar accepteert ook dtmfSequence vóór verbinding.
    voicecall.continue callId, message Blokkeert totdat de beurt is afgerond en retourneert het transcript.
    voicecall.continue.start callId, message Asynchrone variant: retourneert onmiddellijk een operationId.
    voicecall.continue.result operationId Vraagt het resultaat van een openstaande voicecall.continue.start-bewerking op.
    voicecall.speak callId, message Spreekt zonder te wachten; gebruikt de realtimebrug wanneer realtime.enabled.
    voicecall.dtmf callId, digits
    voicecall.end callId
    voicecall.status callId? Laat callId weg om alle actieve oproepen weer te geven.

    dtmfSequence is alleen geldig met mode: "conversation"; oproepen in de meldingsmodus moeten nadat de oproep bestaat voicecall.dtmf gebruiken als ze cijfers na de verbinding nodig hebben.

    Probleemoplossing

    Instellen van Webhooktoegang mislukt

    Voer de configuratie uit vanuit dezelfde omgeving waarin de Gateway draait:

    bash
    openclaw voicecall setupopenclaw voicecall setup --json

    Voor twilio, telnyx en plivo moet webhook-exposure groen zijn. Een geconfigureerde publicUrl mislukt nog steeds wanneer deze naar lokale of particuliere netwerkruimte verwijst, omdat de provider die adressen niet 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, fd00::/8 of andere NAT- bereiken voor providers niet als publicUrl.

    Uitgaande Twilio-oproepen in de meldingsmodus sturen hun eerste OPENCLAW_DOCS_MARKER:calloutOpen:U2F5-TwiML rechtstreeks mee in het verzoek om de oproep aan te maken, zodat het eerste gesproken bericht niet afhankelijk is van het ophalen van Webhook-TwiML door Twilio. Een openbare Webhook blijft vereist voor status- callbacks, gespreksoproepen, DTMF vóór verbinding, realtime streams en oproepbesturing na verbinding.

    Gebruik één openbaar toegangspad:

    json5
    {plugins: {entries: {"voice-call": {  config: {    publicUrl: "https://voice.example.com/voice/webhook",    // or    tunnel: { provider: "ngrok" },    // or    tailscale: { mode: "funnel", path: "/voice/webhook" },  },},},},}

    Start of herlaad de Gateway na het wijzigen van de configuratie en voer vervolgens uit:

    bash
    openclaw voicecall setupopenclaw voicecall smoke

    voicecall smoke is een proefuitvoering, tenzij je --yes meegeeft.

    Providerreferenties mislukken

    Controleer de geselecteerde provider en de vereiste referentievelden:

    • Twilio: twilio.accountSid, twilio.authToken en fromNumber, of TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN en TWILIO_FROM_NUMBER.
    • Telnyx: telnyx.apiKey, telnyx.connectionId, telnyx.publicKey en fromNumber, of TELNYX_API_KEY, TELNYX_CONNECTION_ID en TELNYX_PUBLIC_KEY.
    • Plivo: plivo.authId, plivo.authToken en fromNumber, of PLIVO_AUTH_ID en PLIVO_AUTH_TOKEN.

    De aanmeldgegevens moeten op de Gateway-host aanwezig zijn. Het bewerken van een lokaal shellprofiel heeft geen invloed op een Gateway die al actief is, totdat deze opnieuw wordt gestart of zijn omgeving opnieuw laadt.

    Gesprekken starten, maar Webhooks van de provider komen niet aan

    Controleer of de providerconsole naar de exacte openbare Webhook-URL verwijst:

    text
    https://voice.example.com/voice/webhook

    Inspecteer vervolgens de runtimestatus:

    bash
    openclaw voicecall status --call-id <id>openclaw voicecall tailopenclaw logs --follow

    Veelvoorkomende oorzaken:

    • publicUrl verwijst naar een ander pad dan serve.path.
    • De tunnel-URL is gewijzigd nadat de Gateway is gestart.
    • Een proxy stuurt het verzoek door, maar verwijdert of herschrijft de host-/protoheaders.
    • De firewall of DNS routeert de openbare hostnaam naar een andere locatie dan de Gateway.
    • De Gateway is opnieuw gestart zonder dat de Voice Call-Plugin is ingeschakeld.

    Wanneer een reverse proxy of tunnel vóór de Gateway staat, stelt u webhookSecurity.allowedHosts in op de openbare hostnaam, of gebruikt u webhookSecurity.trustedProxyIPs voor een bekend proxyadres. Gebruik webhookSecurity.trustForwardingHeaders alleen wanneer u de proxygrens beheert.

    Handtekeningverificatie mislukt

    Providerhandtekeningen worden gecontroleerd aan de hand van de openbare URL die OpenClaw reconstrueert uit het inkomende verzoek. Als handtekeningen niet kunnen worden geverifieerd:

    • Controleer of de Webhook-URL van de provider exact overeenkomt met publicUrl, inclusief schema, host en pad.
    • Werk bij gratis ngrok-URL's publicUrl bij wanneer de hostnaam van de tunnel verandert.
    • Zorg dat de proxy de oorspronkelijke host- en protoheaders behoudt, of configureer webhookSecurity.allowedHosts.
    • Schakel skipSignatureVerification niet in buiten lokale tests.

    Twilio-deelnames aan Google Meet mislukken

    Google Meet gebruikt deze Plugin voor deelname via inbellen met Twilio. Controleer eerst Voice Call:

    bash
    openclaw voicecall setupopenclaw voicecall smoke --to "+15555550123"

    Controleer vervolgens expliciet het Google Meet-transport:

    bash
    openclaw googlemeet setup --transport twilio

    Als Voice Call correct werkt, maar de Meet-deelnemer nooit deelneemt, controleert u het inbelnummer en de pincode van Meet, en --dtmf-sequence. Het telefoongesprek kan correct werken terwijl de vergadering een onjuiste DTMF-reeks weigert of negeert.

    Google Meet start via voicecall.start het Twilio-telefoongedeelte met een DTMF-reeks vóór de verbinding. Reeksen die van een pincode zijn afgeleid, bevatten de voiceCall.dtmfDelayMs van de Google Meet-Plugin (standaard 12000 ms) als voorafgaande Twilio-wachttekens, omdat de inbelprompts van Meet vertraagd kunnen binnenkomen. Voice Call leidt vervolgens terug naar realtimeverwerking voordat om de introductiebegroeting wordt verzocht.

    Gebruik openclaw logs --follow voor het live faseverloop. Bij een correct werkende Twilio-deelname aan Meet wordt deze volgorde vastgelegd:

    • Google Meet delegeert de Twilio-deelname aan Voice Call.
    • Voice Call slaat DTMF-TwiML voor de verbinding op.
    • De initiële TwiML van Twilio wordt verwerkt en aangeboden vóór de realtimeverwerking.
    • Voice Call biedt realtime-TwiML aan voor het Twilio-gesprek.
    • Google Meet vraagt na de vertraging na DTMF introductiespraak aan met voicecall.speak.

    openclaw voicecall tail toont nog steeds opgeslagen gespreksrecords; dit is nuttig voor de gespreksstatus en transcripties, maar niet elke Webhook-/realtimeovergang verschijnt daar.

    Realtimegesprek heeft geen spraak

    Controleer of slechts één audiomodus is ingeschakeld: realtime.enabled en streaming.enabled kunnen niet beide true zijn.

    Controleer voor realtime Twilio-/Telnyx-gesprekken ook het volgende:

    • Een realtimeprovider-Plugin is geladen en geregistreerd.
    • realtime.provider is niet ingesteld of bevat de naam van een geregistreerde provider.
    • De API-sleutel van de provider is beschikbaar voor het Gateway-proces.
    • openclaw logs --follow toont dat realtime-TwiML is aangeboden, de realtimebridge is gestart en de initiële begroeting in de wachtrij is geplaatst.

    Gerelateerd

    Was this useful?
    On this page

    On this page