---
title: "Anwendungsdaten in einer Sprachsequenz verwenden"
description: "Fragen Sie während eines Anrufs typisierte Daten bei einem HTTPS-Empfänger ab, verzweigen Sie in einem späteren Schritt danach, behandeln Sie technische Fehler explizit und halten Sie private Antworten von gespeicherten Anrufdaten getrennt."
canonical: "https://bird.com/de-de/dokumentation/guides/voice/sequences/code/webhooks"
---

# Anwendungsdaten in einer Sprachsequenz verwenden

Verwenden Sie `voice.webhook`, wenn Ihre Anwendung Daten enthält, die der Anruf benötigt, etwa einen Bestellstatus, ein Team oder eine Terminbestätigung. Der Schritt gibt diese Daten über `success` zurück, und ein späterer Branch-Schritt wählt anhand dieser Daten den Pfad.

## Antwort definieren

Setzen Sie `config.output_schema` auf ein Objektschema für die zurückgegebenen Daten. Der Schritt hat zwei Ausgänge: `success` liefert Daten in diesem Schema, und `failure` behandelt technische Probleme. Ohne Konfiguration ist die Ausgabe ein leeres Objekt.

Die Eingabe enthält eine statische HTTPS `url` und optionale Objektdaten `data`. Für die Daten sind ein literales Objekt, `$literal` oder ein vollständiges Objekt per `$expr` möglich. Dynamische URLs, eigene Header und Anmeldedaten werden nicht unterstützt.

## Anfragen prüfen

