2019-11-08 07:13:43 +03:00
|
|
|
const {URL} = require('url');
|
2019-11-13 13:52:23 +03:00
|
|
|
const _ = require('lodash');
|
2019-11-08 07:13:43 +03:00
|
|
|
const mailgun = require('mailgun-js');
|
|
|
|
const configService = require('../../config');
|
2019-11-04 08:36:10 +03:00
|
|
|
const common = require('../../lib/common');
|
2019-11-08 07:13:43 +03:00
|
|
|
let mailgunInstance;
|
|
|
|
|
|
|
|
function createMailgun(config) {
|
|
|
|
const baseUrl = new URL(config.baseUrl);
|
|
|
|
|
|
|
|
return mailgun({
|
|
|
|
apiKey: config.apiKey,
|
|
|
|
domain: config.domain,
|
|
|
|
protocol: baseUrl.protocol,
|
|
|
|
host: baseUrl.host,
|
|
|
|
port: baseUrl.port,
|
|
|
|
endpoint: baseUrl.pathname
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-11-08 13:26:05 +03:00
|
|
|
const config = configService.get('bulkEmail');
|
2019-11-08 07:13:43 +03:00
|
|
|
|
|
|
|
if (!config || !config.mailgun) {
|
|
|
|
common.logging.warn(`Bulk email service is not configured`);
|
|
|
|
} else {
|
|
|
|
try {
|
|
|
|
mailgunInstance = createMailgun(config.mailgun);
|
|
|
|
} catch (err) {
|
|
|
|
common.logging.warn(`Bulk email service is not configured`);
|
|
|
|
}
|
|
|
|
}
|
2019-11-04 08:36:10 +03:00
|
|
|
|
2019-11-04 13:24:02 +03:00
|
|
|
/**
|
2019-11-04 08:36:10 +03:00
|
|
|
* An email address
|
|
|
|
* @typedef { string } EmailAddress
|
|
|
|
*/
|
|
|
|
|
2019-11-04 13:24:02 +03:00
|
|
|
/**
|
2019-11-04 08:36:10 +03:00
|
|
|
* An object representing an email to send
|
|
|
|
* @typedef { Object } Email
|
|
|
|
* @property { string } html - The html content of the email
|
2019-11-04 08:36:10 +03:00
|
|
|
* @property { string } subject - The subject of the email
|
2019-11-04 08:36:10 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
/**
|
|
|
|
* @param {Email} message - The message to send
|
|
|
|
* @param {[EmailAddress]} recipients - the recipients to send the email to
|
2019-11-06 13:50:41 +03:00
|
|
|
* @param {[object]} recipientData - list of data keyed by email to inject into the email
|
2019-11-13 13:52:23 +03:00
|
|
|
* @returns {Promise<Array<object>>} An array of promises representing the success of the batch email sending
|
2019-11-04 08:36:10 +03:00
|
|
|
*/
|
2019-11-06 13:50:41 +03:00
|
|
|
async send(message, recipients, recipientData) {
|
2019-11-13 13:52:23 +03:00
|
|
|
let BATCH_SIZE = 1000;
|
|
|
|
|
2019-11-08 07:13:43 +03:00
|
|
|
if (!mailgunInstance) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
let fromAddress = message.from;
|
2019-11-13 13:52:23 +03:00
|
|
|
if (/@localhost$/.test(message.from) || /@ghost.local$/.test(message.from)) {
|
2019-11-08 07:13:43 +03:00
|
|
|
fromAddress = 'localhost@example.com';
|
|
|
|
common.logging.warn(`Rewriting bulk email from address ${message.from} to ${fromAddress}`);
|
2019-11-13 13:52:23 +03:00
|
|
|
|
|
|
|
BATCH_SIZE = 2;
|
2019-11-08 07:13:43 +03:00
|
|
|
}
|
|
|
|
try {
|
2019-11-13 13:52:23 +03:00
|
|
|
const chunkedRecipients = _.chunk(recipients, BATCH_SIZE);
|
2019-11-13 13:36:19 +03:00
|
|
|
|
2019-11-13 13:52:23 +03:00
|
|
|
return Promise.map(chunkedRecipients, (toAddresses) => {
|
|
|
|
const recipientVariables = {};
|
|
|
|
toAddresses.forEach((email) => {
|
|
|
|
recipientVariables[email] = recipientData[email];
|
2019-11-13 13:36:19 +03:00
|
|
|
});
|
|
|
|
|
2019-11-13 13:52:23 +03:00
|
|
|
const messageData = Object.assign({}, message, {
|
|
|
|
to: toAddresses,
|
|
|
|
from: fromAddress,
|
|
|
|
'recipient-variables': recipientVariables
|
|
|
|
});
|
|
|
|
|
|
|
|
if (config.mailgun.tag) {
|
|
|
|
Object.assign(messageData, {
|
|
|
|
'o:tag': config.mailgun.tag
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
return mailgunInstance.messages().send(messageData);
|
|
|
|
});
|
|
|
|
} catch (err) {
|
|
|
|
common.logging.error({err});
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
async getStats(messageId) {
|
|
|
|
try {
|
|
|
|
let filter = {
|
|
|
|
'message-id': messageId
|
|
|
|
};
|
|
|
|
|
|
|
|
return await mailgunInstance.events().get(filter);
|
2019-11-08 07:13:43 +03:00
|
|
|
} catch (err) {
|
|
|
|
common.logging.error({err});
|
2019-11-04 08:36:10 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|