Migrate Val Town email
Send and receive email through a provider such as Resend.
An email provider sends and receives the mail, and Easel runs your code. The
examples use Resend. @valtown.email addresses don't
move, so tell anyone who sends to them about the new address.
Send email
Verify a domain with Resend, install resend, and add RESEND_API_KEY and
MAIL_FROM to the project's environment variables. Then replace std/email:
Pass an idempotency key that stays the same if the code sends the message
again, such as digest-${date}, so a retry doesn't deliver it twice.
Receive email
Resend sends a webhook for each received email. Add a receiving address in
Resend, add its signing secret as RESEND_WEBHOOK_SECRET, and add this
handler, which verifies the webhook, checks the sender, and calls the val's
email handler:
lib/email-webhook.ts
Route a URL to it, then point Resend's email.received webhook at that URL on
your production domain. Without Hono, export POST = handleEmailWebhook from
api/incoming-email.ts instead.
Resend retries webhooks, so the same email can arrive twice. Have the handler record each email's ID in the same database transaction as its other writes, and use the ID as the idempotency key for replies:
lib/handle-email.ts
Verify
Send an email to the new address from a trusted sender and check that the handler ran once. Then resend the same webhook event from Resend and check that nothing happens twice.
Back to the feature list.