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.
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>—d0727a16ist die feste Modulkennung von EventBridge (die ersten acht Zeichen der Modul-IDd0727a16-daf5-47b2-9ad1-f4bcd23ff65b); die UUID identifiziert den einzelnen Webhook - Methoden: je Webhook konfigurierbar —
POST(Standard),GET,PUT,PATCHoderANY(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 zu404. - 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.
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:
- Capability-URL (immer): Nur Aufrufe mit gültiger, aktiver UUID werden angenommen.
Unbekannte und deaktivierte Webhooks sind in der Antwort nicht unterscheidbar (beide
404). - Gemeinsames Geheimnis (optional): Ist im Webhook ein Geheimnis hinterlegt, muss jeder
Aufruf den Header
X-Webhook-Secretmit 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 mit401. Kann ein gespeichertes Geheimnis nicht entschlüsselt werden (z. B. nach einer Datenrücksicherung), lehnt der Webhook alle Aufrufe mit401ab, 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:
| Feld | Inhalt |
|---|---|
method | HTTP-Methode in Großbuchstaben (POST, GET, …) |
path | vollständiger Anfragepfad (/fp/d0727a16/hook/<UUID>) |
remoteAddr | Absenderadresse aus Sicht der Anlage |
contentType | Wert des Content-Type-Headers oder null |
headers | alle Anfrage-Header; Namen kleingeschrieben, Mehrfachwerte mit , zusammengefasst. Cookie wird nie aufgenommen; x-webhook-secret ist durch <redacted> ersetzt |
query | Query-Parameter der URL (ausschließlich aus dem Query-String — der Body wird dafür nicht ausgewertet) |
body | die 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 |
{
"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:
{
"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:
{
"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.
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
| Status | Antwortkörper | Bedeutung |
|---|---|---|
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
- PowerShell
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'
Invoke-RestMethod -Method Post `
-Uri 'https://pbx.example.de/fp/d0727a16/hook/3f2c8a71-5b0e-4d92-a6c4-8e17d9b25f40' `
-ContentType 'application/json' `
-Headers @{ 'X-Webhook-Secret' = 'mein-geheimnis' } `
-Body '{"kunde":{"name":"Muster GmbH"},"ticketId":4711}'
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
413abgewiesen. - 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.