Zum Hauptinhalt springen

Eingehende Webhooks

EventBridge stellt je konfiguriertem Webhook eine eindeutige HTTP(S)-Adresse bereit, über die externe Systeme — CRM, Ticketsystem, HR-Software, n8n, Monitoring — ohne STARFACE-Anmeldung Aktionen in der Anlage auslösen. Ein angenommener Aufruf wird in ein Fluxpunkt-Ereignis (FpEvent) übersetzt; darauf reagieren gewöhnliche Event-Handler mit Bedingungen, Verzögerungen und der vollen Palette ausgehender Aktionen. Die Verwaltung erfolgt im Tab Webhooks der Modulkonfiguration.

Verwendung durch Dritte

Diese Schnittstelle ist für die Nutzung durch Drittsysteme freigegeben. Änderungen und Erweiterungen werden je Version in den Release Notes dokumentiert.

Grundlagen

  • Typ: HTTP(S)-Endpunkt mit JSON-Antworten (application/json)
  • URL-Schema: https://<starface-host>/fp/d0727a16/hook/<UUID>d0727a16 ist die feste Modulkennung von EventBridge (die ersten acht Zeichen der Modul-ID d0727a16-daf5-47b2-9ad1-f4bcd23ff65b); die UUID identifiziert den einzelnen Webhook
  • Methoden: je Webhook konfigurierbar — POST (Standard), GET, PUT, PATCH oder ANY (alle Methoden)
  • Authentifizierung: Capability-URL mit zufälliger 128-Bit-UUID; optional zusätzlich ein gemeinsames Geheimnis im Header X-Webhook-Secret
  • Nutzlast: beliebig; JSON wird strukturiert ausgewertet, maximal 1 MiB je Anfrage
  • Lizenz: Aktivieren eines Webhooks erfordert eine gültige Modullizenz; inaktive Webhooks antworten wie unbekannte mit 404
  • Verfügbar seit: Modulversion 26.7.23

URL-Aufbau und Verwaltung

Die UUID wird ausschließlich serverseitig erzeugt (zufällige 128-Bit-UUID, 36 Zeichen) und ist über die Moduloberfläche nicht änderbar. Es gelten folgende Regeln:

  • Genau ein Pfadsegment: Nach /hook/ folgt die UUID; ein abschließender / wird toleriert. Zusätzliche Pfadsegmente führen zu 404.
  • URL erneuern: Neue URL generieren erzeugt sofort eine neue UUID; die alte Adresse antwortet ab diesem Moment mit 404.
  • Duplizieren: Eine Kopie erhält immer eine neue UUID und startet inaktiv.
  • Löschen: Entfernt den Webhook einschließlich seiner aufgezeichneten Aufrufe.

Der Pfad /fp/…/hook/… liegt bewusst außerhalb der STARFACE-Anmeldung: Es läuft dort kein Authentifizierungsfilter der Anlage. Die nicht erratbare UUID ist der Zugangsschlüssel.

URL wie ein Passwort behandeln

Wer die vollständige URL kennt, kann den Webhook auslösen. Übertragen Sie sie nur über sichere Kanäle, hinterlegen Sie für exponierte Endpunkte zusätzlich ein Geheimnis (X-Webhook-Secret) und generieren Sie die URL bei Verdacht auf Weitergabe neu. Eine Häufung von 401-Aufrufen im Panel Letzte Aufrufe deutet auf eine bekannt gewordene URL hin.

Authentifizierung

Zwei Stufen, beide serverseitig geprüft, bevor Nutzdaten verarbeitet werden:

  1. Capability-URL (immer): Nur Aufrufe mit gültiger, aktiver UUID werden angenommen. Unbekannte und deaktivierte Webhooks sind in der Antwort nicht unterscheidbar (beide 404).
  2. Gemeinsames Geheimnis (optional): Ist im Webhook ein Geheimnis hinterlegt, muss jeder Aufruf den Header X-Webhook-Secret mit exakt diesem Wert tragen. Der Vergleich erfolgt in konstanter Zeit; das Geheimnis wird verschlüsselt gespeichert. Fehlt der Header oder stimmt der Wert nicht, antwortet der Endpunkt mit 401. Kann ein gespeichertes Geheimnis nicht entschlüsselt werden (z. B. nach einer Datenrücksicherung), lehnt der Webhook alle Aufrufe mit 401 ab, statt die Prüfung stillschweigend zu deaktivieren (fail-closed).

401-Versuche werden im Panel Letzte Aufrufe vermerkt, jedoch ohne ihre Nutzlast — nicht autorisierte Absender können den Aufzeichnungspuffer nicht mit eigenen Inhalten füllen.

