Points de terminaison Webhook Encore
Instructions
Utilisez api.raw(...) pour recevoir les webhooks entrants des services tiers. Les endpoints raw vous donnent un accès direct aux objets request et response de style Node.js, dont vous avez besoin pour la vérification de signature (la vérification nécessite généralement le corps raw non analysé).
1. Import
import { api } from "encore.dev/api";
2. Définir l'endpoint avec api.raw
export const stripeWebhook = api.raw(
{ expose: true, path: "/webhooks/stripe", method: "POST" },
async (req, res) => {
const sig = req.headers["stripe-signature"];
// Lire le corps raw
const chunks: Buffer[] = [];
for await (const chunk of req) chunks.push(chunk);
const rawBody = Buffer.concat(chunks).toString("utf8");
// Vérifier la signature, analyser l'événement...
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify({ received: true }));
}
);
3. Vérifier la signature
La plupart des fournisseurs signent les webhooks. Lisez le secret avec secret(...) depuis encore.dev/config (voir la skill encore-secret) et vérifiez avant de faire confiance au payload :
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());
Pour GitHub, vérifiez le HMAC-SHA256 dans l'en-tête X-Hub-Signature-256 par rapport au corps raw en utilisant votre secret webhook.
Fournisseurs courants
| Fournisseur | En-tête de signature | Vérification |
|---|---|---|
| Stripe | Stripe-Signature |
stripe.webhooks.constructEvent(rawBody, sig, secret) |
| GitHub | X-Hub-Signature-256 |
HMAC-SHA256 sur le corps raw |
| Slack | X-Slack-Signature |
HMAC-SHA256 sur v0:{timestamp}:{rawBody} |
| Shopify | X-Shopify-Hmac-Sha256 |
HMAC-SHA256 (base64) sur le corps raw |
| Twilio | X-Twilio-Signature |
HMAC-SHA1 sur l'URL + champs de formulaire triés |
Toujours répondre rapidement
Les émetteurs de webhooks font des tentatives de renvoi sur les réponses non-2xx ou lentes. Accusez réception avec un 2xx dès que le payload est vérifié, puis mettez en file d'attente le travail réel via Pub/Sub (voir encore-pubsub) plutôt que de le faire dans le gestionnaire de requête.
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();
Directives
- Utilisez
api.rawuniquement pour les webhooks et autres intégrations HTTP de bas niveau. - Vérifiez toujours la signature du fournisseur avant de faire confiance au payload.
- Répondez toujours 2xx rapidement — transférez le travail lent vers Pub/Sub.
- Stockez le secret de signature avec
secret(...); ne l'intégrez jamais en dur. - Pour les endpoints JSON typés dans votre propre service, utilisez
api(...)simple depuis la skillencore-api.