Skip to content

Automations

An automation moves the contacts of a transactional object's contact list through a flow of steps: a trigger, then waits, conditions and actions. You can build it in the DUO editor or with the API.

How a flow works

  • Every automation belongs to a transactional object and uses its contact list. The flow sends messages of that object.
  • A flow starts at one or more entry nodes and follows the child of each node. ifElse and externalEvent nodes have a second branch, child2. A node whose next node is null ends the flow for the contact.
  • A contact is in at most one node of an automation at a time. Its position is kept for about two months.
  • New automations are disabled. Enable them when the flow is ready.
Step Node types
Trigger contactSignup, contactAnniversary, externalEventEntry, smsReceivedEntry
Wait wait, externalEvent, smsReceived
Condition ifElse
Action sendMessage, setField, httpCallback

The settings of each type are described in Automation Node.

Build a flow with the API

Example: when your shop reports a payment, wait one hour; then, if the contact is a VIP customer, send a thank-you message and notify your CRM.

In the commands, {t} is the transactional object ID, {a} the automation ID, and the other {…} are the node IDs returned by each POST.

  1. Create the automation.

    curl -u "username:api_key" -H "Accept: application/json" \
      -d "name=Payment+follow-up" \
      https://app.duo.pt/transactional/{t}/automation
    

    Keep transactionalAutomation.id as {a}.

  2. Add the entry node and name the event.

    curl -u "username:api_key" -H "Accept: application/json" \
      -d "type=externalEventEntry&connectFrom=null&connectTo=null" \
      https://app.duo.pt/transactional/{t}/automation/{a}/node
    
    curl -u "username:api_key" -H "Accept: application/json" \
      -d "x-verb=PUT&event=payment&fields_to_set[argument][]=&fields_to_set[custom_field][]=" \
      https://app.duo.pt/transactional/{t}/automation/{a}/node/{entry}/externalEventEntry
    
  3. Wait one hour.

    curl -u "username:api_key" -H "Accept: application/json" \
      -d "type=wait&connectFrom={entry}&connectTo=null" \
      https://app.duo.pt/transactional/{t}/automation/{a}/node
    
    curl -u "username:api_key" -H "Accept: application/json" \
      -d "x-verb=PUT&period=3600" \
      https://app.duo.pt/transactional/{t}/automation/{a}/node/{wait}/wait
    
  4. Check the contact. Here the custom field {vip_field} of the list must be yes.

    curl -u "username:api_key" -H "Accept: application/json" \
      -d "type=ifElse&connectFrom={wait}&connectTo=null" \
      https://app.duo.pt/transactional/{t}/automation/{a}/node
    
    curl -u "username:api_key" -H "Accept: application/json" \
      --data-urlencode "x-verb=PUT" \
      --data-urlencode "payload[topoperator]=AND" \
      --data-urlencode "payload[condition_field][]={vip_field}" \
      --data-urlencode "payload[condition_operator][]===" \
      --data-urlencode "payload[condition_operand][]=yes" \
      https://app.duo.pt/transactional/{t}/automation/{a}/node/{if}/ifElse
    
  5. Send the message on the true branch.

    curl -u "username:api_key" -H "Accept: application/json" \
      -d "type=sendMessage&connectFrom={if}&connectTo=null" \
      https://app.duo.pt/transactional/{t}/automation/{a}/node
    
    curl -u "username:api_key" -H "Accept: application/json" \
      -d "x-verb=PUT&message={message_id}" \
      https://app.duo.pt/transactional/{t}/automation/{a}/node/{send}/sendMessage
    

    To add steps to the false branch, use connectFrom={if}[1].

  6. Notify your CRM after the message: create a node with type=httpCallback&connectFrom={send}&connectTo=null and configure it as shown in Automation Node.

  7. Enable the automation.

    curl -u "username:api_key" -H "Accept: application/json" \
      -d "x-verb=PUT&id={a}&enabled=true" \
      https://app.duo.pt/transactional/{t}/automation/{a}
    
  8. Fire the event for a customer (Event).

    payload=$(printf '{"type":"automation","node":"externalEventEntry","nodeId":%d}' {entry} | base64 | tr -d '\n')
    curl -u "username:api_key" -H "Accept: application/json" -X POST \
      --data-urlencode "email=ana@example.com" \
      "https://app.duo.pt/transactional/{t}/event/$payload"
    

Check the flow with GET /transactional/{t}/automation/{a} and the messages sent with Transactional Stats.

Waiting for an event

An externalEvent node holds the contact until you fire its event (the contact goes to child) or until period seconds pass (the contact goes to child2). Fire it like an entry event, with "node":"externalEvent" and the node's ID in the payload. Set a timeout only when you need the second branch; with period=0 the contact waits for the event only.

Calling your service

An httpCallback node sends POST <url> (form-encoded, User-Agent: duo/<version>, 60-second timeout) with the parameters you configured. A 2xx answer moves the contact to child. On any other answer, or if the request fails, the contact does not continue, unless you set http_error: then the status code is stored in that custom field and the contact continues. With http_result, the response body is stored in a custom field.

Requests are not signed and not retried. Put a secret token in a static parameter and check it on your side, answer quickly, and make your service safe to call twice for the same contact.

Limitations

  • existingContact and loopingContact nodes are not processed at the moment.
  • The segment of contactSignup and the fields_to_set of event nodes are stored but not applied.
  • Messages sent by an automation have no %Transactional:…% values: use custom fields in them.
  • Contacts that are not subscribed still move through the flow, but receive no messages.