Skip to content

Commit

Permalink
Integrate Loops.so for email marketing
Browse files Browse the repository at this point in the history
  • Loading branch information
zachlatta authored and JosiasAurel committed Apr 4, 2024
1 parent 79565ee commit 11013d9
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 4 deletions.
3 changes: 2 additions & 1 deletion .env.example
Expand Up @@ -5,4 +5,5 @@ PUBLIC_MAX_ITERATIONS=
PUBLIC_MAX_LOOP_TIME_MS=
GRAPHITE_HOST=
STUCK_AIRTABLE_BASE=
SENDGRID_API_KEY=
SENDGRID_API_KEY=
LOOPS_API_KEY=
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -29,6 +29,7 @@
"dotenv": "^16.3.1",
"firebase-admin": "^11.10.1",
"js-beautify": "^1.15.1",
"loops": "^1.0.1",
"ms": "^2.1.3",
"nanoid": "^4.0.1",
"node-statsd": "^0.1.1",
Expand Down
32 changes: 32 additions & 0 deletions src/lib/game-saving/email.ts
@@ -1,4 +1,5 @@
import _sendgrid from '@sendgrid/mail'
import { LoopsClient } from 'loops'
import type { Game, User } from './account'
import { lazy } from '../utils/lazy'

Expand All @@ -10,6 +11,10 @@ const sendgrid = lazy(() => {
return _sendgrid
})

const loops = lazy(() => {
return new LoopsClient(import.meta.env.LOOPS_API_KEY)
})

interface EmailSpec {
subject: string
html: string
Expand All @@ -25,6 +30,33 @@ export const mail = async (to: string, spec: EmailSpec): Promise<void> => {
})
}

const findOrCreateEmailListContact = async (email: string): Promise<Object | undefined> => {
const foundContacts = await loops.findContact(email)

if (foundContacts.length == 0) { // if the contact isn't already in the DB
return await loops.createContact(email, {
source: 'Sprig editor',
userGroup: 'Hack Clubber'
})
} else {
return foundContacts[0]
}
}

export const addToEmailList = async (email: string, userId: string): Promise<void> => {
await findOrCreateEmailListContact(email)
await loops.updateContact(email, {
sprigEditorUserId: userId
})
}

export const updateEmailListLastModifiedTime = async (email: string, lastModified: Date): Promise<void> => {
await findOrCreateEmailListContact(email)
await loops.updateContact(email, {
sprigEditorGameLastModifiedAt: lastModified.getTime()
})
}

export const loginCodeTemplate = (code: string): EmailSpec => ({
subject: `Sprig Login Code: ${code}`,
html: `
Expand Down
5 changes: 3 additions & 2 deletions src/pages/api/auth/email-login-code.ts
@@ -1,6 +1,6 @@
import type { APIRoute } from 'astro'
import { getUserByEmail, makeLoginCode, makeUser } from '../../../lib/game-saving/account'
import { isValidEmail, loginCodeTemplate, mail } from '../../../lib/game-saving/email'
import { isValidEmail, loginCodeTemplate, mail, addToEmailList } from '../../../lib/game-saving/email'

export const post: APIRoute = async ({ request }) => {
let email: string
Expand All @@ -14,6 +14,7 @@ export const post: APIRoute = async ({ request }) => {

const user = await getUserByEmail(email) ?? await makeUser(email, null)
const code = await makeLoginCode(user.id)
await mail(user.email, loginCodeTemplate(code))
await mail(user.email, loginCodeTemplate(code))
await addToEmailList(user.email, user.id)
return new Response(JSON.stringify({}), { status: 200 })
}
5 changes: 4 additions & 1 deletion src/pages/api/games/save.ts
@@ -1,6 +1,7 @@
import type { APIRoute } from 'astro'
import { Timestamp } from 'firebase-admin/firestore'
import { getGame, getSession, setDocument, updateDocument } from '../../../lib/game-saving/account'
import { updateEmailListLastModifiedTime } from '../../../lib/game-saving/email'

export const post: APIRoute = async ({ request, cookies }) => {
let code: string
Expand Down Expand Up @@ -30,10 +31,12 @@ export const post: APIRoute = async ({ request, cookies }) => {
if (session.user.id !== game.ownerId) return new Response(`Can't edit a game you don't own`, { status: 403 })
trackingId = session.user.id
trackingType = 'user'

await updateEmailListLastModifiedTime(session.user.email, new Date())
}

await updateDocument('games', gameId, {
code,
code,
modifiedAt: Timestamp.now(),
tutorialName: tutorialName ?? null
});
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Expand Up @@ -3469,6 +3469,11 @@ longest-streak@^3.0.0:
resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-3.1.0.tgz#62fa67cd958742a1574af9f39866364102d90cd4"
integrity sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==

loops@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/loops/-/loops-1.0.1.tgz#bb652a85afc60b7fb90ba788c9cb04c13d50b5c2"
integrity sha512-Nd8vRvYj+BFVLHSQmODsLQ+GFHsS/rcFlwAWdmwtuANMd1aqBpiCFq1snlryXWlgtPilLsjZyz1THaU4b2vtwg==

lower-case@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28"
Expand Down

0 comments on commit 11013d9

Please sign in to comment.