Skip to content

Commit

Permalink
Merge pull request #46 from JHWelch/add-emails
Browse files Browse the repository at this point in the history
Add emails
  • Loading branch information
JHWelch authored Sep 4, 2023
2 parents 37057c9 + 24e25ea commit a8402db
Show file tree
Hide file tree
Showing 10 changed files with 1,632 additions and 201 deletions.
15 changes: 15 additions & 0 deletions .github/workflows/deploy-to-app-engine.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,26 @@ jobs:
- name: Place .env file
run: echo "${{ secrets.ENV_FILE }}" | base64 -d > .env

- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: '18.15.0'
cache: 'npm'

- name: Install Dependencies
run: npm ci

- name: Auth with Google
uses: google-github-actions/auth@v1
with:
workload_identity_provider: ${{ secrets.GOOGLE_WORKFLOW_IDENTITY_PROVIDER }}
service_account: ${{ secrets.GOOGLE_SERVICE_ACCOUNT }}

- name: Build email templates
run: npm run build-emails

- name: Deploy to Google
uses: google-github-actions/deploy-appengine@v1

- name: Upload email templates
run: npm run upload-emails
75 changes: 75 additions & 0 deletions __tests__/data/firestore/firestoreAdapter.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,3 +239,78 @@ describe ('sendEmail', () => {
)
})
})

describe('sendEmailTemplate', () => {
describe('rsvpConfirmation template', () => {
it('sends an email', async () => {
await firestore.sendEmailTemplate(
'[email protected]',
'rsvpConfirmation',
{
date: 'Thursday, January 1st',
theme: 'test theme',
movies: [
{
title: 'test title',
year: '2021',
time: '6:00pm',
posterUrl: 'https://example.com/poster.jpg',
},
],
})

expect(addDoc).toHaveBeenCalledWith(
FirebaseMock.mockCollection('mail'),
{
to: '[email protected]',
template: {
name: 'rsvpConfirmation',
data: {
date: 'Thursday, January 1st',
theme: 'test theme',
movies: [
{
title: 'test title',
year: '2021',
time: '6:00pm',
posterUrl: 'https://example.com/poster.jpg',
},
],
},
},
}
)
})
})
})

describe('updateTemplates', () => {
it('should update the templates with new data', async () => {
await firestore.updateTemplates([
{
name: 'templateId',
subject: 'new subject',
html: 'new html',
}, {
name: 'templateId2',
subject: 'new subject 2',
html: 'new html 2',
},
])

expect(transaction.set).toHaveBeenCalledWith(
FirebaseMock.mockDoc('mail-templates', 'templateId'),
{
subject: 'new subject',
html: 'new html',
}
)
expect(transaction.set).toHaveBeenCalledWith(
FirebaseMock.mockDoc('mail-templates', 'templateId2'),
{
subject: 'new subject 2',
html: 'new html 2',
}
)
})
})
24 changes: 24 additions & 0 deletions ci/uploadTemplates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/* eslint-disable no-console */
import * as dotenv from 'dotenv'
import fs from 'fs'
import Config from '../src/config/config.js'
import FirestoreAdapter from '../src/data/firestore/firestoreAdapter.js'
import emails from '../emails/emails.js'

dotenv.config()

const adapter = new FirestoreAdapter(new Config())

const getHtml = (name: string | null) =>
fs.readFileSync(`./emails/built/${name}.html`, 'utf8')

console.log('Templates to update:')
console.table(emails.templates)

console.log('Updating templates...')
adapter.updateTemplates(emails.templates.map(email => ({
...email,
html: getHtml(email.name),
})))

console.log('Templates successfully updated!')
2 changes: 2 additions & 0 deletions emails/built/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
11 changes: 11 additions & 0 deletions emails/emails.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default {
templates: [
{
name: 'reminder',
subject: 'Reminder: {{ theme }} is Tomorrow',
}, {
name: 'rsvpConfirmation',
subject: 'Thanks for RSVPing to {{ theme }}',
},
],
}
102 changes: 102 additions & 0 deletions emails/reminder.mjml
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<mjml>
<mj-head>
<mj-title>Movie Reminder</mj-title>

<mj-attributes>
<mj-all font-family="Verdana, sans-serif" />

<mj-text font-size="16px" color="#111827" line-height="16px"/>
</mj-attributes>

<mj-html-attributes>
<mj-selector path=".list table table">
<mj-html-attribute name="role">list</mj-html-attribute>
</mj-selector>

<mj-selector path=".list table table > tbody">
<mj-html-attribute name="role">presentation</mj-html-attribute>
</mj-selector>
</mj-html-attributes>
</mj-head>
<mj-body>
<mj-section full-width="full-width" background-color="#F9FAFB">
<mj-column width="100%">
<mj-text
padding="0px"
align="center"
font-size="12px"
color="#7c3aed"
>Wowell World Studios Presents: Thursday&nbsp;Night&nbsp;Movie&nbsp;Club</mj-text>
</mj-column>
</mj-section>

