Workflows
Introduction
A workflow is something that happens after a submission: an email, a webhook call, or a push to a mailing list or CRM. Each form has its own workflows, on its Workflows tab, and each runs only when its conditions hold.
Creating a workflow
Choose Add Workflow on the form's Workflows tab. A workflow has:
| Setting | |
|---|---|
| Name | For you. Shown in the log. |
| Enabled | A switched-off workflow does not run. |
| Event | Submission Created, Submission Updated (an edit from the control panel, or a visitor editing through submission_handle=), Submission Created or Updated, Submission Status Changed (see below), Draft Saved (a visitor saved the form to finish later) or Draft Reminder (a saved draft has waited the form's reminder days) or Submission Action (someone ran one of the form's submission actions). See Save and resume. |
| Action | Send an email, Call a webhook or Send to a connection. |
| Conditions | Optional. The workflow runs only when they hold for the submitted answers, using the same condition builder as fields. |
Workflows receive every answer, including real file ids for uploads, even when the form does not store submissions or their data. A form with storage turned off is a workflows only form.
When a status changes
Submission Status Changed runs when someone moves a submission to another status on its control panel page, or a submission action moves it. Use it to tell the person who submitted that their application was approved, or to push an accepted lead to a CRM.
Pick which move with conditions: Status is the status it has now, and Previous status is the one it had. "Status is Approved" runs on any move to Approved; add "Previous status is Pending" to run only from Pending.
The same save also runs Submission Updated workflows, first. Submission Created or Updated workflows run once for that save, not twice. The Run workflows switch on the submission's page silences both.
Send an email
| Setting | |
|---|---|
| Recipients | Any number of rows, each delivered as To, Cc or Bcc: a typed address, a member, every member of a role, or a form field. |
| From name, From email, Reply-to, Subject | A blank From uses the site's webmaster name and address, and a blank Subject uses the form's name. The subject, the From name and Reply-to can include answers with {field:HANDLE}, so replying to a notification can go straight to the person who submitted: set Reply-to to {field:email}. Only valid addresses are kept (up to five), and Reply-to is left off when none is. The From email is always a fixed address, because mail sent "from" a visitor's address is usually rejected as spoofed. |
| Message | One of the email theme's messages, such as Submission, which lists every answer, or text written on the workflow. |
| Use the email layout | Wrap the message in the email theme's _layout. |
| Attach uploaded files | Attach the files uploaded with the submission. |
| Attachments | Files from ExpressionEngine's file manager to attach to every email this workflow sends, such as a brochure. |
A form field recipient only sends to an address the field can safely resolve to. Otherwise anyone who submits the form could make your site email any address. The field must be one of:
- an option field whose choices come from Recipients, where each choice has addresses that never reach the page;
- an option field whose choices are Members;
- a field with Allow as Workflow Recipient turned on, such as a "send me a copy" email field. Turn that on only where you mean it.
See Email notifications for a worked example.
Call a webhook
Posts the submission as JSON to a URL.
| Setting | |
|---|---|
| URL | Where to post. |
| Secret | Optional. When set, each request carries an X-Formidable-Signature header: the HMAC-SHA256 of the request body, keyed with the secret. |
| What to send | Any of: the form (id, handle, name), the submission (id, status, member id, date), the answers, and the member who submitted. The event name is always sent. |
| Member details | Which member fields to include, when the member is sent: username, screen name, email address, primary role, join date, and custom member fields. |
| Leave out of the answers | Answers not to send, such as anything sensitive the receiving service does not need. |
To check a signature, compute the HMAC of the raw request body with your secret and compare it with the header in constant time:
<?php
$body = file_get_contents('php://input');
$expected = hash_hmac('sha256', $body, getenv('FORMIDABLE_WEBHOOK_SECRET'));
$given = $_SERVER['HTTP_X_FORMIDABLE_SIGNATURE'] ?? '';
if (! hash_equals($expected, $given)) {
http_response_code(401);
exit;
}
$payload = json_decode($body, true);
// $payload['event'] is always present; the rest depends on "What to send".
Send to a connection
Pushes the submission to a third-party service through a saved connection: a mailing list or a CRM.
| Setting | |
|---|---|
| Connection | Which saved connection to use. |
| Target | The list, audience or object at the provider, where the provider needs one. |
| Mapping | Which form field fills which of the provider's fields. |
Map form fields to email, name, first_name, last_name, phone and company, and each provider translates them into its own field names, so one mapping works with any provider. Any other key is sent as that provider's own custom field, named exactly as the provider knows it.
Reading the results
Every run is recorded, with what it sent and what came back. A form's Workflows tab switches between three views:
- Simple: a table of the form's workflows, each with when it runs, what it does and to whom, whether it has conditions, how its last run went, and whether it's on. Click a name to edit it.
- Detailed: each workflow written out in words, conditions and all.
- Recent runs: the latest runs, filterable by result, with a link to the full log. The tab shows a red dot when a workflow's most recent run failed.
To run workflows in the background with retries, add a queue. Both are covered in The workflow log and queue.
For developers
Formidable calls hooks at each step: formidable_workflow_should_run to veto a workflow, formidable_workflow_email, formidable_webhook_payload and formidable_connection_payload to change what's sent, and formidable_workflow_complete after each run.