Mailtrap 电子邮件集成
使用Mailtrap的Email API和Sandbox为应用程序添加事务性电子邮件发送功能的模式,涵盖身份验证、环境分离和常见投递陷阱。
何时激活
- 实现“发送邮件”功能(注册确认、密码重置、通知、收据)
- 调试为什么开发/预发环境中邮件未到达
- 设置项目的第一个电子邮件发送集成
- 审查直接调用电子邮件API而没有沙箱分离的代码
核心概念
沙箱与生产环境的分离。 Mailtrap提供了Sandbox API,它捕获电子邮件而不实际投递,用于开发/预发环境,以便测试邮件永远不会到达真实的收件箱。生产发送使用独立的已验证域名端点。切勿将开发环境指向生产发送端点。
身份验证。 请求使用Authorization头中的Bearer令牌。令牌按项目作用域划分;沙箱和生产环境通常使用不同的令牌。
域名验证。 生产发送需要通过DNS记录(SPF、DKIM、DMARC)验证发送域名,然后Mailtrap才会将邮件投递给真实收件人。跳过此步骤会导致静默投递失败或进入垃圾邮件文件夹。
代码示例
// 通过Mailtrap的Email API发送(生产环境)
async function sendEmail(to: string, subject: string, html: string) {
const response = await fetch("https://send.api.mailtrap.io/api/send", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.MAILTRAP_API_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
from: { email: "[email protected]", name: "Your App" },
to: [{ email: to }],
subject,
html,
}),
});
if (!response.ok) {
throw new Error(`Email send failed: ${response.status}`);
}
return response.json();
}
// 相同调用,在非生产环境中路由到沙箱
const MAILTRAP_ENDPOINT = process.env.NODE_ENV === "production"
? "https://send.api.mailtrap.io/api/send"
: `https://sandbox.api.mailtrap.io/api/send/${process.env.MAILTRAP_INBOX_ID}`;
反模式
| 反模式 | 为什么有问题 | 替代方案 |
|---|---|---|
| 在开发/测试中使用生产发送端点 | 真实的测试邮件会到达真实收件箱,带来垃圾邮件投诉和测试数据泄露的风险 | 将非生产环境路由到沙箱端点 |
| 在源代码中硬编码API令牌 | 如果提交到版本控制,存在凭证泄露风险 | 从环境变量/密钥管理器加载令牌 |
| 在域名验证完成之前发送邮件 | 邮件静默失败或进入垃圾邮件 | 在启用生产发送前验证SPF/DKIM/DMARC记录 |
| 发送失败时没有重试/错误处理 | 静默的通知失败(例如用户从未收到密码重置邮件) | 检查响应状态、记录失败、提供可操作错误信息 |
最佳实践
- 将沙箱和生产环境的令牌放在不同的环境变量中,切勿跨环境共享一个令牌
- 在任何涉及电子邮件发送的生产启动之前验证发送域名的DNS记录
- 记录投递失败,并提供足够的上下文以便调试(收件人、模板、时间戳、响应代码)
- 将电子邮件发送视为可能失败的网络调用:用try/catch包裹,切勿假设成功
相关技能
api-and-interface-design、security-and-hardening、ci-cd-and-automation