SMTP 邮件服务使用指南
[我严格遵守规则]
SMTP 邮件服务使用指南
主流邮件服务对比
| 服务 | 免费额度 | 特点 | 推荐场景 |
|---|---|---|---|
| Resend | 100封/天 | 最简单,现代 API,开发体验最佳 | 个人/创业项目首选 |
| Nodemailer + 163/QQ | 免费 | 国内直接用,无需注册第三方 | 国内项目最方便 |
| SendGrid | 100封/天 | 老牌,功能全 | 企业级 |
| AWS SES | 62000封/月(EC2) | 最便宜,大规模 | 高量级生产环境 |
| Mailgun | 100封/天 | API 友好 | 中等规模 |
方案一:Resend(最推荐,最简单)
1. 注册获取 API Key
- 访问 resend.com → 注册 → Dashboard → API Keys → 创建
2. 安装
pnpm add resend
3. 在项目中使用
// src/server/email.service.ts
import { Resend } from "resend";
const resend = new Resend(process.env.RESEND_API_KEY);
export async function sendVerificationEmail(email: string, token: string) {
const link = `${process.env.NEXT_PUBLIC_APP_URL}/verify?token=${token}`;
await resend.emails.send({
from: "AgentsChattingRoom <noreply@yourdomain.com>", // 需要验证域名
to: email,
subject: "请验证你的邮箱",
html: `
<h2>欢迎注册 AgentsChattingRoom</h2>
<p>点击下方链接验证你的邮箱:</p>
<a href="${link}">${link}</a>
<p>链接 24 小时内有效。</p>
`,
});
}
export async function sendPasswordResetEmail(email: string, token: string) {
const link = `${process.env.NEXT_PUBLIC_APP_URL}/reset?token=${token}`;
await resend.emails.send({
from: "AgentsChattingRoom <noreply@yourdomain.com>",
to: email,
subject: "重置密码",
html: `
<h2>密码重置</h2>
<p>点击下方链接重置密码:</p>
<a href="${link}">${link}</a>
<p>链接 24 小时内有效。如非本人操作,请忽略。</p>
`,
});
}
4. 环境变量
RESEND_API_KEY=re_xxxxxxxxxxxx
注意:Resend 免费版只能发到自己邮箱,要发给任意用户需要验证你的域名(在 DNS 添加几条记录)。
方案二:Nodemailer + QQ/163 邮箱(国内零成本)
不需要注册任何第三方服务,用已有邮箱直接发。
1. 安装
pnpm add nodemailer
pnpm add -D @types/nodemailer
2. 获取授权码
- QQ 邮箱:设置 → 账户 → POP3/SMTP 服务 → 开启 → 获取授权码
- 163 邮箱:设置 → POP3/SMTP → 开启 → 设置授权码
3. 在项目中使用
// src/server/email.service.ts
import nodemailer from "nodemailer";
const transporter = nodemailer.createTransport({
host: process.env.SMTP_HOST, // "smtp.qq.com" 或 "smtp.163.com"
port: 465,
secure: true, // 使用 SSL
auth: {
user: process.env.SMTP_USER, // "your@qq.com"
pass: process.env.SMTP_PASS, // 授权码(不是邮箱密码)
},
});
export async function sendVerificationEmail(email: string, token: string) {
const link = `${process.env.NEXT_PUBLIC_APP_URL}/verify?token=${token}`;
await transporter.sendMail({
from: `"AgentsChattingRoom" <${process.env.SMTP_USER}>`,
to: email,
subject: "请验证你的邮箱",
html: `
<h2>欢迎注册</h2>
<p>点击链接验证邮箱:<a href="${link}">${link}</a></p>
<p>24 小时内有效。</p>
`,
});
}
export async function sendPasswordResetEmail(email: string, token: string) {
const link = `${process.env.NEXT_PUBLIC_APP_URL}/reset?token=${token}`;
await transporter.sendMail({
from: `"AgentsChattingRoom" <${process.env.SMTP_USER}>`,
to: email,
subject: "重置密码",
html: `
<h2>密码重置</h2>
<p>点击链接重置密码:<a href="${link}">${link}</a></p>
<p>24 小时内有效。</p>
`,
});
}
4. 环境变量
# QQ 邮箱
SMTP_HOST=smtp.qq.com
SMTP_USER=your@qq.com
SMTP_PASS=xxxxxxxxxxxxxxxx # QQ 邮箱授权码
# 或 163 邮箱
SMTP_HOST=smtp.163.com
SMTP_USER=your@163.com
SMTP_PASS=xxxxxxxxxxxxxxxx # 163 授权码
方案三:SendGrid(企业级)
pnpm add @sendgrid/mail
import sgMail from "@sendgrid/mail";
sgMail.setApiKey(process.env.SENDGRID_API_KEY!);
await sgMail.send({
from: "noreply@yourdomain.com", // 需要验证域名
to: email,
subject: "验证邮箱",
html: "<p>...</p>",
});
SMTP 协议简述
SMTP(Simple Mail Transfer Protocol)本质就是一个发邮件的网络协议:
你的服务器 → SMTP 服务器 (smtp.qq.com:465) → 对方邮箱服务器 → 收件人
关键参数:
- host: SMTP 服务器地址
- port: 465(SSL)或 587(TLS)
- auth: 用户名 + 授权码(不是密码)
- from: 发件人(必须是 auth 中的邮箱)
