About Metaflows

Metaflows allow functionality to be executed on an in-progress call, triggered by DTMFs from the caller/callee. For instance, a callee could setup a metaflow on their user doc such that when they receive a call, they can press "*9" to initiate a recording of the call.


Actions applied to a call outside of the normal callflow, initiated by the caller(s)

Key Description Type Default Required
binding_digit What DTMF will trigger the collection and analysis of the subsequent DTMF sequence string('1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '*', '#') * false
digit_timeout How long to wait between DTMF presses before processing the collected sequence (milliseconds) integer false
listen_on Which leg(s) of the call to listen for DTMF string('both', 'self', 'peer') false
numbers A list of static numbers with their flows object false
numbers./^[0-9]+$/ #/definitions/metaflow false
patterns A list of patterns with their flows object false
patterns./.+/ #/definitions/metaflow false

A metaflow node defines a module to execute, data to provide to that module, and one or more children to branch to

Key Description Type Default Required
children Children metaflows object false
children./.+/ #/definitions/metaflow false
data The data/arguments of the metaflow module object false
module The name of the metaflow module to execute at this node string(1..64) true

Metaflow structure

Any document can be amended with a "metaflows" top-level key; however, at the moment Kazoo only processes a "metaflows" key on: the account doc, a callflow doc, a user doc, or a device doc.

Let's take a peek

Inside the "metaflows" object should be a familiar couple of keys, plus a couple metaflows-specific options:

  • numbers: An object with keys that correspond to collected DTMF sequence after the binding_digit is pressed
  • patterns: An object with keys of regexes to match against the collected DTMF sequence
  • binding_digit: DTMF to trigger a metaflow; defaults to '*'.
  • digit_timeout_ms: how long to wait for another DTMF before processing the collected DTMFs
  • listen_on: restrict which leg of the call to listen on for DTMF
    • "self": listen for DTMF on the leg of the device/user with the metaflow
    • "peer": listen on the opposite leg of the device/user
    • "both": listen to both legs of the call for DTMF

The keys in the numbers object represent the DTMF sequence to match, minus the binding_digit. If the caller presses '*234', the numbers object will be searched for a key of '234'.

The value of each key is the metaflow object to run on a match. It mirrors the callflow's action format:

  • module: Which metaflow module to execute
  • data: An object with module-specific data for execution
  • children: An object of children metaflow actions (optional)
            ,"data":{"text":"hello world"}

The keys in the patterns object represent regular expressions to be matched against the collected DTMF sequence (minus the binding_digit as well). The collected DTMFs and the captures (if any) will be included in the data payload.

First, an example patterns object:


This regex will match 1 and any four digits (let's say 2001). The data object will go from empty to:


The callflow metaflow module, in this case, would look at the "captured" list and take the first element. Using that, it would look up a callflow and, if found, ask a callflow app to execute that extension's callflow against the call (why, I'm not sure yet, but it is there).

Binding Digit

What DTMF triggers a metaflow collection? Typically this would be '*' or '#', but could ostensibly be any DTMF.


There is also a global flag in system_config/konami key use_fast_rearm which allows immediate retries of failed entries; defaults to 'false'. When 'true', the binding digit will typically reset the previous input allowing the user to start over at any time if they made a mistake. This also means you can't have the binding digit in the number sequence that follows, because the binding digit will discard the prior digits. For example if your binding digit is '' and you have "123456" number configured when you dial "123456" it will activate metaflow "456", not "123456". An exception to this rule when you need a double binding digit, so binding digit '' and number "" is a valid shortcut. Another valid example is binding digit '' and number "123", so when you dial "123" the first '' is the binding digit that arms metaflows, but the second '' is part of the number and will be treated as "123", not as just "123".

Digit Timeout

How long to wait, in milliseconds, for the next DTMF. Once this timeout expires, the available metaflows will be searched, first numbers then patterns, for one that matches.

Listen On

Most of the time, a metaflow will only be concerned with receiving the DTMF from the call leg of the user/device configured with a metaflow. This is the "self" option (and the default if left unspecified). A metaflow can alternatively listen only to the other leg of the call using "peer", or to both sides of the call using "both".

Putting it together

Remember, this "metaflows" object can be put on any account, callflow, user, or device doc.

      ,"data":{"text":"hello world"}


Using Crossbar to modify metaflows is very simple. There are only three actions:

  • GET - Gets the current metaflows on the document
  • POST - Updates the metaflows on the document
  • DELETE - Removes the metaflows object from the document

There are two URIs used to manipulate metaflows

Account Metaflow URI


This URI is used to manipulate the metaflows available to anyone in the account.

GET - Fetch account metaflows:
curl -v -X GET -H "X-Auth-Token: {AUTH_TOKEN}" http://server:8000/v1/accounts/{ACCOUNT_ID}/metaflows
POST - Update account metaflows:
curl -v -X POST -H "X-Auth-Token: {AUTH_TOKEN}" -H "Content-Type: application/json" http://server:8000/v1/accounts/{ACCOUNT_ID}/metaflows -d '{"data":{"numbers":{"2":{"module":"tts","data":{"text":"2 pressed"}}},"binding_digit":"*","patterns": {"^1(\\d+)$": {"module": "callflow"}}}}'
DELETE - Remove account metaflows:
curl -v -X DELETE -H "X-Auth-Token: {AUTH_TOKEN}" http://server:8000/v1/accounts/{ACCOUNT_ID}/metaflows
Callflow/User/Device/etc Metaflow URI


Here, {THINGS} would be "callflows", "users", "devices", etc, and {THING_ID} would be a callflow, user, device, or whatever id. Let's look at adding metaflows to a device.

GET - Fetch device metaflows:
curl -v -X GET -H "X-Auth-Token: {AUTH_TOKEN}" http://server:8000/v1/accounts/{ACCOUNT_ID}/devices/{DEVICE_ID}/metaflows
POST - Update device metaflows:
curl -v -X POST -H "X-Auth-Token: {AUTH_TOKEN}" -H "Content-Type: application/json" http://server:8000/v1/accounts/{ACCOUNT_ID}/devices/{DEVICE_ID}/metaflows -d '{"data":{"numbers":{"2":{"module":"tts","data":{"text":"2 pressed"}}},"binding_digit":"*"}}'
DELETE - Remove device metaflows:
curl -v -X GET -H "X-Auth-Token: {AUTH_TOKEN}" http://server:8000/v1/accounts/{ACCOUNT_ID}/devices/{DEVICE_ID}/metaflows


Metaflows can be configured to be started without needing to attach them to a device, user, etc. You can configure default metaflows on an account or across the system.

To start a metaflow handler for an account: sup kapps_account_config set {ACCOUNT_ID} metaflows default_metaflow true

To start a metaflow for all accounts: sup kapps_config set_default metaflows default_metaflow true

Now, this in and of itself isn't too useful

Edit this page here