export interface EmailOptions { to: string; subject: string; html?: string; text?: string; } export interface SendResult { success: boolean; id?: string; error?: string; } export interface Env { RESEND_API_KEY: string; FROM_EMAIL?: string; } /** * Send an email via Resend API and log the result to D1. */ export async function sendEmail( env: Env, db: D1Database, opts: EmailOptions, ): Promise { const from = env.FROM_EMAIL || "onboarding@resend.dev"; const id = crypto.randomUUID(); try { const response = await fetch("https://api.resend.com/emails", { method: "POST", headers: { Authorization: `Bearer ${env.RESEND_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ from, to: opts.to, subject: opts.subject, html: opts.html, text: opts.text, }), }); if (!response.ok) { const errorBody = await response.text(); let errorMessage: string; try { const parsed = JSON.parse(errorBody); errorMessage = parsed.message || parsed.error || errorBody; } catch { errorMessage = errorBody; } await db .prepare( "INSERT INTO email_log (id, to_address, from_address, subject, status, error, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)", ) .bind(id, opts.to, from, opts.subject, "failed", errorMessage, Math.floor(Date.now() / 1000)) .run(); return { success: false, error: errorMessage }; } const data = (await response.json()) as { id: string }; await db .prepare( "INSERT INTO email_log (id, to_address, from_address, subject, status, resend_id, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)", ) .bind(id, opts.to, from, opts.subject, "sent", data.id, Math.floor(Date.now() / 1000)) .run(); return { success: true, id: data.id }; } catch (err) { const errorMessage = err instanceof Error ? err.message : "Unknown error"; await db .prepare( "INSERT INTO email_log (id, to_address, from_address, subject, status, error, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)", ) .bind(id, opts.to, from, opts.subject, "failed", errorMessage, Math.floor(Date.now() / 1000)) .run(); return { success: false, error: errorMessage }; } } /** * Welcome email template. */ export function welcomeEmail(to: string, name: string): EmailOptions { return { to, subject: `Welcome, ${name}!`, html: `

Welcome, ${name}!

Thanks for signing up. We're glad to have you on board.

If you have any questions, just reply to this email.

`, }; } /** * Notification email template. */ export function notificationEmail( to: string, title: string, body: string, ): EmailOptions { return { to, subject: title, html: `

${title}

${body}

`, }; }