mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-27 10:42:45 +03:00
Added Zapier-specific email templates
refs https://github.com/TryGhost/Toolbox/issues/292 - When the handler recognizes a Zapier client it should send an email using Zapier-specific template with instructions more suitable for Zap failure
This commit is contained in:
parent
1a0a4272f3
commit
b2f585e0d0
@ -31,7 +31,14 @@ class APIVersionCompatibilityService {
|
||||
const emails = await this.fetchEmailsToNotify();
|
||||
|
||||
for (const email of emails) {
|
||||
const template = 'generic-mismatch';
|
||||
const template = (trimmedUseAgent === 'Zapier')
|
||||
? 'zapier-mismatch'
|
||||
: 'generic-mismatch';
|
||||
|
||||
const subject = (trimmedUseAgent === 'Zapier')
|
||||
? 'Attention required: One of your Zaps has failed'
|
||||
: `Attention required: Your ${trimmedUseAgent} integration has failed`;
|
||||
|
||||
const {html, text} = await this.emailContentGenerator.getContent({
|
||||
template,
|
||||
data: {
|
||||
@ -43,7 +50,7 @@ class APIVersionCompatibilityService {
|
||||
});
|
||||
|
||||
await this.sendEmail({
|
||||
subject: `Attention required: Your ${trimmedUseAgent} integration has failed`,
|
||||
subject,
|
||||
to: email,
|
||||
html,
|
||||
text
|
||||
|
@ -0,0 +1,159 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Integration error</title>
|
||||
<style>
|
||||
/* -------------------------------------
|
||||
RESPONSIVE AND MOBILE FRIENDLY STYLES
|
||||
------------------------------------- */
|
||||
@media only screen and (max-width: 620px) {
|
||||
table[class=body] h1 {
|
||||
font-size: 28px !important;
|
||||
margin-bottom: 10px !important;
|
||||
}
|
||||
table[class=body] p,
|
||||
table[class=body] ul,
|
||||
table[class=body] ol,
|
||||
table[class=body] td,
|
||||
table[class=body] span,
|
||||
table[class=body] a {
|
||||
font-size: 16px !important;
|
||||
}
|
||||
table[class=body] .title {
|
||||
font-size: 22px !important;
|
||||
}
|
||||
table[class=body] .wrapper,
|
||||
table[class=body] .article {
|
||||
padding: 10px !important;
|
||||
}
|
||||
table[class=body] .content {
|
||||
padding: 0 !important;
|
||||
}
|
||||
table[class=body] .container {
|
||||
padding: 0 !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
table[class=body] .main {
|
||||
border-left-width: 0 !important;
|
||||
border-radius: 0 !important;
|
||||
border-right-width: 0 !important;
|
||||
}
|
||||
table[class=body] .btn table {
|
||||
width: 100% !important;
|
||||
}
|
||||
table[class=body] .btn a {
|
||||
width: 100% !important;
|
||||
}
|
||||
table[class=body] .img-responsive {
|
||||
height: auto !important;
|
||||
max-width: 100% !important;
|
||||
width: auto !important;
|
||||
}
|
||||
table[class=body] p[class=small],
|
||||
table[class=body] a[class=small] {
|
||||
font-size: 12x !important;
|
||||
}
|
||||
}
|
||||
/* -------------------------------------
|
||||
PRESERVE THESE STYLES IN THE HEAD
|
||||
------------------------------------- */
|
||||
@media all {
|
||||
.ExternalClass {
|
||||
width: 100%;
|
||||
}
|
||||
.ExternalClass,
|
||||
.ExternalClass p,
|
||||
.ExternalClass span,
|
||||
.ExternalClass font,
|
||||
.ExternalClass td,
|
||||
.ExternalClass div {
|
||||
line-height: 100%;
|
||||
}
|
||||
.recipient-link a {
|
||||
color: inherit !important;
|
||||
font-family: inherit !important;
|
||||
font-size: inherit !important;
|
||||
font-weight: inherit !important;
|
||||
line-height: inherit !important;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
#MessageViewBody a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
font-size: inherit;
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
}
|
||||
hr {
|
||||
border-width: 0;
|
||||
height: 0;
|
||||
margin-top: 34px;
|
||||
margin-bottom: 34px;
|
||||
border-bottom-width: 1px;
|
||||
border-bottom-color: #EEF5F8;
|
||||
}
|
||||
a {
|
||||
color: #3A464C;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="background-color: #ffffff; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; -webkit-font-smoothing: antialiased; font-size: 14px; line-height: 1.5em; margin: 0; padding: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;">
|
||||
|
||||
<table border="0" cellpadding="0" cellspacing="0" class="body" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;">
|
||||
<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>
|
||||
<td class="container" 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; display: block; Margin: 0 auto; max-width: 540px; padding: 10px; width: 540px;">
|
||||
|
||||
<div class="content" style="box-sizing: border-box; display: block; Margin: 0 auto; max-width: 600px; padding: 30px 20px;">
|
||||
|
||||
<!-- START CENTERED CONTAINER -->
|
||||
<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 -->
|
||||
<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;">
|
||||
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;">
|
||||
<tr>
|
||||
<td align="center" style="padding-top: 20px; padding-bottom: 12px;"><img src="https://static.ghost.org/v4.0.0/images/ghost-orb-1.png" width="60" height="60" style="width: 60px; height: 60px;" /></td>
|
||||
</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: 16px; vertical-align: top;">
|
||||
<p class="title" style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 21px; color: #3A464C; font-weight: normal; line-height: 25px; margin-bottom: 0px; margin-top: 50px; font-weight: 600; color: #15212A;">Uh-oh!</p>
|
||||
</td>
|
||||
</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: 16px; vertical-align: top; padding-top: 24px; padding-bottom: 10px;">
|
||||
<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: 16px; color: #3A464C; font-weight: normal; margin: 0; line-height: 25px; margin-bottom: 30px;">
|
||||
Ghost has noticed that one of the Zaps in your Zapier integration has <span style="font-weight: 600;">stopped working</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: 16px; color: #3A464C; font-weight: normal; margin: 0; line-height: 25px; margin-bottom: 30px;">
|
||||
To get this resolved as quickly as possible, please log in to your Zapier account to view any failing Zaps and recreate them using the most recent Ghost-supported versions. Zap errors can be found <a href="https://zapier.com/app/history/usage" style="color: #738A94;">here</a> in your “Zap history”.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</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'; vertical-align: top; padding-top: 80px; padding-bottom: 10px;">
|
||||
<div class="footer">
|
||||
<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'; color: #738A94; font-weight: normal; margin: 0; line-height: 18px; margin-bottom: 0px; font-size: 11px;">This email was sent from <a href="{{ siteUrl }}" style="color: #738A94;">{{ siteUrl }}</a> to <a href="mailto:{{recipientEmail}}" style="color: #738A94;">{{recipientEmail}}</a></p>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- END MAIN CONTENT AREA -->
|
||||
</table>
|
||||
|
||||
<!-- END CENTERED CONTAINER -->
|
||||
</div>
|
||||
</td>
|
||||
<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>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
@ -213,4 +213,41 @@ describe('APIVersionCompatibilityService', function () {
|
||||
assert.match(sendEmail.args[0][0].text, /This email was sent from https:\/\/amazeballsghostsite.com/);
|
||||
assert.match(sendEmail.args[0][0].text, /to test_env@example.com/);
|
||||
});
|
||||
|
||||
it('Sends Zapier-specific email when userAgent is a Zapier client', async function (){
|
||||
const sendEmail = sinon.spy();
|
||||
const fetchHandled = sinon.spy();
|
||||
const saveHandled = sinon.spy();
|
||||
|
||||
const compatibilityService = new APIVersionCompatibilityService({
|
||||
sendEmail,
|
||||
fetchEmailsToNotify: async () => ['test_env@example.com'],
|
||||
fetchHandled,
|
||||
saveHandled,
|
||||
getSiteUrl,
|
||||
getSiteTitle
|
||||
});
|
||||
|
||||
await compatibilityService.handleMismatch({
|
||||
acceptVersion: 'v4.5',
|
||||
contentVersion: 'v5.1',
|
||||
userAgent: 'Zapier/4.20 GhostAdminSDK/2.4.0'
|
||||
});
|
||||
|
||||
assert.equal(sendEmail.called, true);
|
||||
assert.equal(sendEmail.args[0][0].to, 'test_env@example.com');
|
||||
assert.equal(sendEmail.args[0][0].subject, `Attention required: One of your Zaps has failed`);
|
||||
|
||||
assert.match(sendEmail.args[0][0].html, /Ghost has noticed that one of the Zaps in your Zapier integration has <span style="font-weight: 600;">stopped working<\/span>\./);
|
||||
assert.match(sendEmail.args[0][0].html, /To get this resolved as quickly as possible, please log in to your Zapier account to view any failing Zaps and recreate them using the most recent Ghost-supported versions. Zap errors can be found <a href="https:\/\/zapier.com\/app\/history\/usage" style="color: #738A94;">here<\/a> in your “Zap history”\./);
|
||||
|
||||
assert.match(sendEmail.args[0][0].html, /This email was sent from <a href="https:\/\/amazeballsghostsite.com"/);
|
||||
assert.match(sendEmail.args[0][0].html, /to <a href="mailto:test_env@example.com"/);
|
||||
|
||||
assert.match(sendEmail.args[0][0].text, /Ghost has noticed that one of the Zaps in your Zapier integration has stopped/);
|
||||
assert.match(sendEmail.args[0][0].text, /To get this resolved as quickly as possible, please log in to your Zapier/);
|
||||
|
||||
assert.match(sendEmail.args[0][0].text, /This email was sent from https:\/\/amazeballsghostsite.com/);
|
||||
assert.match(sendEmail.args[0][0].text, /to test_env@example.com/);
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user