mcpField
E
encore-webhook

encore-webhook

github.com/encoredev开发30428 次安装2 天前更新
代码仓库

关于 encore-webhook

encore-webhook 是为 Encore 服务编写第三方 Webhook 接收端点的技能。它说明如何读取原始请求体、验证签名,并快速确认请求后将后续工作交给 Pub/Sub。

主要功能

  1. 01使用 api.raw 接收 Webhook
  2. 02读取未经解析的请求体
  3. 03验证提供方签名
  4. 04通过 secret(...) 保存签名密钥
  5. 05快速响应并将任务交给 Pub/Sub

适用场景

  1. 01接收 Stripe 或 GitHub Webhook
  2. 02在处理前验证 Webhook 载荷
  3. 03避免慢任务拖延 Webhook 响应
  4. 04将已验证事件排入异步队列

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/encoredev/skills --skill encore-webhook

安装后在 Claude Code 中输入/encore-webhook确认已加载。

详细介绍

Encore Webhook 端点

说明

使用 api.raw(...) 接收来自第三方服务的入站 Webhook。原始端点可让你直接访问 Node.js 风格的请求和响应对象;验证签名需要这些对象(验证通常需要未经解析的原始请求正文)。

1. 导入
import { api } from "encore.dev/api";
2. 使用 api.raw 定义端点
export const stripeWebhook = api.raw(
  { expose: true, path: "/webhooks/stripe", method: "POST" },
  async (req, res) => {
    const sig = req.headers["stripe-signature"];
    // Read raw body
    const chunks: Buffer[] = [];
    for await (const chunk of req) chunks.push(chunk);
    const rawBody = Buffer.concat(chunks).toString("utf8");

    // Verify signature, parse event...

    res.writeHead(200, { "Content-Type": "application/json" });
    res.end(JSON.stringify({ received: true }));
  }
);
3. 验证签名

大多数提供商都会对 Webhook 签名。使用 encore.dev/config 中的 secret(...) 读取密钥(请参阅 encore-secret 技能),并在信任负载之前验证签名:

import { secret } from "encore.dev/config";
const stripeWebhookSecret = secret("StripeWebhookSecret");

// inside handler:
import Stripe from "stripe";
const stripe = new Stripe(stripeApiKey());
const event = stripe.webhooks.constructEvent(rawBody, sig, stripeWebhookSecret());

对于 GitHub,请使用 Webhook 密钥,根据原始请求正文验证 X-Hub-Signature-256 标头中的 HMAC-SHA256。

常见提供商

提供商签名标头验证方式
StripeStripe-Signaturestripe.webhooks.constructEvent(rawBody, sig, secret)
GitHubX-Hub-Signature-256对原始请求正文执行 HMAC-SHA256
SlackX-Slack-Signature对 v0:{timestamp}:{rawBody} 执行 HMAC-SHA256
ShopifyX-Shopify-Hmac-Sha256对原始请求正文执行 HMAC-SHA256(base64)
TwilioX-Twilio-Signature对 URL 和排序后的表单字段执行 HMAC-SHA1

始终快速响应

Webhook 发送方会在收到非 2xx 响应或响应缓慢时重试。验证负载后,请立即使用 2xx 确认收到,然后通过 Pub/Sub 将实际工作加入队列(请参阅 encore-pubsub),而不是在请求处理程序中执行。

import { Topic } from "encore.dev/pubsub";

interface StripeEvent { id: string; type: string; data: unknown; }
const stripeEvents = new Topic<StripeEvent>("stripe-events", {
  deliveryGuarantee: "at-least-once",
});

// inside the raw handler, after verification:
await stripeEvents.publish({ id: event.id, type: event.type, data: event.data });
res.writeHead(200); res.end();

指南

  • 仅将 api.raw 用于 Webhook 和其他底层 HTTP 集成。
  • 在信任负载之前,始终验证提供商的签名。
  • 始终快速返回 2xx 响应——将耗时工作交给 Pub/Sub。
  • 使用 secret(...) 存储签名密钥;切勿将其直接写入代码。
  • 对于你自己服务中的带类型 JSON 端点,请使用 encore-api 技能中的普通 api(...)。

评论

支持 Markdown