line

New User Activation Emails: Wait for events and trigger emails

This sample project is an in-product notification workflow that triggers emails within a web app when the user completes actions. Emails are sent via our connector Sendgrid. Our example is based on a Zenaton new user journey but can easily be configured to send emails and trigger actions based on any events within an application or external services.

Workflow Logic

When a new user registers, we start a new "NewUserWorkflow instance for that user.

This workflow will wait for events and send emails when the events happen. The workflow can run for days, months or even longer if the events we are waiting for happen later.

new user workflow

In our sample web_app, we send 2 events to our workflow to trigger activities ('installed agent', and 'ran first workflow').

We use several Zenaton functions in our workflow such as 'wait for event' and 'wait for duration' and connectors to manage the authentication for sendgrid and Airtable.

The github repository is split into two directories:

  • web_app: A simple NodeJS web app where we launch the workflow instance per user and send events when the user completes each action
  • worker: Runs our workflow and tasks and receives the events for each workflow instance.

Web_App UI for testing

We've provided a simple UI in the web_app that allows you to simulate the user events (register and install agent or launch workflow) to trigger actions in the workflow and see the corresponding tasks executions on your Zenaton dashboard:

web app sample project

When a user registers in our web app, we start a workflow instance web_app/server.js

app.post('/api/register', function (req, res) {
  console.log(`Register a new user: ${req.body.email}`)
  const user = { ...req.body }

  // Launch the 'OnboardingWorkflow' Zenaton Workflow.
  // We pass the user as a parameter to this new workflow instance.
  // the withTag function is used to give the new instance an ID
  // so we will be able later to send an event to it.
  client.run.withTag(user.email).workflow('NewUserWorkflow')

  res.json()
})

We will send each product event to the specific user's workflow instance from within our web_app.

app.post('/api/event', function (req, res) {
  console.log(`Send the event '${req.body.event.name}' for the user '${req.body.email}'`)

  // Send an event to a Zenaton Workflow instance
  client.select
    .workflow('NewUserWorkflow')
    .withTag(req.body.email)
    .send(req.body.event.name, req.body.event.data)

  res.json()
})

Our basic workflow logic is at worker/src/Workflows/OnboardingWorkflow_basicEmail.js

"use strict";
const { workflow, duration } = require('zenaton')

module.exports = workflow('OnboardingWorkflow_basicEmail', function* (user) {
  // Wait a maximum of 1 month for user to install the agent.
  const install_agent_event = yield this.wait.event("install_agent").for(duration.months(1))
  if (null === install_agent_event) {
    // If the user has not installed the agent within 1 month.
    // Send an email to recommend tutorial.
    yield this.run.task('SendEmailWithSendgrid', {
      email: user.email, subject: 'What are the next steps ?', content: 'Have you seen our tutorial ?'
    })
  } else {
    // When the user installs the agent. Wait a maximum of 20 minutes for the user to launch a workflow.
    const launch_workflow_event = yield this.wait.event('launch_workflow').for(duration.minutes(20))
    if (null === launch_workflow_event) {
      // The user did not launch a workflow within 20 minutes.

      // Send an email to offer technical assistance.
      yield this.run.task('SendEmailWithSendgrid', {
        email: user.email, subject: 'Need some help ?', content: 'TDB'
      })
    } else {
      // The user installed the agent and ran a workflow.
      yield this.wait.for(duration.hours(3))
      // Send an email to congratulate the user and offer resources and suggestions for next steps.
      yield this.run.task('SendEmailWithSendgrid', {
        email: user.email, subject: 'What are the next steps ?', content: 'Look at our real-world examples ...'
      })
    }
  }
})

Three workflow versions to send emails

We have provided 3 variants of this workflow depending on how we want to send the emails. We've used the Zenaton Sendgrid API connector but you can also build your own connector to other mail services.

Basic Version: send text email using sendgrid

Template with Conditional Blocks: send email by triggering the sendgrid dynamic template feature that segments sections of the email based on input variables.

Hybrid: Send email via sendgrid and pull dynamic text from airtable database dependent on variables. This would allow non-technical people to easily edit the text content using AirTable. You could change this to pull from any database.

Deploy Workflow on Heroku

To deploy the basic workflow version that send text email using sendgrid, you will need to:

- Set up your SendGrid api connector on the Zenaton dashboard using our guide

- Fork the repo so that you can easily change the variables and logic within the workflow and see the impact

- Deploy it using this button Deploy. We also have other deployment options

Then you can start to use it:

- Click on 'Register' to simulate signup which launches the workflow instance for a user

- Click on the 'installation' and 'activation' buttons to simulate sending events to the running workflow for that user

Note: you can also change the 'wait' duration to 5 seconds to speed up your testing experience.