Sign inGet Started

Usare i dati dell'applicazione in una sequenza vocale

Usa voice.webhook quando la tua applicazione possiede dati che servono alla chiamata: lo stato di un ordine, un team o la conferma di un appuntamento. Il passaggio restituisce quei dati su success; un passaggio Branch successivo sceglie il percorso in base a essi.

Definire la risposta

Imposta config.output_schema su uno schema di oggetto per i dati restituiti. Il passaggio ha due uscite: success trasporta i dati conformi a quello schema e failure gestisce i problemi tecnici. Se la configurazione è omessa, l'uscita è un oggetto vuoto.

L'input contiene un HTTPS url statico e un oggetto data facoltativo. I dati accettano un oggetto letterale, $literal o un $expr che rappresenta l'intero oggetto. URL dinamici, intestazioni personalizzate e credenziali non sono supportati.

Verificare le richieste

Bird firma ogni richiesta, comprese le continuazioni, con il segreto di callback del tuo spazio di lavoro tramite le intestazioni Standard Webhooks: webhook-id, webhook-timestamp e webhook-signature. La firma copre l'ID, il timestamp e il body esatto. Nelle 24 ore successive alla rotazione di un segreto, webhook-signature contiene una voce v1, per ogni segreto attivo, quindi la verifica riesce con entrambi. Le chiamate possono impiegare circa un minuto per iniziare a firmare con il nuovo segreto, quindi continua ad accettare quello precedente fino alla fine del periodo di sovrapposizione. La tua risposta non è firmata: Bird convalida il certificato TLS del tuo receiver e la connessione HTTPS autentica ciò che il receiver restituisce.

Prima di analizzare il body, verifica le intestazioni sul body grezzo con la funzione verify di una libreria Standard Webhooks. webhooks.unwrap degli SDK analizza gli eventi della piattaforma e non serve per queste richieste. Ruota prima il segreto in Webhooks → Direct callbacks, perché quello iniziale non viene mai mostrato. La firma dimostra che la richiesta è stata firmata da chi possiede il segreto del tuo spazio di lavoro. Anche i tuoi receiver di callback SMS possiedono lo stesso segreto e possono firmare, quindi conservalo solo sui receiver di cui ti fidi. Chiunque possa modificare le sequenze dello spazio di lavoro sceglie l'URL e data. Verifica che target_url sia il tuo URL per rifiutare una richiesta che Bird ha firmato per un altro receiver, e autorizza le azioni di business nel tuo receiver. L'autorizzazione del cliente non viene mai inoltrata.

Le richieste webhook delle sequenze non presentano un certificato client, anche quando il tuo spazio di lavoro impone mTLS. Configura il receiver in modo che accetti connessioni senza certificato client e autentica invece la richiesta firmata.

Confronta il valore firmato webhook-timestamp, un timestamp Unix in secondi, con l'orologio sincronizzato di un server. Rifiuta le richieste spostate di oltre cinque minuti nel passato o nel futuro. Elimina i duplicati in base a webhook-id prima di eseguire effetti collaterali. Se possibile, salva l'ID e il risultato in modo atomico insieme all'azione e restituisci il risultato salvato quando una richiesta si ripete. Ogni continuazione ha un proprio ID. Usa una chiave di idempotenza di business separata se richieste distinte non devono ripetere la stessa azione.

Restituire i dati

Il ricevitore restituisce questa struttura di risposta chiusa:

Esempio di codice
{
  "schema_version": 1,
  "type": "outcome",
  "output": { "status": "confirmed", "message": "Your appointment is confirmed." }
}

output deve corrispondere allo schema configurato. La risposta restituisce dati, non una porta, un ID di nodo o nuovi comandi. Una continuazione è {"schema_version":1,"type":"continue","url":"https://example.com/voice/next"} sull'origine canonica dell'URL originale.

