initial commit: rocket.new export of broadcastbeat
This commit is contained in:
119
supabase/functions/send-contributor-invite/index.ts
Normal file
119
supabase/functions/send-contributor-invite/index.ts
Normal file
@@ -0,0 +1,119 @@
|
||||
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, inviterName, role, token, message, siteUrl } = await req?.json();
|
||||
|
||||
const RESEND_API_KEY = Deno?.env?.get("RESEND_API_KEY");
|
||||
if (!RESEND_API_KEY) {
|
||||
throw new Error("RESEND_API_KEY is not set");
|
||||
}
|
||||
|
||||
const acceptUrl = `${siteUrl || "https://broadcastb5322.builtwithrocket.new"}/invite/accept?token=${token}`;
|
||||
|
||||
const roleLabel = role === "editor" ? "Editor" : role === "admin" ? "Administrator" : "Contributor";
|
||||
|
||||
const htmlBody = `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
</head>
|
||||
<body style="margin:0;padding:0;background:#0d1117;font-family:Arial,sans-serif;">
|
||||
<table width="100%" cellpadding="0" cellspacing="0" style="background:#0d1117;padding:40px 20px;">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<table width="600" cellpadding="0" cellspacing="0" style="background:#111827;border-radius:8px;overflow:hidden;border:1px solid #1f2937;">
|
||||
<tr>
|
||||
<td style="background:#1a2535;padding:24px 32px;border-bottom:1px solid #2a3a50;">
|
||||
<p style="margin:0;color:#3b82f6;font-size:13px;font-weight:700;letter-spacing:2px;text-transform:uppercase;">BroadcastBeat</p>
|
||||
<p style="margin:4px 0 0;color:#9ca3af;font-size:12px;">Digital Platform for Broadcast Engineering</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding:32px;">
|
||||
<h1 style="margin:0 0 16px;color:#f9fafb;font-size:22px;font-weight:700;">You've been invited to contribute</h1>
|
||||
<p style="margin:0 0 16px;color:#9ca3af;font-size:15px;line-height:1.6;">
|
||||
${inviterName || "A BroadcastBeat administrator"} has invited you to join BroadcastBeat as a <strong style="color:#3b82f6;">${roleLabel}</strong>.
|
||||
</p>
|
||||
${message ? `<div style="background:#1f2937;border-left:3px solid #3b82f6;padding:12px 16px;border-radius:4px;margin:0 0 24px;">
|
||||
<p style="margin:0;color:#d1d5db;font-size:14px;font-style:italic;">"${message}"</p>
|
||||
</div>` : ""}
|
||||
<p style="margin:0 0 24px;color:#9ca3af;font-size:14px;line-height:1.6;">
|
||||
As a ${roleLabel}, you'll be able to submit articles for publication on our platform. Click the button below to accept your invitation and set up your account.
|
||||
</p>
|
||||
<table cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<td style="background:#3b82f6;border-radius:6px;">
|
||||
<a href="${acceptUrl}" style="display:inline-block;padding:12px 28px;color:#ffffff;font-size:14px;font-weight:700;text-decoration:none;letter-spacing:0.5px;">Accept Invitation</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p style="margin:24px 0 0;color:#6b7280;font-size:12px;">
|
||||
This invitation expires in 7 days. If you did not expect this invitation, you can safely ignore this email.
|
||||
</p>
|
||||
<p style="margin:12px 0 0;color:#4b5563;font-size:11px;word-break:break-all;">
|
||||
Or copy this link: ${acceptUrl}
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="background:#0d1117;padding:16px 32px;border-top:1px solid #1f2937;">
|
||||
<p style="margin:0;color:#4b5563;font-size:11px;text-align:center;">© BroadcastBeat · Digital Platform for Broadcast Engineering</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>`;
|
||||
|
||||
const res = 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've been invited to contribute to BroadcastBeat`,
|
||||
html: htmlBody,
|
||||
}),
|
||||
});
|
||||
|
||||
const data = await res?.json();
|
||||
|
||||
if (!res?.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