Socket
Socket
Sign inDemoInstall

campaign

Package Overview
Dependencies
Maintainers
1
Versions
40
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

campaign

Compose responsive email templates easily, fill them with models, and send them out.


Version published
Weekly downloads
128
increased by13.27%
Maintainers
1
Weekly downloads
 
Created
Source

campaign.png

Compose responsive email templates easily, fill them with models, and send them out.

This is the stuff responsible for sending beautiful emails in Pony Foo. I've now isolated the code and made it into a reusable package, called campaign. It comes with a dead simple API, and a beautiful responsive layout, originally written by MailChimp, adapted by me, and easily configurable.

It uses Mustache to fill out the email templates, and Mandrill to actually send the emails, although providing your own service to actually send the emails is easy.

Reference

Quick links for reference.

Getting Started

Install using npm.

npm i --save campaign

Set it up.

Construct a client.

var client = require('campaign')();

(the default client needs an API keep for Mandrill, read on)

Send emails!

client.send(template, options, done);
client.sendString('<p>{{something}}</p>', options, done);

(detailed information below)

Client Options

Here are the default options, they are explained below.

{
    "mandrill": {
        "apiKey": "<not provided>",
        "debug": false
    },
    "from": "<not provided>",
    "client": "<defaults>",
    "trap": false,
    "headerImage": "<not provided>",
    "layout": "<defaults>"
}

trap

If true, then emails won't be sent to any of the recipients, but they'll be sent to the provided trap address instead. For example, you could set trap to nico@bevacqua.io, and all emails would be sent to me instead of the intended recipients. Great for spamming me, and also great for testing.

When you trap recipients, the email will get a nifty JSON at the end detailing the actual recipients that would've gotten it.

mandrill

By default, the Mandrill service is used to send the emails. Mandrill is really awesome and you should be using it. It has a generous free plan.

At the time they host the source code in Bit Bucket, which is kind of cryptic, but you can read through it nonetheless.

You need to provide an API key in apiKey, and that's all there is to it. You might prefer to ignore this configuration option, and merely set process.env.MANDRILL_APIKEY. That works, too.

from

The from address for our emails. The client is responsible for trying to make it look like that's the send address. Not necessarily used for authentication.

client

You can actually use other email clients, providing your own. To do so, you need to provide a client object. The client object should have a send function, which takes a model, and a done callback.

Given that I originally worked with Mandrill, the client API is based on their API client. I'll add details upon request.

headerImage

You may provide the full path to an image. This image will be encoded in base64 and embedded into the email as a heading. Embedding helps people view your emails offline.

This image should have a 3:1ish ratio. For instance, I use 600x180 in my blog's emails.

layout

The layout used in your emails. Templates for email sending are meant to have the bare minimum needed to fill out an email. Since you want a consistent UX, the same layout should be used for every email your product sends.

A default layout template is provided. You can provide a different one, just set layout to the absolute path of a Mustache template file. For information about the model passed to the layout, see the Templates section.

Email Sending Options

Once you've created a client, you can start sending emails. Here are the default options, and what you need to fill out.

{
    "subject": "<not provided>",
    "preview": "<options.subject>",
    "to": "<not provided>",
    "images": "<empty>",
    "social": {
        "twitter": "<not provided>",
        "landing": "<not provided>",
        "name": "<not provided>"
    },
    "mandrill": {
        "tags": "<not provided>",
        "merge": "<not provided>"
    },
    "styles": "<defaults>"
}
.send vs .sendString

The only difference between .send and .sendString is that .send takes the path to a file, rather than the template itself. .send compiles the template and keeps it in a cache, while .sendString compiles the template every time.

subject

The email subject.

preview

This is the line that most email clients show as the preview of the email message. It defaults to the subject line. Changing it is extremely encouraged.

to

These are the recipients of the email you're sending. Simply provide a single recipient's email address, or an array of email addresses.

images

If you want to provide the template with images other than the optional header when creating the campaign client, you can provide a list of file paths and names (to reference them in your templates), as shown below.

[
    { name: 'housing', file: path.join(__dirname, 'housing.png')}
]

social

Social metadata used when sending an email can help build your brand. You can provide a twitter handle, a name for your brand, and a landing page.

The name is used as the name of the send address, as well as in the "Visit " link.

mandrill

Configuration specifically used by the Mandrill client.

Mandrill allows you to add dynamic content to your templates, and this feature is supported by the default Mandrill client in campaign, out the box. Read more about merge variables.

mandrill.merge