Per instradare la chiamata in base ai dati, collega success a uno step logic.branch con casi come steps.decision.output.status == 'confirmed'. Dichiara il campo nello schema come stringa enum, così il receiver può restituire solo quei valori.

La richiesta contiene l'identità di run, sessione e chiamata, l'identità della sequenza ammessa e del nodo, il tuo data materializzato e results. Inserisci l'input di business in data. Il risultato di un Gather privato diretto può comparire una sola volta in results, e le registrazioni completate riportano un ID quando disponibile. Queste osservazioni non diventano automaticamente campi delle espressioni.

Leggere la richiesta ricevuta dal receiver

Un'esecuzione di test di una bozza invia questa struttura. Gli ID e i timestamp seguenti sono fittizi; la richiesta reale usa il run ammesso e l'occorrenza corrente del nodo:

Esempio di codice
{
  "schema_version": 1,
  "method": "POST",
  "target_url": "https://example.com/decision",
  "run_id": "vsr_01k5yb7p000000000000000000",
  "sequence": {
    "id": "vsq_01k5yb7p000000000000000000",
    "version_id": null,
    "draft_revision": 1,
    "entry_node_id": "start",
    "mode": "test"
  },
  "session_id": "vcs_01k5yb7p000000000000000000",
  "call": { "id": "vcl_01k5yb7p000000000000000000", "orig": null, "dest": null },
  "node": { "id": "decision", "occurrence_id": "00000000-0000-4000-8000-000000000001" },
  "data": { "appointment_id": "appointment_123" },
  "results": []
}

Per un run pubblicato, version_id identifica la versione selezionata e draft_revision è null. Per una chiamata che ha eseguito una definizione inline, id, version_id e draft_revision sono tutti null. mode può essere test o production. Origine e destinazione usano oggetti nullable delle parti della chiamata. Verifica la firma prima di considerare attendibili questi campi di identità.

Un'osservazione Gather in results contiene type: "gather", node_id, l'UUID command_id, digits e reason. Un'osservazione di registrazione contiene type: "recording", l'UUID command_id, state e, quando disponibile, un recording_id. Usa le cifre private solo per la richiesta a cui sono destinate: non diventano output conservati delle espressioni. Le richieste di continuazione mantengono la stessa occorrenza del nodo, e le osservazioni già consegnate vengono rimosse da results.

Gestire gli errori

Un campione tecnico usa la porta failure con {"code":"webhook_unavailable"} o {"code":"webhook_invalid_response"}. Un errore collegato segue il percorso di recupero; uno non collegato fa fallire il run. Un success non collegato termina il run normalmente. Le richieste webhook reali hanno una scadenza di tre secondi e non vengono riprovate automaticamente. L'anteprima non invia alcuna richiesta.

La scadenza di tre secondi include la lettura del segreto di firma. Collega failure a un percorso di recupero, così la chiamata può proseguire quando il receiver non è disponibile o restituisce una risposta non valida. Una richiesta scaduta potrebbe aver già causato un effetto collaterale sul receiver.

Considera privati data, l'identità della chiamata e le cifre del Gather. Limita l'accesso al receiver e al segreto, evita di registrare nei log i body o i segreti e conserva l'input del chiamante solo per il tempo necessario alla tua applicazione. Non inserire dati privati o credenziali negli URL: la traccia della chiamata conserva l'URL completo, inclusa la query. URL e dati configurati e l'output convalidato vengono conservati nella cronologia dei run; le cifre temporanee del Gather sono escluse dall'input acquisito dello step. Restituisci solo i dati di cui la sequenza ha bisogno.

Leggi i dati restituiti in steps.decision.output e gli errori tecnici in steps.decision.error.code. Se i due percorsi si riuniscono, controlla il wrapper con has(steps.decision.output) o has(steps.decision.error) prima di usarlo. Un 200 HTTP dal tuo receiver non indica un esito valido finché il body non rispetta il contratto.

Continua con la documentazione, le guide e gli esempi per questo argomento.