关于 postmark-webhooks
面向开发者的 Postmark Webhook 处理指南,涵盖邮件事件处理、基于 URL 的认证、安全检查和本地测试。
主要功能
- 01处理投递、退信、打开和点击事件
- 02处理垃圾邮件投诉与订阅变更
- 03使用 URL 凭据进行认证
- 04校验负载并保护端点
- 05使用 Hookdeck CLI 本地测试
适用场景
- 01跟踪邮件互动与投递情况
- 02在退信或投诉后更新联系人
- 03实现取消订阅和重新订阅处理
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ hookdeck/ webhook-skills --skill postmark-webhooks安装后在 Claude Code 中输入/postmark-webhooks确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
TODO.mdexamples/express/.env.examplepackage.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/postmark/route.tsexamples/nextjs/test/webhook.test.tsreferences/overview.mdsetup.mdverification.md详细介绍
Postmark Webhooks
何时使用此技能
- 设置 Postmark Webhook 处理程序以跟踪电子邮件事件
- 处理电子邮件送达事件(退信、已送达、打开、点击)
- 处理垃圾邮件投诉和订阅变更
- 实现电子邮件互动分析
- 排查 Webhook 身份验证问题
核心代码
身份验证
Postmark 不使用签名验证。Webhook 通过将凭据包含在 Webhook URL 本身中进行身份验证。
// Express - Basic Auth in URL
// Configure webhook URL in Postmark as:
// https://username:[email protected]/webhooks/postmark
app.post('/webhooks/postmark', express.json(), (req, res) => {
// Basic auth is handled by your web server or proxy
// Additional validation can check expected payload structure
const event = req.body;
// Validate expected fields exist
if (!event.RecordType || !event.MessageID) {
return res.status(400).send('Invalid payload structure');
}
// Process event
console.log(`Received ${event.RecordType} event for ${event.Email}`);
res.sendStatus(200);
});
// Alternative: Token in URL
// Configure webhook URL as:
// https://yourdomain.com/webhooks/postmark?token=your-secret-token
app.post('/webhooks/postmark', express.json(), (req, res) => {
const token = req.query.token;
if (token !== process.env.POSTMARK_WEBHOOK_TOKEN) {
return res.status(401).send('Unauthorized');
}
const event = req.body;
console.log(`Received ${event.RecordType} event`);
res.sendStatus(200);
});
处理多个事件
// Postmark sends one event per request (not batched)
app.post('/webhooks/postmark', express.json(), (req, res) => {
const event = req.body;
switch (event.RecordType) {
case 'Bounce':
console.log(`Bounce: ${event.Email} - ${event.Type} - ${event.Description}`);
// Update contact as undeliverable
break;
case 'SpamComplaint':
console.log(`Spam complaint: ${event.Email}`);
// Remove from mailing list
break;
case 'Open':
console.log(`Email opened: ${event.Email} at ${event.ReceivedAt}`);
// Track engagement
break;
case 'Click':
console.log(`Link clicked: ${event.Email} - ${event.OriginalLink}`);
// Track click-through rate
break;
case 'Delivery':
console.log(`Delivered: ${event.Email} at ${event.DeliveredAt}`);
// Confirm delivery
break;
case 'SubscriptionChange':
console.log(`Subscription change: ${event.Email} - ${event.ChangedAt}`);
// Update subscription preferences
break;
case 'Inbound':
console.log(`Inbound email from: ${event.Email} - Subject: ${event.Subject}`);
// Process incoming email
break;
case 'SMTP API Error':
console.log(`SMTP API error: ${event.Email} - ${event.Error}`);
// Handle API error, maybe retry
break;
default:
console.log(`Unknown event type: ${event.RecordType}`);
}
res.sendStatus(200);
});
常见事件类型
| 事件 | RecordType | 描述 | 关键字段 |
|---|---|---|---|
| 退信 | Bounce | 硬退信、软退信或邮件被拦截 | Email、Type、TypeCode、Description |
| 垃圾邮件投诉 | SpamComplaint | 收件人将邮件标记为垃圾邮件 | Email、BouncedAt |
| 打开 | Open | 邮件已打开(需要启用打开跟踪) | Email、ReceivedAt、Platform、UserAgent |
| 点击 | Click | 链接被点击(需要启用点击跟踪) | Email、ClickedAt、OriginalLink |
| 送达 | Delivery | 已成功送达 | Email、DeliveredAt、Details |
| 订阅变更 | SubscriptionChange | 取消订阅/重新订阅 | Email、ChangedAt、SuppressionReason |
| 入站 | Inbound | 收到入站邮件 | Email、FromFull、Subject、TextBody、HtmlBody |
| SMTP API 错误 | SMTP API Error | SMTP API 调用失败 | Email、Error、ErrorCode、MessageID |
环境变量
# For token-based authentication
POSTMARK_WEBHOOK_TOKEN="your-secret-token-here"
# For basic auth (if not using URL-embedded credentials)
WEBHOOK_USERNAME="your-username"
WEBHOOK_PASSWORD="your-password"
安全最佳实践
- 始终使用 HTTPS - 切勿使用 HTTP URL 配置 Webhook
- 使用强凭据 - 生成较长的随机令牌或密码
- 验证载荷结构 - 处理前检查是否包含预期字段
- 实施 IP 允许列表 - Postmark 会公布其 IP 范围
- 考虑使用 Webhook 网关 - 例如 Hookdeck,以增加安全防护层
本地开发
如需在本地测试 Webhook,请使用 Hookdeck CLI:
npx hookdeck-cli listen 3000 postmark --path /webhooks/postmark
无需账号。提供本地隧道和 Web UI,可用于检查请求。
资源
- overview.md - Postmark Webhook 的介绍及常见事件类型
- setup.md - 在 Postmark 控制面板中配置 Webhook
- verification.md - 身份验证方法和安全最佳实践
- examples/ - Express、Next.js 和 FastAPI 的完整实现
推荐:webhook-handler-patterns
如需生产就绪的 Webhook 处理,也请安装 webhook-handler-patterns 技能:
相关技能
- sendgrid-webhooks - 使用 ECDSA 验证处理 SendGrid Webhook
- resend-webhooks - 使用 Svix 签名处理 Resend Webhook
- stripe-webhooks - 使用 HMAC-SHA256 处理 Stripe Webhook
- webhook-handler-patterns - 幂等性、错误处理、重试逻辑
- hookdeck-event-gateway - 生产级 Webhook 基础设施
评论
支持 Markdown