Skip to content
This repository has been archived by the owner on Nov 24, 2021. It is now read-only.

adding AWS SES transport #17

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Email helper for KeystoneJS and Node.js Applications. Makes it easy to send dyna
Features include:

* Express-like template system (including support for any express-compatible template engine)
* Support for different email sending services (Mandrill and Mailgun are available now, more may be added)
* Support for different email sending services (Mandrill, Mailgun and AWS SES are available now, more may be added)
* Understands Keystone User models, making it easy to send emails to the results of a query
* Automatically transforms user variables into the correct format for each email service, for mail-merge style variable use
* CSS Stylesheets are automatically inlined for robust email client compatibility
Expand Down Expand Up @@ -110,6 +110,21 @@ The following `send()` options are applicable when using `nodemailer` as the tra

See [the Nodemailer README](https://github.com/nodemailer/nodemailer) for more information about supported transports and plugins.

## Usage with AWS SES

The following `send()` options are applicable when using `awsses` as the transport:

- `apiKey` (required, String) Your API Key, defaults to `process.env.AWS_SES_API_KEY`
- `apiSecret` (required, String) Your Secret Key, defaults to `process.env.AWS_SES_SECRET_KEY`
- `region` (required, String) Your Sending Region i.e., us-east-1, defaults to `process.env.AWS_SES_REGION`
- `from` (String or Object) The name and email to send from (see below)
- `inline_css` (Boolean) inline CSS classes in your template, defaults to `true`
- `to` (String, Object or Array) The recipient(s) of the email (see below)
- `cc` (String, Object or Array) The CC recipient(s) of the email (same format as `to`, see below)
- `bcc` (String, Object or Array) The BCC recipient(s) of the email (same format as `to`, see below)

See [the AWS SES API Docs](http://docs.aws.amazon.com/ses/latest/APIReference/API_SendEmail.html) for the full set of supported options.

## From option

The `from` option can be a String (email address), or Object containing `name` and `email`. In the object form, `name` can also be an object containing `first` and `last` (which will be concatenated with a space). This simplifies usage with `User` models in KeystoneJS. For example:
Expand Down Expand Up @@ -181,6 +196,10 @@ You could previously use a directory as the template name, and Keystone.Email wo

Keystone would previous return errors if the subject, contents, recipient(s) or the sender address were invalid. This is no longer handled by the library, please make sure you validate these options before sending the emails. If the transport validates these options, errors will be passed directly to the callback.

### AWS SES limitations

AWS SES does not support click tracking

## License

MIT Licensed. Copyright (c) 2016 Jed Watson.
Expand Down
31 changes: 31 additions & 0 deletions lib/transports/awsses/getSendOptions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
var assign = require('object-assign');

var getRecipientsAndVars = require('../mailgun/getRecipientsAndVars');
var processAddress = require('../../util/processAddress');

var defaultOptions = {
accessKeyId: process.env.AWS_SES_API_KEY,
secretAccessKey: process.env.AWS_SES_SECRET_KEY,
region: process.env.AWS_SES_REGION || 'us-east-1',
};

function getSendOptions (options) {
// default options
options = assign({ Destination: {} }, defaultOptions, options);
// process from name and email
options.Source = processAddress(options.from).address;
// process recipients, including cc and bcc
options.Destination.ToAddresses = getRecipientsAndVars(options.to).recipients;
// handle cc
if (options.cc && options.cc.length > 0) {
options.Destination.CcAddresses = getRecipientsAndVars(options.cc).recipients;
}
// handle bcc
if (options.bcc && options.bcc.length > 0) {
options.Destination.BccAddresses = getRecipientsAndVars(options.bcc).recipients;
}
// return
return options;
}

module.exports = getSendOptions;
39 changes: 39 additions & 0 deletions lib/transports/awsses/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
var assign = require('object-assign');
var aws = require('aws-sdk');
var juice = require('juice');
var getSendOptions = require('./getSendOptions');

function send (email, options, callback) {
// init options
options = assign({ Message: { Subject: {}, Body: { Html: {} } } }, getSendOptions(options), email);

// validate
if (!options.Destination.ToAddresses.length) {
return callback(new Error('No recipients to send to'));
}

// handle html body
options.Message.Body.Html.Data = options.inlineCSS ? juice(options.html) : options.html;

// add subject
if (options.subject) {
options.Message.Subject.Data = options.subject;
}

// init aws
aws.config.accessKeyId = options.apiKey;
aws.config.secretAccessKey = options.apiSecret;
aws.config.region = options.region;

// init ses
var ses = new aws.SES({ apiVersion: '2010-12-01' });

// send emails
ses.sendEmail({
Message: options.Message,
Destination: options.Destination,
Source: options.Source,
}, callback);
}

module.exports = send;
15 changes: 9 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"description": "Email helper for KeystoneJS Apps",
"main": "index.js",
"dependencies": {
"aws-sdk": "^2.7.11",
"debug": "^3.1.0",
"html-to-text": "^4.0.0",
"juice": "^4.3.1",
Expand All @@ -24,11 +25,11 @@
"pug": "^2.0.3"
},
"scripts": {
"test": "npm run lint && npm run test-unit",
"test-unit": "mocha tests",
"coverage": "istanbul cover _mocha tests",
"codeclimate": "codeclimate-test-reporter < coverage/lcov.info",
"lint": "eslint . --ignore-path .gitignore"
"coverage": "istanbul cover _mocha tests",
"lint": "eslint . --ignore-path .gitignore",
"test": "npm run lint && npm run test-unit",
"test-unit": "mocha tests"
},
"repository": {
"type": "git",
Expand All @@ -38,8 +39,10 @@
"email",
"keystone",
"keystonejs",
"mandrill",
"mailgun"
"mailgun",
"ses",
"aws",
"mandrill"
],
"author": "Jed Watson",
"license": "MIT",
Expand Down
2 changes: 2 additions & 0 deletions tests/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,10 @@ describe('utils', function () {
it('should return transport if transport is found', function () {
var res1 = getTransport('mailgun');
var res2 = getTransport('mandrill');
var res3 = getTransport('awsses');
assert.equal(typeof res1, 'function');
assert.equal(typeof res2, 'function');
assert.equal(typeof res3, 'function');
});
});

Expand Down