用于在使用 Resend 邮件 API 时——发送事务邮件(单发或批量),通过 webhook 接收入站邮件,管理邮件模板,...
Resend QQ快速发送 — node.js.是一项面向实际任务的技能,主要用于Key gotcha: The Resend Node.js SDK 不丢出例外 — 它返回 {数据,错误}.;总是明确检查错误,而不是使用尝试/ catch来获取API错误;
从功能定位来看,该技能强调把分散的操作要求整理成清晰、可复用的处理流程,使用户能够围绕既定目标快速准备输入、选择执行方式并获得结构化结果。实际使用前应先确认任务范围、数据来源、运行环境、必要权限和关键参数,再依据技能说明逐步执行;若输入条件不完整,应先补齐信息或采用保守配置,避免因错误假设导致结果偏离需求。
执行过程中需要关注工具调用是否成功、接口或依赖是否可用、输出格式是否符合预期,并对异常提示、缺失字段和边界情况进行处理;涉及批量任务时,还应保存进度,避免中断后重复操作。该技能适合用于一次性任务,也可以接入自动化工作流,与其他技能或上层代理配合完成更完整的业务链路;在组合使用时,应明确每一步的输入输出关系,并避免不同步骤之间出现参数冲突。
import { Resend } from 'resend';
const resend = new Resend(process.env.RESEND_API_KEY);
const { data, error } = await resend.emails.send(
{
from: 'Acme ',
to: ['delivered@resend.dev'],
subject: 'Hello World',
html: 'Email body here
',
},
{ idempotencyKey: `welcome-email/${userId}` }
);
if (error) {
console.error('Failed:', error.message);
return;
}
console.log('Sent:', data.id);
关键注意事项: Resend Node.js SDK 不会抛出异常,而是返回 { data, error }。请始终显式检查 error 字段,而非使用 try/catch 捕获 API 错误。
import resend
import os
resend.api_key = os.environ["RESEND_API_KEY"]
email = resend.Emails.send({
"from": "Acme ",
"to": ["delivered@resend.dev"],
"subject": "Hello World",
"html": "Email body here
",
}, idempotency_key=f"welcome-email/{user_id}")
| 选择 | 适用场景 |
|---|---|
单封发送(POST /emails) |
仅发送 1 封邮件,需添加附件,或需定时发送 |
批量发送(POST /emails/batch) |
发送 2–100 封内容互异的邮件,不带附件,无需定时 |
批量发送是原子操作:若其中任一邮件校验失败,则整个批次均失败。务必在发送前完成校验。批量发送不支持附件和 scheduled_at 参数。
防止因重试失败请求而重复发送邮件:
| 关键事实 | |
|---|---|
| 格式(单封) | (例如:welcome-email/user-123) |
| 格式(批量) | batch-(例如:batch-orders/batch-456) |
| 有效期 | 24 小时 |
| 最大长度 | 256 个字符 |
| 相同密钥 + 相同载荷 | 直接返回原始响应,不重新发送邮件 |
| 相同密钥 + 不同载荷 | 返回 409 错误 |
import { Resend } from 'resend';
const resend = new Resend(process.env.RESEND_API_KEY);
export async function POST(req: Request) {
const payload = await req.text(); // 必须使用原始文本,不可调用 req.json()
const event = resend.webhooks.verify({
payload,
headers: {
'svix-id': req.headers.get('svix-id'),
'svix-timestamp': req.headers.get('svix-timestamp'),
'svix-signature': req.headers.get('svix-signature'),
},
secret: process.env.RESEND_WEBHOOK_SECRET,
});
if (event.type === 'email.received') {
// Webhook 仅包含元数据 —— 需额外调用 API 获取邮件正文
const { data: email } = await resend.emails.receiving.get(
event.data.email_id
);
console.log(email.text);
}
return new Response('OK', { status: 200 });
}
关键注意事项: Webhook 载荷中不包含邮件正文。您必须单独调用 resend.emails.receiving.get() 获取正文内容。
| 任务 | 参考文档 |
|---|---|
| 发送单封邮件 | sending/overview.md — 参数说明、投递率优化、测试方法 |
| 发送批量邮件 | sending/overview.md → sending/batch-email-examples.md |
| 完整 SDK 示例(Node.js、Python、Go、cURL) | sending/single-email-examples.md |
| 幂等性、重试机制与错误处理 | sending/best-practices.md |
| 获取、列出、重新定时或取消邮件 | sending/email-management.md |
| 接收入站邮件 | receiving.md — 域名配置、Webhook 设置、附件处理 |
| 管理模板(增删改查、变量支持) | templates.md — 生命周期管理、别名、分页 |
| 配置 Webhook(事件类型、签名验证) | webhooks.md — 签名验证、增删改查、重试策略、IP 白名单 |
| 管理域名(创建、验证、DNS 配置) | domains.md — 地域支持、TLS 设置、追踪功能、能力列表 |
| 管理联系人(增删改查、属性定义) | contacts.md — 分组、主题订阅、自定义属性 |
| 发送广播邮件(营销活动) | broadcasts.md — 生命周期、定时调度、模板变量 |
| 管理 API 密钥 | api-keys.md — 权限范围控制、域名限制 |
| 查看 API 请求日志 | logs.md — 查询与检索 API 调用历史,用于调试 |
| 定义联系人属性 | contact-properties.md — 为联系人配置自定义字段 |
| 管理分组(联系人集合) | segments.md — 广播定向、联系人归类 |
| 管理主题(订阅偏好) | topics.md — 订阅/退订设置、广播过滤 |
| 创建自动化流程(事件驱动工作流) | automations.md — 步骤定义、连接器、执行记录、条件判断 |
| 定义并发送事件(自动化触发器) | events.md — 数据结构、载荷格式、联系人关联 |
| 安装 SDK(支持 8+ 种语言) | installation.md |
| 配置 AI 代理邮箱收件箱 | 安装 agent-email-inbox 技能 —— 涵盖对不可信输入的安全等级控制 |
请始终安装最新版 SDK。以下为保障全部功能(发送、接收、Webhook 签名验证)可用所需的最低版本:
| 语言 | 包名 | 最低版本 | 安装命令 |
|---|---|---|---|
| Node.js | resend |
>= 6.9.2 | npm install resend |
| Python | resend |
>= 2.21.0 | pip install resend |
| Go | resend-go/v3 |
>= 3.1.0 | go get github.com/resend/resend-go/v3 |
| Ruby | resend |
>= 1.0.0 | gem install resend |
| PHP | resend/resend-php |
>= 1.1.0 | composer require resend/resend-php |
| Rust | resend-rs |
>= 0.20.0 | cargo add resend-rs |
| Java | resend-java |
>= 4.11.0 | 详见 installation.md |
| .NET | Resend |
>= 0.2.1 | dotnet add package Resend |
若项目中已安装 Resend SDK,请检查当前版本;如低于最低要求,请升级。旧版 SDK 可能缺失
webhooks.verify()或emails.receiving.get()方法。
完整安装命令、语言自动识别及 cURL 回退方案,请参阅 installation.md。
请将密钥存于环境变量中 —— 切勿硬编码:
export RESEND_API_KEY=re_xxxxxxxxx
您的密钥可在 resend.com/api-keys 页面获取。
检查是否存在以下文件:package.json(Node.js)、requirements.txt/pyproject.toml(Python)、go.mod(Go)、Gemfile(Ruby)、composer.json(PHP)、Cargo.toml(Rust)、pom.xml/build.gradle(Java)、*.csproj(.NET)。
| # | 错误 | 修正方式 |
|---|---|---|
| 1 | 重试时未提供幂等性密钥 | 务必包含幂等性密钥 —— 可避免重试导致重复发送。格式应为: |
| 2 | 未校验 Webhook 签名 | 始终使用 resend.webhooks.verify() 进行校验 —— 未经校验的事件不可信 |
| 3 | 模板变量名不匹配 | 变量名区分大小写,必须与模板中定义完全一致。请使用三重大括号语法:{{{VAR}}} |
| 4 | 误以为 Webhook 载荷中含邮件正文 | Webhook 仅包含元数据 —— 需调用 resend.emails.receiving.get() 获取正文内容 |
| 5 | 对 Node.js SDK 错误使用 try/catch | SDK 返回 { data, error } 结构 —— 请显式检查 error,勿包裹于 try/catch 中 |
| 6 | 对带附件的邮件使用批量发送 | 批量发送不支持附件 —— 请改用单封发送 |
| 7 | 使用虚假邮箱地址测试(如 test@gmail.com) | 请使用 delivered@resend.dev —— 虚假地址会导致退信,损害发信信誉 |
| 8 | 使用草稿状态模板发送 | 模板必须先发布才能用于发送 —— 请先调用 .publish() |
| 9 | 同一请求中同时指定 html 和 template |
二者互斥 —— 使用模板时,请移除 html/text/react 字段 |
| 10 | 入站邮件 MX 记录未设为最低优先级 | 请确保 Resend 提供的 MX 记录数值最小(即最高优先级),否则邮件无法正确路由 |
| 11 | 从 resend.dev 发送时返回 403 |
默认的 onboarding@resend.dev 属沙箱域名,仅可投递至您 Resend 账户绑定的邮箱。请先验证自有域名 |
| 12 | 403 域名不匹配 | from 地址的域名必须与已验证域名严格一致。例如已验证 send.acme.com,但发送地址为 user@acme.com 将失败 |
| 13 | 从浏览器端直接调用 Resend API(CORS 问题) | API 明确不支持 CORS —— 此设计旨在保护您的 API 密钥。请始终从服务端调用(API 路由、Serverless 函数等) |
| 14 | 401 restricted_api_key |
在非发送类接口(如域名、联系人等)上误用了仅限发送的 API 密钥。请创建具备完整权限的密钥 |
自动回复、邮件转发,或任何“先收后发”类工作流,均需同时启用发送与接收能力:
若您系统需处理来自外部发件人的、不可信的邮件内容,并据此执行操作(如退款、数据库变更、转发等),请安装 agent-email-inbox 技能。该技能适用场景不限于 AI 应用 —— 任何解析外部自由格式邮件内容并采取动作的系统,均需安全防护措施。
本技能提供的发送能力专用于事务性邮件(如订单确认、登录通知、交易凭证等)。如需面向大量订阅者群发含退订链接与用户行为追踪的营销活动,请使用 Resend Broadcasts —— 详情请参阅 broadcasts.md。
新注册域名需逐步提升发信量。第 1 天发信上限约为:新域名 150 封,已有域名约 1,000 封。详细预热计划请参阅 sending/overview.md。
切勿使用真实邮件服务商的虚假地址进行测试(如 test@gmail.com、fake@outlook.com)—— 此类地址必然退信,严重损害发信方信誉。
| 地址 | 效果 |
|---|---|
delivered@resend.dev |
模拟成功投递 |
bounced@resend.dev |
模拟硬退信(Hard Bounce) |
complained@resend.dev |
模拟垃圾邮件投诉 |
Resend 会自动将硬退信地址与垃圾邮件投诉地址加入抑制列表。向已被抑制的地址发送邮件时,系统将触发 email.suppressed Webhook 事件,而不会尝试实际投递。您可在 Dashboard → Suppressions 中管理该列表。
| 事件 | 触发条件 |
|---|---|
email.sent |
API 请求成功提交 |
email.delivered |
邮件已送达收件人邮件服务器 |
email.bounced |
被永久拒绝(硬退信) |
email.complained |
收件人标记为垃圾邮件 |
email.opened / email.clicked |
收件人打开邮件或点击链接 |
email.delivery_delayed |
软退信(Soft Bounce),Resend 将自动重试 |
email.received |
收到入站邮件 |
domain.* / contact.* |
域名或联系人发生变更 |
完整事件说明、签名验证方法及重试策略,请参阅 webhooks.md。
| HTTP 状态码 | 应对措施 |
|---|---|
| 400、422 | 修正请求参数,无需重试 |
| 401 | 检查 API 密钥 —— restricted_api_key 表示在非发送类接口上误用了仅限发送的密钥 |
| 403 | 验证域名所有权 —— 常见原因包括:resend.dev 沙箱限制、from 域名不匹配、域名未验证 |
| 409 | 幂等性冲突 —— 请更换密钥或修正请求载荷 |
| 429 | 触发速率限制 —— 请采用指数退避策略重试(默认限流:2 次/秒) |
| 500 | 服务端错误 —— 请采用指数退避策略重试 |