使用 Resend 发送邮件

在 Cloudflare Workers 上配置 Better Auth 与联系邮件的 Resend 投递。

事务邮件通过 Resend 完整接入。邮箱验证、密码重置与联系消息共用 sendEmail() 和 React Email 模板。Newsletter 模板只是附带资源,没有接入用户 流程。

已包含的流程

流程调用位置模板收件人
邮箱验证src/lib/auth.tsverify-email.tsx新用户
密码重置src/lib/auth.tsforgot-password.tsx发起重置的用户
联系表单src/routes/api/contact.tscontact-message.tsxwebsiteConfig.mail.supportEmail
Newsletter未接通subscribe-newsletter.tsx

src/lib/email/index.ts 在首次调用 sendEmail() 时延迟创建 Resend client。这种 请求期初始化对 Workers 很重要:服务端 secret 不应在顶层模块求值时被捕获。 Resend SDK 通过其 HTTP API 投递,适合 Worker runtime。

email-layout.tsxemail-button.tsx 提供共用 React Email 外壳和按钮。当前 邮件主题与模板为英文;UI 国际化不会自动让邮件本地化。

subscribe-newsletter.tsx 只是可复用模板。项目没有订阅接口、订阅者表、确认 流程、偏好中心或退订流程。

配置

创建 Resend key

本地开发把服务端值加入 .env

RESEND_API_KEY=re_your_key

生产环境存为 Worker secret:

pnpm wrangler secret put RESEND_API_KEY

不要改成 VITE_*,也不要提交进 wrangler.jsonc

验证发送域名

添加 Resend 要求的 DNS 记录并等待验证;再按投递策略配置 SPF、DKIM 与 DMARC。

设置发件人与支持邮箱

修改 src/config/website-config.ts

mail: {
	provider: "resend",
	fromEmail: "Example <noreply@mail.example.com>",
	supportEmail: "support@example.com",
}

fromEmail 必须被已验证的 Resend 域名允许;supportEmail 接收联系表单消息。

本地行为与错误

没有有效 key 时,sendEmail() 会捕获 provider 错误并返回 { success: false, error },不会投递邮件。应用仍可用于本地 UI/数据库开发,但 验证和重置流程无法完成端到端测试。

当前认证 callback 会等待 sendEmail(),却不会检查其结构化结果;联系接口也 没有向客户端传播 provider 返回的失败,因此 Resend 拒绝邮件时,请求仍可能显示 成功。在关键流程依赖邮件前,应记录不含敏感数据的失败标识,并按产品策略选择 传播、重试或入队。

联系接口会用 Zod 校验姓名、邮箱、主题和消息长度,但它是公开接口。上线前增加 限流、垃圾/滥用防护与可观测性。

自定义模板

修改 src/lib/email/templates 下的文件,让共用布局适合全部事务邮件。品牌替换时 也要修改硬编码的 SoarStarter footer 与当前年份处理。

邮件本地化应由触发流程显式传入 locale,再选择对应主题和模板文案。延迟任务不应 从浏览器状态猜语言;需要可靠本地化时应保存用户所选语言。

验证

  • 注册用户并收到验证邮件,链接使用生产 origin 且可完成验证。
  • 发起密码重置并通过收到的链接完成流程。
  • 提交联系表单,配置的支持邮箱收到消息。
  • 非法联系 payload 校验失败,滥用流量被 spam 防护拒绝。
  • API key 缺失/无效时服务端有可见诊断,且不泄露正文或 secret。
  • 监控 Resend 控制台事件、退信与投诉。

生产注意事项

遵守 provider 的发件人和速率限制。关键邮件应增加重试/队列,在 callback 可能 重复时考虑幂等,并为持续投递失败告警。不要记录收件人或正文。认证 URL 应使用 部署 origin,Worker secret 通过 Wrangler 轮换。

相关页面

On this page