Given that Mandrill's merge API is fairly obscure, we process it in our client, so that you can configure it assigning something like what's below to mandrill.merge.

{
    "locals": [{
        "email": "someone@accounting.is",
        "model": {
            "something": "is a merge local for the guy with that email"
        }
    }],
    "globals": [{
        "these": "are merge globals for everyone"
    }]
}

Mandrill lets you tag your emails so that you can find different campaigns later on. Read more about tagging. By default, emails will be tagged with the template name.

styles

Read about styles below.

Templates

There are two types of templates: the layout, and the email's body template. A default layout is provided, so let's talk about the email templates first, and then the layout.

Email body Templates

The body template determines what goes in the message body. The options we used to configure our email are also used as the model for the body template, as sometimes it might be useful to include some of that metadata in the model itself.

The API expects an absolute path to the body template.

client.send(body, options, done);

Other than the options listed above, you can provide any values you want, and then reference those in the template.

The layout Template

The layout has one fundamental requirement in order to be mildly functional, it should have a {{{body}}} in it, so that the actual email's content can be rendered. Luckily the default layout is good enough that you shouldn't need to touch it.

Purposely, the layout template isn't passed the full model, but only a subset, containing:

{
    "_header": "<!!options._header>",
    "subject": "<options.subject>",
    "preview": "<options.preview>",
    "generated": "<when>",
    "body": "<html>",
    "trapped": "<options.trapped>",
    "social": "<options.social>",
    "styles": "<options.style>"
}

In this case, the _header would whether a header image was provided. Then, generated contains the moment the email was rendered, using the 'YYYY/MM/DD HH:mm, UTC Z' format string. Lastly, trapped contains the metadata extracted from the model when trap is set to true, in the client options.

Styling the layout

These are the default styles, and you can override them in the options passed to client.send.

{
    "styles": {
        "bodyBackgroundColor": "#eaeadf",
        "bodyTextColor": "#505050",
        "codeFontFamily": "Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif",
        "fontFamily": "Helvetica",
        "footerBackgroundColor": "#f4f4f4",
        "headerColor": "#412917",
        "horizontalBorderColor": "#dedede",
        "layoutBackgroundColor": "#f3f4eb",
        "layoutTextColor": "#808080",
        "linkColor": "#e92c6c",
        "quoteBorderColor": "#cbc5c0"
    }
}

Unsubscribe Facilities

The default layout supports an optional unsubscribe_html merge variable, which can be filled out like below.

{
    "merge": {
        "locals": [{
            "email": "someone@somewhere.com",
            "model": {
                "unsubscribe_html": "<a href='http://sth.ng/unsubscribe/hash_someone'>unsubscribe</a>"
            }
        }, {
            "email": "someone@else.com",
            "model": {
                "unsubscribe_html": "<a href='http://sth.ng/unsubscribe/hash_someone_else'>unsubscribe</a>"
            }
        }]
    }
}

That'd be a perfect use for merge variables, which were described above in the send options. Remember, those are just supported by Mandrill, though. They deal with those after you make a request to their API.

Here is a screenshot of an email sent using this library by the Pony Foo blog, in production.

sample.png

Debugging

To help you debug, an alternative client is provided. Set it up like this:

var campaign = require('campaign');
var client = campaign({
    client: campaign.clients.console()
});

// build and send mails as usual

Rather than actually sending emails, you will get a lot of JSON output in your terminal. Useful!

Clients

There are a few clients you can use. The default client sends mails through Mandrill. There is also a console logging client, explained above, and a nodemailer client, detailed below.

Using nodemailer

To use with nodemailer, simply use that client.

var nodemailer = require('nodemailer');
var smtp = nodemailer.createTransport('SMTP', {
    service: 'Gmail',
    auth: {
        user: 'gmail.user@gmail.com',
        pass: 'userpass'
    }
});

var campaign = require('campaign');
var client = campaign({
    client: campaign.clients.nodemailer({
        transport: smtp,
        transform: function (options) {
            // add whatever options you want,
            // or return a completely different object
        }
    })
});

// build and send mails as usual

That's that.

Making your own client

If the existing clients don't satisfy your needs, you may provide your own. The client option just needs to be an object with a send method. For an example, check out the nodemailer client source code.

You can easily write your own email sender, like this.

var campaign = require('campaign');
var client = campaign({
    client: {
        send: function (model, done) {
            // use the data in the model to send your email messages
        }
    }
});

// build and send mails as usual

If you decide to go for your own client, campaign will still prove useful thanks to its templating features.

License

MIT

Keywords

FAQs

Package last updated on 02 Jan 2014

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc