diff --git a/ghost/staff-service/lib/email-templates/new-free-signup.hbs b/ghost/staff-service/lib/email-templates/new-free-signup.hbs index f1338a862b..bc9061de48 100644 --- a/ghost/staff-service/lib/email-templates/new-free-signup.hbs +++ b/ghost/staff-service/lib/email-templates/new-free-signup.hbs @@ -111,7 +111,12 @@ <div class="content" style="box-sizing: border-box; display: block; Margin: 0 auto; max-width: 600px; padding: 30px 20px;"> <!-- START CENTERED CONTAINER --> - <span class="preheader" style="color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;"></span> + {{#> preview}} + {{#*inline "content"}} + Congratulations! You have a new free member. + {{/inline}} + {{/preview}} + <table class="main" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; background: #ffffff; border-radius: 8px;"> <!-- START MAIN CONTENT AREA --> diff --git a/ghost/staff-service/lib/email-templates/new-paid-cancellation.hbs b/ghost/staff-service/lib/email-templates/new-paid-cancellation.hbs index d0bf6d78be..2daaf8e79d 100644 --- a/ghost/staff-service/lib/email-templates/new-paid-cancellation.hbs +++ b/ghost/staff-service/lib/email-templates/new-paid-cancellation.hbs @@ -111,9 +111,16 @@ <div class="content" style="box-sizing: border-box; display: block; Margin: 0 auto; max-width: 600px; padding: 30px 20px;"> <!-- START CENTERED CONTAINER --> - <span class="preheader" style="color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;"> - {{#if subscriptionData.cancellationReason}}Reason: {{subscriptionData.cancellationReason}} - {{/if}} - </span> + {{#> preview}} + {{#*inline "content"}} + {{#if subscriptionData.cancellationReason}} + Reason: {{subscriptionData.cancellationReason}} + {{else}} + A paid member has just canceled their subscription. + {{/if}} + {{/inline}} + {{/preview}} + <table class="main" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; background: #ffffff; border-radius: 8px;"> <!-- START MAIN CONTENT AREA --> diff --git a/ghost/staff-service/lib/email-templates/new-paid-started.hbs b/ghost/staff-service/lib/email-templates/new-paid-started.hbs index 6d37dd144c..309256b506 100644 --- a/ghost/staff-service/lib/email-templates/new-paid-started.hbs +++ b/ghost/staff-service/lib/email-templates/new-paid-started.hbs @@ -111,7 +111,12 @@ <div class="content" style="box-sizing: border-box; display: block; Margin: 0 auto; max-width: 600px; padding: 30px 20px;"> <!-- START CENTERED CONTAINER --> - <span class="preheader" style="color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;">{{tierData.name}} - {{tierData.details}} - </span> + {{#> preview}} + {{#*inline "content"}} + {{tierData.name}}: {{tierData.details}} {{#if offerData}}- Offer: {{offerData.name}} - {{offerData.details}}{{/if}} + {{/inline}} + {{/preview}} + <table class="main" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; background: #ffffff; border-radius: 8px;"> <!-- START MAIN CONTENT AREA --> diff --git a/ghost/staff-service/lib/email-templates/partials/preview.hbs b/ghost/staff-service/lib/email-templates/partials/preview.hbs new file mode 100644 index 0000000000..d734ac52ca --- /dev/null +++ b/ghost/staff-service/lib/email-templates/partials/preview.hbs @@ -0,0 +1,6 @@ +<span class="preheader" style="color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;"> + {{> content}} + <!-- Add spaces to prevent pulling text from email body to preview --> + ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ + ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ ‌ +</span> diff --git a/ghost/staff-service/lib/emails.js b/ghost/staff-service/lib/emails.js index 1382114456..8ac37d692b 100644 --- a/ghost/staff-service/lib/emails.js +++ b/ghost/staff-service/lib/emails.js @@ -1,6 +1,7 @@ -const {promises: fs} = require('fs'); +const {promises: fs, readFileSync} = require('fs'); const path = require('path'); const moment = require('moment'); +const glob = require('glob'); class StaffServiceEmails { constructor({logging, models, mailer, settingsHelpers, settingsCache, urlUtils}) { @@ -12,6 +13,7 @@ class StaffServiceEmails { this.urlUtils = urlUtils; this.Handlebars = require('handlebars'); + this.registerPartials(); } async notifyFreeMemberSignup(member, options) { @@ -271,6 +273,17 @@ class StaffServiceEmails { return this.mailer.send(msg); } + registerPartials() { + const rootDirname = './email-templates/partials/'; + const files = glob.sync('*.hbs', {cwd: path.join(__dirname, rootDirname)}); + files.forEach((fileName) => { + const name = fileName.replace(/.hbs$/, ''); + const filePath = path.join(__dirname, rootDirname, `${name}.hbs`); + const content = readFileSync(filePath, 'utf8'); + this.Handlebars.registerPartial(name, content); + }); + } + async renderEmailTemplate(templateName, data) { const htmlTemplateSource = await fs.readFile(path.join(__dirname, './email-templates/', `${templateName}.hbs`), 'utf8'); const htmlTemplate = this.Handlebars.compile(Buffer.from(htmlTemplateSource).toString()); diff --git a/ghost/staff-service/test/staff-service.test.js b/ghost/staff-service/test/staff-service.test.js index ae5e5abc29..a7d0516720 100644 --- a/ghost/staff-service/test/staff-service.test.js +++ b/ghost/staff-service/test/staff-service.test.js @@ -417,6 +417,11 @@ describe('StaffService', function () { mailStub.calledWith( sinon.match.has('html', 'Offer') ).should.be.false(); + + // check preview text + mailStub.calledWith( + sinon.match.has('html', sinon.match('Test Tier: $50.00/month')) + ).should.be.true(); }); it('sends paid subscription start alert with percent offer - first payment', async function () { @@ -434,6 +439,11 @@ describe('StaffService', function () { mailStub.calledWith( sinon.match.has('html', sinon.match('first payment')) ).should.be.true(); + + // check preview text + mailStub.calledWith( + sinon.match.has('html', sinon.match('Test Tier: $50.00/month - Offer: Half price - 50% off, first payment')) + ).should.be.true(); }); it('sends paid subscription start alert with fixed type offer - repeating duration', async function () { @@ -561,7 +571,7 @@ describe('StaffService', function () { ).should.be.false(); mailStub.calledWith( - sinon.match.has('html', sinon.match('Reason: Changed my mind! - ')) + sinon.match.has('html', sinon.match('Reason: Changed my mind!')) ).should.be.true(); mailStub.calledWith( sinon.match.has('html', sinon.match('Cancellation reason')) @@ -592,6 +602,11 @@ describe('StaffService', function () { mailStub.calledWith( sinon.match.has('html', sinon.match('Cancellation reason')) ).should.be.false(); + + // check preview text + mailStub.calledWith( + sinon.match.has('html', sinon.match('A paid member has just canceled their subscription.')) + ).should.be.true(); }); }); });