mcpField
V
vercel-webhooks

vercel-webhooks

github.com/hookdeck開発95204 回インストール今日更新
リポジトリ

vercel-webhooks について

vercel-webhooksは、VercelのWebhookを扱う開発者向けのスキルです。デプロイ、プロジェクト、ドメイン、インテグレーションのイベント資料と、署名検証や複数フレームワークのハンドラー例を提供します。

主な機能

  1. 01Webhook署名検証の例
  2. 02デプロイ・プロジェクト・ドメインイベントの資料
  3. 03Express、Next.js、FastAPIの例
  4. 04Hookdeck CLIのローカルトンネル手順

活用シーン

  1. 01デプロイ状況を監視して後続タスクを開始
  2. 02デプロイ失敗をチームに通知
  3. 03プロジェクト削除後に外部リソースを整理
  4. 04ローカルでWebhookリクエストを確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/hookdeck/webhook-skills --skill vercel-webhooks

インストール後、Claude Code で/vercel-webhooksを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

TODO.md
examples/express/
.env.example
package.json
README.md
examples/express/src/
index.js
examples/express/test/
webhook.test.js
examples/fastapi/
.env.example
main.py
README.md
requirements.txt
test_webhook.py
examples/nextjs/
.env.example
package.json
README.md
vitest.config.ts
examples/nextjs/app/webhooks/vercel/
route.ts
examples/nextjs/test/
webhook.test.ts
references/
overview.md
setup.md
verification.md

詳細

Vercel Webhooks

このスキルを使用する場面

  • Vercel の Webhook ハンドラーを設定する
  • 署名検証の失敗をデバッグする
  • Vercel のイベントタイプとペイロードを理解する
  • デプロイ、プロジェクト、ドメイン、またはインテグレーションのイベントを処理する
  • デプロイステータスの変更を監視する

重要なコード(これを使用)

手動検証を行う Express Webhook ハンドラー
const express = require('express');
const crypto = require('crypto');

const app = express();

// CRITICAL: Use express.raw() for webhook endpoint - Vercel needs raw body
app.post('/webhooks/vercel',
  express.raw({ type: 'application/json' }),
  async (req, res) => {
    const signature = req.headers['x-vercel-signature'];

    if (!signature) {
      return res.status(400).send('Missing x-vercel-signature header');
    }

    // Verify signature using SHA1 HMAC
    const expectedSignature = crypto
      .createHmac('sha1', process.env.VERCEL_WEBHOOK_SECRET)
      .update(req.body)
      .digest('hex');

    // Use timing-safe comparison
    let signaturesMatch;
    try {
      signaturesMatch = crypto.timingSafeEqual(
        Buffer.from(signature),
        Buffer.from(expectedSignature)
      );
    } catch (err) {
      // Buffer length mismatch = invalid signature
      signaturesMatch = false;
    }

    if (!signaturesMatch) {
      console.error('Invalid Vercel webhook signature');
      return res.status(400).send('Invalid signature');
    }

    // Parse the verified payload
    const event = JSON.parse(req.body.toString());

    // Handle the event
    switch (event.type) {
      case 'deployment.created':
        console.log('Deployment created:', event.payload.deployment.id);
        break;
      case 'deployment.succeeded':
        console.log('Deployment succeeded:', event.payload.deployment.id);
        break;
      case 'deployment.error':
        console.log('Deployment failed:', event.payload.deployment.id);
        break;
      case 'project.created':
        console.log('Project created:', event.payload.project.name);
        break;
      default:
        console.log('Unhandled event:', event.type);
    }

    res.json({ received: true });
  }
);
Python(FastAPI)Webhook ハンドラー
import os
import hmac
import hashlib
from fastapi import FastAPI, Request, HTTPException, Header

app = FastAPI()
webhook_secret = os.environ.get("VERCEL_WEBHOOK_SECRET")

@app.post("/webhooks/vercel")
async def vercel_webhook(
    request: Request,
    x_vercel_signature: str = Header(None)
):
    if not x_vercel_signature:
        raise HTTPException(status_code=400, detail="Missing x-vercel-signature header")

    # Get raw body
    body = await request.body()

    # Compute expected signature
    expected_signature = hmac.new(
        webhook_secret.encode(),
        body,
        hashlib.sha1
    ).hexdigest()

    # Timing-safe comparison
    if not hmac.compare_digest(x_vercel_signature, expected_signature):
        raise HTTPException(status_code=400, detail="Invalid signature")

    # Parse verified payload
    event = await request.json()

    # Handle event
    if event["type"] == "deployment.created":
        print(f"Deployment created: {event['payload']['deployment']['id']}")
    elif event["type"] == "deployment.succeeded":
        print(f"Deployment succeeded: {event['payload']['deployment']['id']}")
    # ... handle other events

    return {"received": True}

テスト付きの完全な動作例については、以下を参照してください。

一般的なイベントタイプ

イベントトリガーされるタイミング一般的な用途
deployment.created新しいデプロイが開始されたときデプロイの監視を開始する、チームに通知する
deployment.succeededデプロイが正常に完了したときステータスを更新する、デプロイ後のタスクを実行する
deployment.errorデプロイが失敗したときチームに警告する、ロールバック処理を行う
deployment.canceledデプロイがキャンセルされたときリソースをクリーンアップする
project.created新しいプロジェクトが作成されたとき監視を設定する、リソースを構成する
project.removedプロジェクトが削除されたとき外部リソースをクリーンアップする
domain.createdドメインが追加されたときDNS、SSL 設定を更新する

イベントの完全な一覧については、references/overview.md を参照してください。

環境変数

# Required
VERCEL_WEBHOOK_SECRET=your_webhook_secret_from_dashboard

# Optional (for API calls)
VERCEL_TOKEN=your_vercel_api_token

ローカル開発

ローカルで Webhook をテストするには、Hookdeck CLI をインストールしてください。

続いて、トンネルを起動します。

npx hookdeck-cli listen 3000 vercel --path /webhooks/vercel

アカウントは不要です。リクエストを確認できるローカルトンネルと Web UI を利用できます。

リファレンス資料

推奨:webhook-handler-patterns

本番環境に対応した Webhook 処理について学ぶには、webhook-handler-patterns スキルもインストールしてください。

関連スキル

コメント