0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-01-06 22:40:14 -05:00

Refactor mail API with pipeline utility

refs #5508
- refactor mail API with pipeline utility
This commit is contained in:
vdemedes 2015-11-02 14:17:28 +01:00
parent 6474bba64e
commit 51ce3572a0

View file

@ -2,17 +2,35 @@
// API for sending Mail // API for sending Mail
var _ = require('lodash').runInContext(), var _ = require('lodash').runInContext(),
Promise = require('bluebird'), Promise = require('bluebird'),
pipeline = require('../utils/pipeline'),
config = require('../config'), config = require('../config'),
canThis = require('../permissions').canThis,
errors = require('../errors'), errors = require('../errors'),
mailer = require('../mail'), mailer = require('../mail'),
Models = require('../models'), Models = require('../models'),
utils = require('./utils'),
path = require('path'), path = require('path'),
fs = require('fs'), fs = require('fs'),
templatesDir = path.resolve(__dirname, '..', 'mail', 'templates'), templatesDir = path.resolve(__dirname, '..', 'mail', 'templates'),
htmlToText = require('html-to-text'), htmlToText = require('html-to-text'),
readFile = Promise.promisify(fs.readFile),
docName = 'mail',
mail; mail;
_.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
/**
* Send mail helper
*/
function sendMail(object) {
return mailer.send(object.mail[0].message).catch(function (err) {
err = new errors.EmailError(err.message);
return Promise.reject(err);
});
}
/** /**
* ## Mail API Methods * ## Mail API Methods
* *
@ -30,23 +48,39 @@ mail = {
* @returns {Promise} * @returns {Promise}
*/ */
send: function (object, options) { send: function (object, options) {
return canThis(options.context).send.mail().then(function () { var tasks;
return mailer.send(object.mail[0].message)
.then(function (data) { /**
delete object.mail[0].options; * ### Format Response
// Sendmail returns extra details we don't need and that don't convert to JSON * @returns {Mail} mail
delete object.mail[0].message.transport; */
object.mail[0].status = {
message: data.message function formatResponse(data) {
}; delete object.mail[0].options;
return object; // Sendmail returns extra details we don't need and that don't convert to JSON
}) delete object.mail[0].message.transport;
.catch(function (error) { object.mail[0].status = {
return Promise.reject(new errors.EmailError(error.message)); message: data.message
}); };
}, function () {
return Promise.reject(new errors.NoPermissionError('You do not have permission to send mail.')); return object;
}); }
/**
* ### Send Mail
*/
function send() {
return sendMail(object, options);
}
tasks = [
utils.handlePermissions(docName, 'send'),
send,
formatResponse
];
return pipeline(tasks, options || {});
}, },
/** /**
@ -58,21 +92,52 @@ mail = {
* @returns {Promise} * @returns {Promise}
*/ */
sendTest: function (options) { sendTest: function (options) {
return Models.User.findOne({id: options.context.user}).then(function (result) { var tasks;
return mail.generateContent({template: 'test'}).then(function (emailContent) {
var payload = {mail: [{ /**
message: { * ### Model Query
to: result.get('email'), */
subject: 'Test Ghost Email',
html: emailContent.html, function modelQuery() {
text: emailContent.text return Models.User.findOne({id: options.context.user});
} }
}]};
return mail.send(payload, options); /**
* ### Generate content
*/
function generateContent(result) {
return mail.generateContent({template: 'test'}).then(function (content) {
var payload = {
mail: [{
message: {
to: result.get('email'),
subject: 'Test Ghost Email',
html: content.html,
text: content.text
}
}]
};
return payload;
}); });
}, function () { }
return Promise.reject(new errors.NotFoundError('Could not find the current user'));
}); /**
* ### Send mail
*/
function send(payload) {
return sendMail(payload, options);
}
tasks = [
modelQuery,
generateContent,
send
];
return pipeline(tasks);
}, },
/** /**
@ -84,32 +149,32 @@ mail = {
* @returns {*} * @returns {*}
*/ */
generateContent: function (options) { generateContent: function (options) {
var defaultData = { var defaults,
siteUrl: config.forceAdminSSL ? (config.urlSSL || config.url) : config.url data;
},
emailData = _.defaults(defaultData, options.data);
_.templateSettings.interpolate = /{{([\s\S]+?)}}/g; defaults = {
siteUrl: config.forceAdminSSL ? (config.urlSSL || config.url) : config.url
};
data = _.defaults(defaults, options.data);
// read the proper email body template // read the proper email body template
return new Promise(function (resolve, reject) { return readFile(path.join(templatesDir, options.template + '.html'), 'utf8').then(function (content) {
fs.readFile(templatesDir + '/' + options.template + '.html', {encoding: 'utf8'}, function (err, fileContent) { var compiled,
if (err) { htmlContent,
reject(err); textContent;
}
// insert user-specific data into the email // insert user-specific data into the email
var compiled = _.template(fileContent), compiled = _.template(content);
htmlContent = compiled(emailData), htmlContent = compiled(data);
textContent;
// generate a plain-text version of the same email // generate a plain-text version of the same email
textContent = htmlToText.fromString(htmlContent); textContent = htmlToText.fromString(htmlContent);
resolve({
html: htmlContent, return {
text: textContent html: htmlContent,
}); text: textContent
}); };
}); });
} }
}; };