Verarbeitung der Nutzlast

Der Anfrage-Umschlag (Envelope)

Jeder angenommene Aufruf wird in ein JSON-Objekt — den Envelope — verpackt. Auf dieses Objekt beziehen sich alle JsonPath-Ausdrücke des Webhooks:

FeldInhalt
methodHTTP-Methode in Großbuchstaben (POST, GET, …)
pathvollständiger Anfragepfad (/fp/d0727a16/hook/<UUID>)
remoteAddrAbsenderadresse aus Sicht der Anlage
contentTypeWert des Content-Type-Headers oder null
headersalle Anfrage-Header; Namen kleingeschrieben, Mehrfachwerte mit , zusammengefasst. Cookie wird nie aufgenommen; x-webhook-secret ist durch <redacted> ersetzt
queryQuery-Parameter der URL (ausschließlich aus dem Query-String — der Body wird dafür nicht ausgewertet)
bodydie Nutzlast: gültiges JSON wird als Struktur eingebettet (JsonPath in die Tiefe möglich), alles andere als unveränderte Zeichenkette. Die JSON-Erkennung erfolgt am Inhalt, nicht am Content-Type
Envelope eines POST-Aufrufs (Beispiel)
{
"method": "POST",
"path": "/fp/d0727a16/hook/3f2c8a71-5b0e-4d92-a6c4-8e17d9b25f40",
"remoteAddr": "203.0.113.10",
"contentType": "application/json",
"headers": {
"host": "pbx.example.de",
"user-agent": "curl/8.5.0",
"accept": "*/*",
"content-type": "application/json",
"content-length": "48",
"x-webhook-secret": "<redacted>"
},
"query": {},
"body": {
"kunde": { "name": "Muster GmbH" },
"ticketId": 4711
}
}

Das Panel Letzte Aufrufe zeigt für jeden angenommenen Aufruf genau diesen Envelope an — die verlässlichste Vorlage beim Verfassen der JsonPath-Ausdrücke.

Variablen-Extraktion (Parser)

Die Parser-Zeilen des Webhooks bilden Envelope-Werte auf frei benannte {{Variablen}}-Platzhalter ab — je Zeile entweder ein JsonPath in den Envelope ($.body.kunde.name, $.headers.x-signature, $.query.personId, $.remoteAddr, …) oder ein fester Wert. Skalare Treffer werden zur Zeichenkette; Objekte und Arrays werden als JSON-Text übernommen; ein nicht vorhandener Pfad lässt die Variable unbelegt.

Zusätzlich stehen ohne Konfiguration die impliziten Variablen {{webhookId}} und {{webhookName}} (ID und Name des aufgerufenen Webhooks) bereit. Es gilt die Rangfolge Parser-Variablen > implizite Variablen > Zustandsvariablen > globale Variablen — Details in der Platzhalter-Referenz.

Ereignis-Erzeugung

