103 lines
4.1 KiB
TypeScript
Executable File
103 lines
4.1 KiB
TypeScript
Executable File
import { serve } from 'https://deno.land/std@0.168.0/http/server.ts';
|
|
|
|
const RESEND_API_KEY = Deno.env.get('RESEND_API_KEY');
|
|
const FROM = 'Fourge Branding <hello@fourgebranding.com>';
|
|
|
|
const corsHeaders = {
|
|
'Access-Control-Allow-Origin': '*',
|
|
'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
|
|
};
|
|
|
|
serve(async (req) => {
|
|
if (req.method === 'OPTIONS') {
|
|
return new Response('ok', { headers: corsHeaders });
|
|
}
|
|
|
|
try {
|
|
const { type, to, data } = await req.json();
|
|
|
|
let subject = '';
|
|
let html = '';
|
|
|
|
if (type === 'new_request') {
|
|
subject = `New Request: ${data.serviceType} — ${data.clientName}`;
|
|
html = `
|
|
<h2>New Request Received</h2>
|
|
<p><strong>From:</strong> ${data.clientName} (${data.clientEmail})</p>
|
|
<p><strong>Company:</strong> ${data.company || '—'}</p>
|
|
<p><strong>Service:</strong> ${data.serviceType}</p>
|
|
<p><strong>Project:</strong> ${data.projectName}</p>
|
|
${data.deadline ? `<p><strong>Deadline:</strong> ${data.deadline}</p>` : ''}
|
|
<hr />
|
|
<p><strong>Description:</strong></p>
|
|
<p>${data.description}</p>
|
|
<br />
|
|
<a href="https://portal.fourgebranding.com/tasks/${data.taskId}" style="background:#F5A523;color:#1a1a1a;padding:10px 20px;border-radius:6px;text-decoration:none;font-weight:600;">View Job</a>
|
|
`;
|
|
}
|
|
|
|
else if (type === 'sent_to_client') {
|
|
subject = `Your ${data.serviceType} is ready for review!`;
|
|
html = `
|
|
<h2>Hi ${data.clientFirstName},</h2>
|
|
<p>Your <strong>${data.serviceType}</strong> for <strong>${data.projectName}</strong> is ready for review.</p>
|
|
${data.message ? `<p>${data.message}</p>` : ''}
|
|
<p>Please log in to the portal to review and approve or request changes.</p>
|
|
<br />
|
|
<a href="https://portal.fourgebranding.com/my-requests/${data.taskId}" style="background:#F5A523;color:#1a1a1a;padding:10px 20px;border-radius:6px;text-decoration:none;font-weight:600;">Review Your Work</a>
|
|
<br /><br />
|
|
<p style="color:#666;font-size:13px;">— The Fourge Branding Team</p>
|
|
`;
|
|
}
|
|
|
|
else if (type === 'revision_submitted') {
|
|
subject = `Revision Request: ${data.serviceType} — ${data.clientName}`;
|
|
html = `
|
|
<h2>Revision Requested</h2>
|
|
<p><strong>From:</strong> ${data.clientName}</p>
|
|
<p><strong>Job:</strong> ${data.serviceType} — ${data.projectName}</p>
|
|
<p><strong>New Version:</strong> ${data.version}</p>
|
|
${data.deadline ? `<p><strong>New Deadline:</strong> ${data.deadline}</p>` : ''}
|
|
<hr />
|
|
<p><strong>Requested changes:</strong></p>
|
|
<p>${data.description}</p>
|
|
<br />
|
|
<a href="https://portal.fourgebranding.com/tasks/${data.taskId}" style="background:#F5A523;color:#1a1a1a;padding:10px 20px;border-radius:6px;text-decoration:none;font-weight:600;">View Job</a>
|
|
`;
|
|
}
|
|
|
|
else if (type === 'client_approved') {
|
|
subject = `Approved! ${data.serviceType} — ${data.clientName}`;
|
|
html = `
|
|
<h2>Job Approved ✓</h2>
|
|
<p><strong>${data.clientName}</strong> has approved <strong>${data.serviceType}</strong> for <strong>${data.projectName}</strong>.</p>
|
|
<p>This job is now complete.</p>
|
|
<br />
|
|
<a href="https://portal.fourgebranding.com/tasks/${data.taskId}" style="background:#F5A523;color:#1a1a1a;padding:10px 20px;border-radius:6px;text-decoration:none;font-weight:600;">View Job</a>
|
|
`;
|
|
}
|
|
|
|
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: FROM, to, subject, html }),
|
|
});
|
|
|
|
const result = await res.json();
|
|
|
|
return new Response(JSON.stringify(result), {
|
|
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
|
|
status: res.ok ? 200 : 400,
|
|
});
|
|
|
|
} catch (err) {
|
|
return new Response(JSON.stringify({ error: err.message }), {
|
|
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
|
|
status: 500,
|
|
});
|
|
}
|
|
});
|