-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Send nicer and more meaningful emails. HTML templates with handlebars. Generate screenshots when running tests for visual testing.
- Loading branch information
Showing
20 changed files
with
880 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,13 @@ | ||
# port on which the service will run | ||
PORT=3005 | ||
|
||
# name of the app that sends the emails - featured in the message subject or body | ||
APP_NAME=Sleepy.bike | ||
# provide path to a logo to display on top of emails - keep it small! | ||
# absolute path, or relative path to the base of the project | ||
APP_LOGO=./logo.png | ||
SUPPORT_EMAIL=[email protected] | ||
|
||
# server base url, e.g. to construct correct email verification link | ||
# this is the base url that end users see | ||
BASE_URL=http://localhost:3005 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,3 +6,7 @@ node_modules | |
database.sqlite | ||
|
||
*.pem | ||
|
||
# Screenshots of emails from testing | ||
screenshots/* | ||
!screenshots/.keep |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,13 @@ import SMTPTransport from 'nodemailer/lib/smtp-transport' | |
// server base url, e.g. to construct correct email verification links | ||
export const baseUrl = process.env.BASE_URL ?? 'http://localhost:3005' | ||
|
||
export const appName = process.env.APP_NAME ?? 'Sleepy.bike' | ||
|
||
// default is sleepy.bike logo | ||
export const appLogo = process.env.APP_LOGO ?? './logo.png' | ||
|
||
export const supportEmail = process.env.SUPPORT_EMAIL ?? '[email protected]' | ||
|
||
// identity under which the mailer is operating | ||
export const mailerCredentials = { | ||
email: process.env.MAILER_IDENTITY_EMAIL ?? 'bot@example', | ||
|
@@ -26,7 +33,7 @@ const stringToBoolean = (value: string | undefined): boolean => { | |
} | ||
// SMTP transport for nodemailer (setup for sending emails) | ||
export const smtpTransportOptions: SMTPTransport.Options = { | ||
host: process.env.SMTP_TRANSPORT_HOST || undefined, | ||
host: process.env.SMTP_TRANSPORT_HOST || '0.0.0.0', | ||
port: process.env.SMTP_TRANSPORT_PORT | ||
? +process.env.SMTP_TRANSPORT_PORT | ||
: 1025, // default works for maildev | ||
|
@@ -39,7 +46,8 @@ export const smtpTransportOptions: SMTPTransport.Options = { | |
} | ||
|
||
// email address which will be the sender of the notifications and email verification messages | ||
export const emailSender = process.env.EMAIL_SENDER | ||
export const emailSender = | ||
process.env.EMAIL_SENDER ?? '[email protected]' | ||
|
||
export const port: number = +(process.env.PORT ?? 3005) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,19 @@ | ||
import * as nodemailer from 'nodemailer' | ||
import Mail from 'nodemailer/lib/mailer' | ||
import { smtpTransportOptions } from '../config' | ||
import * as path from 'path' | ||
import { appLogo, smtpTransportOptions } from '../config' | ||
|
||
export const sendMail = async (options: Mail.Options) => { | ||
const smtpTransport = nodemailer.createTransport(smtpTransportOptions) | ||
await smtpTransport.sendMail(options) | ||
await smtpTransport.sendMail({ | ||
...options, | ||
attachments: [ | ||
{ | ||
filename: path.basename(appLogo), | ||
path: appLogo, | ||
cid: '[email protected]', | ||
}, | ||
...(options.attachments ?? []), | ||
], | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import * as fs from 'fs-extra' | ||
import Handlebars from 'handlebars' | ||
import juice from 'juice' | ||
import path from 'path' | ||
import * as config from '../config' | ||
|
||
Handlebars.registerHelper('encodeURIComponent', encodeURIComponent) | ||
|
||
type LayoutData = { | ||
appName?: string | ||
appLogo?: string | ||
supportEmail?: string | ||
title?: string | ||
} | ||
|
||
export const generateHtmlMessage = async <T>( | ||
type: string, | ||
data: T & LayoutData, | ||
) => { | ||
const layout = await fs.readFile(path.join(__dirname, 'layout.hbs'), 'utf8') | ||
const layoutTemplate = Handlebars.compile(layout) | ||
const content = await fs.readFile(path.join(__dirname, `${type}.hbs`), 'utf8') | ||
const contentTemplate = Handlebars.compile<T>(content) | ||
const stylesheet = await fs.readFile( | ||
path.join(__dirname, 'styles.css'), | ||
'utf8', | ||
) | ||
|
||
const { | ||
appName = config.appName, | ||
appLogo = config.appLogo, | ||
supportEmail = config.supportEmail, | ||
title = '', | ||
} = data | ||
|
||
const compiledContent = contentTemplate({ | ||
...data, | ||
appName, | ||
appLogo, | ||
title, | ||
}) | ||
const emailHtml = layoutTemplate({ | ||
title, | ||
appName, | ||
appLogo, | ||
supportEmail, | ||
body: compiledContent, | ||
}) | ||
const emailHtmlInlineCss = juice(emailHtml, { extraCss: stylesheet }) | ||
|
||
return emailHtmlInlineCss | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<html> | ||
<head> | ||
<meta charset='utf-8' /> | ||
<title>{{title}}</title> | ||
</head> | ||
<body> | ||
<header><img | ||
alt='logo of {{appName}}' | ||
src='cid:[email protected]' | ||
height='32' | ||
/></header> | ||
{{{body}}} | ||
<footer> | ||
<p>You can contact us at | ||
<a href='mailto:{{supportEmail}}'>{{supportEmail}}</a></p> | ||
</footer> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<p>Hello{{#if target.name}} {{/if}}{{target.name}}!</p> | ||
<p> | ||
<a href={{actor.id}}>{{#if | ||
actor.name | ||
}}{{actor.name}}{{else}}Somebody{{/if}}</a> | ||
sent you a message from | ||
{{appName}}. | ||
</p> | ||
|
||
<blockquote>{{object.content}}</blockquote> | ||
|
||
<a | ||
href='https://sleepy.bike/messages/{{encodeURIComponent actor.id}}' | ||
class='action-button' | ||
>Reply on | ||
{{appName}}</a> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
.action-button { | ||
padding: 0.25rem 0.5rem; | ||
text-align: center; | ||
display: inline-block; | ||
border: 2px solid black; | ||
color: black; | ||
text-decoration: none; | ||
} | ||
|
||
.action-button:hover { | ||
background-color: #e6e6e6; | ||
} | ||
|
||
body { | ||
font-family: Arial, sans-serif; | ||
} | ||
|
||
footer { | ||
margin-top: 2rem; | ||
font-size: 0.9rem; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<p>To verify your email for | ||
{{appName}} | ||
notifications, please click the following link: | ||
</p> | ||
|
||
<p> | ||
<a href={{{emailVerificationLink}}} class='action-button'> | ||
Verify my email for | ||
{{appName}}</a> | ||
</p> | ||
|
||
<p>If the above link doesn't work, you can try copy-pasting the link directly | ||
into your browser:</p> | ||
|
||
<p>{{emailVerificationLink}}</p> | ||
|
||
<p>This email verification for | ||
{{appName}} | ||
was initialized by Solid identity | ||
{{actor}}. If you've received this message unexpectedly and you believe it to | ||
be an error, please ignore it, or contact us for support.</p> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.