Added publication icon to donation notification email (#20704)

REF MOM-317
- Added site icon to add some flair and personal branding to the
donation notification email.
This commit is contained in:
Sanne de Vries 2024-08-05 13:43:24 +02:00 committed by GitHub
parent 978ccc8483
commit 5ed2793369
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 48 additions and 18 deletions

View File

@ -17,6 +17,7 @@ class StaffServiceWrapper {
const mailer = new GhostMailer(); const mailer = new GhostMailer();
const settingsCache = require('../../../shared/settings-cache'); const settingsCache = require('../../../shared/settings-cache');
const urlUtils = require('../../../shared/url-utils'); const urlUtils = require('../../../shared/url-utils');
const {blogIcon} = require('../../../server/lib/image');
const settingsHelpers = require('../settings-helpers'); const settingsHelpers = require('../settings-helpers');
this.api = new StaffService({ this.api = new StaffService({
@ -26,6 +27,7 @@ class StaffServiceWrapper {
settingsHelpers, settingsHelpers,
settingsCache, settingsCache,
urlUtils, urlUtils,
blogIcon,
DomainEvents, DomainEvents,
memberAttributionService: memberAttribution.service, memberAttributionService: memberAttribution.service,
labs labs

View File

@ -4,7 +4,7 @@ const {MilestoneCreatedEvent} = require('@tryghost/milestones');
// @NOTE: 'StaffService' is a vague name that does not describe what it's actually doing. // @NOTE: 'StaffService' is a vague name that does not describe what it's actually doing.
// Possibly, "StaffNotificationService" or "StaffEventNotificationService" would be a more accurate name // Possibly, "StaffNotificationService" or "StaffEventNotificationService" would be a more accurate name
class StaffService { class StaffService {
constructor({logging, models, mailer, settingsCache, settingsHelpers, urlUtils, DomainEvents, labs, memberAttributionService}) { constructor({logging, models, mailer, settingsCache, settingsHelpers, urlUtils, blogIcon, DomainEvents, labs, memberAttributionService}) {
this.logging = logging; this.logging = logging;
this.labs = labs; this.labs = labs;
/** @private */ /** @private */
@ -22,6 +22,7 @@ class StaffService {
settingsHelpers, settingsHelpers,
settingsCache, settingsCache,
urlUtils, urlUtils,
blogIcon,
labs labs
}); });
} }

View File

@ -5,12 +5,13 @@ const glob = require('glob');
const {EmailAddressParser} = require('@tryghost/email-addresses'); const {EmailAddressParser} = require('@tryghost/email-addresses');
class StaffServiceEmails { class StaffServiceEmails {
constructor({logging, models, mailer, settingsHelpers, settingsCache, urlUtils, labs}) { constructor({logging, models, mailer, settingsHelpers, settingsCache, blogIcon, urlUtils, labs}) {
this.logging = logging; this.logging = logging;
this.models = models; this.models = models;
this.mailer = mailer; this.mailer = mailer;
this.settingsHelpers = settingsHelpers; this.settingsHelpers = settingsHelpers;
this.settingsCache = settingsCache; this.settingsCache = settingsCache;
this.blogIcon = blogIcon;
this.urlUtils = urlUtils; this.urlUtils = urlUtils;
this.labs = labs; this.labs = labs;
@ -44,6 +45,7 @@ class StaffServiceEmails {
attributionUrl: attribution?.url || '', attributionUrl: attribution?.url || '',
referrerSource: attribution?.referrerSource, referrerSource: attribution?.referrerSource,
siteTitle: this.settingsCache.get('title'), siteTitle: this.settingsCache.get('title'),
siteIconUrl: this.blogIcon.getIconUrl(true),
siteUrl: this.urlUtils.getSiteUrl(), siteUrl: this.urlUtils.getSiteUrl(),
siteDomain: this.siteDomain, siteDomain: this.siteDomain,
accentColor: this.settingsCache.get('accent_color'), accentColor: this.settingsCache.get('accent_color'),
@ -103,6 +105,7 @@ class StaffServiceEmails {
offerData, offerData,
subscriptionData, subscriptionData,
siteTitle: this.settingsCache.get('title'), siteTitle: this.settingsCache.get('title'),
siteIconUrl: this.blogIcon.getIconUrl(true),
siteUrl: this.urlUtils.getSiteUrl(), siteUrl: this.urlUtils.getSiteUrl(),
siteDomain: this.siteDomain, siteDomain: this.siteDomain,
accentColor: this.settingsCache.get('accent_color'), accentColor: this.settingsCache.get('accent_color'),
@ -153,6 +156,7 @@ class StaffServiceEmails {
tierData, tierData,
subscriptionData, subscriptionData,
siteTitle: this.settingsCache.get('title'), siteTitle: this.settingsCache.get('title'),
siteIconUrl: this.blogIcon.getIconUrl(true),
siteUrl: this.urlUtils.getSiteUrl(), siteUrl: this.urlUtils.getSiteUrl(),
siteDomain: this.siteDomain, siteDomain: this.siteDomain,
accentColor: this.settingsCache.get('accent_color'), accentColor: this.settingsCache.get('accent_color'),
@ -182,6 +186,7 @@ class StaffServiceEmails {
return { return {
siteTitle: this.settingsCache.get('title'), siteTitle: this.settingsCache.get('title'),
siteIconUrl: this.blogIcon.getIconUrl(true),
siteUrl: this.urlUtils.getSiteUrl(), siteUrl: this.urlUtils.getSiteUrl(),
siteDomain: this.siteDomain, siteDomain: this.siteDomain,
accentColor: this.settingsCache.get('accent_color'), accentColor: this.settingsCache.get('accent_color'),
@ -282,6 +287,7 @@ class StaffServiceEmails {
const templateData = { const templateData = {
siteTitle: this.settingsCache.get('title'), siteTitle: this.settingsCache.get('title'),
siteUrl: this.urlUtils.getSiteUrl(), siteUrl: this.urlUtils.getSiteUrl(),
siteIconUrl: this.blogIcon.getIconUrl(true),
siteDomain: this.siteDomain, siteDomain: this.siteDomain,
fromEmail: this.fromEmailAddress, fromEmail: this.fromEmailAddress,
toEmail: to, toEmail: to,

View File

@ -21,21 +21,33 @@
<tr> <tr>
<td class="wrapper" style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 14px; vertical-align: top; box-sizing: border-box;"> <td class="wrapper" style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 14px; vertical-align: top; box-sizing: border-box;">
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;"> <table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;">
{{#if siteIconUrl}}
<tr>
<td align="center" style="padding-bottom: 56px; text-align: center;"><a href="{{siteUrl}}"><img src="{{siteIconUrl}}" alt="{{siteTitle}}" border="0" width="48" height="48"></a></td>
</tr>
{{/if}}
<tr> <tr>
<td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 14px; vertical-align: top;"> <td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 14px; vertical-align: top;">
<h1 style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 26px; color: #15212A; font-weight: bold; line-height: 28px; margin: 0; margin-bottom: 15px;">Cha-ching! 💰 You received {{donation.amount}} from {{donation.name}}.</h1> <h1 style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 26px; color: #15212A; font-weight: bold; line-height: 28px; margin: 0; padding-bottom: 24px;">Cha-ching! You received a {{donation.amount}} tip from {{donation.name}}.</h1>
<table width="100" border="0" cellpadding="0" cellspacing="0" class="btn btn-primary" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; table-layout: fixed; width: 100%; min-width: 100%; box-sizing: border-box; background: #F9F9FA; border-radius: 7px;"> <table width="100" border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; table-layout: fixed; width: 100%; min-width: 100%; box-sizing: border-box; background: #F4F5F6; border-radius: 8px;">
<tbody> <tbody>
<tr> <tr>
<td align="center" style="padding: 32px 24px; text-align: center;"> <td align="center" style="padding: 24px; text-align: center;">
<p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; line-height: 26px; padding: 0; text-align: left; margin: 0; color: #15171A; font-weight: 400;">Type:</p> <p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; line-height: 26px; padding: 0; text-align: left; margin: 0; color: #15171A; font-weight: 400;">From:</p>
<p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 17px; line-height: 26px; padding: 0; text-align: left; margin: 0; margin-bottom: 20px; color: #15171A; font-weight: 700;">One-time payment</p> <p class="text-link" style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 17px; line-height: 26px; padding: 0; text-align: left; margin: 0; padding-bottom: 24px; color: #15171A; font-weight: 700;">{{donation.name}} (<span style="color:{{accentColor}}; text-decoration: none;">{{donation.email}}</span>)</p>
<p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; line-height: 26px; padding: 0; text-align: left; margin: 0; color: #15171A; font-weight: 400;">From:</p> <p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; line-height: 26px; padding: 0; text-align: left; margin: 0; color: #15171A; font-weight: 400;">Amount received:</p>
<p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 17px; line-height: 26px; padding: 0; text-align: left; margin: 0; margin-bottom: 20px; color: #15171A; font-weight: 700;">{{#if memberData}}<a style="color:{{accentColor}}" href="{{memberData.adminUrl}}">{{donation.name}} ({{donation.email}})</a>{{else}}{{donation.name}} ({{donation.email}}){{/if}}</p> <p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 17px; line-height: 26px; padding: 0; text-align: left; margin: 0; color: #15171A; font-weight: 700;">{{donation.amount}}</p>
<p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; line-height: 26px; padding: 0; text-align: left; margin: 0; color: #15171A; font-weight: 400;">Amount received:</p> </td>
<p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 17px; line-height: 26px; padding: 0; text-align: left; margin: 0; color: #15171A; font-weight: 700;">{{donation.amount}}</p> </tr>
</td> <tr>
</tr> <td style="padding:0 24px 24px;">
{{#if memberData}}
<a href="{{memberData.adminUrl}}" style="border:solid 1px {{accentColor}};border-radius:8px;box-sizing:border-box;display:inline-block;font-size:15px;font-weight:normal;margin:0;padding:10px 20px;text-decoration:none;background-color:{{accentColor}};border-color:{{accentColor}};color:#ffffff">View member</a>
{{else}}
<a href="{{adminUrl}}" style="border:solid 1px {{accentColor}};border-radius:8px;box-sizing:border-box;display:inline-block;font-size:15px;font-weight:normal;margin:0;padding:10px 20px;text-decoration:none;background-color:{{accentColor}};border-color:{{accentColor}};color:#ffffff">View dashboard</a>
{{/if}}
</td>
</tr>
</tbody> </tbody>
</table> </table>
</td> </td>
@ -43,13 +55,13 @@
<!-- START FOOTER --> <!-- START FOOTER -->
<tr> <tr>
<td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 14px; vertical-align: top; padding-top: 80px;"> <td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 12px; vertical-align: top; padding-top: 56px;">
<p class="small" style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; line-height: 18px; font-size: 12px; color: #738A94; font-weight: normal; margin: 0; margin-bottom: 2px;">This message was sent from <a class="small" href="{{siteUrl}}" style="text-decoration: underline; color: #738A94; font-size: 11px;">{{siteDomain}}</a> to <a class="small" href="mailto:{{toEmail}}" style="text-decoration: underline; color: #738A94; font-size: 11px;">{{toEmail}}</a></p> <p class="small" style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; line-height: 18px; font-size: 12px; color: #7C8B9A; font-weight: normal; margin: 0;">This message was sent from <a class="small" href="{{siteUrl}}" style="text-decoration: underline; color: #7C8B9A; font-size: 12px;">{{siteDomain}}</a> to <a class="small" href="mailto:{{toEmail}}" style="text-decoration: underline; color: #7C8B9A; font-size: 12px;">{{toEmail}}</a></p>
</td> </td>
</tr> </tr>
<tr> <tr>
<td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 14px; vertical-align: top; padding-top: 2px"> <td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 12px; vertical-align: top;">
<p class="small" style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; line-height: 18px; font-size: 12px; color: #738A94; font-weight: normal; margin: 0; margin-bottom: 2px;">Dont want to receive these emails? Manage your preferences <a class="small" href="{{staffUrl}}" style="text-decoration: underline; color: #738A94; font-size: 11px;">here</a>.</p> <p class="small" style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; line-height: 18px; font-size: 12px; color: #7C8B9A; font-weight: normal; margin: 0;">Dont want to receive these emails? Manage your preferences <a class="small" href="{{staffUrl}}" style="text-decoration: underline; color: #7C8B9A; font-size: 12px;">here</a>.</p>
</td> </td>
</tr> </tr>

View File

@ -149,6 +149,12 @@ describe('StaffService', function () {
} }
}; };
const blogIcon = {
getIconUrl: () => {
return 'https://ghost.example/siteicon.png';
}
};
const settingsHelpers = { const settingsHelpers = {
getDefaultEmailDomain: () => { getDefaultEmailDomain: () => {
return 'ghost.example'; return 'ghost.example';
@ -184,6 +190,7 @@ describe('StaffService', function () {
}, },
settingsCache, settingsCache,
urlUtils, urlUtils,
blogIcon,
settingsHelpers, settingsHelpers,
labs labs
}); });
@ -220,6 +227,7 @@ describe('StaffService', function () {
DomainEvents, DomainEvents,
settingsCache, settingsCache,
urlUtils, urlUtils,
blogIcon,
settingsHelpers settingsHelpers
}); });
service.subscribeEvents(); service.subscribeEvents();
@ -339,6 +347,7 @@ describe('StaffService', function () {
}, },
settingsCache, settingsCache,
urlUtils, urlUtils,
blogIcon,
settingsHelpers, settingsHelpers,
labs: { labs: {
isSet: () => { isSet: () => {