---
title: "Usare i dati dell'applicazione in una sequenza vocale"
description: "Chiedi a un ricevitore HTTPS dati tipizzati durante una chiamata, usali per una diramazione in un passaggio successivo, gestisci esplicitamente gli errori tecnici e tieni le risposte private separate dai dati di chiamata conservati."
canonical: "https://bird.com/it-it/documentazione/guides/voice/sequences/code/webhooks"
---

# 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](https://www.standardwebhooks.com/): `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:

```json
{
  "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:

```json
{
  "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](/docs/guides/voice/create-calls), `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.

## Related resources

- [Voice sequences](/docs/guides/voice/sequence-builder) (docs)
