encore-webhook について
encore-webhook は、Encore サービスでサードパーティの Webhook エンドポイントを作るスキルです。生のリクエスト本文へのアクセス、署名検証、迅速な応答後の Pub/Sub 処理を説明します。
主な機能
- 01api.raw による Webhook 受信
- 02未解析のリクエスト本文の読み取り
- 03プロバイダー署名の検証
- 04secret(...) による署名シークレットの保存
- 05迅速に応答して処理を Pub/Sub に委譲
活用シーン
- 01Stripe や GitHub の Webhook 受信
- 02処理前の Webhook ペイロード検証
- 03時間のかかるハンドラーによる応答遅延の回避
- 04検証済みイベントの非同期処理キューへの登録
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ encoredev/ skills --skill encore-webhookインストール後、Claude Code で/encore-webhookを入力して読み込まれたか確認します。
詳細
Encore Webhook エンドポイント
手順
api.raw(...) を使用して、サードパーティサービスからの受信 Webhook を受け取ります。Raw エンドポイントでは、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 を生のボディに対して検証します。
一般的なプロバイダー
| プロバイダー | 署名ヘッダー | 検証 |
|---|---|---|
| Stripe | Stripe-Signature | stripe.webhooks.constructEvent(rawBody, sig, secret) |
| GitHub | X-Hub-Signature-256 | 生のボディに対する HMAC-SHA256 |
| Slack | X-Slack-Signature | v0:{timestamp}:{rawBody} に対する HMAC-SHA256 |
| Shopify | X-Shopify-Hmac-Sha256 | 生のボディに対する HMAC-SHA256(base64) |
| Twilio | X-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 対応