Zum Hauptinhalt springen

Webhook

Verwenden Sie den Webhook-Trigger, wenn ein Flow als Reaktion auf einen HTTP-Aufruf von außerhalb von Business Central starten soll – ein Drittanbieter-Callback, eine eigene Integration, ein Slack-Bot, alles, was JSON per POST senden kann. Der Flow kann vollständig asynchron laufen (der Aufrufer erhält sofort eine leere 200) oder synchron bis zu einem Schritt „Respond to Webhook" (der Aufrufer wartet auf die Antwort des Flows).

Typische Beispiele:

  • Empfangen eines Callbacks vom Zahlungs-Provider und Aktualisieren der zugehörigen Rechnung.
  • Ein Partner-Portal soll einen Auftragsimport auslösen.
  • Als SOAP/REST-Brücke fungieren, die ein eingehendes Payload transformiert und an ein anderes System weiterreicht.

Was passiert, wenn der Flow läuft

  1. Der Aufrufer sendet {activity, secret, payload} per POST an den AutoFlow-Webhook-Endpunkt.
  2. AutoFlow sucht den registrierten Webhook-Flow anhand der activity.
  3. Das übergebene secret wird mit SHA-256 gehasht und (in konstanter Zeit) gegen den hinterlegten Hash verglichen. Stimmt es nicht überein, wird HTTP 401 mit dem Body Unauthorized zurückgegeben; es wird keine Ausführung gestartet, und das übergebene Secret wird nirgendwo geloggt.
  4. Der Flow startet, wobei das Payload als Trigger-Output Payload (eine Zeichenkette mit dem JSON-Body, exakt so wie der Aufrufer ihn gesendet hat) verfügbar ist.
  5. Abhängig vom Antwortmodus des Triggers:
    • Sofortantwort: Der Aufrufer erhält sofort die Standardantwort des Triggers; der Flow läuft asynchron über einen JobQueueEntry weiter.
    • Auf Antwort-Schritt warten: Der Flow läuft synchron im Request-Thread, bis ein Schritt „Respond to Webhook" eine Antwort liefert, das konfigurierte Timeout greift oder der Flow endet. Nach Yield/Timeout laufen verbleibende Schritte asynchron weiter.
vorsicht

Sleep und andere zeitbasierte Verzögerungsschritte dürfen nur nach dem Schritt „Respond to Webhook" stehen. Das Zeitfenster für die synchrone Antwort kann nicht pausiert werden – eine Verzögerung vor „Respond" wird dem Aufrufer als 500-Fehler zurückgegeben.

Der Endpunkt

Es gibt einen zentralen Endpunkt für alle Webhook-Flows. Er ist als unbound OData V4-Funktion auf dem Codeunit-Webservice mse365AFWebhook veröffentlicht:

POST <bc-server>/<instance>/ODataV4/mse365AFWebhook_Invoke?company=<company-name>

Der genaue Host hängt von Ihrer Umgebung ab (BC SaaS, On-Prem, Cosmo Alpaca-Container). Sobald der Flow veröffentlicht ist, zeigt die Flow-Karte die aufgelöste URL im Bereich Webhook-Aufruf an.

Die Authentifizierung erfolgt über die Standard-BC-Webservice-Mechanismen (die beiden unterstützten Wege und die jeweils nötigen Berechtigungen beschreibt der Abschnitt Authentifizierung unten). Der Endpunkt erwartet drei Felder im JSON-Body:

FeldTypPflichtBeschreibung
activitystringjaIdentifiziert den auszuführenden Flow. Wird kleingeschrieben gespeichert; der Vergleich ist case-insensitive.
secretstringjaPro-Flow-Shared-Secret. Wird gegen den SHA-256-Hash in der Trigger-Konfiguration verglichen.
payloadobjectjaBeliebiges JSON, das dem Flow als Trigger-Output Payload zur Verfügung steht.