Bird signiert jede Anfrage, auch Fortsetzungen, mit dem Callback-Secret Ihres Workspace und verwendet dafür [Standard Webhooks](https://www.standardwebhooks.com/)-Header: `webhook-id`, `webhook-timestamp` und `webhook-signature`. Die Signatur deckt die ID, den Zeitstempel und den exakten Body ab. In den 24 Stunden nach einer Rotation des Secrets enthält `webhook-signature` pro aktivem Secret einen `v1,`-Eintrag, sodass jedes der beiden Secrets die Prüfung besteht. Es kann etwa eine Minute dauern, bis Anrufe mit dem neuen Secret signieren. Akzeptieren Sie das vorherige Secret daher weiter, bis die Überlappung endet. Ihre Antwort wird nicht signiert: Bird prüft das TLS-Zertifikat Ihres Empfängers, und die HTTPS-Verbindung authentifiziert, was er zurückgibt.

Prüfen Sie die Header vor dem Parsen über den unveränderten Body mit der Verify-Funktion einer Standard-Webhooks-Bibliothek. `webhooks.unwrap` in den SDKs parst Plattformereignisse und ist nicht für diese Anfragen gedacht. Rotieren Sie das Secret zuerst unter **Webhooks → Direct callbacks**, da das ursprüngliche Secret nie angezeigt wird. Die Signatur belegt, dass jemand mit Ihrem Workspace-Secret die Anfrage signiert hat. Ihre SMS-Callback-Empfänger haben dasselbe Secret und können ebenfalls signieren. Hinterlegen Sie es daher nur auf Empfängern, denen Sie vertrauen. Wer die Sequenzen des Workspace bearbeiten darf, legt die URL und `data` fest. Prüfen Sie, ob `target_url` Ihre eigene URL ist, damit Sie eine Anfrage ablehnen, die Bird für einen anderen Empfänger signiert hat, und autorisieren Sie geschäftliche Aktionen in Ihrem Empfänger. Die Autorisierung des Kunden wird nie weitergeleitet.

Webhook-Anfragen von Sequenzen legen kein Client-Zertifikat vor, auch wenn Ihr Workspace mTLS erzwingt. Konfigurieren Sie den Empfänger so, dass er Verbindungen ohne Client-Zertifikat annimmt, und authentifizieren Sie stattdessen die signierte Anfrage.

Vergleichen Sie den signierten `webhook-timestamp`, einen Unix-Zeitstempel in Sekunden, mit einer synchronisierten Serveruhr. Lehnen Sie Anfragen ab, die mehr als fünf Minuten in der Vergangenheit oder Zukunft liegen. Deduplizieren Sie anhand von `webhook-id`, bevor Sie Nebeneffekte auslösen. Speichern Sie ID und Ergebnis nach Möglichkeit atomar zusammen mit der Aktion, und geben Sie bei einer wiederholten Anfrage das gespeicherte Ergebnis zurück. Jede Fortsetzung hat eine eigene ID. Verwenden Sie einen separaten geschäftlichen Idempotenzschlüssel, wenn verschiedene Anfragen dieselbe Aktion nicht wiederholen dürfen.

## Daten zurückgeben

Der Empfänger gibt diese geschlossene Antwortstruktur zurück:

```json
{
  "schema_version": 1,
  "type": "outcome",
  "output": { "status": "confirmed", "message": "Your appointment is confirmed." }
}
```

`output` muss dem konfigurierten Schema entsprechen. Die Antwort liefert Daten, keinen Port, keine Knoten-ID und keine neuen Befehle. Eine Fortsetzung ist `{"schema_version":1,"type":"continue","url":"https://example.com/voice/next"}` auf dem kanonischen Origin der ursprünglichen URL.

Um anhand der Daten zu verzweigen, verbinden Sie `success` mit einem `logic.branch`-Schritt mit Fällen wie `steps.decision.output.status == 'confirmed'`. Deklarieren Sie das Feld im Schema als String-`enum`, damit der Empfänger nur diese Werte zurückgeben kann.

Die Anfrage enthält die Identität von Run, Session und Anruf, die Identität der zugelassenen Sequenz und des Knotens, Ihr materialisiertes `data` sowie `results`. Legen Sie geschäftliche Eingaben in `data` ab. Ein direktes privates Gather-Ergebnis kann einmal in `results` erscheinen, und abgeschlossene Aufnahmen enthalten eine ID, sofern verfügbar. Diese Beobachtungen sind nicht automatisch als Ausdrucksfelder verfügbar.

## Die Anfrage an den Empfänger lesen

Ein Testlauf eines Entwurfs sendet diese Struktur. Die IDs und Zeitstempel unten sind fiktiv. Die tatsächliche Anfrage verwendet den zugelassenen Run und das aktuelle Vorkommen des Knotens:

```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": []
}
```

Bei einem veröffentlichten Run identifiziert `version_id` die ausgewählte Version, und `draft_revision` ist null. Bei einem Anruf, der eine [Inline-Definition](/docs/guides/voice/create-calls) ausgeführt hat, sind `id`, `version_id` und `draft_revision` alle null. `mode` kann `test` oder `production` sein. Ursprung und Ziel verwenden nullbare Objekte für Anrufbeteiligte. Prüfen Sie die Signatur, bevor Sie diesen Identitätsfeldern vertrauen.

Eine Gather-Beobachtung in `results` enthält `type: "gather"`, `node_id`, die UUID `command_id`, `digits` und `reason`. Eine Aufnahme-Beobachtung enthält `type: "recording"`, die UUID `command_id`, `state` und, sofern verfügbar, eine `recording_id`. Verwenden Sie private Ziffern nur für die vorgesehene Anfrage. Sie werden nicht zu gespeicherten Ausdrucksausgaben. Fortsetzungsanfragen behalten dasselbe Vorkommen des Knotens bei, wobei bereits zugestellte Beobachtungen aus `results` entfernt sind.

## Fehler behandeln

Ein technisches Ergebnis verwendet den Port `failure` mit `{"code":"webhook_unavailable"}` oder `{"code":"webhook_invalid_response"}`. Ist dieser Port verbunden, folgt der Run dem Wiederherstellungspfad. Ist er nicht verbunden, schlägt der Run fehl. Ein nicht verbundenes `success` beendet den Run regulär. Live-Webhook-Anfragen haben eine Frist von drei Sekunden und werden nicht automatisch erneut versucht. Die Vorschau sendet keine Anfrage.

Die Frist von drei Sekunden schließt das Lesen des Signaturgeheimnisses ein. Verbinden Sie `failure` mit einem Wiederherstellungspfad, damit der Anruf weiterlaufen kann, wenn der Empfänger nicht erreichbar ist oder eine ungültige Antwort zurückgibt. Eine Anfrage mit Zeitüberschreitung kann beim Empfänger bereits eine Aktion ausgelöst haben.

Behandeln Sie `data`, die Anrufidentität und Gather-Ziffern als privat. Beschränken Sie den Zugriff auf den Empfänger und das Geheimnis, protokollieren Sie keine Bodys oder Geheimnisse, und speichern Sie Eingaben von Anrufern nur so lange, wie Ihre Anwendung sie benötigt. Setzen Sie keine privaten Daten oder Zugangsdaten in URLs, denn der Anruf-Trace speichert die vollständige URL einschließlich des Querystrings. Die erstellte URL, die erstellten Daten und die validierte Ausgabe werden im Run-Verlauf gespeichert. Flüchtige Gather-Ziffern sind von der erfassten Schritteingabe ausgenommen. Geben Sie nur Daten zurück, die die Sequenz benötigt.

Lesen Sie zurückgegebene Daten unter `steps.decision.output` und technische Fehler unter `steps.decision.error.code`. Wenn beide Pfade zusammenlaufen, prüfen Sie den Wrapper mit `has(steps.decision.output)` oder `has(steps.decision.error)`, bevor Sie ihn verwenden. Ein HTTP 200 von Ihrem Empfänger bedeutet erst dann ein gültiges Ergebnis, wenn sein Body den Vertrag erfüllt.

## Related resources

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