Ghost/core/server/api/canary/email-preview.js

90 lines
3.2 KiB
JavaScript
Raw Normal View History

2019-11-05 08:14:26 +03:00
const models = require('../../models');
const i18n = require('../../../shared/i18n');
Refactored `common` lib import to use destructuring (#11835) * refactored `core/frontend/apps` to destructure common imports * refactored `core/frontend/services/{apps, redirects, routing}` to destructure common imports * refactored `core/frontend/services/settings` to destructure common imports * refactored remaining `core/frontend/services` to destructure common imports * refactored `core/server/adapters` to destructure common imports * refactored `core/server/data/{db, exporter, schema, validation}` to destructure common imports * refactored `core/server/data/importer` to destructure common imports * refactored `core/server/models/{base, plugins, relations}` to destructure common imports * refactored remaining `core/server/models` to destructure common imports * refactored `core/server/api/canary/utils/serializers/output` to destructure common imports * refactored remaining `core/server/api/canary/utils` to destructure common imports * refactored remaining `core/server/api/canary` to destructure common imports * refactored `core/server/api/shared` to destructure common imports * refactored `core/server/api/v2/utils` to destructure common imports * refactored remaining `core/server/api/v2` to destructure common imports * refactored `core/frontend/meta` to destructure common imports * fixed some tests referencing `common.errors` instead of `@tryghost/errors` - Not all of them need to be updated; only updating the ones that are causing failures * fixed errors import being shadowed by local scope
2020-05-22 21:22:20 +03:00
const errors = require('@tryghost/errors');
2019-11-05 08:14:26 +03:00
const mega = require('../../services/mega');
const labs = require('../../../shared/labs');
2019-11-05 08:14:26 +03:00
module.exports = {
docName: 'email_preview',
read: {
options: [
'fields',
'memberSegment'
2019-11-05 08:14:26 +03:00
],
validation: {
options: {
fields: ['html', 'plaintext', 'subject']
}
},
data: [
'id',
'status'
2019-11-05 08:14:26 +03:00
],
permissions: true,
query(frame) {
2019-11-06 14:32:11 +03:00
const options = Object.assign(frame.options, {formats: 'html,plaintext', withRelated: ['authors', 'posts_meta']});
const data = Object.assign(frame.data, {status: 'all'});
return models.Post.findOne(data, options)
2019-11-05 08:14:26 +03:00
.then((model) => {
if (!model) {
Refactored `common` lib import to use destructuring (#11835) * refactored `core/frontend/apps` to destructure common imports * refactored `core/frontend/services/{apps, redirects, routing}` to destructure common imports * refactored `core/frontend/services/settings` to destructure common imports * refactored remaining `core/frontend/services` to destructure common imports * refactored `core/server/adapters` to destructure common imports * refactored `core/server/data/{db, exporter, schema, validation}` to destructure common imports * refactored `core/server/data/importer` to destructure common imports * refactored `core/server/models/{base, plugins, relations}` to destructure common imports * refactored remaining `core/server/models` to destructure common imports * refactored `core/server/api/canary/utils/serializers/output` to destructure common imports * refactored remaining `core/server/api/canary/utils` to destructure common imports * refactored remaining `core/server/api/canary` to destructure common imports * refactored `core/server/api/shared` to destructure common imports * refactored `core/server/api/v2/utils` to destructure common imports * refactored remaining `core/server/api/v2` to destructure common imports * refactored `core/frontend/meta` to destructure common imports * fixed some tests referencing `common.errors` instead of `@tryghost/errors` - Not all of them need to be updated; only updating the ones that are causing failures * fixed errors import being shadowed by local scope
2020-05-22 21:22:20 +03:00
throw new errors.NotFoundError({
message: i18n.t('errors.api.posts.postNotFound')
2019-11-05 08:14:26 +03:00
});
}
return mega.postEmailSerializer.serialize(model, {isBrowserPreview: true, apiVersion: 'canary'}).then((emailContent) => {
if (labs.isSet('emailCardSegments') && frame.options.memberSegment) {
emailContent = mega.postEmailSerializer.renderEmailForSegment(emailContent, frame.options.memberSegment);
}
Refactor mega service to use stored email content and batch/recipient records no issue - store raw content in email record - keep any replacement strings in the html/plaintext content so that it can be used when sending email rather than needing to re-serialize the post content which may have changed - split post email serializer into separate serialization and replacement parsing functions - serialization now returns any email content that is derived from the post content (subject/html/plaintext) rather than post content plus replacements - `parseReplacements` has been split out so that it can be run against email content rather than a post, this allows mega and the email preview service to work with the stored email content - move mailgun-specific functionality into the mailgun provider - previously mailgun-specific behaviour was spread across the post email serializer, mega, and bulk-email service - the per-batch `send` functionality was moved from the `bulk-email` service to the mailgun provider and updated to take email content, recipient info, and replacement info so that all mailgun-specific headers and replacement formatting can be handled in one place - exposes the `BATCH_SIZE` constant because batch sizes are limited to what the provider allows - `bulk-email` service split into three methods - `send` responsible for taking email content and recipients, parsing replacement info from the email content and using that to collate a recipient data object, and finally coordinating the send via the mailgun provider. Usable directly for use-cases such as test emails - `processEmail` takes an email ID, loads it and coordinates sending related batches concurrently - `processEmailBatch` takes an email_batch ID, loads it along with associated email_recipient records and passes the data through to the `send` function, updating the batch status as it's processed - `processEmail` and `processEmailBatch` take IDs rather than objects ready for future use by job-queues, it's best to keep job parameters as minimal as possible - refactored `mega` service - modified `getEmailData` to collate email content (from/reply-to/subject/html/plaintext) rather than being responsible for dealing with replacements and mailgun-specific replacement formats - used for generating email content before storing in the email table, and when sending test emails - from/reply-to calculation moved out of the post-email-serializer into mega and extracted into separate functions used by `getEmailData` - `sendTestEmail` updated to generate `EmailRecipient`-like objects for each email address so that appropriate data can be supplied to the updated `bulk-email.send` method - `sendEmailJob` updated to create `email_batches` and associated `email_recipients` records then hand over processing to the `bulk-email` service - member row fetching extracted into a separate function and used by `createEmailBatches` - moved updating of email status from `mega` to the `bulk-email` service, keeps concept of Successful/FailedBatch internal to the `bulk-email` service
2020-09-24 11:35:29 +03:00
const replacements = mega.postEmailSerializer.parseReplacements(emailContent);
replacements.forEach((replacement) => {
Refactor mega service to use stored email content and batch/recipient records no issue - store raw content in email record - keep any replacement strings in the html/plaintext content so that it can be used when sending email rather than needing to re-serialize the post content which may have changed - split post email serializer into separate serialization and replacement parsing functions - serialization now returns any email content that is derived from the post content (subject/html/plaintext) rather than post content plus replacements - `parseReplacements` has been split out so that it can be run against email content rather than a post, this allows mega and the email preview service to work with the stored email content - move mailgun-specific functionality into the mailgun provider - previously mailgun-specific behaviour was spread across the post email serializer, mega, and bulk-email service - the per-batch `send` functionality was moved from the `bulk-email` service to the mailgun provider and updated to take email content, recipient info, and replacement info so that all mailgun-specific headers and replacement formatting can be handled in one place - exposes the `BATCH_SIZE` constant because batch sizes are limited to what the provider allows - `bulk-email` service split into three methods - `send` responsible for taking email content and recipients, parsing replacement info from the email content and using that to collate a recipient data object, and finally coordinating the send via the mailgun provider. Usable directly for use-cases such as test emails - `processEmail` takes an email ID, loads it and coordinates sending related batches concurrently - `processEmailBatch` takes an email_batch ID, loads it along with associated email_recipient records and passes the data through to the `send` function, updating the batch status as it's processed - `processEmail` and `processEmailBatch` take IDs rather than objects ready for future use by job-queues, it's best to keep job parameters as minimal as possible - refactored `mega` service - modified `getEmailData` to collate email content (from/reply-to/subject/html/plaintext) rather than being responsible for dealing with replacements and mailgun-specific replacement formats - used for generating email content before storing in the email table, and when sending test emails - from/reply-to calculation moved out of the post-email-serializer into mega and extracted into separate functions used by `getEmailData` - `sendTestEmail` updated to generate `EmailRecipient`-like objects for each email address so that appropriate data can be supplied to the updated `bulk-email.send` method - `sendEmailJob` updated to create `email_batches` and associated `email_recipients` records then hand over processing to the `bulk-email` service - member row fetching extracted into a separate function and used by `createEmailBatches` - moved updating of email status from `mega` to the `bulk-email` service, keeps concept of Successful/FailedBatch internal to the `bulk-email` service
2020-09-24 11:35:29 +03:00
emailContent[replacement.format] = emailContent[replacement.format].replace(
replacement.match,
replacement.fallback || ''
);
});
Refactor mega service to use stored email content and batch/recipient records no issue - store raw content in email record - keep any replacement strings in the html/plaintext content so that it can be used when sending email rather than needing to re-serialize the post content which may have changed - split post email serializer into separate serialization and replacement parsing functions - serialization now returns any email content that is derived from the post content (subject/html/plaintext) rather than post content plus replacements - `parseReplacements` has been split out so that it can be run against email content rather than a post, this allows mega and the email preview service to work with the stored email content - move mailgun-specific functionality into the mailgun provider - previously mailgun-specific behaviour was spread across the post email serializer, mega, and bulk-email service - the per-batch `send` functionality was moved from the `bulk-email` service to the mailgun provider and updated to take email content, recipient info, and replacement info so that all mailgun-specific headers and replacement formatting can be handled in one place - exposes the `BATCH_SIZE` constant because batch sizes are limited to what the provider allows - `bulk-email` service split into three methods - `send` responsible for taking email content and recipients, parsing replacement info from the email content and using that to collate a recipient data object, and finally coordinating the send via the mailgun provider. Usable directly for use-cases such as test emails - `processEmail` takes an email ID, loads it and coordinates sending related batches concurrently - `processEmailBatch` takes an email_batch ID, loads it along with associated email_recipient records and passes the data through to the `send` function, updating the batch status as it's processed - `processEmail` and `processEmailBatch` take IDs rather than objects ready for future use by job-queues, it's best to keep job parameters as minimal as possible - refactored `mega` service - modified `getEmailData` to collate email content (from/reply-to/subject/html/plaintext) rather than being responsible for dealing with replacements and mailgun-specific replacement formats - used for generating email content before storing in the email table, and when sending test emails - from/reply-to calculation moved out of the post-email-serializer into mega and extracted into separate functions used by `getEmailData` - `sendTestEmail` updated to generate `EmailRecipient`-like objects for each email address so that appropriate data can be supplied to the updated `bulk-email.send` method - `sendEmailJob` updated to create `email_batches` and associated `email_recipients` records then hand over processing to the `bulk-email` service - member row fetching extracted into a separate function and used by `createEmailBatches` - moved updating of email status from `mega` to the `bulk-email` service, keeps concept of Successful/FailedBatch internal to the `bulk-email` service
2020-09-24 11:35:29 +03:00
return emailContent;
});
2019-11-05 08:14:26 +03:00
});
}
2019-11-05 12:09:07 +03:00
},
sendTestEmail: {
statusCode: 200,
headers: {},
options: [
'id'
],
validation: {
options: {
id: {
required: true
}
}
},
2019-11-06 08:09:55 +03:00
permissions: true,
2019-11-05 12:09:07 +03:00
async query(frame) {
const options = Object.assign(frame.options, {status: 'all'});
let model = await models.Post.findOne(options, {withRelated: ['authors']});
2019-11-05 12:09:07 +03:00
if (!model) {
Refactored `common` lib import to use destructuring (#11835) * refactored `core/frontend/apps` to destructure common imports * refactored `core/frontend/services/{apps, redirects, routing}` to destructure common imports * refactored `core/frontend/services/settings` to destructure common imports * refactored remaining `core/frontend/services` to destructure common imports * refactored `core/server/adapters` to destructure common imports * refactored `core/server/data/{db, exporter, schema, validation}` to destructure common imports * refactored `core/server/data/importer` to destructure common imports * refactored `core/server/models/{base, plugins, relations}` to destructure common imports * refactored remaining `core/server/models` to destructure common imports * refactored `core/server/api/canary/utils/serializers/output` to destructure common imports * refactored remaining `core/server/api/canary/utils` to destructure common imports * refactored remaining `core/server/api/canary` to destructure common imports * refactored `core/server/api/shared` to destructure common imports * refactored `core/server/api/v2/utils` to destructure common imports * refactored remaining `core/server/api/v2` to destructure common imports * refactored `core/frontend/meta` to destructure common imports * fixed some tests referencing `common.errors` instead of `@tryghost/errors` - Not all of them need to be updated; only updating the ones that are causing failures * fixed errors import being shadowed by local scope
2020-05-22 21:22:20 +03:00
throw new errors.NotFoundError({
message: i18n.t('errors.api.posts.postNotFound')
2019-11-05 12:09:07 +03:00
});
}
const {emails = [], memberSegment} = frame.data;
const response = await mega.mega.sendTestEmail(model, emails, 'canary', memberSegment);
if (response && response[0] && response[0].error) {
Refactored `common` lib import to use destructuring (#11835) * refactored `core/frontend/apps` to destructure common imports * refactored `core/frontend/services/{apps, redirects, routing}` to destructure common imports * refactored `core/frontend/services/settings` to destructure common imports * refactored remaining `core/frontend/services` to destructure common imports * refactored `core/server/adapters` to destructure common imports * refactored `core/server/data/{db, exporter, schema, validation}` to destructure common imports * refactored `core/server/data/importer` to destructure common imports * refactored `core/server/models/{base, plugins, relations}` to destructure common imports * refactored remaining `core/server/models` to destructure common imports * refactored `core/server/api/canary/utils/serializers/output` to destructure common imports * refactored remaining `core/server/api/canary/utils` to destructure common imports * refactored remaining `core/server/api/canary` to destructure common imports * refactored `core/server/api/shared` to destructure common imports * refactored `core/server/api/v2/utils` to destructure common imports * refactored remaining `core/server/api/v2` to destructure common imports * refactored `core/frontend/meta` to destructure common imports * fixed some tests referencing `common.errors` instead of `@tryghost/errors` - Not all of them need to be updated; only updating the ones that are causing failures * fixed errors import being shadowed by local scope
2020-05-22 21:22:20 +03:00
throw new errors.EmailError({
statusCode: response[0].error.statusCode,
message: response[0].error.message,
context: response[0].error.originalMessage
});
}
return response;
2019-11-05 12:09:07 +03:00
}
2019-11-05 08:14:26 +03:00
}
};