Sending automated template emails with Mandrill and Node JS

Getting started

Using email templates makes it easy to rapidly change, adapt and test different campaigns or onboarding messages without having to redeploy your application.

It also allows designers to add more value in a visual way to a more personal interaction

We’ll be going through an example of Mandrill (part of Mailchimp) dynamic templates using Node and javascript.

Adding a template in Mandrill

Let’s set up a really simple email template in Mandrill. We’re using the handlebars to specify dynamic content like firstName, lastName or some link that we want to send to the user.

You can customize as much as you want by even adding inline css and making a responsive template.

<div>
  <h2>
      Hello {{firstName}} {{lastName}},
  </h2>
</div>
    You can check out this <a src="{{link}}">link</a>!
<div>

Now we just need to save it and give it a template name that we’ll be using further to our call to messages.sendTemplate API.

Node integration

First we need to add the mandrill dependency to our package.json

npm install mandrill-api --save

In order to use the library we need to require it:

const mandrill = require('mandrill-api/mandrill');
const mandrill_client = new mandrill.Mandrill('YOUR_API_KEY');

Then we start by setting up the email content in javascript. This is an object that will be used to fill the template we set up on the platform.

const emailContent = {
    firstName: 'Gabriel',
    lastName: 'MANOLACHE',
    link: 'https://gmanolache.com'
};

The sendTemplate api requires us an object that looks something like this:

{
    template_name: 'my-template-name-here',
    template_content: [],
    message: message,
    async: false,
    ip_pool: 'Main Pool'
 }

Let’s set up the message:

const message = {
        'subject': 'Hello Template email subject',
        'from_email': 'blog@gmanolache.com',
        'from_name': "Gabriel MANOLACHE",
        'to': [{
            'email': 'target@gmanolache.com',
            'type': 'to'
        }],
        'merge_language': 'handlebars',
        'headers': {
            'Reply-To': 'blog@gmanolache.com'
        },
        'global_merge_vars': arrayFromObject(emailContent)
    }

Mandrill asks us to send global_merge_vars as key-value mappings which is unfortunate but let’s look at arrayFromObject:

const arrayFromObject = (content) => {
    const val = [];
    for (const key in content) {
        val.push({name: key, content: content[key]})
    }
    return val;
};

We’re converting our emailContent to an array with objects that contain name and content keys so it will work with Mandrill sendTemplate API

Let’s tie it all up together:

const arrayFromObject = (content) => {
    const val = [];
    for (const key in content) {
        val.push({name: key, content: content[key]})
    }
    return val;
};

const sendEmail = async (emailContent, targetEmailAddress) => {
    const message = {
        'subject': 'Hello Template email subject',
        'from_email': process.env.EMAIL_FROM,
        'from_name': process.env.EMAIL_NAME_FROM,
        'to': [{
            'email': targetEmailAddress,
            'type': 'to'
        }],
        'merge_language': 'handlebars',
        'headers': {
            'Reply-To': process.env.EMAIL_FROM
        },
        'global_merge_vars': arrayFromObject(emailContent)
    };

    const template = {
        template_name: process.env.MANDRILL_TEMPLATE_NAME,
        template_content: [],
        message: message,
        async: false,
        ip_pool: 'Main Pool'
    };

    return new Promise((resolve, reject) => {
        mandrill_client.messages.sendTemplate(template, (result) => {
            resolve(result)
        }, (e) => {
            console.error(e);
            reject(e)
        });
    });
};

Note that I am using environment variables for:

  • EMAIL_FROM - my email address
  • EMAIL_NAME_FROM - can be the full name
  • MANDRILL_TEMPLATE_NAME - the name I gave to my template html in Mandrill

Sending the email

If you’re using async/await (and you should):

try {
    await sendEmail(emailContent, 'blog@gmanolache.com');
} catch (error) {
    console.log("Cannot send the email, error:" + error);
}

or using promises:

sendEmail(emailContent, 'blog@gmanolache.com')
.then((result) => console.log(result))
.catch((error) => console.log("Cannot send the email, error:" + error));

You can check the code on github here

More info on Mandrill API

Gabriel MANOLACHE

big data engineer, machine learning enthusiast

Paris, France https://gmanolache.com