Die Antwort ist in den Standard-OData-Wrapper eingebettet; das Feld value ist eine JSON-Zeichenkette mit drei verschachtelten Feldern:

{
"@odata.context": "<server>/ODataV4/$metadata#Edm.String",
"value": "{\"statusCode\":201,\"contentType\":\"application/json\",\"body\":\"{\\\"ok\\\":true}\"}"
}

Parsen Sie value, um statusCode, contentType und body der Flow-Antwort zu erhalten. Die äußere HTTP-Schicht ist im Erfolgsfall immer 200; HTTP-Statuscodes außerhalb des 2xx-Bereichs sind Infrastruktur-Fehlern vorbehalten:

  • 404, wenn für die übergebene activity kein Flow registriert ist.
  • 500, wenn eine ungefangene Exception aus dem Runner austritt.

Authentifizierung

Der Endpunkt ist ein Standard-Webservice von Business Central, der Aufrufer authentifiziert sich also über einen der Standard-Mechanismen von BC. In der Praxis gibt es zwei Wege, und jeder braucht die passenden Berechtigungen, sonst schlägt der Aufruf nach der Secret-Prüfung fehl — der Flow muss zum Ausführen BC-Tabellen lesen und schreiben.

Service-to-Service (Microsoft-Entra-Anwendung) — empfohlen

Für ein externes System registrieren Sie eine Microsoft-Entra-Anwendung und rufen den Endpunkt mit einem OAuth-Client-Credentials-Token auf (Scope https://api.businesscentral.dynamics.com/.default). Einrichtung:

  1. Registrieren Sie im Microsoft-Entra-Tenant eine App und erstellen Sie ein Client-Secret (oder Zertifikat).
  2. Öffnen Sie in Business Central Microsoft Entra-Anwendungen, fügen Sie die App über ihre Client-ID hinzu, erteilen Sie die Zustimmung und setzen Sie Status auf Aktiviert.
  3. Weisen Sie der App auf derselben Karte den Berechtigungssatz mse365 AF Integr. (AutoFlow Integration (S2S)) zu.

Dieser letzte Schritt ist entscheidend: Ein Service-to-Service-Aufrufer besitzt keine Business-Central-Benutzerlizenz und erhält daher — anders als ein angemeldeter Benutzer — keinen impliziten Zugriff auf die AutoFlow-Anwendungstabellen. mse365 AF ALL allein genügt für eine Entra-App nicht; mse365 AF Integr. ergänzt den Zugriff auf die Laufzeittabellen (Ausführungsstatus, den Job-Queue-Eintrag, der den Flow ausführt, hinterlegte Anmeldedaten), den sonst die Lizenz beisteuert. Die Begründung steht unter Berechtigungssätze.

Web Service Access Key / Basic Auth — Legacy

Alternativ authentifizieren Sie sich als lizenzierter Business-Central-Service-User mit dessen Web Service Access Key (Basic Auth), wie im Beispiel-Aufruf unten. Da es sich um einen echten lizenzierten Benutzer handelt, ist über die ohnehin nötigen Ausführungsrechte hinaus kein zusätzlicher AutoFlow-Berechtigungssatz erforderlich. Nutzen Sie diesen Weg nur, wo Service-to-Service nicht verfügbar ist — er bindet die Integration an einen lizenzierten, benannten Benutzer und einen langlebigen Schlüssel.

Trigger konfigurieren

Öffnen Sie den Flow-Editor, wählen Sie Wenn ein Webhook empfangen wird, und füllen Sie die Konfigurationskarte aus.

Beschreibung

Beschreibt, wodurch dieser Flow ausgelöst wird. Erscheint in Trigger-Listen und in der Ausführungshistorie.

Activity

  • Zweck: Der eindeutige Schlüssel, den der Aufrufer mitsendet. Pro Activity ist genau ein veröffentlichter Flow zulässig.
  • Tipps: Verwenden Sie einen stabilen, namensraum-fähigen Namen wie crm.customer.updated oder payment-gateway.charge-succeeded. Der Wert wird kleingeschrieben gespeichert, sodass myFlow und MyFlow beim Veröffentlichen als Duplikat erkannt werden.

Secret

  • Zweck: Authentifiziert den Aufrufer. Ohne passendes Secret liefert der Aufruf 401 zurück und es wird keine Ausführung gestartet.
  • Tipps: Klicken Sie auf das Feld Secret (oder dessen Assist-Edit-Button), um einen neuen 32-stelligen Zufallswert zu generieren. Der Klartext wird einmalig in einem Dialog angezeigt; übernehmen Sie ihn sofort in den Secret-Speicher des Aufrufers. In der Flow-Konfiguration wird ausschließlich der SHA-256-Hash persistiert.
  • Ein Secret ist erforderlich – ohne gesetzten Wert ist die Konfiguration ungültig.

Antwortmodus

  • Sofortantwort (Standard): Der Aufrufer erhält sofort die leere Standardantwort; der Flow läuft im Hintergrund. Verwenden Sie dies für Fire-and-Forget-Integrationen.
  • Auf Antwort-Schritt warten: Der Aufrufer wartet, bis der Flow einen Schritt „Respond to Webhook" erreicht (oder das Sync-Timeout greift). Verwenden Sie dies, wenn der Aufrufer eine synchrone Rückmeldung des Flows benötigt.

Sync-Timeout (Sekunden)

  • Zweck: Wie lange die synchrone Phase eines „Auf Antwort-Schritt warten"-Aufrufs laufen darf, bevor der Aufrufer die Standardantwort erhält und der Flow asynchron weiterläuft.
  • Standard: 30 Sekunden. Nur sichtbar, wenn der Antwortmodus „Auf Antwort-Schritt warten" ist.

Standard-Statuscode / Standard-Content-Type

  • Zweck: Was der Aufrufer sieht, wenn der Flow endet, ohne einen Schritt „Respond to Webhook" zu erreichen (Timeout, kein Respond-Schritt vorhanden, Antwortmodus „Sofortantwort").
  • Standard: 200 und application/json.

