line

Automated Reminder Emails

Two workflows to send automated reminder emails if a user doesn't complete a process or a sequence of reminders leading up to an event.

This github project includes two workflows that make use of the Zenaton wait function to send automated email reminders to a user but in different ways.

Workflow 1: Automated emails to remind a user to do something

This workflow will wait for the user to do something inside an application such as upload a document or respond to a notification, etc and continue to send escalating reminders on a defined sequence if the user does not.

Workflow 2: Automated email sequence leading up to an Event

The workflow uses the wait until a date to send a sequence of emails (or it could be a text message) a specified time before an event. The event time could be updated in real time if it has changed.

To see a more complicated variant of this workflow see an example where we calculate the ETA of a deliver and send notifications as the time changes.

Workflow #1 Code:

module.exports.handle = function*({email, max_wait, nb_max_reminder}) {
  let nb_reminder = 0;
  let event = null;

  do {
    // Wait for the event EventA
    event = yield this.wait.event("EventA").for(max_wait);
    if(event === null) {
      yield this.run.task("SendEmail", email, `ReminderA #${nb_reminder + 1}...`, "...");
    }

    nb_reminder++;
  } while ((nb_reminder < nb_max_reminder) && event === null);
  
  if(event) {
    yield this.run.task("SendEmail", email, 'Congrats for EventA', "...");
  }

  // Reset the number of reminder
  nb_reminder = 0;
  do {
    // Wait for the event EventB
    event = yield this.wait.event("EventB").for(max_wait);
    if(event === null) {
      yield this.run.task("SendEmail", email, `ReminderB #${nb_reminder + 1}...`, "...");
    }

    nb_reminder++;
  } while ((nb_reminder < nb_max_reminder) && event === null);
  
  if(event) {
    yield this.run.task("SendEmail", email, 'Congrats for EventB', "...");
  }
};

Workflow #2 Code:

module.exports.handle = function*({email, max_wait, nb_max_reminder}) {
  let nb_reminder = 0;
  let event = null;

  do {
    // Wait for the event EventA
    event = yield this.wait.event("EventA").for(max_wait);
    if(event === null) {
      yield this.run.task("SendEmail", email, `ReminderA #${nb_reminder + 1}...`, "...");
    }

    nb_reminder++;
  } while ((nb_reminder < nb_max_reminder) && event === null);
  
  if(event) {
    yield this.run.task("SendEmail", email, 'Congrats for EventA', "...");
  }

  // Reset the number of reminder
  nb_reminder = 0;
  do {
    // Wait for the event EventB
    event = yield this.wait.event("EventB").for(max_wait);
    if(event === null) {
      yield this.run.task("SendEmail", email, `ReminderB #${nb_reminder + 1}...`, "...");
    }

    nb_reminder++;
  } while ((nb_reminder < nb_max_reminder) && event === null);
  
  if(event) {
    yield this.run.task("SendEmail", email, 'Congrats for EventB', "...");
  }
};

SendEmail Task

const sendGridApiToken = process.env.SENDGRID_API_KEY;
const fromEmail = "contact@your-company.com";

const axios = require('axios');

module.exports.handle = async function(email, subject, content) {
  axios({
    method: 'POST',
    headers: {
      'content-type': 'application/json',
      'authorization': `Bearer ${sendGridApiToken}`,
    },
    url: 'https://api.sendgrid.com/v3/mail/send',
    data: {
      personalizations: [
        {
          to: [ {email: email} ],
          subject: subject
        }
      ],
      content: [
        {
          type: "text/plain",
          value: content
        }
      ],
      from: { email: fromEmail }
    }
  })
};

Dashboard View of a Workflow Instance

Make it your own!

You can fork the project on github and deploy to heroku in a few clicks or download to your local environment to play with it. You can add more rules or steps and trigger actions in other services based on the workflow logic.