SaasEmail Marketing

How to send automated email sequences using Node.js and Candymail

The Candymail NPM package allows you to send marketing email sequences directly from your Node.js server from a single JSON file. Think of it as a docker.yaml but for email marketing.

Featured Image

Automated email sequences are an incredible marketing tool for any startup. An email inbox is one of the few 1:1 marketing channels at your disposal. Use it well.

The Candymail NPM package allows you to send marketing email sequences directly from your Node.js server from a single JSON file. Think of it as a **docker.yaml** but for email marketing.

Full docs — https://candymail.saasbase.dev

Let’s say we are building a brand new video editor for the web and looking to delight our new users. We can set up an **Onboarding** email sequence that welcomes our users and slowly introduces them to the platform.

Let’s get started.

Step 1: Define the Onboarding Email Sequence

Here are 3 emails I would add to my sequence to onboard a new user:

  1. Welcome the user immediately when they sign up
Subject: Welcome to VideoMaker+ Thanks for joining! You’re officially a part of the VideoMaker+ family! Join 100’s of passionate filmmakers like you making a difference in everyday life by making the most wonderful content.
  1. 1 day later — Show the user the most basic way to get started with the platform
Subject: How to edit your first video? Ready to get started? Here’s how you can add subtitles to your first video and add some flair: 1. Record 1-min video of you talking into the camera 2. Import the footage into VideoMaker+ app 3. Click on Effects > Retro 4. Turn on: Automatic Subtitles 5. Export! And that’s it. You now have a retro-looking video with auto-generated subtitles ready to be shared with the world!
  1. 3 days later — Check up on how they’re doing and gather feedback
Subject: A friendly check-in from VideoMaker+ Looks like you’ve been using VideoMaker+ in the last few days — and we love that! I just wanted to quickly check-in and how your experience has been with our service. 1. How did you hear about VideoMaker+? 2. What do you like/dislike about VideoMaker+? 3. What can we do to improve your experience? Now that we know what the content is going to look like. Let’s create our automation file.

Step 2: Create a new automation file

Candymail uses a single JSON file to describe the automation sequence. The above definition can be encoded into a candymail.automation.json like so,

{ "workflows": [ { "name": "onboarding", "description": "Onboard new VideoMaker+ users", "trigger_name": "onboarding", "emails": [ { "trigger": "time", "sendDelay": 1, "subject": "Welcome to VideoMaker+", "body": "<div style='text-align:left'><p>Thanks for joining!<br/><br/>You're officially a part of the VideoMaker+ family! Join 100's of passionate film makers like you making a difference in everyday life by making the most wonderful content.</p></div>", "from": "[email protected]" }, { "trigger": "time", "sendDelay": 24, "subject": "How to edit your first video?", "body": "<div style='text-align:left'><p>Ready to get started? Here's how you can add subtitles to your first video and add some flair:</p><br/><p>1. Record 1-min video of you talking into the camera<br/> 2. Import the footage into VideoMaker+ app<br/> 3. Click on Effects &gt; Retro<br/> 4. Turn on: Automatic Subtitles<br/> 5. Export!</p><br/><p>And that's it. You now have a retro looking video with auto-generated subtitles ready to be shared with the world!</p></div>", "from": "[email protected]" }, { "trigger": "time", "sendDelay": 72, "subject": "A friendly check-in from VideoMaker+", "body": "<div style='text-align:left'><p>Looks like you've been using VideoMaker+ in the last few days - and we love that! I just wanted to quickly check-in and how your experience has been with the app.</p><br/><p>1. How did you hear about VideoMaker+?<br/>2. What do you like/dislike about VideoMaker+?<br/>3. What can we do to improve your experience?</p></div>", "from": "[email protected]" } ] } ] }

Note: Remember to change the [email protected] to your own sender email address.

Step 3: Set up a basic Express Server

Create a new folder.

Let’s initialize our project by creating a package.json

npm init -y

Install dependencies with a quick,

npm install express

Add another file named app.js

const express = require('express'); const port = 3000; const app = express(); app.get('/', async function(req, res, next) { res.send('Hello World!') }); app.listen(port, () => console.log(`Listening on port ${port}!`);)

We can now run our simple server by running,

npm start

Our application should be live at http://localhost:4242.

Step 4: Install Candymail

Import the candymail.automation.file to the root level of the project directory.

Let’s install Candymail by running,

npm install --save candymail

In app.js,

require('dotenv').config(); const candymail = require('candymail'); const express = require('express'); const app = express(); const port = 3000; const automation = require('./candymail.automation.json') candymail.init(automation.workflows, { mail: { host: 'smtp.gmail.com', port: 465, secure: true, auth: { user: process.env.MAIL_USER, pass: process.env.MAIL_PASSWORD, }, tls: { rejectUnauthorized: true, }, }, hosting: { url: process.env.HOSTING_URL }, db: { reset: true }, debug: { trace: true }, }).then((e) => { candymail.start(); app.get('/', async (req, res) => { res.send('Go to /start to trigger the first workflow'); }); app.listen(port, () => { console.log(`Learn about our new features at http://localhost:${port}`) }); })

Step 5: Add env vars

Create a file at root called .env

[email protected] MAIL_PASSWORD=password [email protected] HOSTING_URL=http://localhost:3000

Step 6: Set up a "Sign up" endpoint

Let’s set up an /signup endpoint to capture when a user successfully signs up.

app.post("/signup", (req, res) => { const user = process.env.RECIPIENT_EMAIL; candymail.runWorkflow("onboarding", user); res.send("onboarding started"); });

Perfect! Now when the user [email protected] signs up, they will receive a sequence of 3 emails as part of the onboarding process.

But what if the user doesn't want to not receive the emails anymore? Fear not, every email is sent out with an **Unsubscribe** link in the footer that makes a GET request to the /unsubscribe endpoint on your hosting server.

Step 7: Set up Unsubscribe

app.get("/unsubscribe", (req, res) => { const { email } = req.query; candymail.unsubscribeUser(email); res.send(`Sent an unsubscribe request for ${email}`); });

Step 8: Test it out

npm start

Let’s fire up Postman and make a POST request to /signup . This will start the automation sequence - **Onboarding**. We are also printing out the scheduled messages to be sent out at what time. Notice that the time listed is in UTC. We should expect 3 emails to be sent — 1 at the top of the next hour, the next one in 24 hours, and the one after that in 72 hours.

Here’s the first email I received in my inbox. Every email comes with an unsubscribe link that the user can click on and they will stop getting future communications.