added support for ses

This commit is contained in:
Andris Reinman 2017-02-17 15:56:55 +02:00
parent 7fde2a9619
commit 66bfcebd47
11 changed files with 575 additions and 136 deletions

View file

@ -12,6 +12,7 @@ let fs = require('fs');
let path = require('path');
let templates = new Map();
let htmlToText = require('html-to-text');
let aws = require('aws-sdk');
module.exports.transport = false;
@ -121,7 +122,7 @@ function getTemplate(template, callback) {
}
function createMailer(callback) {
settings.list(['smtpHostname', 'smtpPort', 'smtpEncryption', 'smtpUser', 'smtpPass', 'smtpLog', 'smtpDisableAuth', 'smtpMaxConnections', 'smtpMaxMessages', 'smtpSelfSigned', 'pgpPrivateKey', 'pgpPassphrase', 'smtpThrottling'], (err, configItems) => {
settings.list(['smtpHostname', 'smtpPort', 'smtpEncryption', 'smtpUser', 'smtpPass', 'smtpLog', 'smtpDisableAuth', 'smtpMaxConnections', 'smtpMaxMessages', 'smtpSelfSigned', 'pgpPrivateKey', 'pgpPassphrase', 'smtpThrottling', 'mailTransport', 'sesKey', 'sesSecret', 'sesRegion'], (err, configItems) => {
if (err) {
return callback(err);
}
@ -134,28 +135,70 @@ function createMailer(callback) {
module.exports.transport.checkThrottling = null;
}
module.exports.transport = nodemailer.createTransport({
pool: true,
host: configItems.smtpHostname,
port: Number(configItems.smtpPort) || false,
secure: configItems.smtpEncryption === 'TLS',
ignoreTLS: configItems.smtpEncryption === 'NONE',
auth: configItems.smtpDisableAuth ? false : {
user: configItems.smtpUser,
pass: configItems.smtpPass
},
debug: !!configItems.smtpLog,
logger: !configItems.smtpLog ? false : {
debug: log.verbose.bind(log, 'Mail'),
info: log.info.bind(log, 'Mail'),
error: log.error.bind(log, 'Mail')
},
maxConnections: Number(configItems.smtpMaxConnections),
maxMessages: Number(configItems.smtpMaxMessages),
tls: {
rejectUnauthorized: !configItems.smtpSelfSigned
}
}, config.nodemailer);
let throttling = Number(configItems.smtpThrottling) || 0;
if (throttling) {
// convert to messages/second
throttling = 1 / (throttling / (3600 * 1000));
}
let transportOptions;
let logfunc = function () {
let args = [].slice.call(arguments);
let level = args.shift();
args.shift();
args.unshift('Mail');
log[level].apply(log, args);
};
if (configItems.mailTransport === 'smtp' || !configItems.mailTransport) {
transportOptions = {
pool: true,
host: configItems.smtpHostname,
port: Number(configItems.smtpPort) || false,
secure: configItems.smtpEncryption === 'TLS',
ignoreTLS: configItems.smtpEncryption === 'NONE',
auth: configItems.smtpDisableAuth ? false : {
user: configItems.smtpUser,
pass: configItems.smtpPass
},
debug: !!configItems.smtpLog,
logger: !configItems.smtpLog ? false : {
debug: logfunc.bind(null, 'verbose'),
info: logfunc.bind(null, 'info'),
error: logfunc.bind(null, 'error')
},
maxConnections: Number(configItems.smtpMaxConnections),
maxMessages: Number(configItems.smtpMaxMessages),
tls: {
rejectUnauthorized: !configItems.smtpSelfSigned
}
};
} else if (configItems.mailTransport === 'ses') {
transportOptions = {
SES: new aws.SES({
apiVersion: '2010-12-01',
accessKeyId: configItems.sesKey,
secretAccessKey: configItems.sesSecret,
region: configItems.sesRegion
}),
debug: !!configItems.smtpLog,
logger: !configItems.smtpLog ? false : {
debug: logfunc.bind(null, 'verbose'),
info: logfunc.bind(null, 'info'),
error: logfunc.bind(null, 'error')
},
maxConnections: Number(configItems.smtpMaxConnections),
sendingRate: throttling,
tls: {
rejectUnauthorized: !configItems.smtpSelfSigned
}
};
} else {
return callback(new Error('Invalid mail transport'));
}
module.exports.transport = nodemailer.createTransport(transportOptions, config.nodemailer);
module.exports.transport.use('stream', openpgpEncrypt({
signingKey: configItems.pgpPrivateKey,
@ -167,26 +210,25 @@ function createMailer(callback) {
oldListeners.forEach(listener => module.exports.transport.on('idle', listener));
}
let throttling = Number(configItems.smtpThrottling) || 0;
if (throttling) {
// convert to messages/second
throttling = 1 / (throttling / (3600 * 1000));
}
let lastCheck = Date.now();
module.exports.transport.checkThrottling = function (next) {
if (!throttling) {
return next();
}
let nextCheck = Date.now();
let checkDiff = (nextCheck - lastCheck);
lastCheck = nextCheck;
if (checkDiff < throttling) {
log.verbose('Mail', 'Throttling next message in %s sec.', (throttling - checkDiff) / 1000);
setTimeout(next, throttling - checkDiff);
} else {
next();
}
};
if (configItems.mailTransport === 'smtp' || !configItems.mailTransport) {
module.exports.transport.checkThrottling = function (next) {
if (!throttling) {
return next();
}
let nextCheck = Date.now();
let checkDiff = (nextCheck - lastCheck);
lastCheck = nextCheck;
if (checkDiff < throttling) {
log.verbose('Mail', 'Throttling next message in %s sec.', (throttling - checkDiff) / 1000);
setTimeout(next, throttling - checkDiff);
} else {
next();
}
};
} else {
module.exports.transport.checkThrottling = next => next();
}
db.clearCache('sender', () => {
callback(null, module.exports.transport);

View file

@ -266,7 +266,7 @@ module.exports.add = (url, campaignId, callback) => {
};
module.exports.updateLinks = (campaign, list, subscription, serviceUrl, message, callback) => {
if (campaign.trackingDisabled || !message.trim()) {
if (campaign.trackingDisabled || !message || !message.trim()) {
// tracking is disabled, do not modify the message
return setImmediate(() => callback(null, message));
}