关于 resend
resend 技能为开发者提供通过 SDK 集成 Resend 邮件功能的指导,涵盖收发邮件、账户资源管理、Webhook,以及幂等性和错误处理等实践。
主要功能
- 01单封与批量邮件发送
- 02收件与 Webhook 处理
- 03邮件、域名和联系人管理
- 04模板、广播与自动化
- 05幂等性和错误处理指导
适用场景
- 01为应用添加事务性邮件
- 02处理收到的邮件和附件
- 03管理联系人和营销广播
- 04在重试时避免重复发送
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ resend/ resend-skills --skill resend安装后在 Claude Code 中输入/resend确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/api-keys.mdautomations.mdbroadcasts.mdcontact-properties.mdcontacts.mddomains.mdevents.mdfetch-all-templates.mjsinboxes.mdinstallation.mdlogs.mdreceiving.mdsegments.mdtemplates.mdtopics.mdusage.mdwebhooks.mdreferences/sending/batch-email-examples.mdbest-practices.mdemail-management.mdoverview.mdsingle-email-examples.md详细介绍
Resend
快速发送 — Node.js
import { Resend } from 'resend';
const resend = new Resend(process.env.RESEND_API_KEY);
const { data, error } = await resend.emails.send(
{
from: 'Acme <[email protected]>',
to: ['[email protected]'],
subject: 'Hello World',
html: '<p>Email body here</p>',
},
{ 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 错误。
快速发送 — Python
import resend
import os
resend.api_key = os.environ["RESEND_API_KEY"]
email = resend.Emails.send({
"from": "Acme <[email protected]>",
"to": ["[email protected]"],
"subject": "Hello World",
"html": "<p>Email body here</p>",
}, idempotency_key=f"welcome-email/{user_id}")
单封邮件与批量发送的选择
| 选择 | 适用场景 |
|---|---|
单封(POST /emails) | 1 封邮件,需要附件或定时发送 |
批量(POST /emails/batch) | 2-100 封不同的邮件,无附件,也不定时发送 |
批量发送具有原子性:如果有一封邮件未通过验证,整个批次都会失败。发送前请务必验证。批量发送不支持附件或 scheduled_at。
幂等键(重试时至关重要)
在重试失败的请求时,防止重复发送邮件:
| 键信息 | |
|---|---|
| 格式(单封) | <event-type>/<entity-id>(例如:welcome-email/user-123) |
| 格式(批量) | batch-<event-type>/<batch-id>(例如:batch-orders/batch-456) |
| 有效期 | 24 小时 |
| 最大长度 | 256 个字符 |
| 相同键 + 相同负载 | 返回原始响应,不会重新发送 |
| 相同键 + 不同负载 | 返回 409 错误 |
快速接收(Node.js)
import { Resend } from 'resend';
const resend = new Resend(process.env.RESEND_API_KEY);
export async function POST(req: Request) {
const payload = await req.text(); // Must use raw text, not 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 has metadata only — call API for body
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、附件 |
| 管理模板(CRUD、变量) | templates.md — 生命周期、别名、分页 |
| 设置 Webhook(事件、验证) | webhooks.md — 验证、CRUD、重试计划、IP 允许列表 |
| 管理域名(创建、验证、认领、DNS) | domains.md — 区域、TLS、跟踪、认领、功能 |
| 管理联系人(CRUD、属性) | contacts.md — 分组、主题、自定义属性、批量 CSV 导入 |
| 发送广播(营销活动) | broadcasts.md — 生命周期、安排发送、模板变量 |
| 管理 API 密钥 | api-keys.md — 权限范围、域名限制 |
| 查看 API 请求日志 | logs.md — 列出并检索 API 调用历史、调试 |
| 定义联系人属性 | contact-properties.md — 联系人的自定义字段 |
| 管理分组(联系人组) | segments.md — 广播定向、联系人分组 |
| 管理主题(订阅) | topics.md — 订阅/退订偏好、广播筛选 |
| 创建自动化流程(事件驱动工作流) | automations.md — 步骤、连接、运行、条件 |
| 定义并发送事件(自动化触发器) | events.md — 架构、负载、联系人关联 |
| 检查账户用量和配额 | usage.md — 邮件、联系人、分组、广播、AI 额度、自动化运行次数、域名、速率限制 |
| 管理收件箱(会话、回复、草稿) | inboxes.md — 标签、文件夹、搜索、Agent 设置、收件箱 Webhook 事件 |
| 安装 SDK(8 种以上语言) | installation.md |
| 设置 AI Agent 收件箱 | 安装 agent-email-inbox 技能 — 涵盖不可信输入的安全级别 |
SDK 版本要求
始终安装最新版本的 SDK。较旧的 SDK 可能缺少 webhooks.verify()、emails.receiving.get() 或 domains.claims.*。
如果项目已安装 Resend SDK,请对照 installation.md 中的最低版本要求检查其版本,若版本过低则升级。
请参阅 installation.md,了解各语言的最低版本、完整安装命令、语言检测和 cURL 备用方案。
常见设置
API 密钥
存储在环境变量中,切勿硬编码:
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 | 重试时未使用幂等键 | 始终包含幂等键,以避免重试时重复发送。格式:<event-type>/<entity-id> |
| 2 | 未验证 webhook 签名 | 始终使用 resend.webhooks.verify() 进行验证——未经验证的事件不可信 |
| 3 | 模板变量名称不匹配 | 变量名称区分大小写,必须与模板定义完全一致。使用三重大括号 {{{VAR}}} 语法 |
| 4 | 期望 webhook 负载中包含邮件正文 | Webhook 仅包含元数据——调用 resend.emails.receiving.get() 获取正文内容 |
| 5 | 使用 try/catch 处理 Node.js SDK 错误 | SDK 返回 { data, error }——显式检查 error,不要用 try/catch 包裹 |
| 6 | 对带附件的邮件使用批量发送 | 批量发送不支持附件——请改用单封发送 |
| 7 | 使用虚假邮箱地址([email protected])进行测试 | 使用 [email protected]——虚假地址会退信并损害发件人信誉 |
| 8 | 使用草稿模板发送 | 模板必须先发布才能发送——先调用 .publish() |
| 9 | 在同一次发送调用中同时使用 html 和 template | 两者互斥——使用模板时,请移除 html/text/react |
| 10 | 入站邮件的 MX 记录优先级不是最低数值 | 确保 Resend 的 MX 记录数值最低(优先级最高),否则邮件无法正确路由 |
| 11 | 从 resend.dev 发送时收到 403 | 默认的 [email protected] 是沙盒地址,只能向你的 Resend 账户邮箱投递。请先验证自己的域名 |
| 12 | 403 域名不匹配 | from 地址的域名必须与已验证的域名完全一致。已验证 send.acme.com,但使用 [email protected] 发送会失败 |
| 13 | 从浏览器调用 Resend API(CORS) | API 不支持 CORS,这是为了保护你的 API 密钥而有意为之。始终从服务端调用(API 路由、无服务器函数) |
| 14 | 401 restricted_api_key | 将仅用于发送的 API 密钥用于非发送端点(域名、联系人等)。请改用具有完整访问权限的密钥 |
跨领域注意事项
同时发送和接收
自动回复、邮件转发或任何先接收再发送的工作流都需要同时具备两种能力:
- 先设置入站域名(参见 receiving.md)
- 设置发送功能(参见 sending/overview.md)
- 注意:批量发送不支持附件或定时发送——转发带附件的邮件时请使用单封发送
AI Agent 收件箱
如果你的系统会处理不可信的邮件内容并执行操作(退款、数据库变更、转发),请安装 agent-email-inbox 技能。无论是否涉及 AI,此建议都适用——任何会解读外部发件人自由格式邮件内容的系统都需要采取安全措施。
营销邮件
此技能中的发送功能适用于事务性邮件(收据、确认、通知)。对于面向大型订阅者列表的营销活动(包含退订链接和互动跟踪),请使用 Resend Broadcasts——API 参见 broadcasts.md。
域名预热
新域名必须逐步提高发送量。第 1 天限额:约 150 封邮件(新域名)或约 1,000 封(现有域名)。预热计划请参见 sending/overview.md。
测试
切勿使用真实邮件服务商的虚假地址进行测试([email protected]、[email protected])——这些地址会退信并损害发件人信誉。
| 地址 | 结果 |
|---|---|
[email protected] | 模拟成功投递 |
[email protected] | 模拟硬退信 |
[email protected] | 模拟垃圾邮件投诉 |
抑制列表
Resend 会自动抑制硬退信和投诉垃圾邮件的地址。向已抑制地址发送邮件时,会触发 email.suppressed webhook 事件,而不会尝试投递。请在 Dashboard → Suppressions 中管理。
Webhook 事件类型
| 事件 | 触发条件 |
|---|---|
email.sent | API 请求成功 |
email.delivered | 已送达收件人的邮件服务器 |
email.bounced | 被永久拒收(硬退信) |
email.complained | 收件人将邮件标记为垃圾邮件 |
email.opened / email.clicked | 收件人参与互动 |
email.delivery_delayed | 软退信,Resend 将重试 |
email.received | 收到入站邮件 |
domain.* / contact.* | 域名/联系人变更 |
完整详情、签名验证和重试计划,请参阅 webhooks.md。
错误处理速查
| 代码 | 操作 |
|---|---|
| 400, 422 | 修正请求参数,不要重试 |
| 401 | 检查 API 密钥——restricted_api_key 表示在非发送端点上使用了仅限发送的密钥 |
| 403 | 验证域名所有权——常见原因:resend.dev 沙盒、from 域名不匹配、域名未验证 |
| 409 | 幂等性冲突——使用新密钥或修正负载 |
| 429 | 请求频率受限——使用指数退避重试(默认速率限制:2 req/s) |
| 500 | 服务器错误——使用指数退避重试 |