让 AI 编程助手发邮件(2026):用 HTTP 调事务邮件 API
给 Cursor 或 Claude 一把 sending_access 密钥,用 POST /emails 发验证码、邀请和魔法登录——无需自建 SMTP,并配好幂等与已验证域名。
为什么 AI 编程助手也要会发邮件
当你让 Cursor 或 Claude 搭一个应用时,最先落地的往往不是界面,而是账号流程:六位验证码、魔法登录链接、团队邀请,或「确认这个邮箱」的 URL。这些都属于事务邮件——必须从已验证域名发出,扛得住重试,且不能在工具调用超时时连发两封互相矛盾的码。
Rovela 在官网上把自己定位为面向 developers and AI agents(开发者与 AI 智能体) 的邮件基础设施:普通 HTTP API、DKIM 签名投递、入站 Webhook;无论是人手敲 curl,还是智能体跑工具,走的是同一条发送路径。没有另一套「智能体专用协议」要学。只要运行时能用环境变量里的 Bearer 令牌打 HTTPS,就能发信。
这对搜索意图和安全都很重要:你不需要官方 Cursor 插件、Claude Tool 或 MCP Server 才能发 OTP。你需要的是快速开始、一把 sending_access 密钥,以及「绝不把密钥贴进对话记录」的习惯。
智能体真正会发的那一个请求
一切可以收敛成一次鉴权调用:
curl -X POST https://api.rovela.dev/emails \
-H "Authorization: Bearer $ROVELA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: signup-otp-alice-20261104" \
-d '{
"from": "Acme <security@mail.yourdomain.com>",
"to": "alice@example.com",
"subject": "Your Acme code: 482913",
"html": "<p>Your verification code is <b>482913</b>.</p><p>It expires in 10 minutes.</p>",
"text": "Your verification code is 482913. It expires in 10 minutes."
}'
成功时响应形如 {"object":"email","id":"…"}。按发送邮件 API说明,这里的 200 表示消息已入队等待投递,并不等于已经进收件箱。投递是异步的;需要证据时用消息事件或 Webhook。
智能体(或它写出来的应用)应和资深工程师一样处理:密钥放环境变量,令牌/验证码在你自己的库里生成与核销,安全类邮件同时带 html 与 text,好让通知预览也能看到码或完整链接。
环境变量、最小权限、已验证域名
按鉴权文档做四件事:
- 在控制台添加并验证发信域名,等 DNS 生效。未验证域名的发送会被
400拒绝,而不是静默入队(见快速开始)。 - 创建形如
re_…的 API 密钥。生产发送优先sending_access:只能发信。需要读事件、管域名时再用full_access。 - 只把密钥导出到智能体被允许使用的服务器或沙箱环境(例如
ROVELA_API_KEY),不要放进浏览器包、公开仓库里的.env,或会被记入日志的提示词。 - 若替多个客户代发,可把密钥限制在单个域名上,降低泄露面。
官网「Works with」里列出 Claude、Cursor,是因为它们能发起 HTTP——集成故事到此为止:智能体写或执行的,就是人也会写的 fetch / curl。不要编造文档里不存在的产品表面。
智能体会话的安全清单:
- 明确指示:「从
$ROVELA_API_KEY读取;不要打印;不要写进提交或 Issue。」 - 若对话或 CI 日志曾出现密钥,用「先创建再吊销」轮换(鉴权)。
- OTP 哈希、魔法登录令牌、邀请密钥放在你的存储里——Rovela 负责投递,不替你签发登录令牌。
套餐与额度见定价页。本文不编造具体数字;选型时以该页为准。
验证码、邀请、魔法登录:短模式
HTTP 请求体故意很无聊。变化的是应用侧:
| 流程 | 你自己做的 | 邮件里发什么 |
|---|---|---|
| 邮箱 OTP | 随机码、存 HMAC、过期与尝试次数 | 主题 + html/text 中的码(验证码示例) |
| 魔法登录 | 一次性不透明令牌,核销一次 | html 与 text 中的绝对 HTTPS URL(魔法登录链接) |
| 团队邀请 | 邀请记录 + 接受路由 | 带角色上下文的邀请 URL(团队邀请链接) |
| 验证邮箱 | 确认令牌,翻转 email_verified | 确认 URL(邮箱验证链接) |
链接类邮件务必在纯文本里写完整 URL。若别处开了点击追踪,安全链接建议关掉,让用户看到的 href 就是你签发的那个。更完整的配方见上文各篇与 AI 应用事务邮件总览。
智能体可能写出的最小 Node 发送形态:
const res = await fetch("https://api.rovela.dev/emails", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.ROVELA_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": idempotencyKey,
},
body: JSON.stringify({
from: "Acme <security@mail.yourdomain.com>",
to: email,
subject: `Your Acme code: ${code}`,
html: `<p>Your code is <b>${code}</b>. It expires in 10 minutes.</p>`,
text: `Your code is ${code}. It expires in 10 minutes.`,
}),
});
Python requests、Go net/http,或智能体调用的 shell 工具,形态相同。
智能体重试时的幂等
智能体会重试,Serverless 冷启动和网络抖动也会。请带上 Idempotency-Key(最长 256 字符)。24 小时内相同请求的重放会返回原先响应,而不会再投递第二封互相冲突的 OTP。
实用约定:
- 用稳定业务 id 生成键:
otp:{userId}:{purpose}:{window},或在第一次尝试前生成 UUID 并在重试时复用。 - 不要每次重试都换新键——那等于关掉幂等。
429/5xx可重试;400(域名未验证、收件人被抑制)是配置或地址问题,不是「再猛发一次」。
哪些事不要交给自动化
给智能体发信密钥很强,也要收口:
- 不要让智能体擅自创建
full_access或改 DNS,除非有人审。 - 不要把线上密钥贴进聊天让模型「记住」——用宿主环境或沙箱已挂载的密钥管理。
- 不要让它发明自建 SMTP、开放中继或「关掉 DKIM」。未验证/未签名发送本来就会被拒绝。
- 不要因为 API 返回
200就认为进箱完成。验证码进垃圾箱要靠域名卫生与文案纪律(验证码/魔法登录进垃圾箱)。 - 不要用发验证码的同一个子域做大规模营销;声誉车道要分开。
若还要收信,那是另一条能力面——见入站邮件 API / Webhook。
下一步怎么接
- 走一遍快速开始:账号 → 域名 →
sending_access→ 第一次POST /emails。 - 用发送邮件 API与鉴权接好一条认证流程。
- 从 AI 应用事务邮件借结构,再深入魔法登录、邀请或验证链接。
- 产品形态(API + 邮箱 + 入站)对照定价;若在迁移,可看 Resend alternative。
AI 编程助手最快的路径,是把邮件层做成无聊的 HTTP:环境里的最小权限密钥、已验证域名、带幂等的 POST /emails——并把秘密留在对话之外。