npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

devmailer

vundefined

Published

devmailer =========

Readme

API

Some tools for easier generating transactional mail. Built to work with SendGrid & MailChimp. More services will be added if demand presents it self.

Configuration


var devmailer = new require('devmailer').Devmailer({
  tmpDir: __dirname+'/tmp', // devmailer needs access to the filesystem to support partials
  sendgrid: {
    user: 'YOUR USER',
    password: 'YOUR PASSWORD'
  }
});

// Alternatively:
var devmailer = new (require('devmailer')).Devmailer({ ... });

Messages

General re-useable templates for transactional email

var message = new devmailer.Message({
  template: {url: 'http://some.host/email.jade'},
  templatePartials: [
    {url: 'http://some.host/email_header.jade', name: 'header'}
    {url: 'http://some.host/email_footer.jade', name: 'footer'}
  ],
  stylesheet: {url: 'http://some.host/email.css'},
});

devmailer.Message is aliased as devmailer.MessageTemplate

Templates and Stylesheets

Templates and stylesheets can be passed to messages in a few different ways. Templates and stylesheets can be supplied either with a src or a url, if using src or a non-extension url, supply a type aswell. Currently we support jade, mustache and html for templates and css and sass/compass for stylesheets.

For compass/sass support you need to have it installed as a binary (via rubygems). Support via node modules is not a priority currently.


var template;
var stylesheet;

/* Basic HTML with a source */
template = {type: 'html', src: '<p><a href="#"></a></p>'};

/* Basic HTML via a url (with proper extension) */
template = {url: 'http://some.host/email.html'};

/* Basic HTML via a url (without identifying extension) */
template = {type: 'html' url: 'http://some.host/email.template'};

/* Basic HTML via a path (without identifying extension) */
template = { path: '/usr/dev/email.html'};

/* Basic HTML via a path (without identifying extension) */
template = {type: 'html' path: '/usr/dev/email.template'};

/* Basic CSS with a source */
stylesheet = {type: 'css', src: 'p { font-family: Arial}'};

/* Basic CSS via a url (with proper extension) */
stylesheet = {url: 'http://some.host/email.css'};

/* Basic CSS via a url (without identifying extension) */
stylesheet = {type: 'css' url: 'http://some.host/email.stylesheet'};

The types can then be swapped for your specific needs. When supplying templates or stylesheets to a Message they will be wrapped by devmailer.ContentTemplate and devmailer.ContentStylesheet respectively. You can also wrap them yourself, but currently there is no added benefit to this.

CSS Inlining

When supplying the Message with stylesheets we will (after compilation) inline the stylesheet into the markup using juice.

Note: Juice uses jsdom in its inlining proces, which requires you to have a relatively welformed markup. If you get error messages along the lines of cannot read property 'contains' of null or cannot read property 'compareDocumentPosition' of null you are probably missing an <html> or <body> tag.

Partials/Includes

Partials for both templates are supported. They are passed in as regular templates via the option templatePartials. Partials need to be referenced by name, so you can give them a name property in the template options. Partial support for stylesheets will not be supported for the first releases, but might be a thing for the future.

Note: If you have several instances of devmailer.Message, it is not possible to have different partials with the same name in them. E.g., this is not possible:

var message1 = new devmailer.Message({
  template: {url: 'http://some.host/email.jade'},
  templatePartials: [
    {url: 'http://some.host/email_header.jade', name: 'header'}
  ]
};

var message2 = new devmailer.Message({
  template: {url: 'http://some.host/another_email.jade'},
  templatePartials: [
    {url: 'http://some.host/a_totally_different_header.jade', name: 'header'}
  ]
};

Depending on the order in which the partials are loaded asynchronously, either email_header or a_totally_different_header will be injected in both templates when you include header.

Subject and from

Subject and from fields can be specified both on a global or per recipient basis. If you want to specify per recipient, simply add subject and/or from to the recipient object, like this:

message.generate({
  recipients: [
    { to: '[email protected]', name: 'Mick', subject: 'Hello Mick', from: '[email protected]' }
  ]
}, function (err, res) {
  ...
});

If all messages generated from a template should have the same subject / from you can specify it when instantiating Message:

new devmailer.Message({
  template: {
    type: 'mustache',
    src: '<html><p>Hi {{name}}</p></html>'
  },
  subject: 'Hello'
});

If you want all messages from the current batch (current call to send or generate) to have the same subject / from you can specify the as globals:

message.generate({
  globals: {
    subject: 'Hello'
  },
  recipients: [
    { to: '[email protected]', name: 'Mick', subject: 'Hello Mick', from: '[email protected]' } // Gets the subject Hello Mick
    { to: '[email protected]', name: 'Jan', from: '[email protected]' } // Get the subject Hello
  ]
}, function (err, res) {
  ...
});

You can also combine the above, so that some messages use the global values, and some use their own subject / from field. The lookup order is: recipient, globals, message-defaults.

It is also possible to generate subjects and senders from a function, that is passed each recipient. The function can be both synchronous and asynchronous. If the number of arguments to the function is 1, it will be treated as a sync function, otherwise it will be treated as an async function. Async functions are passed recipient data and a callback:

// Sync
new devmailer.Message({
  template: {
    type: 'mustache',
    src: '<html><p>Hi {{name}}</p></html>'
  },
  subject: function (data) {
    return 'Hello '+data.name;
  }
});

// Async
new devmailer.Message({
  template: {
    type: 'mustache',
    src: '<html><p>Hi {{name}}</p></html>'
  },
  subject: function (data, callback) {
    callback(null, 'Hello '+data.name);
  }
});

Transport

Currently devmailer supports sendgrid and custom transport as methods of sending your email:

Sendgrid

devmailer = new Devmailer({
  sendgrid: {
    user: "",
    pass: ""
  }
});

Custom transport

You can provide at custom transport object to override the default transport method. This can be used e.g. to stub sending, so emails are saved to a database instead of being sent. The example below shows usings a custom transport to save messages to redis. A transport object must implement the ´sendMail´ and ´close´ methods.

var redis = require('redis'),
  client = redis.createClient();

client.select(1);
transport = {
  sendMail: function (options, callback) {
    options.timestamp = Math.floor(Date.now() / 1000);
    client.lpush("stub_email:"+options.to, JSON.stringify(options), function (err) {
      callback(err, { message: "Saved to redis as stub_email:"+options.to});
    });
  },
  close: function () {

  }
};

devmailer = new Devmailer({
  transport: transport
});

Usage

var message = new devmailer.Message({
  template: {url: 'http://some.host/email.jade'},
  templatePartials: [
    {url: 'http://some.host/email_header.jade', name: 'header'}
    {url: 'http://some.host/email_footer.jade', name: 'footer'}
  ],
  stylesheet: {url: 'http://some.host/email.css'},
});

/* Send emails */
...

/* Testing */
...

/* Generate email content - mostly for unit tests*/
...