import { resolve } from "node:path"; import { Resend } from "resend"; import { config } from "./config.ts"; import { renderNewsletter } from "./render.tsx"; // ───────────────────────────────────────────────────────────────────────────── // TEST SENDS ONLY. The recipient is the single RESEND_TEST_TO address — there is // no CLI flag or code path that can send to any other address. This script // exists so you can preview a newsletter in a real inbox (yours) before the // actual campaign, which is sent manually from Resend's web editor. // ───────────────────────────────────────────────────────────────────────────── const LOCKED_TO = process.env.RESEND_TEST_TO; // Sandbox sender: Resend only delivers onboarding@resend.dev mail to the email // on your own Resend account, so this is doubly locked. Override the display // name only via RESEND_FROM if you later verify your own domain. const FROM = process.env.RESEND_FROM ?? `${config.brandName} (test) `; function usage(): never { console.error( "Usage: bun run send-test [subject] [--dry] [--upload-assets]\n" + " Sends a TEST email of to the RESEND_TEST_TO address only.\n" + " --dry render + report without contacting Resend.\n" + " --upload-assets upload local images to R2 and rewrite their URLs.\n" + " Requires RESEND_API_KEY and RESEND_TEST_TO (e.g. in a .env file).", ); process.exit(1); } async function main() { const args = process.argv.slice(2); const dry = args.includes("--dry"); const positional = args.filter((a) => !a.startsWith("--")); const [inputArg, subjectArg] = positional; if (!inputArg) usage(); if (!LOCKED_TO) { console.error( "RESEND_TEST_TO is not set. Set it to the recipient of test sends (e.g. in a .env file).", ); process.exit(1); } const { html, subject: defaultSubject, issue, title } = await renderNewsletter( resolve(inputArg), { upload: args.includes("--upload-assets") }, ); const subject = subjectArg ?? defaultSubject; console.log(`Newsletter ${issue}: ${title}`); console.log(` from: ${FROM}`); console.log(` to: ${LOCKED_TO}`); console.log(` subject: ${subject}`); console.log(` html: ${html.length} bytes`); if (dry) { console.log("\n--dry: not sending."); return; } const apiKey = process.env.RESEND_API_KEY; if (!apiKey) { console.error( "\nRESEND_API_KEY is not set. Add it to a .env file (bun loads it automatically).", ); process.exit(1); } const resend = new Resend(apiKey); const { data, error } = await resend.emails.send({ from: FROM, to: [LOCKED_TO], subject, html, }); if (error) { console.error("\nResend error:", error); process.exit(1); } console.log(`\nSent test email to ${LOCKED_TO} (id: ${data?.id})`); } await main();