Payload nicht protokollieren

  • Zweck: Lässt das eingehende Payload aus dem Ausführungsprotokoll weg. Verwenden Sie dies für Webhooks, die sensible Daten transportieren (PII, Zahlungsdaten).

Antwort an den Aufrufer

Wenn der Antwortmodus Auf Antwort-Schritt warten ist, hält der Trigger den HTTP-Request des Aufrufers offen, bis der Flow ein Signal zurückgibt. Dieses Signal ist der Schritt Respond to Webhook, verfügbar in der Essentials-Palette. Platzieren Sie ihn dort, wo der Aufrufer entlassen werden soll – idealerweise so früh wie möglich, mit der eigentlichen Arbeit dahinter.

Im Modus „Sofortantwort" ist der Schritt wirkungslos: Der Aufrufer hat die Standardantwort bereits vor dem Start des Flows erhalten, deshalb wird ein Respond-to-Webhook-Schritt beim Ausführen des Flows ignoriert.

Typische Muster:

  • Erst bestätigen, dann arbeiten: sofort {"received": true} zurückgeben und die langsame Folgearbeit asynchron erledigen.
  • Synchrone Validierung: eine schnelle Prüfung durchführen und dem Partner-Portal ein Urteil zurückgeben (z. B. 422 mit {"approved": false, "reason": "..."}).
  • API-Brücke: ein transformiertes Payload an ein anderes System weiterreichen und dessen Antwort als Webhook-Antwort zurückgeben.

Was passiert, wenn Respond to Webhook läuft

  1. Der Runner wertet den konfigurierten Status Code, Content-Type und Body aus (SmartFields und SmartFormulas werden aufgelöst).
  2. Die Werte werden an den Webhook-Endpunkt als statusCode, contentType und body im Antwort-Wrapper signalisiert.
  3. Der Runner verlässt die synchrone Schleife. Schritte nach Respond to Webhook laufen asynchron über einen JobQueueEntry weiter – aus Sicht des Aufrufers ist der Request bereits beendet.

