initial commit: rocket.new export of broadcastbeat
This commit is contained in:
124
supabase/functions/send-newsletter-confirmation/index.ts
Normal file
124
supabase/functions/send-newsletter-confirmation/index.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
import { serve } from "https://deno.land/std@0.192.0/http/server.ts";
|
||||
|
||||
serve(async (req) => {
|
||||
// ✅ CORS preflight
|
||||
if (req.method === "OPTIONS") {
|
||||
return new Response("ok", {
|
||||
headers: {
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"Access-Control-Allow-Methods": "POST, OPTIONS",
|
||||
"Access-Control-Allow-Headers": "*",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const { email, topics } = await req.json();
|
||||
|
||||
if (!email) {
|
||||
return new Response(JSON.stringify({ error: "Email is required" }), {
|
||||
status: 400,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const RESEND_API_KEY = Deno.env.get("RESEND_API_KEY");
|
||||
if (!RESEND_API_KEY) {
|
||||
throw new Error("RESEND_API_KEY is not set");
|
||||
}
|
||||
|
||||
const topicsList = topics && topics.length > 0
|
||||
? `<ul style="margin:12px 0;padding-left:20px;color:#cccccc;">${topics.map((t: string) => `<li style="margin:4px 0;">${t}</li>`).join("")}</ul>`
|
||||
: "<p style='color:#888;'>All topics</p>";
|
||||
|
||||
const htmlBody = `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Welcome to BroadcastBeat</title>
|
||||
</head>
|
||||
<body style="margin:0;padding:0;background-color:#111111;font-family:Arial,Helvetica,sans-serif;">
|
||||
<table width="100%" cellpadding="0" cellspacing="0" style="background-color:#111111;padding:40px 20px;">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<table width="600" cellpadding="0" cellspacing="0" style="background-color:#1a1a1a;border:1px solid #2a2a2a;border-radius:4px;overflow:hidden;max-width:600px;width:100%;">
|
||||
<!-- Header -->
|
||||
<tr>
|
||||
<td style="background-color:#1a2535;padding:24px 32px;border-bottom:1px solid #2a3a50;">
|
||||
<p style="margin:0;font-family:Georgia,serif;font-size:22px;font-weight:bold;color:#e8e8e8;letter-spacing:0.02em;">BroadcastBeat</p>
|
||||
<p style="margin:4px 0 0;font-size:11px;color:#888;letter-spacing:0.06em;text-transform:uppercase;">Digital Platform for Broadcast Engineering</p>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Body -->
|
||||
<tr>
|
||||
<td style="padding:32px;">
|
||||
<p style="margin:0 0 8px;font-size:13px;font-weight:700;letter-spacing:0.08em;text-transform:uppercase;color:#3b82f6;border-left:3px solid #3b82f6;padding-left:8px;">Newsletter Confirmed</p>
|
||||
<h1 style="margin:16px 0 12px;font-family:Georgia,serif;font-size:24px;color:#e8e8e8;line-height:1.3;">You're subscribed!</h1>
|
||||
<p style="margin:0 0 20px;font-size:14px;color:#aaaaaa;line-height:1.6;">
|
||||
Thanks for subscribing to BroadcastBeat. You'll receive the latest broadcast industry news, product launches, and insights delivered straight to your inbox.
|
||||
</p>
|
||||
<p style="margin:0 0 8px;font-size:12px;font-weight:700;letter-spacing:0.06em;text-transform:uppercase;color:#888;">Your selected topics:</p>
|
||||
${topicsList}
|
||||
<div style="margin:28px 0;border-top:1px solid #2a2a2a;"></div>
|
||||
<a href="https://broadcastb5322.builtwithrocket.new/home-page" style="display:inline-block;background-color:#cc0000;color:#ffffff;font-size:13px;font-weight:700;letter-spacing:0.04em;text-transform:uppercase;text-decoration:none;padding:10px 24px;border-radius:2px;">
|
||||
Read Latest News →
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Footer -->
|
||||
<tr>
|
||||
<td style="background-color:#0d0d0d;padding:20px 32px;border-top:1px solid #2a2a2a;">
|
||||
<p style="margin:0;font-size:11px;color:#555;line-height:1.6;">
|
||||
You're receiving this because you subscribed at BroadcastBeat.
|
||||
No spam — unsubscribe anytime by replying to this email.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>`;
|
||||
|
||||
const response = await fetch("https://api.resend.com/emails", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Authorization": `Bearer ${RESEND_API_KEY}`,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
from: "onboarding@resend.dev",
|
||||
to: [email],
|
||||
subject: "You're subscribed to BroadcastBeat!",
|
||||
html: htmlBody,
|
||||
}),
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(data.message || "Failed to send email");
|
||||
}
|
||||
|
||||
return new Response(JSON.stringify({ success: true, id: data.id }), {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
return new Response(JSON.stringify({ error: error.message }), {
|
||||
status: 500,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user