<mj-section full-width="full-width" background-color="#e9d5ff">
<mj-column width="100%">
<mj-text
align="center"
font-size="12px"
line-height="8px"
>{{ date }}</mj-text>

<mj-text
align="center"
font-size="20px"
font-weight="bold"
line-height="8px"
>{{ theme }}</mj-text>

<mj-button
background-color="#7c3aed"
color="#ffffff"
font-size="12px"
font-weight="bold"
align="center"
width="120px"
href="https://movies.wowellworld.com/"
>RSVP</mj-button>
</mj-column>
</mj-section>

<mj-section full-width="full-width" background-color="#F9FAFB">
{{ #each movies as |movie| }}
<mj-column width="50%">
<mj-text
align="center"
font-size="16px"
font-weight="bold"
color="#111827"
padding="5px"
>{{ movie.title }}</mj-text>

<mj-image
src="{{ movie.posterUrl }}"
alt="{{ movie.title }} Poster"
align="center"
width="220px"
/>
</mj-column>
{{ /each }}
</mj-section>

<mj-section full-width="full-width" background-color="#e9d5ff">
<mj-column width="400px">
{{ #each movies as |movie| }}
<mj-text font-size="16px" padding="15px 25px">
<b>{{ movie.time }}</b> - <i>{{ movie.title }} ({{ movie.year }})</i>
</mj-text>
{{ /each }}

<mj-button
padding="30px 0px"
background-color="#7c3aed"
color="#ffffff"
font-size="12px"
font-weight="bold"
align="center"
width="120px"
href="https://movies.wowellworld.com/"
>RSVP</mj-button>
</mj-column>
</mj-section>
</mj-body>
</mjml>
123 changes: 123 additions & 0 deletions emails/rsvpConfirmation.mjml
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<mjml>
<mj-head>
<mj-title>Movie Reminder</mj-title>

<mj-attributes>
<mj-all font-family="Verdana, sans-serif" />

<mj-text font-size="16px" color="#111827" line-height="16px"/>
</mj-attributes>

<mj-html-attributes>
<mj-selector path=".list table table">
<mj-html-attribute name="role">list</mj-html-attribute>
</mj-selector>

<mj-selector path=".list table table > tbody">
<mj-html-attribute name="role">presentation</mj-html-attribute>
</mj-selector>
</mj-html-attributes>

<mj-style>
a {
color: #7c3aed;
}

a:hover {
color: #a56eff;
}

a:visited {
color: #5200a3;
}
</mj-style>
</mj-head>
<mj-body>
<mj-section full-width="full-width" background-color="#F9FAFB">
<mj-column width="100%">
<mj-text
padding="0px"
align="center"
font-size="12px"
>
<a href="https://movies.wowellworld.com/">
Wowell World Studios Presents: Thursday&nbsp;Night&nbsp;Movie&nbsp;Club
</a>
</mj-text>

<mj-text
align="center"
font-size="18px"
font-weight="bold"
>Thanks for RSVPing</mj-text>
</mj-column>
</mj-section>

<mj-section full-width="full-width" background-color="#e9d5ff">
<mj-column width="100%">
<mj-text
align="center"
font-weight="bold"
line-height="8px"
>See you Soon!</mj-text>

<mj-text
align="center"
font-size="12px"
line-height="8px"
>{{ date }}</mj-text>

<mj-text
align="center"
font-size="20px"
font-weight="bold"
line-height="8px"
>{{ theme }}</mj-text>
</mj-column>
</mj-section>

<mj-section full-width="full-width" background-color="#F9FAFB">
{{ #each movies as |movie| }}
<mj-column width="50%">
<mj-text
align="center"
font-size="16px"
font-weight="bold"
color="#111827"
padding="5px"
>{{ movie.title }}</mj-text>

<mj-image
src="{{ movie.posterUrl }}"
alt="{{ movie.title }} Poster"
align="center"
width="220px"
/>
</mj-column>
{{ /each }}
</mj-section>

<mj-section full-width="full-width" background-color="#e9d5ff">
<mj-column width="400px">
{{ #each movies as |movie| }}
<mj-text font-size="16px" padding="15px 25px">
<b>{{ movie.time }}</b> - <i>{{ movie.title }} ({{ movie.year }})</i>
</mj-text>
{{ /each }}
</mj-column>
</mj-section>

<mj-section full-width="full-width" background-color="#F9FAFB">
<mj-column width="100%">
<mj-text
padding="0px"
align="center"
font-size="12px"
>
<a href="https://movies.wowellworld.com">
Wowell World Studios Presents: Thursday&nbsp;Night&nbsp;Movie&nbsp;Club
</a>
</mj-text>
</mj-column>
</mj-body>
</mjml>
Loading

0 comments on commit a8402db

Please sign in to comment.