Formulare in Workflows
Zuletzt aktualisiert 25 May 2026

Wenn Sie bereits mit Workflows und Flexie Scripting gearbeitet haben, wird Ihnen alles auf dieser Seite vertraut vorkommen. Es ist derselbe __data-Notizblock und dieselbe Art von Listener- und Aktions-Verdrahtung, nur speziell für Formulare.
Die drei Formular-Submit-Listener
Jedes Formular-Submit-Ereignis landet als Workflow-Listener, den Sie als Quelle eines Workflows nutzen können (der allererste Schritt). Welcher Listener gilt, hängt von der Art des Formulars ab:
virtual_workflow.form_submit
__virtual
__data.form_submission.<key>
form.internal_submit
__data.internal_form_submission.data.<key>
virtual_workflow.internal_virtual_entity_submit
__virtual
__data.internal_form_submission.data.<key>
Wenn Sie einen Workflow bauen, dessen Quelle „Listener" ist, und einen dieser Listener auswählen, blendet der Builder die Listener aus, die nicht zum Datensatztyp des Workflows passen. So können Sie nicht versehentlich den falschen Listener mit dem falschen Datensatztyp kombinieren.
1. Der externe (öffentliche) Formular-Listener
Listener-Schlüssel: virtual_workflow.form_submit
Workflow-Datensatztyp: __virtual
Was Sie in __data erhalten
{
"form_submission": {
"<form field key>": "<submitted value>",
"<form field key>": "<submitted value>",
"attachments": [
{ "...file metadata..." }
]
}
}
Die Felder liegen direkt unter form_submission, ohne verschachtelten data-Wrapper und ohne Metadaten zum Absender, denn öffentliche Übermittlungen sind anonym.
Werte auslesen
{# Form had fields "First Name", "Email", "Notes" #}
Hi {{ __data.form_submission['First Name'] }},
We received your message:
{{ __data.form_submission.Notes }}
We'll reply to {{ __data.form_submission.Email }}.
(Klammer-Schreibweise für Schlüssel mit Leerzeichen, siehe Übermittlungen: Klammer-Schreibweise.)
Nützliche Muster
Aus einer öffentlichen Formularübermittlung einen Lead erstellen:
- Trigger: dieser Listener.
- Entscheidung: prüfen, dass
{{ __data.form_submission['Email'] }}nicht leer ist. - Aktion: einen Lead mit Feldwerten aus
__data.form_submission.<key>erstellen. - Aktion: eine eigene Antwort an den Absender zurückschreiben, siehe Eine eigene Antwort schreiben.
2. Der interne entitätsgebundene Formular-Listener
Listener-Schlüssel: form.internal_submit
Workflow-Datensatztyp: Der Datensatztyp, an den das Formular gebunden ist (Lead, Contact, …).
Was Sie in __data erhalten
{
"internal_form_submission": {
"date_added": "2026-05-25 12:34:56",
"__submitted_from_user_id": 7,
"__submitted_from_user_full_name": "John Doe",
"data": {
"<form field key>": "<submitted value>",
"<form field key>": "<submitted value>"
}
}
}
Beachten Sie die zwei Unterschiede gegenüber dem externen Formular:
- Der Wurzelschlüssel ist
internal_form_submission. - Die Felder sind unter einem
data-Unterschlüssel verschachtelt, zusammen mit den Absender-Metadaten.
Außerdem sind, da der Workflow auf dem Datensatz läuft, gegen den das Formular geöffnet wurde, die Felder dieses Datensatzes ebenfalls auf der obersten Ebene verfügbar:
Contact's first name (from the record): {{ first_name }}
Form's first-name field (from submission): {{ __data.internal_form_submission.data['First Name'] }}
Nützliche Muster
Den Datensatz aus dem Formular aktualisieren:
- Trigger: dieser Listener.
- Aktion: den Contact aktualisieren und die Felder aus
__data.internal_form_submission.data.<key>setzen.
Festhalten, wer es war:
{# In a workflow step's "Add a note" action #}
Form "Qualification" submitted by
{{ __data.internal_form_submission.__submitted_from_user_full_name }}
on {{ date(__data.internal_form_submission.date_added, "M j, Y H:i") }}.
3. Der interne virtuelle Formular-Listener
Listener-Schlüssel: virtual_workflow.internal_virtual_entity_submit
Workflow-Datensatztyp: __virtual
Was Sie in __data erhalten
{
"internal_form_submission": {
"__submitted_from_user_id": 7,
"__submitted_from_user_full_name": "John Doe",
"data": {
"<form field key>": "<submitted value>"
}
}
}
Gleiche Wurzel und gleiche Verschachtelung wie beim entitätsgebundenen Formular, aber kein date_added und keine Felder des aktuellen Datensatzes (der Workflow läuft auf dem virtuellen Typ).
Nützliche Muster
Aus einem virtuellen Formular einen neuen Datensatz erzeugen:
- Trigger: dieser Listener.
- Aktion: einen Lead / Contact / Case mit den Feldern aus
__data.internal_form_submission.data.<key>erstellen. - Optional: die ID des neuen Datensatzes (
__data.__entity_inserted_id) speichern und mit Schritten fortfahren, die sie benötigen.
Selbst einen Zeitstempel setzen:
Da dieser Listener kein date_added enthält, verwenden Sie now() in Ihrem ersten Schritt, um den Moment festzuhalten:
{% set submittedAt = now() %}
…und schreiben Sie diesen dann in jeden Datensatz, den Sie erstellen.
Direkter Vergleich: welche Wurzel, welche Verschachtelung, welche Metadaten?
virtual_workflow.form_submit
__virtual
__data-Wurzelform_submission
data-Wrapper)
date_addedform.internal_submit
__data-Wurzelinternal_form_submission
data
date_addedvirtual_workflow.internal_virtual_entity_submit
__virtual
__data-Wurzelinternal_form_submission
data
date_addedMerken Sie sich das; es ist der Spickzettel, der den häufigsten Fehler bei Formular-Workflows verhindert (falscher Pfad zum Wert).
Mitten im Workflow ein Formular an einen Nutzer schicken
Die Aktion „Trigger Internal Form"
Ein Workflow kann während seiner Ausführung ein Formular an einen angemeldeten Nutzer schicken und dann fortfahren, sobald der Nutzer es übermittelt.
Die Einstellungen der Aktion:
| Einstellung | Was sie festlegt |
|---|---|
| Welches Formular | Das interne Formular, das geschickt werden soll. (Muss ein internes Formular sein.) |
| Welcher Nutzer | Der aktuelle Eigentümer, ein bestimmter Nutzer, der Nutzer, der den Workflow ausgelöst hat, oder eine beliebige regelbasierte Auswahl. |
| (Entitätsgebundene Formulare) Welcher Datensatz | Der Datensatz, an den die Übermittlung angehängt werden soll, in der Regel der aktuelle Datensatz, auf dem der Workflow läuft. |
Die Aktion ist sofortig, sie reiht den Schritt nicht in eine Warteschlange ein. Das Formular erscheint sofort beim gewählten Nutzer in seiner Oberfläche, und der nächste Schritt des Workflows läuft, sobald dieser Nutzer das Formular übermittelt. Wenn Sie ein langes Warten zeitlich begrenzen müssen (z. B. „wenn es niemand innerhalb von 24 Stunden ausfüllt, eskalieren"), kombinieren Sie dies mit einem Zweig im Stil eingeschränkter Zeiten.
Es gibt zwei Varianten der Aktion:
form.triggerinternal, für Workflows auf einem echten Datensatztyp (das Formular wird an diesen Datensatz angehängt).form.triggerinternal.virtual, für Workflows auf dem virtuellen Datensatztyp.
Der Builder zeigt Ihnen die richtige für den Workflow, in dem Sie sich befinden.
Eine eigene Antwort pro Übermittlung schreiben
Das ist das Muster, das aus einem Formular eine kleine Request/Response-API macht: Der Absender wartet nach dem Klick auf Senden einen Moment, während der Workflow entscheidet, was er antworten soll, und sieht dann eine auf seine Eingaben zugeschnittene Antwort.
So funktioniert es
- Der Absender klickt auf Senden.
- Flexie speichert die Übermittlung und startet den Workflow.
- Das Frontend fragt bis zu 20 Sekunden lang ab und wartet darauf, dass der Workflow eine Antwort schreibt.
- Der Workflow hat irgendwo in seinem Baum eine Form-Respond-Aktion, die die Antwort erzeugt.
- Wenn diese Aktion läuft, wird die Antwort an den abfragenden Absender ausgeliefert, und er sieht sie.
- Vergehen 20 Sekunden, ohne dass eine Form-Respond-Aktion feuert, fällt das Formular auf sein Standardverhalten nach dem Absenden zurück (die Nachricht oder Weiterleitung, die in den Einstellungen des Formulars festgelegt ist).
Die Aktion „Form Respond"
Die Aktion hat zwei Varianten:
form.form_respond, für Workflows mit entitätsgebundenen internen Formularen.virtual_workflow.form_respond, für Workflows mit externen und virtuellen Formularen.
Die Einstellungen:
| Einstellung | Was sie bewirkt |
|---|---|
| Antworttyp | Einer von message, redirect, error, json (siehe unten). |
| Antwortwert | Der Inhalt der Antwort, berechnet mit Flexie Scripting. |
Form der Antwort
Es gibt genau vier Antworttypen. Wählen Sie den, der dem entspricht, was der Browser des Absenders tun soll:
| Antworttyp | Was der Absender sieht | Nützlich für |
|---|---|---|
message |
Eine Bestätigungsnachricht, die auf dem Formular angezeigt wird | „Danke, wir melden uns bei Ihnen unter {{ __data.form_submission.Email }}." |
redirect |
Der Browser navigiert zu einer URL | Sie auf eine Danke-Seite zu schicken, die von ihren Eingaben abhängt |
error |
Eine rote Fehlermeldung auf dem Formular (das Formular bleibt mit ihren Eingaben offen) | Eine Übermittlung mit Begründung ablehnen („Diese E-Mail ist bereits hinterlegt, bitte melden Sie sich stattdessen an.") |
json |
Ein roher JSON-Body | Wenn Ihr Frontend die Submit-URL des Formulars per JavaScript aufruft und die Antwort programmatisch statt als gerenderte Nachricht möchte |
Beispiel: verzweigte eigene Nachricht
Trigger: Listener — virtual_workflow.form_submit
Step 1: Decision — does {{ __data.form_submission['Email'] }}
match an existing contact?
Yes ─► Form Respond (error):
"An account already exists for that email,
please reset your password."
No ─► Step 2: Create a Contact
Step 3: Form Respond (redirect):
"https://www.yoursite.com/welcome
?id={{ __data.__entity_inserted_id }}"
Hinweise zum Timing
- Das Polling-Fenster beträgt 20 Sekunden. Eine Form-Respond-Aktion, die später feuert, erreicht den Absender nicht; nur die Standardantwort tut das.
- Wenn Ihr Workflow lange braucht, bevor er den Form-Respond-Schritt erreicht (z. B. macht er zuerst einen langsamen Webhook-Aufruf), lassen Sie das Formular besser seine Standardantwort zurückgeben, erledigen die lange Arbeit asynchron und benachrichtigen den Absender anschließend auf anderem Weg (E-Mail, SMS).
- Die Standardantwort des Formulars (in den Formulareinstellungen festgelegt) ist immer der Fallback. Es lohnt sich, sie für sich genommen sinnvoll zu gestalten („Danke, wir melden uns bald"), statt sich darauf zu verlassen, dass Form Respond immer rechtzeitig feuert.
Formulare mit anderen Workflow-Bausteinen kombinieren
Formulare fügen sich in dieselben Workflow-Muster ein wie jeder andere Listener-Trigger:
- Virtuelle Bedingungen: nach den Werten in
__data.form_submission.*oder__data.internal_form_submission.data.*verzweigen. - Lookups: mit
findOne/findManyprüfen, ob ein übermittelter Wert bereits in Ihren Daten existiert. - Die Webhook-Aktion: die Übermittlung an ein anderes System weiterleiten.
- Der KI-Schritt: die KI die Übermittlung klassifizieren lassen („sieht das nach einem Vertriebs-Lead oder einer Support-Frage aus?") und verzweigen.
Schnellreferenzkarte
EXTERNAL public form
listener: virtual_workflow.form_submit
record type: __virtual
read fields as: {{ __data.form_submission['<key>'] }}
no submitter info, no date
INTERNAL entity-bound form
listener: form.internal_submit
record type: the bound type (Lead, Contact, …)
read fields as: {{ __data.internal_form_submission.data['<key>'] }}
read submitter as: {{ __data.internal_form_submission.__submitted_from_user_full_name }}
read timestamp as: {{ __data.internal_form_submission.date_added }}
top-level fields: the record's own fields (e.g. {{ first_name }})
INTERNAL virtual form
listener: virtual_workflow.internal_virtual_entity_submit
record type: __virtual
read fields as: {{ __data.internal_form_submission.data['<key>'] }}
read submitter as: {{ __data.internal_form_submission.__submitted_from_user_full_name }}
(no date_added — use now() if you need one)
WORKFLOW ACTIONS
form.triggerinternal push an internal entity-bound form to a user
form.triggerinternal.virtual push an internal virtual form to a user
form.form_respond write custom response (entity-bound)
virtual_workflow.form_respond write custom response (external / virtual)
RESPONSE TYPES (for *form_respond actions)
message — confirmation message on the form
redirect — send the browser to a URL
error — red error message, form stays open
json — raw JSON body for JS callers
RESPONSE WINDOW
20 seconds from submit; after that, the form's default response is used.
Zurück zu
- Formulare-Überblick: die Übersicht über den Bereich.
- Übermittlungen: ansehen, was gesammelt wurde.
- Workflows: die übergeordnete Automatisierungs-Engine.