Skip to content

Commit 11b8f5a

Browse files
zenorochavcapretz
andauthored
feat(web): Add react.email/api (#1186)
Co-authored-by: Vitor Capretz <[email protected]>
1 parent f0d91eb commit 11b8f5a

File tree

4 files changed

+232
-3
lines changed

4 files changed

+232
-3
lines changed

apps/web/.eslintrc.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
module.exports = {
2-
extends: ['custom/next'],
2+
extends: ["custom/next"],
3+
rules: {
4+
"eslint-comments/require-description": "off",
5+
},
36
};

apps/web/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,15 @@
1111
"dependencies": {
1212
"@radix-ui/colors": "1.0.1",
1313
"@radix-ui/react-slot": "1.0.2",
14+
"@sindresorhus/is": "6.1.0",
15+
"@supabase/supabase-js": "2.39.3",
1416
"@vercel/analytics": "1.0.1",
1517
"classnames": "2.3.2",
1618
"next": "13.5.3",
1719
"prism-react-renderer": "2.1.0",
1820
"react": "18.2.0",
19-
"react-dom": "18.2.0"
21+
"react-dom": "18.2.0",
22+
"resend": "2.0.0"
2023
},
2124
"devDependencies": {
2225
"@next/eslint-plugin-next": "13.5.3",

apps/web/src/pages/api/send/test.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/* eslint-disable turbo/no-undeclared-env-vars */
2+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
3+
/* eslint-disable @typescript-eslint/no-confusing-void-expression */
4+
import { Resend } from "resend";
5+
import { createClient } from "@supabase/supabase-js";
6+
import type { NextApiRequest, NextApiResponse } from "next";
7+
import is from "@sindresorhus/is";
8+
9+
const resend = new Resend(process.env.RESEND_API_KEY);
10+
const supabaseUrl = process.env.SUPABASE_URL || "";
11+
const supabaseKey = process.env.SUPABASE_ANON_KEY || "";
12+
const supabase = createClient(supabaseUrl, supabaseKey);
13+
14+
export default async function sendTest(
15+
req: NextApiRequest,
16+
res: NextApiResponse,
17+
) {
18+
if (req.method === "OPTIONS") {
19+
return res.status(200).json({});
20+
}
21+
22+
if (req.method === "POST") {
23+
try {
24+
const { to, subject, html } = req.body;
25+
26+
const ip = req.headers["x-vercel-forwarded-for"];
27+
const latitude = req.headers["x-vercel-ip-latitude"];
28+
const longitude = req.headers["x-vercel-ip-longitude"];
29+
const city = req.headers["x-vercel-ip-city"];
30+
const country = req.headers["x-vercel-ip-country"];
31+
const countryRegion = req.headers["x-vercel-ip-country-region"];
32+
33+
const savePromise = supabase
34+
.from(process.env.SUPABASE_TABLE_NAME || "")
35+
.insert([
36+
{
37+
to: [to],
38+
subject,
39+
html,
40+
ip,
41+
latitude,
42+
longitude,
43+
city,
44+
country,
45+
country_region: countryRegion,
46+
},
47+
]);
48+
49+
const sendPromise = resend.emails.send({
50+
from: "React Email <[email protected]>",
51+
to: [to],
52+
subject,
53+
html,
54+
});
55+
56+
await Promise.all([savePromise, sendPromise]);
57+
58+
res.status(200).json({ message: "Test email sent" });
59+
} catch (error) {
60+
if (is.error(error)) {
61+
return res.status(500).json({ error: error.message });
62+
}
63+
}
64+
}
65+
}

pnpm-lock.yaml

Lines changed: 159 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)