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:
parent
6474bba64e
commit
51ce3572a0
1 changed files with 118 additions and 53 deletions
|
@ -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
|
||||||
});
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue