line

Zenaton Workflow Quick-Start Guide

Browse our quick start guide to build your first workflow: connect internal & external services, trigger actions and write workflow logic using Zenaton functions and plain javascript.

Build your first workflow with Zenaton

Overview

A workflow is a series of steps written in plain javascript code using Zenaton functions to orchestrate data and events across multiple APIs and applications.

  • The Zenaton 'wait for duration' or 'wait for event' functions control the flow of logic within the workflow and trigger steps at the right time.
  • Trigger synchronous or asynchronous tasks in your application using the http connector task function.
  • Send events to a running workflow via http and trigger actions based on their data or if they do not occur.
  • Connect to APIs using our pre-build API connectors to manage authentication for API calls or to any API using http requests.
  • Pass data to a workflow using workflow parameters that are sent at the time of workflow launch or within events as they are received by the workflow.

Workflow structure

A Zenaton workflow has the following structure:

module.exports.handle = function*() { 
// describe your workflow steps here // using the functions below
};

Launch a workflow

There are 2 ways to launch a workflow:

  • via curl from within your application
  • SDK only: schedule a workflow or launch from code (link to docs + open new browser)

A workflow instance is launched with the parameters that you include.

[
  {"id": 123, "name": "John"},
  {"id": 456, "items": [
     {"sku": 987, "name": "item_a"},
     {"sku": 654, "name": "item_b"}
    ]
   }
]

Note: it's a list of JSON serializable objects.

Then don't forget to reference them in your main function:

module.exports.handle = function*(user, cart)

Send events to a workflow

Sending events to a running workflow

  • via curl from within your application
  • SDK only: use Zenaton syntax to send from within your application (link to docs)

An event is composed of a _name_ and _data_, which is a list of JSON serializable objects.

[  
  {
    "name": "updateCart",
    "data": [
      {
       "items": [
         {"sku": 45678, "name": "item_c"},
         {"sku": 29517, "name": "item_d"}
       ]
      }
    ]
  }
]

View executions

View real-time execution data in one place:

  • Error details and logs
  • Event data

Zenaton API connectors

Use our pre-cooked connectors

Use one of our pre-cooked connectors to call an API in your workflow and manage authentication and tokens.

  1. Add a new connector by clicking on 'add new' and enter your credentials.
  2. Initialize the connector in your workflow.
const gmail = this.connector("gmail", "CONNECTOR_ID")
  1. Call the service.
//Request payload
const params = {
    headers: { ... },
    query: { ... },
    body: { ... }
}    

//Synchronous request
const output = yield gmail.get("users/me/messages", params)
  1. Add the code to your workflow of what you want to do with the connector.See our snippets for each connector.
//Example for Github to list my public repositories
const output = yield github.get("/user/repos", { query: { visibility: "public" } });

Call with http connector

Call any other 3rd Party APIs by using our generic http connector Include the HTTP client at the beginning of the workflow

const http = this.connector("http")

Send an HTTP request asynchronously and the workflow will continue running without waiting for a response.

http.post('https://httpbin.org/anything', {body: {...}})

Send an HTTP request synchronously and wait for a response before proceeding to the next step in your workflow by adding the yield keyword

const data = yield http.get('https://httpbin.org/anything')

Add a query-string, headers and body

http.post('https://httpbin.org/anything', {
  query: { foo: 'bar'}
  headers: { 'content-type': 'application/json'},
  body: { name: 'John'}
})

There are 2 ways to trigger processing of tasks on your server:

  • by http calls if your services expose an endpoint
  • if not, install the Zenaton Agent that will act as a queuing client and execute tasks on your servers (link to documentation)

Calling your own services by http

Within a workflow, you can connect to your own services exposing an endpoint, by using our generic http connector (link to documentation):

const http = this.connector("http")    

//asynchronous call

http.post('your_own_endpoint', {body: {...}})    

//synchronous call

const data = yield http.get('your_own_endpoint')

Make sure your services are reachable from the public internet and if needed, add authorization info in the header requests:

http.post('your_own_endpoint', {
  query: { foo: 'bar'}
  headers: { 'content-type': '...', authorization: '{ ... }'},
  body: { name: 'John'}
})

Wait for Time and Events

Wait for a duration

Using seconds

//Wait for 5 days
yield this.wait.for(5 \* 24 \* 3600)

Or using Zenaton duration helpers

const { duration } = require("zenaton")
    
//Wait for 2h40
yield this.wait.for(duration.hours(2).minutes(30))

Learn more about the duration helpers.

Wait until a date

const { datetime } = require("zenaton")

//Wait until next monday at 8:00
yield this.wait.until(datetime.monday().at("8:00"))

Learn more about the datetime helper or how to setup timezones here.

Wait for an event

You can pause a workflow and wait until an event is received.

yield this.wait.event("UserActivatedEvent").forever()

But in case the event doesn't happen, add a time limit to ensure that the workflow will complete:

const { duration } = require("zenaton")    

//Wait for the UserActivatedEvent event until 5 days.
yield this.wait.event("UserActivatedEvent").for(duration.days(5))

The workflow can trigger different steps depending on the event received or the data in the event.

const event = yield this.wait.event("UserActivatedEvent").for(duration.hours(2))    

if (event === null) {
  // the event does not happen within 2 hours.
} else {
  // the event occurs, the workflow receives its data
  const \[name, data] = event    

  if(data.foo === 'bar') {
    //do something
  } else {
    //do something else
  }
}

Learn more about the wait function in our  documentation.