0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-03-11 02:12:21 -05:00

Added email retry logic for failed batches (#11402)

no issue

- When whole email batch fails we want to allow retrying sending a batch when post is republished
- Refactored naming for email event handling in mega
This commit is contained in:
Naz Gargol 2019-11-18 21:28:54 +07:00 committed by GitHub
parent f14e3fa11b
commit c2aec69af9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 6 deletions

View file

@ -149,9 +149,18 @@ module.exports = {
return model;
}
if (!model.get('email') && (model.get('status') === 'published') && model.wasChanged()) {
const postPublished = model.wasChanged() && (model.get('status') === 'published') && (model.previous('status') !== 'published');
if (postPublished) {
let postEmail = model.relations.email;
if (!postEmail) {
const email = await mega.addEmail(model.toJSON());
model.set('email', email);
} else if (postEmail && postEmail.get('status') === 'failed') {
const email = await mega.retryFailedEmail(postEmail);
model.set('email', email);
}
}
return model;

View file

@ -82,6 +82,21 @@ const addEmail = async (post) => {
}
};
/**
* retryFailedEmail
*
* Accepts an Email model and resets it's fields to trigger retry listeners
*
* @param {object} model Email model
*/
const retryFailedEmail = async (model) => {
return await models.Email.edit({
status: 'pending'
}, {
id: model.get('id')
});
};
// 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
const serialize = async (model) => {
@ -160,7 +175,7 @@ async function handleUnsubscribeRequest(req) {
}
}
async function listener(emailModel, options) {
async function pendingEmailHandler(emailModel, options) {
// CASE: do not send email if we import a database
// TODO: refactor post.published events to never fire on importing
if (options && options.importing) {
@ -187,7 +202,7 @@ async function listener(emailModel, options) {
});
let meta = [];
let error;
let error = null;
try {
// NOTE: meta can contains an array which can be a mix of successful and error responses
@ -228,14 +243,24 @@ async function listener(emailModel, options) {
}
}
const statusChangedHandler = (emailModel, options) => {
const emailRetried = emailModel.wasChanged() && (emailModel.get('status') === 'pending') && (emailModel.previous('status') === 'failed');
if (emailRetried) {
pendingEmailHandler(emailModel, options);
}
};
function listen() {
common.events.on('email.added', listener);
common.events.on('email.added', pendingEmailHandler);
common.events.on('email.edited', statusChangedHandler);
}
// Public API
module.exports = {
listen,
addEmail,
retryFailedEmail,
sendTestEmail,
handleUnsubscribeRequest,
createUnsubscribeUrl