2022-11-21 12:29:53 +03:00
|
|
|
const errors = require('@tryghost/errors');
|
|
|
|
const tpl = require('@tryghost/tpl');
|
|
|
|
|
|
|
|
const messages = {
|
|
|
|
postNotFound: 'Post not found.',
|
2022-11-23 13:33:44 +03:00
|
|
|
noEmailsProvided: 'No emails provided.',
|
|
|
|
emailNotFound: 'Email not found.'
|
2022-11-21 12:29:53 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
class EmailController {
|
|
|
|
service;
|
|
|
|
models;
|
|
|
|
|
|
|
|
/**
|
2023-01-04 17:22:49 +03:00
|
|
|
*
|
|
|
|
* @param {EmailService} service
|
2022-11-23 13:33:44 +03:00
|
|
|
* @param {{models: {Post: any, Newsletter: any, Email: any}}} dependencies
|
2022-11-21 12:29:53 +03:00
|
|
|
*/
|
|
|
|
constructor(service, {models}) {
|
|
|
|
this.service = service;
|
|
|
|
this.models = models;
|
|
|
|
}
|
|
|
|
|
|
|
|
async _getFrameData(frame) {
|
2022-11-30 15:56:28 +03:00
|
|
|
// Bit absurd situation in email-previews endpoints that one endpoint is using options and other one is using data.
|
|
|
|
// So we need to handle both cases.
|
|
|
|
let post;
|
|
|
|
if (frame.options.id) {
|
|
|
|
post = await this.models.Post.findOne({...frame.options, status: 'all'}, {withRelated: ['posts_meta', 'authors']});
|
|
|
|
} else {
|
|
|
|
post = await this.models.Post.findOne({...frame.data, status: 'all'}, {...frame.options, withRelated: ['posts_meta', 'authors']});
|
|
|
|
}
|
2022-11-21 12:29:53 +03:00
|
|
|
|
|
|
|
if (!post) {
|
|
|
|
throw new errors.NotFoundError({
|
|
|
|
message: tpl(messages.postNotFound)
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
let newsletter;
|
2023-01-09 16:48:30 +03:00
|
|
|
const slug = frame?.options?.newsletter ?? frame?.data?.newsletter ?? null;
|
|
|
|
if (slug) {
|
|
|
|
newsletter = await this.models.Newsletter.findOne({slug}, {require: true});
|
2022-11-21 12:29:53 +03:00
|
|
|
} else {
|
|
|
|
newsletter = (await post.getLazyRelation('newsletter')) ?? (await this.models.Newsletter.getDefaultNewsletter());
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
post,
|
|
|
|
newsletter,
|
|
|
|
segment: frame.options.memberSegment ?? frame.data.memberSegment ?? null
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
async previewEmail(frame) {
|
|
|
|
const {post, newsletter, segment} = await this._getFrameData(frame);
|
|
|
|
return await this.service.previewEmail(post, newsletter, segment);
|
|
|
|
}
|
|
|
|
|
|
|
|
async sendTestEmail(frame) {
|
|
|
|
const {post, newsletter, segment} = await this._getFrameData(frame);
|
|
|
|
|
|
|
|
const emails = frame.data.emails ?? [];
|
|
|
|
|
|
|
|
if (emails.length === 0) {
|
|
|
|
throw new errors.ValidationError({
|
|
|
|
message: tpl(messages.noEmailsProvided)
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-01-04 17:22:49 +03:00
|
|
|
await this.service.sendTestEmail(post, newsletter, segment, emails);
|
2022-11-21 12:29:53 +03:00
|
|
|
}
|
2022-11-23 13:33:44 +03:00
|
|
|
|
|
|
|
async retryFailedEmail(frame) {
|
|
|
|
const email = await this.models.Email.findOne(frame.data, {require: false});
|
2023-01-04 17:22:49 +03:00
|
|
|
|
2022-11-23 13:33:44 +03:00
|
|
|
if (!email) {
|
|
|
|
throw new errors.NotFoundError({
|
|
|
|
message: tpl(messages.emailNotFound)
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
return await this.service.retryEmail(email);
|
|
|
|
}
|
2022-11-21 12:29:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = EmailController;
|