mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-05 01:40:21 +03:00
Hooked mega service to listen to email.added event
- This was needed because we switched to synchronous request handling (to allow including email data with post.publish event)
This commit is contained in:
parent
4e1caa8b08
commit
eca129c18d
@ -1,6 +1,7 @@
|
|||||||
const models = require('../../models');
|
const models = require('../../models');
|
||||||
const common = require('../../lib/common');
|
const common = require('../../lib/common');
|
||||||
const urlUtils = require('../../lib/url-utils');
|
const urlUtils = require('../../lib/url-utils');
|
||||||
|
const {mega} = require('../../services/mega');
|
||||||
const allowedIncludes = ['tags', 'authors', 'authors.roles', 'email'];
|
const allowedIncludes = ['tags', 'authors', 'authors.roles', 'email'];
|
||||||
const unsafeAttrs = ['status', 'authors', 'visibility'];
|
const unsafeAttrs = ['status', 'authors', 'visibility'];
|
||||||
|
|
||||||
@ -141,6 +142,24 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
query(frame) {
|
query(frame) {
|
||||||
return models.Post.edit(frame.data.posts[0], frame.options)
|
return models.Post.edit(frame.data.posts[0], frame.options)
|
||||||
|
.then(async (model) => {
|
||||||
|
if (!model.get('send_email_when_published')) {
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!model.get('email') && (model.get('status') === 'published') && model.wasChanged()) {
|
||||||
|
|
||||||
|
const email = await mega.addEmail(model.toJSON());
|
||||||
|
|
||||||
|
if (frame.options.include && frame.options.includes('email')) {
|
||||||
|
model.set('email', email);
|
||||||
|
}
|
||||||
|
|
||||||
|
return model;
|
||||||
|
} else {
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
})
|
||||||
.then((model) => {
|
.then((model) => {
|
||||||
if (
|
if (
|
||||||
model.get('status') === 'published' && model.wasChanged() ||
|
model.get('status') === 'published' && model.wasChanged() ||
|
||||||
|
@ -386,7 +386,7 @@ module.exports = {
|
|||||||
maxlength: 50,
|
maxlength: 50,
|
||||||
nullable: false,
|
nullable: false,
|
||||||
defaultTo: 'sending',
|
defaultTo: 'sending',
|
||||||
validations: {isIn: [['sending', 'sent', 'failed']]}
|
validations: {isIn: [['pending', 'sending', 'sent', 'failed']]}
|
||||||
},
|
},
|
||||||
error: {type: 'string', maxlength: 2000, nullable: true},
|
error: {type: 'string', maxlength: 2000, nullable: true},
|
||||||
stats: {type: 'text', maxlength: 65535, nullable: true},
|
stats: {type: 'text', maxlength: 65535, nullable: true},
|
||||||
|
@ -8,7 +8,9 @@ const models = require('../../models');
|
|||||||
const postEmailSerializer = require('./post-email-serializer');
|
const postEmailSerializer = require('./post-email-serializer');
|
||||||
const urlUtils = require('../../lib/url-utils');
|
const urlUtils = require('../../lib/url-utils');
|
||||||
|
|
||||||
const sendEmail = async (post, members) => {
|
const internalContext = {context: {internal: true}};
|
||||||
|
|
||||||
|
const getEmailData = (post, members) => {
|
||||||
const emailTmpl = postEmailSerializer.serialize(post);
|
const emailTmpl = postEmailSerializer.serialize(post);
|
||||||
|
|
||||||
const membersToSendTo = members.filter((member) => {
|
const membersToSendTo = members.filter((member) => {
|
||||||
@ -23,8 +25,13 @@ const sendEmail = async (post, members) => {
|
|||||||
}, emailData);
|
}, emailData);
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
return bulkEmailService.send(emailTmpl, emails, emailData)
|
return {emailTmpl, emails, emailData};
|
||||||
.then(() => ({emailTmpl, emails}));
|
};
|
||||||
|
|
||||||
|
const sendEmail = async (post, members) => {
|
||||||
|
const {emailTmpl, emails, emailData} = getEmailData(post, members);
|
||||||
|
|
||||||
|
return bulkEmailService.send(emailTmpl, emails, emailData);
|
||||||
};
|
};
|
||||||
|
|
||||||
const sendTestEmail = async (post, emails) => {
|
const sendTestEmail = async (post, emails) => {
|
||||||
@ -33,6 +40,27 @@ const sendTestEmail = async (post, emails) => {
|
|||||||
return bulkEmailService.send(emailTmpl, emails);
|
return bulkEmailService.send(emailTmpl, emails);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const addEmail = async (post) => {
|
||||||
|
const {members} = await membersService.api.members.list(Object.assign({filter: 'subscribed:true'}, {limit: 'all'}));
|
||||||
|
const {emailTmpl, emails} = getEmailData(post, members);
|
||||||
|
|
||||||
|
const existing = await models.Email.findOne({post_id: post.id}, internalContext);
|
||||||
|
|
||||||
|
if (!existing) {
|
||||||
|
return models.Email.add({
|
||||||
|
post_id: post.id,
|
||||||
|
status: 'pending',
|
||||||
|
email_count: emails.length,
|
||||||
|
subject: emailTmpl.subject,
|
||||||
|
html: emailTmpl.html,
|
||||||
|
plaintext: emailTmpl.plaintext,
|
||||||
|
submitted_at: moment().toDate()
|
||||||
|
}, internalContext);
|
||||||
|
} else {
|
||||||
|
return existing;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// NOTE: serialization is needed to make sure we are using current API and do post transformations
|
// NOTE: serialization is needed to make sure we are using current API and do post transformations
|
||||||
// such as image URL transformation from relative to absolute
|
// such as image URL transformation from relative to absolute
|
||||||
const serialize = async (model) => {
|
const serialize = async (model) => {
|
||||||
@ -111,24 +139,18 @@ async function handleUnsubscribeRequest(req) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function listener(model, options) {
|
async function listener(emailModel, options) {
|
||||||
// CASE: do not send email if we import a database
|
// CASE: do not send email if we import a database
|
||||||
// TODO: refactor post.published events to never fire on importing
|
// TODO: refactor post.published events to never fire on importing
|
||||||
if (options && options.importing) {
|
if (options && options.importing) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!model.get('send_email_when_published')) {
|
const postModel = await models.Post.findOne({id: emailModel.get('post_id')}, internalContext);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const post = await serialize(model);
|
const post = await serialize(postModel);
|
||||||
|
|
||||||
const deliveredEvents = await models.Action.findAll({
|
if (emailModel.get('status') !== 'pending') {
|
||||||
filter: `event:delivered+resource_id:${model.id}`
|
|
||||||
});
|
|
||||||
|
|
||||||
if (deliveredEvents && deliveredEvents.toJSON().length > 0) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,43 +161,24 @@ async function listener(model, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sendEmail(post, members)
|
sendEmail(post, members)
|
||||||
.then(async ({emailTmpl, emails}) => {
|
|
||||||
return models.Email.add({
|
|
||||||
post_id: post.id,
|
|
||||||
status: 'sent',
|
|
||||||
email_count: emails.length,
|
|
||||||
subject: emailTmpl.subject,
|
|
||||||
html: emailTmpl.html,
|
|
||||||
plaintext: emailTmpl.plaintext,
|
|
||||||
submitted_at: moment().toDate()
|
|
||||||
}, {context: {internal: true}});
|
|
||||||
})
|
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
let actor = {id: null, type: null};
|
return models.Email.edit({
|
||||||
if (options.context && options.context.user) {
|
status: 'sent'
|
||||||
actor = {
|
}, {
|
||||||
id: options.context.user,
|
id: emailModel.id,
|
||||||
type: 'user'
|
context: {internal: true}
|
||||||
};
|
});
|
||||||
}
|
|
||||||
const action = {
|
|
||||||
event: 'delivered',
|
|
||||||
resource_id: model.id,
|
|
||||||
resource_type: 'post',
|
|
||||||
actor_id: actor.id,
|
|
||||||
actor_type: actor.type
|
|
||||||
};
|
|
||||||
return models.Action.add(action, {context: {internal: true}});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function listen() {
|
function listen() {
|
||||||
common.events.on('post.published', listener);
|
common.events.on('email.added', listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Public API
|
// Public API
|
||||||
module.exports = {
|
module.exports = {
|
||||||
listen,
|
listen,
|
||||||
|
addEmail,
|
||||||
sendTestEmail,
|
sendTestEmail,
|
||||||
handleUnsubscribeRequest,
|
handleUnsubscribeRequest,
|
||||||
createUnsubscribeUrl
|
createUnsubscribeUrl
|
||||||
|
Loading…
Reference in New Issue
Block a user