genko.meDocs
公開と連携

Webhook

通知先の登録、署名検証、イベント、テスト送信、配送失敗への対処。

Webhookは、コンテンツの変更を外部のURLへHTTP POSTで通知する機能です。サイトの再ビルドやキャッシュ再検証に使います。記事本文を届けるのではなく、変更を知らせる小さなJSONを送ります。

設定にはオーナー権限と、外部からアクセスできるHTTPSの受信URLが必要です。

1. 通知先を準備する

ホスティング先のデプロイフック、または自分のアプリの受信処理を用意します。Next.jsの再検証に使う場合は、プラグインnextRevalidateを利用できます。

自前の受信処理では、通知を受けて何を更新するか決めます。記事が削除された場合や、entryがないテスト通知も扱えるようにしてください。

2. Webhookを登録する

  1. 対象APIの設定画面を開きます。
  2. Webhookの追加から、名前・通知先URLを入力します。
  3. 署名検証する場合はシークレットを設定します。
  4. 保存し、有効になっていることを確認します。

1つのAPIにつき5件まで登録できます。イベントごとの選択はなく、登録したAPIの各イベントを通知します。不要なイベントは受信側で判定します。一時停止するときは無効に切り替えます。

シークレットは受信側の設定にも同じ値を登録します。APIキーとは別の値です。省略すると署名ヘッダーは送られません。

通知先はHTTPSのみです。localhost、プライベートIP、リンクローカルIP、.local.internalなどへの通知はできません。リダイレクトも追跡しないため、最終的な受信URLを設定してください。

3. テスト送信する

一覧のテスト送信を実行し、受信先のログと送信結果を確認します。2xxが返れば配送成功です。テストではeventwebhook.testentrynullになります。

テスト送信は、過去に失敗したイベントの再送ではありません。 実際の記事更新の動作確認には、対象記事を保存して受信側まで確認してください。

イベント

イベント発生する操作
entry.created新規保存。下書きの作成も含む
entry.updated既存記事の保存、手動の公開状態変更、履歴の復元など
entry.deletedコンテンツの削除
entry.published予約公開を定期処理で確定
entry.unpublished日時による公開終了を定期処理で確定
webhook.testテスト送信

手動で「公開」にして保存したときは、作成/更新イベントです。公開に関する処理をentry.publishedだけに限定すると、手動公開を取りこぼします。また、公開から下書きへの変更では、entry.updatedの新しい状態がdraftになるため、古い公開ページの無効化も必要です。

ペイロードとヘッダー

{
  "event": "entry.updated",
  "workspace": "your-workspace",
  "api": "blog",
  "entry": { "id": "abcDEF123456", "status": "published" },
  "triggeredAt": "2026-09-01T01:00:00.000Z"
}

entry.statusdraftpublishedscheduledclosedです。削除通知には削除前の状態が入ります。本文が必要なら、必要なタイミングで配信APIから取得します。

ヘッダー
content-typeapplication/json
user-agentgenko-webhook/1.0
x-genko-eventイベント名
x-genko-signatureシークレット設定時のみ。sha256=に続くHMAC-SHA256の16進文字列

署名を検証する

次はWeb標準のRequest/Responseを使う受信処理の例です。署名はJSONへ変換する前の、生の本文に対して確認します。

import { verifyGenkoSignature } from "@genko-me/sdk";

export async function POST(request: Request) {
  const secret = process.env.GENKO_WEBHOOK_SECRET;
  if (!secret) return new Response("Webhook secret is not configured", { status: 500 });

  const rawBody = await request.text();
  const valid = await verifyGenkoSignature({
    secret,
    rawBody,
    signatureHeader: request.headers.get("x-genko-signature"),
  });
  if (!valid) return new Response("Invalid signature", { status: 401 });

  const payload = JSON.parse(rawBody);
  // 利用するworkspace・api・eventと、必要な値の形を検証してから処理します。
  return Response.json({ received: true, event: payload.event });
}

この例は受信確認までです。実際には再検証や処理キューへの登録など、必要な処理を追加します。重い処理を同期で待たず、同じ更新を繰り返し処理しても破綻しない設計にしてください。

配送の制限と失敗時

タイムアウトは10秒で、自動リトライはありません。管理画面で直近の結果を確認し、受信先のログと照合します。

結果確認すること
301/302などリダイレクト先の最終URLを登録しているか
401シークレットが一致するか。生の本文で検証しているか
404受信ルートが本番へデプロイされているか
タイムアウト10秒以内に応答できるか
成功だが表示が古い受信後の再ビルド・再検証対象が正しいか

失敗した更新を取り戻す場合は、受信側で最新データを取り直す、再ビルドを手動実行するなどの方法を用意してください。テスト送信の成功だけでは、失敗した処理を復旧したことにはなりません。

最終更新: 2026年9月5日

目次