Aus der JSON-Vorlage des Webhooks (Feld Ereignis + Vorlage, identisch zur Aktion „Neues Event generieren") entsteht das veröffentlichte Ereignis. Die Standardvorlage erzeugt ein InboundWebhookReceivedEvent:

Standardvorlage des erzeugten Ereignisses
{
"webhookId": "{{webhookId}}",
"webhookName": "{{webhookName}}",
"data": {
"example": "{{variable}}"
}
}

Mit den Parser-Zeilen kundenName = $.body.kunde.name und ticketId = $.body.ticketId wird aus dem Envelope-Beispiel oben dieses Ereignis:

Veröffentlichtes Ereignis (Beispiel)
{
"webhookId": "9f3a21c4",
"webhookName": "Ticket-Import",
"data": {
"kundenName": "Muster GmbH",
"ticketId": "4711"
}
}

Ein Webhook besitzt selbst keine Bedingungen und keine Aktionen — beides übernimmt der Event-Handler, der auf das erzeugte Ereignis lauscht (Ereignisauswahl InboundWebhookReceivedEvent, Kategorie FLUXPUNKT der Ereignisliste). Der Handler extrahiert die Werte per $.data.… bzw. $.webhookName, filtert per MVEL-Bedingung und führt eine beliebige ausgehende Aktion aus. Ist im Webhook kein Ereignis konfiguriert, wird der Aufruf angenommen (200), ohne ein Ereignis zu veröffentlichen.

Aus Sicherheitsgründen werden Werte aus dem Aufruf beim Füllen der Vorlage nicht rekursiv ersetzt: Enthält ein übermittelter Wert selbst eine Zeichenfolge wie {{apiKey}}, bleibt sie wörtlich erhalten und expandiert nicht gegen globale oder Zustandsvariablen der Anlage.

Anwendungsbeispiel

Eine HR-Software meldet das Einstempeln per Webhook (personId = $.body.payload.person.id). Der Event-Handler lauscht auf InboundWebhookReceivedEvent, prüft per Bedingung personId == "343536" und meldet den zugehörigen Benutzer über ein internes Ereignis an seinen Gruppen an — ohne eine Zeile Code.

Statuscodes

StatusAntwortkörperBedeutung
200{"ok":true}Aufruf angenommen; das konfigurierte Ereignis wurde veröffentlicht
401{"ok":false,"error":"unauthorized"}Header X-Webhook-Secret fehlt, ist falsch — oder das gespeicherte Geheimnis ist nicht entschlüsselbar (fail-closed)
404{"ok":false,"error":"unknown-webhook"}UUID unbekannt oder Webhook deaktiviert (bewusst nicht unterscheidbar); auch bei zusätzlichen Pfadsegmenten
405{"ok":false,"error":"method-not-allowed"}HTTP-Methode entspricht nicht der konfigurierten Methode
413{"ok":false,"error":"body-too-large"}Nutzlast größer als 1 MiB
500{"ok":false}interner Fehler bei der Verarbeitung des Aufrufs

200 bestätigt Annahme und Ereignis-Veröffentlichung — nicht die Ausführung nachgelagerter Handler-Aktionen; diese laufen asynchron.

Beispiele

curl -X POST \
-H 'Content-Type: application/json' \
-H 'X-Webhook-Secret: mein-geheimnis' \
-d '{"kunde":{"name":"Muster GmbH"},"ticketId":4711}' \
'https://pbx.example.de/fp/d0727a16/hook/3f2c8a71-5b0e-4d92-a6c4-8e17d9b25f40'

Antwort 200 OK:

{"ok":true}

Ist als Methode GET oder ANY konfiguriert, genügt ein Aufruf mit Query-Parametern — die Werte stehen dann unter $.query.… bereit:

curl 'https://pbx.example.de/fp/d0727a16/hook/3f2c8a71-5b0e-4d92-a6c4-8e17d9b25f40?personId=343536&aktion=kommen'

Limits

  • Nutzlastgröße: maximal 1 MiB je Anfrage; größere Anfragen werden vor jeder Verarbeitung mit 413 abgewiesen.
  • Ratenbegrenzung: Der Endpunkt besitzt keine eingebaute Ratenbegrenzung. Begrenzen Sie exponierte Endpunkte bei Bedarf netzseitig (Firewall, Reverse Proxy).
  • Aufruf-Aufzeichnung: Je Webhook werden die letzten 10 Aufrufe im Arbeitsspeicher vorgehalten (Panel Letzte Aufrufe); ein Modulneustart leert den Puffer.
  • Cookies: Der Cookie-Header wird grundsätzlich verworfen und erreicht weder Envelope noch Ereignis.

Fehlerbehandlung

Jeder Aufruf eines bekannten Webhooks wird — auch im Fehlerfall — mit Zeitstempel, Absenderadresse, Methode, Statuscode und Ergebnis (ok, method-mismatch, secret-mismatch, error) im Panel Letzte Aufrufe aufgezeichnet; bei 401 ohne Nutzlast. Aufrufe unbekannter UUIDs werden bewusst weder aufgezeichnet noch protokolliert, damit Hintergrundrauschen auf dem öffentlichen Pfad keine Spuren füllt. Verarbeitungsfehler (500) erscheinen zusätzlich im Modul-Log.

Prüfreihenfolge bei ausbleibender Reaktion des Zielsystems: Antwortet der Endpunkt 200 (siehe Letzte Aufrufe)? Lauscht ein aktiver Event-Handler auf das erzeugte Ereignis? Trifft dessen Bedingung zu (Testfunktion des Handlers)?

Versionierung & Kompatibilität

Die Schnittstelle trägt keine Versionsnummer im Pfad. Envelope-Feldnamen, die impliziten Variablen {{webhookId}}/{{webhookName}} und die dokumentierten Statuscodes gelten als stabiler Vertrag; abwärtskompatible Erweiterungen (zusätzliche Envelope-Felder) können ohne Versionswechsel hinzukommen. Änderungen werden je Modulversion in den Release Notes dokumentiert. Die URL eines Webhooks ändert sich nie automatisch — nur durch Neue URL generieren oder Duplizieren.