Skip to content

Commit 28d6641

Browse files
Add support for email sending through Lettermint
1 parent ff2ace2 commit 28d6641

File tree

4 files changed

+61
-11
lines changed

4 files changed

+61
-11
lines changed

.env.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
WEBSITE_URL=http://localhost:5180
22
DATABASE_URL="postgresql://postgres:@localhost:5432/certs-email?schema=public"
3+
EMAIL_PROVIDER=lettermint
4+
LETTERMINT_API_TOKEN=
35
MAILTRAP_API_KEY=

package-lock.json

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
"handlebars": "^4.7.8",
5151
"ipaddr.js": "^2.2.0",
5252
"juice": "^11.1.0",
53+
"lettermint": "^1.5.0",
5354
"mailtrap": "^4.4.0",
5455
"mode-watcher": "^1.1.0",
5556
"pg": "^8.16.3",

src/lib/server/email.ts

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,73 @@
11
import { env } from '$env/dynamic/private';
22
import { MailtrapClient } from 'mailtrap';
3+
import { Lettermint } from 'lettermint';
34
import { building, dev } from '$app/environment';
45
import type { EmailOutbox } from '$prisma/generated/client';
56

6-
if (!building && !env.MAILTRAP_API_KEY) throw new Error('MAILTRAP_API_KEY is not set');
7+
const provider = env.EMAIL_PROVIDER || 'lettermint';
78

8-
const mailtrap = new MailtrapClient({
9-
token: env.MAILTRAP_API_KEY!
10-
});
9+
if (!building) {
10+
if (provider === 'mailtrap' && !env.MAILTRAP_API_KEY) {
11+
throw new Error('MAILTRAP_API_KEY is not set');
12+
}
13+
if (provider === 'lettermint' && !env.LETTERMINT_API_TOKEN) {
14+
throw new Error('LETTERMINT_API_TOKEN is not set');
15+
}
16+
}
17+
18+
let mailtrap: MailtrapClient | undefined;
19+
let lettermint: Lettermint | undefined;
1120

12-
const defaultFrom = { name: 'certs.email', email: 'support@certs.email' };
21+
function getMailtrap() {
22+
if (!mailtrap) mailtrap = new MailtrapClient({ token: env.MAILTRAP_API_KEY! });
23+
return mailtrap;
24+
}
25+
26+
function getLettermint() {
27+
if (!lettermint) lettermint = new Lettermint({ apiToken: env.LETTERMINT_API_TOKEN! });
28+
return lettermint;
29+
}
30+
31+
const defaultFrom = { name: 'certs.email', email: dev ? 'support@dev.certs.email' : 'support@certs.email' };
1332

1433
export const EmailOutboxPriorities = {
1534
High: 0,
1635
Medium: 5,
1736
Low: 10
1837
} as const;
1938

39+
async function sendEmail(options: { to: string[]; subject: string; html: string; tag?: string }) {
40+
if (provider === 'mailtrap') {
41+
await getMailtrap().send({
42+
from: defaultFrom,
43+
to: options.to.map((email) => ({ email })),
44+
subject: options.subject,
45+
html: options.html,
46+
category: options.tag
47+
});
48+
} else {
49+
const email = getLettermint()
50+
.email.from(`${defaultFrom.name} <${defaultFrom.email}>`)
51+
.to(...options.to)
52+
.subject(options.subject)
53+
.html(options.html);
54+
55+
if (options.tag) email.tag(options.tag);
56+
57+
await email.send();
58+
}
59+
}
60+
2061
export async function sendQueuedEmail(job: EmailOutbox) {
21-
let category = undefined;
62+
let tag = undefined;
2263
if (job.templateName) {
23-
category = dev ? `DEV-CERTS-${job.templateName}` : `PROD-CERTS-${job.templateName}`;
64+
tag = dev ? `DEV-CERTS-${job.templateName}` : `PROD-CERTS-${job.templateName}`;
2465
}
2566

26-
await mailtrap.send({
27-
from: defaultFrom,
28-
to: job.recipients.map((email) => ({ email })),
67+
await sendEmail({
68+
to: job.recipients,
2969
subject: job.subject,
3070
html: job.body,
31-
category
71+
tag
3272
});
3373
}

0 commit comments

Comments
 (0)