关于 sendgrid-webhooks
sendgrid-webhooks 是面向开发者的技能,用于实现 SendGrid 邮件事件处理程序,介绍 ECDSA 验证与事件处理,并提供 Express、Next.js 和 FastAPI 示例。
主要功能
- 01SendGrid Webhook 处理指南
- 02ECDSA 签名验证
- 03邮件投递与互动事件参考
- 04Express、Next.js 和 FastAPI 示例
- 05使用 Hookdeck CLI 本地测试
适用场景
- 01跟踪邮件投递与延迟
- 02处理退信、退订和垃圾邮件举报
- 03分析邮件打开与链接点击
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ hookdeck/ webhook-skills --skill sendgrid-webhooks安装后在 Claude Code 中输入/sendgrid-webhooks确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
TODO.mdexamples/express/.env.examplejest.config.jspackage.jsonREADME.mdexamples/express/src/index.jsexamples/express/test/webhook.test.jsexamples/fastapi/.env.examplemain.pyREADME.mdrequirements.txttest_webhook.pyexamples/nextjs/.env.examplepackage.jsonREADME.mdvitest.config.tsexamples/nextjs/app/webhooks/sendgrid/route.tsexamples/nextjs/test/webhook.test.tsreferences/overview.mdsetup.mdverification.md详细介绍
SendGrid Webhooks
适用场景
- 设置 SendGrid Webhook 处理程序,以跟踪邮件投递情况
- 调试 ECDSA 签名验证失败
- 处理邮件事件(退信、已投递、打开、点击、垃圾邮件举报)
- 实现邮件互动分析
必备代码
手动验证签名
SendGrid 使用 ECDSA(椭圆曲线数字签名算法)进行公钥验证。
// Node.js manual verification
const crypto = require('crypto');
function verifySignature(publicKey, payload, signature, timestamp) {
// Decode the base64 signature
const decodedSignature = Buffer.from(signature, 'base64');
// Create the signed content
const signedContent = timestamp + payload;
// Create verifier
const verifier = crypto.createVerify('sha256');
verifier.update(signedContent);
// Add PEM headers if not present
let pemKey = publicKey;
if (!pemKey.includes('BEGIN PUBLIC KEY')) {
pemKey = `-----BEGIN PUBLIC KEY-----\n${publicKey}\n-----END PUBLIC KEY-----`;
}
// Verify the signature
return verifier.verify(pemKey, decodedSignature);
}
// Express middleware
app.post('/webhooks/sendgrid', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.get('X-Twilio-Email-Event-Webhook-Signature');
const timestamp = req.get('X-Twilio-Email-Event-Webhook-Timestamp');
if (!signature || !timestamp) {
return res.status(400).send('Missing signature headers');
}
const publicKey = process.env.SENDGRID_WEBHOOK_VERIFICATION_KEY;
const payload = req.body.toString();
if (!verifySignature(publicKey, payload, signature, timestamp)) {
return res.status(400).send('Invalid signature');
}
// Process events
const events = JSON.parse(payload);
console.log(`Received ${events.length} events`);
res.sendStatus(200);
});
使用 SendGrid SDK
const { EventWebhook } = require('@sendgrid/eventwebhook');
const verifyWebhook = new EventWebhook();
const publicKey = process.env.SENDGRID_WEBHOOK_VERIFICATION_KEY;
app.post('/webhooks/sendgrid', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.get('X-Twilio-Email-Event-Webhook-Signature');
const timestamp = req.get('X-Twilio-Email-Event-Webhook-Timestamp');
const isValid = verifyWebhook.verifySignature(
publicKey,
req.body,
signature,
timestamp
);
if (!isValid) {
return res.status(400).send('Invalid signature');
}
// Process webhook
res.sendStatus(200);
});
常见事件类型
| 事件 | 描述 | 使用场景 |
|---|---|---|
processed | 已收到消息,准备投递 | 跟踪邮件处理情况 |
delivered | 消息已成功投递给收件人 | 确认投递 |
bounce | 消息被永久拒收(被拦截的消息包括 type='blocked') | 更新联系人列表、处理发送失败 |
deferred | 临时投递失败 | 监控延迟 |
open | 收件人打开了邮件 | 跟踪互动情况 |
click | 收件人点击了链接 | 跟踪链接、分析点击率 |
spam report | 邮件被标记为垃圾邮件 | 维护列表质量、维护发件人信誉 |
unsubscribe | 收件人取消订阅 | 更新订阅状态 |
group unsubscribe | 收件人取消订阅某个群组 | 更新群组订阅偏好 |
group resubscribe | 收件人重新订阅某个群组 | 更新群组订阅偏好 |
环境变量
# Your SendGrid webhook verification key (public key)
SENDGRID_WEBHOOK_VERIFICATION_KEY="MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE..."
本地开发
如需在本地测试 Webhook,请使用 Hookdeck CLI:
npx hookdeck-cli listen 3000 sendgrid --path /webhooks/sendgrid
无需账号。它提供本地隧道和 Web UI,用于检查请求。
资源
- overview.md - SendGrid Webhook 的介绍和常见事件类型
- setup.md - 在 SendGrid 控制面板中配置 Webhook,并获取验证密钥
- verification.md - ECDSA 签名验证的详细说明和注意事项
- examples/ - Express、Next.js 和 FastAPI 的完整实现
相关技能
webhook-handler-patterns- 通用模式(幂等性、重试、框架指南)- hookdeck-event-gateway - 可替代队列的 Webhook 基础设施,提供可靠投递、自动重试、重放、速率限制,以及对 Webhook 处理程序的可观测性
评论
支持 Markdown