简介
在 Cloudflare Workers 中发送电子邮件一直是一个挑战。传统的方法通常依赖于 HTTP 邮件 API(如 Resend、SendGrid、MailChannels),但这些服务可能有使用限制或需要额外付费。
现在,有了 worker-mailer,我们可以直接在 Cloudflare Workers 中使用 SMTP 通过 SSL/TLS 发送邮件,而不需要依赖任何第三方 HTTP API。它利用了 Cloudflare 的 TCP Sockets API,实现了真正的端到端加密邮件发送。
为什么选择 Worker Mailer
与传统方法的对比
| 方法 |
优势 |
劣势 |
| HTTP API (Resend/SendGrid) |
设置简单,文档完善 |
需要付费,有发送限制 |
| MailChannels |
免费,无需配置 |
DNS 配置复杂,限制较多 |
| Cloudflare Email Service |
原生集成 |
需要 Pro 计划,发送受限 |
| Worker Mailer |
完全免费,无限制,SSL 加密 |
需要配置 SMTP 服务器 |
Worker Mailer 的特点
- 🚀 零依赖:完全基于 Cloudflare Workers 运行时
- 🔒 SSL/TLS 加密:支持隐式 TLS(端口 465)和 STARTTLS(端口 587)
- 📧 支持富文本邮件:HTML 和纯文本邮件,支持附件
- ✅ 多种认证方式:支持
plain、login 和 CRAM-MD5
- 📝 完整的 TypeScript 支持:类型安全的 API
安装与配置
步骤 1:创建 Worker 项目
1 2
| npm create cloudflare@latest -- worker-mailer-demo cd worker-mailer-demo
|
步骤 2:安装 Worker Mailer
1
| npm install @ribassu/worker-mailer
|
步骤 3:配置 wrangler.toml
需要启用 nodejs_compat 兼容性标志:
1 2 3 4 5 6 7 8 9
| name = "worker-mailer-demo" main = "src/index.ts" compatibility_date = "2025-07-09" compatibility_flags = ["nodejs_compat"]
[vars] SMTP_HOST = "smtp.example.com" SMTP_PORT = "465" SMTP_USERNAME = "[email protected]"
|
步骤 4:设置密码为 Secret
1
| wrangler secret put SMTP_PASSWORD
|
基本使用示例
发送纯文本邮件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| import { WorkerMailer } from '@ribassu/worker-mailer'
interface Env { SMTP_HOST: string SMTP_PORT: string SMTP_USERNAME: string SMTP_PASSWORD: string }
export default { async fetch(request: Request, env: Env): Promise<Response> { const mailer = await WorkerMailer.connect({ credentials: { username: env.SMTP_USERNAME, password: env.SMTP_PASSWORD, }, authType: 'plain', host: env.SMTP_HOST, port: parseInt(env.SMTP_PORT), secure: true, })
await mailer.send({ from: { name: 'WTSolutions', email: env.SMTP_USERNAME }, to: { name: 'Recipient', email: '[email protected]' }, subject: 'Hello from Worker Mailer', text: '这是一封通过 Cloudflare Workers 发送的邮件!', })
return new Response('邮件发送成功!') }, } satisfies ExportedHandler<Env>
|
发送 HTML 邮件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| await mailer.send({ from: { name: 'WTSolutions', email: env.SMTP_USERNAME }, to: { name: 'Recipient', email: '[email protected]' }, subject: '欢迎使用我们的服务', text: '欢迎使用我们的服务!请点击下方链接开始。', html: ` <div style="font-family: sans-serif; padding: 20px;"> <h1>欢迎!</h1> <p>感谢您注册我们的服务。</p> <a href="https://wtsolutions.cn" style="display: inline-block; padding: 10px 20px; background-color: #007bff; color: white; text-decoration: none; border-radius: 4px;"> 立即开始 </a> </div> `, })
|
发送带附件的邮件
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const attachment = { filename: 'document.pdf', content: pdfBuffer, contentType: 'application/pdf', }
await mailer.send({ from: { name: 'WTSolutions', email: env.SMTP_USERNAME }, to: { name: 'Recipient', email: '[email protected]' }, subject: '您的文档', text: '请查收附件中的文档。', html: '<p>请查收附件中的文档。</p>', attachments: [attachment], })
|
支持的 SMTP 服务提供商配置
Gmail / Google Workspace
1 2
| SMTP_HOST = "smtp.gmail.com" SMTP_PORT = "465"
|
注意:需要使用 App Password,而不是账户密码。
Outlook / Office 365
1 2
| SMTP_HOST = "smtp.office365.com" SMTP_PORT = "587"
|
163 邮箱
1 2
| SMTP_HOST = "smtp.163.com" SMTP_PORT = "465"
|
QQ 邮箱
1 2
| SMTP_HOST = "smtp.qq.com" SMTP_PORT = "465"
|
Cloudflare Email Service (SMTP)
Cloudflare 最近发布了 SMTP 提交支持:
1 2
| SMTP_HOST = "smtp.mx.cloudflare.net" SMTP_PORT = "465"
|
使用 Cloudflare API Token 作为密码。
高级配置选项
STARTTLS 模式
对于端口 587,使用 STARTTLS:
1 2 3 4 5 6 7 8 9 10 11
| const mailer = await WorkerMailer.connect({ credentials: { username: env.SMTP_USERNAME, password: env.SMTP_PASSWORD, }, authType: 'login', host: env.SMTP_HOST, port: 587, secure: false, startTls: true, })
|
生命周期钩子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const mailer = await WorkerMailer.connect({ credentials: { username: env.SMTP_USERNAME, password: env.SMTP_PASSWORD, }, host: env.SMTP_HOST, port: 465, secure: true, hooks: { onConnect: () => console.log('Connected to SMTP server'), onAuthenticate: () => console.log('Authenticated successfully'), onSend: (message) => console.log(`Sent email to ${message.to.email}`), onError: (error) => console.error('Error:', error), }, })
|
超时配置
1 2 3 4 5 6 7 8 9 10 11
| const mailer = await WorkerMailer.connect({ credentials: { username: env.SMTP_USERNAME, password: env.SMTP_PASSWORD, }, host: env.SMTP_HOST, port: 465, secure: true, socketTimeoutMs: 30000, responseTimeoutMs: 10000, })
|
Cloudflare Workers 限制说明
端口限制
Cloudflare Workers 不允许使用端口 25(SMTP 默认端口),这是为了防止垃圾邮件。必须使用:
- ✅ 端口 465:隐式 TLS(推荐)
- ✅ 端口 587:STARTTLS
TCP Sockets 权限
确保你的 Worker 具有 connect() 权限。在 wrangler.toml 中配置:
1
| compatibility_date = "2025-07-09"
|
完整示例:联系表单处理
以下是一个完整的示例,处理来自前端的联系表单请求并发送邮件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| import { WorkerMailer } from '@ribassu/worker-mailer'
interface Env { SMTP_HOST: string SMTP_PORT: string SMTP_USERNAME: string SMTP_PASSWORD: string }
interface ContactForm { name: string email: string subject: string message: string }
export default { async fetch(request: Request, env: Env): Promise<Response> { if (request.method !== 'POST') { return new Response('Method not allowed', { status: 405 }) }
try { const form: ContactForm = await request.json()
const mailer = await WorkerMailer.connect({ credentials: { username: env.SMTP_USERNAME, password: env.SMTP_PASSWORD, }, authType: 'plain', host: env.SMTP_HOST, port: parseInt(env.SMTP_PORT), secure: true, })
await mailer.send({ from: { name: form.name, email: form.email }, to: { name: 'Admin', email: env.SMTP_USERNAME }, replyTo: { email: form.email }, subject: `Contact Form: ${form.subject}`, text: ` Name: ${form.name} Email: ${form.email} Subject: ${form.subject} Message: ${form.message} `, html: ` <h2>新的联系表单提交</h2> <p><strong>姓名:</strong> ${form.name}</p> <p><strong>邮箱:</strong> ${form.email}</p> <p><strong>主题:</strong> ${form.subject}</p> <p><strong>消息:</strong></p> <p>${form.message}</p> `, })
return Response.json({ success: true, message: '邮件发送成功' }) } catch (error) { console.error('发送邮件失败:', error) return Response.json( { success: false, message: '发送邮件失败' }, { status: 500 } ) } }, } satisfies ExportedHandler<Env>
|
部署
测试
使用 curl 测试:
1 2 3 4 5 6 7 8
| curl -X POST https://worker-mailer-demo.your-subdomain.workers.dev \ -H "Content-Type: application/json" \ -d '{ "name": "John Doe", "email": "[email protected]", "subject": "Test Email", "message": "This is a test email sent via Worker Mailer." }'
|
总结
@ribassu/worker-mailer 为 Cloudflare Workers 提供了一种全新的邮件发送方式:
- 不依赖 HTTP API:直接通过 TCP Sockets 连接 SMTP 服务器
- 完全免费:没有发送限制,只受 Cloudflare Workers 免费额度限制
- SSL/TLS 加密:确保邮件传输安全
- 灵活配置:支持多种 SMTP 服务提供商和认证方式
如果你正在寻找一种在 Cloudflare Workers 中发送邮件的可靠方案,Worker Mailer 是一个非常好的选择。