Permalink
Browse files

Amazon SES support

  • Loading branch information...
1 parent 36f6831 commit 70502d9baed14e2c327c347dd6509b0121e6c0a8 andris9 committed Aug 13, 2011
Showing with 124 additions and 92 deletions.
  1. +24 −8 README.md
  2. +98 −82 lib/engines/SES.js
  3. +1 −1 lib/mail.js
  4. +1 −1 package.json
View
@@ -71,10 +71,16 @@ is *true* then the message was sent successfully.
See [examples/example.js](https://github.com/andris9/Nodemailer/blob/master/examples/example.js) for a complete example.
-SMTP Setup
+Transfer method setup
----------
-Before sending any e-mails you need to set up SMTP server parameters.
+Before sending any e-mails you need to set up a transfer method for delivering the messages.
+
+To do this you need to define a properties object for a specific transfer method. Setup only one of these methods since only the first one defined will be used.
+
+### SMTP
+
+Use SMTP as the transfer method with the following setup
nodemailer.SMTP = {
host: 'smtp.example.com', // required
@@ -84,20 +90,30 @@ Before sending any e-mails you need to set up SMTP server parameters.
pass: '' // used only when use_authentication is true
}
-### 'sendmail' alternative
+### Amazon SES
+
+Use Amazon SES as the transfer method with the following setup
+
+ nodemailer.SES = {
+ AWSAccessKeyID: 'ACCESSKEY', // required
+ AWSSecretKey: 'SECRETKEY', // required
+ ServiceUrl: 'https://email.us-east-1.amazonaws.com', // optional
+ }
+
+### sendmail
-Alternatively if you don't want to use SMTP but the `sendmail` command then
-set property *sendmail* to true (or as the path to *sendmail* if the command is not in default path).
+Use `sendmail` as the transfer method with the following setup
nodemailer.sendmail = true;
or
nodemailer.sendmail = '/path/to/sendmail';
-If *sendmail* is set, then SMTP options are discarded.
+Aditional setup
+----------------
-### SSL Support (port 465)
+### SSL Support with SMTP (port 465)
If you want to use SSL (not TLS/STARTTLS, just SSL), you need to set the *ssl* parameter to true.
@@ -110,7 +126,7 @@ If you want to use SSL (not TLS/STARTTLS, just SSL), you need to set the *ssl* p
pass: 'my.password'
}
-### TLS Support (port 587)
+### TLS Support with SMTP (port 587)
If you want to use TLS/STARTTLS (port 587), leave *ssl* to false or do not set it, encryption will be started automatically when needed.
View
@@ -1,106 +1,122 @@
-var http = require('http');
-var https = require('https');
-var crypto = require('crypto');
+var http = require('http'),
+ https = require('https'),
+ crypto = require('crypto');
//Taken shamelessly from the [MDN](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date)
function ISODateString(d){
- function pad(n){return n<10 ? '0'+n : n}
- return d.getUTCFullYear()+'-'
- + pad(d.getUTCMonth()+1)+'-'
- + pad(d.getUTCDate())+'T'
- + pad(d.getUTCHours())+':'
- + pad(d.getUTCMinutes())+':'
- + pad(d.getUTCSeconds())+'Z'
+ return d.getUTCFullYear()+'-'
+ + pad(d.getUTCMonth()+1)+'-'
+ + pad(d.getUTCDate())+'T'
+ + pad(d.getUTCHours())+':'
+ + pad(d.getUTCMinutes())+':'
+ + pad(d.getUTCSeconds())+'Z'
+}
+
+function pad(n){
+ return n<10 ? '0'+n : n;
}
//Extracts the hostname from a given URL
function getHostname(url) {
- return url.replace(/^https?:\/\/([^\/]*).*$/, "$1");
+ return url.replace(/^https?:\/\/([^\/]*).*$/, "$1");
}
//Custom keyValPair construction that ignores "special" config keys
function buildKeyValPairs(config) {
- var keys = Object.keys(config).sort();
- var keyValPairs = [];
- for(var k in keys) {
- if(keys[k] != "ServiceUrl") {
- keyValPairs.push((encodeURIComponent(keys[k]) + "=" + encodeURIComponent(config[keys[k]])));
- }
- }
- return keyValPairs.join("&");
+ var keys = Object.keys(config).sort(),
+ keyValPairs = [],
+ k,
+ len;
+
+ for(k=0, len = keys.length; k < len; k++) {
+ if(keys[k] != "ServiceUrl") {
+ keyValPairs.push((encodeURIComponent(keys[k]) + "=" + encodeURIComponent(config[keys[k]])));
+ }
+ }
+
+ return keyValPairs.join("&");
}
//Following signature documentation from [here](http://docs.amazonwebservices.com/ses/latest/DeveloperGuide/index.html?HMACShaSignatures.html)
function buildSignature(date, AWSSecretKey) {
- var sha256 = crypto.createHmac('sha256', AWSSecretKey);
- sha256.update(date);
- return sha256.digest('base64');
+ var sha256 = crypto.createHmac('sha256', AWSSecretKey);
+ sha256.update(date);
+ return sha256.digest('base64');
}
//Adds the callback to the response handler's scope
function buildResponseHandler(callback) {
- return function(response) {
- var body = "";
- response.setEncoding('utf8');
- //Re-assembles response data
- response.on('data', function(d) {
- body += d.toString();
- });
- //Performs error handling and executes callback, if it exists
- response.on('end', function(err) {
- if(err instanceof Error) {
- return callback && callback(err, null);
- }
- if(response.statusCode != 200) {
- return callback &&
- callback(new Error('Email failed: ' + response.statusCode + '\n' + body), null);
- }
- return callback && callback(null, body);
- });
- };
+ return function(response) {
+ var body = "";
+ response.setEncoding('utf8');
+
+ //Re-assembles response data
+ response.on('data', function(d) {
+ body += d.toString();
+ });
+
+ //Performs error handling and executes callback, if it exists
+ response.on('end', function(err) {
+ if(err instanceof Error) {
+ return callback && callback(err, null);
+ }
+ if(response.statusCode != 200) {
+ return callback &&
+ callback(new Error('Email failed: ' + response.statusCode + '\n' + body), null);
+ }
+ return callback && callback(null, body);
+ });
+ };
}
//Constructs the email to be send and sends it to Amazon SES
exports.send = function(emailMessage, config, callback) {
- var email = "";
- var params = "";
- var request;
- var date = new Date();
- //Check if required config settings set
- if(!config.AWSAccessKeyID || !config.AWSSecretKey) {
- return callback(new Error("Missing AWS Credentials"));
- }
- //Set defaults if necessary
- config.ServiceUrl = config.ServiceUrl || "https://email.us-east-1.amazonaws.com";
- //Build Email
- emailMessage.prepareVariables();
- email = emailMessage.generateHeaders() + "\r\n\r\n" + emailMessage.generateBody();
- //Construct the http/https request object
- params = buildKeyValPairs({
- Action: 'SendRawEmail',
- 'RawMessage.Data': (new Buffer(email)).toString('base64'),
- Version: '2010-12-01',
- Timestamp: ISODateString(date)
- });
- var reqObj = {
- host: getHostname(config.ServiceUrl),
- path: "/",
- method: "POST",
- headers: {
- 'Content-Type': 'application/x-www-form-urlencoded',
- 'Content-Length': params.length,
- 'Date': date.toUTCString(),
- 'X-Amzn-Authorization':
- 'AWS3-HTTPS AWSAccessKeyID='+config.AWSAccessKeyID+
- ",Signature="+buildSignature(date.toUTCString(), config.AWSSecretKey)+
- ",Algorithm=HmacSHA256"
- }
- };
- //Execute the request on the correct protocol
- if(/^https:/.test(config.ServiceUrl)) {
- request = https.request(reqObj, buildResponseHandler(callback));
- } else {
- request = http.request(reqObj, buildResponseHandler(callback));
- }
- request.end(params);
+ var email = "",
+ params = "",
+ request,
+ reqObj,
+ date = new Date();
+
+ //Check if required config settings set
+ if(!config.AWSAccessKeyID || !config.AWSSecretKey) {
+ return callback(new Error("Missing AWS Credentials"));
+ }
+
+ //Set defaults if necessary
+ config.ServiceUrl = config.ServiceUrl || "https://email.us-east-1.amazonaws.com";
+
+ //Build Email
+ emailMessage.prepareVariables();
+ email = emailMessage.generateHeaders() + "\r\n\r\n" + emailMessage.generateBody();
+
+ //Construct the http/https request object
+ params = buildKeyValPairs({
+ Action: 'SendRawEmail',
+ 'RawMessage.Data': (new Buffer(email)).toString('base64'),
+ Version: '2010-12-01',
+ Timestamp: ISODateString(date)
+ });
+
+ reqObj = {
+ host: getHostname(config.ServiceUrl),
+ path: "/",
+ method: "POST",
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded',
+ 'Content-Length': params.length,
+ 'Date': date.toUTCString(),
+ 'X-Amzn-Authorization':
+ ['AWS3-HTTPS AWSAccessKeyID='+config.AWSAccessKeyID,
+ "Signature="+buildSignature(date.toUTCString(), config.AWSSecretKey),
+ "Algorithm=HmacSHA256"].join(",")
+ }
+ };
+
+ //Execute the request on the correct protocol
+ if(/^https:/.test(config.ServiceUrl)) {
+ request = https.request(reqObj, buildResponseHandler(callback));
+ } else {
+ request = http.request(reqObj, buildResponseHandler(callback));
+ }
+ request.end(params);
};
View
@@ -20,7 +20,7 @@ fs.readdirSync(__dirname + '/engines').forEach(function(engine) {
* Version constants
*/
var X_MAILER_NAME = "Nodemailer",
- X_MAILER_VERSION = "0.1.24; +http://www.nodemailer.org";
+ X_MAILER_VERSION = "0.2.0; +http://www.nodemailer.org";
/**
* mail
View
@@ -1,7 +1,7 @@
{
"name": "nodemailer",
"description": "Easy to use module to send e-mails, supports unicode and SSL/TLS",
- "version": "0.1.24",
+ "version": "0.2.0",
"author" : "Andris Reinman",
"maintainers":[
{

0 comments on commit 70502d9

Please sign in to comment.