<text> : string, e.g. "Testers"
<template> : string containing expressions, e.g. "Hi @contact.name"
<int> : 32 bit integer
<id> : 32 bit integer containing an object identifier, e.g. 12345
<uuid> : 36 character hexadecimal UUID, e.g. "123e4567-e89b-12d3-a456-426655440000"
<language-code> : 3-digit ISO 639 language code, e.g. "eng"
<language-name> : ISO 639 language name, e.g. "English"
<translatable-text> : <template> | { <language-code>: <template> * }
Example (translated):
{ "eng": "Hello @contact", "fre": "Bonjour @contact" }
Example (untranslated):
"Hello @contact"
<contact-ref> : { "id": <id>, "name": <text> }
Name is used for display purposes in the editor. Example:
{ "id": "1234", "name": "Joe Flow" }
<group-ref> : { "id": <id>, "name": <text> }
Name is used for display purposes in the editor. Example:
{ "id": 2345, "name": "Testers" }
<label-ref> : { "id": <id>, "name": <text> }
Name is used for display purposes in the editor. Example:
{ "id": 3456, "name": "Spam" }
<variable-ref>: { "id": <template> }
The template should contain one of:
"@new_contact"
Example:
{ "id": "@contact.chw_phone" }
<flow>: { "version": 7,
"flow_type": "F" | "M" | "S" | "V",
"base_language": <language-code>,
"action_sets": [ <action-set>* ],
"rule_sets": [ <rule-set>* ],
"entry": <uuid> | null,
"metadata": <metadata> }
Metadata is optional and implementation specific.
<action-set> : { "uuid": <uuid>,
"actions": [ <action>* ],
"destination": <uuid> | null }
The destination must be one of:
null
to make this a terminal node<action> : <reply-action>
| <send-action>
| <email-action>
| <set-language-action>
| <save-to-contact-action>
| <add-to-groups-action>
| <remove-from-groups-action>
| <add-labels-action>
Sends a message to the contact.
<reply-action> : { "type": "reply",
"msg": <translatable-text> }
Sends a message to people other than the contact.
<send-action> : { "type": "send",
"groups": [ <group-ref>* ],
"contacts": [ <contact-ref>* ],
"variables": [ <variable-ref>* ],
"msg": <translatable-text> }
Sends an email to someone.
<email-action> : { "type": "email",
"emails": [ <template>* ],
"subject": <template>,
"msg": <template> }
Sets the contact’s language.
<set-language-action> : { "type": "lang",
"lang": <language-code>,
"name": <language-name> }
Saves an evaluated expression to the contact as a field or their name.
<save-to-contact-action> : { "type": "save",
"field": <text> | null,
"label": <text>,
"value": <template>}
Field must be one of the following:
Adds the contact to one or more groups
<add-to-groups-action> : { "type": "add_group",
"groups": [ (<group-ref> | <template>)* ] }
When a group is a template, only those beginning with “@” are evaluated, and others are assumed to be group names.
Removes the contact from one or more groups
<remove-from-groups-action> : { "type": "del_group",
"groups": [ (<group-ref> | <template>)* ] }
When a group is a template, only those beginning with “@” are evaluated, and others are assumed to be group names.
Adds one or more labels to the incoming message
<add-labels-action> : { "type": "add_label",
"labels": [ (<label-ref> | <template>)* ] }
When a label is a template, only those beginning with “@” are evaluated, and others are assumed to be label names.
<rule-set> : { "uuid": <uuid>,
"ruleset_type": <rule-set-type>,
"label": <text>,
"rules": [ <rule>* ],
"operand": <template> }
<rule-set-type> : "wait_message"
| "wait_recording"
| "wait_digit"
| "wait_digits"
| "webhook"
| "flow_field"
| "form_field"
| "contact_field"
| "expression"
<rule> : { "test": <test>,
"category": <translatable-text>,
"destination": <uuid> | null }
RuleSet types primarily act as a way of having a flow editor store the visual representation of a rule in an intuitive manner for the user.
wait_message
: Wait for text user input, then evaluate response against ruleswait_recording
: Wait for user to record message (ending in #), evaluate against ruleswait_digits
: Wait for user to enter multiple digits (ending in #), evaluate against ruleswait_digit
: Wait for user to enter a single digit, evaluate against ruleswebhook
: Call URL in webhook
with method in webhook_action
passing flow context, save JSON response in @extraflow_field
: Run our rules against a specific flow field (defined in operand)form_field
: Run our rules against a specific form field (defined in operand)contact_field
: Run our rules against a specific contact field (defined in operand)expression
: Run our rules against an expression (defined in operand)Operand defines the value that the rules will be evaluated against. For all wait
ruleset types this is
@step.value
but other types will modify this appropriately. (for example a ruleset_type of contact_field
will have an operand of the form @contact.name
or the like)
The destination must be one of:
null
to make this a terminal rule<test> : <true-test>
| <false-test>
| <and-test>
| <or-test>
| <not-empty-test>
| <contains-test>
| <contains-any-test>
| <starts-with-test>
| <regex-test>
| <has-number-test>
| <equal-test>
| <less-than-test>
| <less-than-or-equal-test>
| <greater-than-test>
| <greater-than-or-equal-test>
| <between-test>
| <has-date-test>
| <date-equal-test>
| <date-after-test>
| <date-before-test>
| <has-phone-test>
| <has-state-test>
| <has-district-test>
Test that always returns true.
<true-test> : { "type": "true" }
Test that always returns false.
<false-test> : { "type": "false" }
Test which returns the AND’ed result of other tests.
<and-test> : { "type": "and", "tests": [ <test>* ] }
Test which returns the OR’ed result of other tests
<or-test> : { "type": "or", "tests": [ <test>* ] }
Test that returns whether the input is non-empty (and non-blank).
<not-empty-test> : { "type": "not_empty" }
Test that returns whether the text contains the given words.
<contains-test> : { "type": "contains", "test": <translatable-text> }
Test that returns whether the text contains any of the given words.
<contains-any-test> : { "type": "contains_any", "test": <translatable-text> }
Test that returns whether the text starts with the given text.
<starts-with-test> : { "type": "starts", "test": <translatable-text> }
Test that returns whether the input matches a regular expression.
<regex-test> : { "type": "regex", "test": <translatable-text> }
Test which returns whether input has a number.
<has-number-test> : { "type": "number", "test": <translatable-text> }
Test which returns whether input is numerically equal a value.
<equal-test> : { "type": "eq", "test": <template> }
Test which returns whether input is numerically less than a value.
<less-than-test> : { "type": "lt", "test": <template> }
Test which returns whether input is numerically less than or equal to a value
<less-than-or-equal-test> : { "type": "lte", "test": <template> }
Test which returns whether input is numerically greater than a value.
<greater-than-test> : { "type": "gt", "test": <template> }
Test which returns whether input is numerically greater than or equal to a value.
<greater-than-or-equal-test> : { "type": "gte", "test": <template> }
Test which returns whether input is a number between two numbers (inclusive).
<between-test> : { "type": "between", "min": <template>, "max": <template> }
Test which returns whether input contains a valid date.
<has-date-test> : { "type": "date" }
Test which returns whether input is a date equal to the given value.
<date-equal-test> : { "type": "date_equal", "test": <template> }
Test which returns whether input is a date after the given value.
<date-after-test> : { "type": "date_after", "test": <template> }
Test which returns whether input is a date before the given value
<date-before-test> : { "type": "date_before", "test": <template> }
Test that returns whether the text contains a valid phone number
<has-phone-test> : { "type": "phone" }
Test that returns whether the text contains a valid state.
<has-state-test> : { "type": "state" }
Test that returns whether the text contains a valid district in the given state.
<has-district-test> : { "type": "district", "test": <template> }