Endet der Flow (oder läuft das Sync-Timeout des Triggers ab), ohne einen Respond-to-Webhook-Schritt erreicht zu haben, erhält der Aufrufer den im Trigger konfigurierten Standard-Statuscode und Standard-Content-Type mit leerem Body.

Respond-to-Webhook-Schritt konfigurieren

Fügen Sie den Schritt Respond to Webhook dem Flow hinzu und füllen Sie die Konfigurationskarte aus.

Beschreibung

Beschreibt, welche Antwort dieser Schritt liefert – erscheint im Ausführungsprotokoll neben dem Schritt.

Status Code

  • Zweck: Der HTTP-Statuscode, der dem Aufrufer über das Feld statusCode im Wrapper zurückgegeben wird.
  • Bereich: 200..599. 1xx-Codes sind als finale HTTP-Antwort nicht zulässig und werden von der Validierung abgelehnt.
  • Tipps: Verwenden Sie 200/201 für Erfolg, 4xx für Fehler des Aufrufers (422 für Validierungsfehler), 5xx für Backend-Probleme.

Content-Type

  • Zweck: Der MIME-Typ des Bodys. Wird dem Aufrufer über das Feld contentType im Wrapper zurückgegeben.
  • Tipps: application/json ist am gebräuchlichsten; text/plain für Diagnose-Strings, application/xml für SOAP-artige Antworten.

Body

  • Zweck: Der Antwort-Body. Unterstützt SmartFields und SmartFormulas, sodass Sie das Payload aus Outputs vorhergehender Schritte zusammensetzen können.
  • Tipps: Für JSON bauen Sie den Body mit einer SmartFormula wie ${\"customerNo\":\"${trigger.Payload.customerNo}\",\"approved\":true}, um Anführungszeichen nicht von Hand escapen zu müssen.

Beispiel-Aufruf

curl -X POST \
"https://<bc-host>/<env>/ODataV4/mse365AFWebhook_Invoke?company=CRONUS%20AG" \
-u 'serviceuser:<web service access key>' \
-H 'Content-Type: application/json' \
-d '{
"activity": "crm.customer.updated",
"secret": "<the 32-char value you copied at rotate time>",
"payload": { "customerNo": "C-001", "name": "Acme" }
}'

Antwort (HTTP 200, Body):

{
"@odata.context": "https://.../ODataV4/$metadata#Edm.String",
"value": "{\"statusCode\":200,\"contentType\":\"application/json\",\"body\":\"\"}"
}

Der Aufrufer parst statusCode und body aus value.

Best Practices

  • Nur HTTPS verwenden – Ihr Secret steht im Request-Body.
  • Bei Verdacht rotieren – die Aktion „Secret rotieren" macht das alte Secret sofort beim Speichern der Konfiguration ungültig.
  • Payload nicht protokollieren, wenn personenbezogene oder finanzielle Daten transportiert werden.
  • Eindeutige Activity-Namen pro Integration – sie sind faktisch Ihre Endpunkt-Pfade.
  • Schnell antworten. Wenn der Antwortmodus „Auf Antwort-Schritt warten" ist, platzieren Sie Respond to Webhook früh im Flow, damit der Aufrufer nicht durch langsame Folgeschritte blockiert wird; lange laufende Arbeit gehört dahinter.
  • Bewusste Statuscodes wählen. Verwenden Sie 200 nicht für Fehlerfälle – 4xx/5xx machen die Fehlerbehandlung auf Aufruferseite handhabbar.
  • Das Secret nicht zurückspiegeln. Es ist nicht als Flow-Output verfügbar, achten Sie aber darauf, in der Antwort keine Teile des eingehenden Payloads zurückzusenden, die der Aufrufer dort nicht sehen sollte.