メインコンテンツへスキップ
このガイドでは、複数の言語でのコード例と本番環境での推奨事項を含め、信頼性の高い Webhook ハンドラーの構築方法を説明します。

TypeScript SDK の使用

TypeScript SDKv0.2.0+)を使用する場合、SDK は型付きペイロードとヘルパー関数を提供し、イベント解析とステータスチェックを処理します。
import {
  parseWebhookEvent,
  isAuthentic,
  isCounterfeit,
  needsResubmission,
  isCancelled,
} from 'legitmark';

app.post('/webhooks/legitmark', express.json(), (req, res) => {
  const event = parseWebhookEvent(req.body);

  if (isAuthentic(event)) {
    markItemAsAuthentic(event.reference_id);
  } else if (isCounterfeit(event)) {
    flagItem(event.reference_id);
  } else if (needsResubmission(event)) {
    requestNewPhotos(event.reference_id, event.sides);
  } else if (isCancelled(event)) {
    closeCase(event.sr_uuid);
  }

  res.status(200).send('OK');
});
parseWebhookEvent() はペイロードの構造を検証し、型付きの LegitmarkWebhookEvent を返します。ヘルパー関数は特定のステータスの組み合わせをチェックします:
ヘルパーtrue を返す条件
isAuthentic(event)COMPLETE + APPROVED — 商品は本物
isCounterfeit(event)COMPLETE + REJECTED — 商品は本物ではない
isCancelled(event)CANCELLED — リクエストがキャンセルされた
needsResubmission(event)media_rejected — 画像の再アップロードが必要
isQcApproved(event)QC + APPROVED — 写真が品質審査を通過
isAuthenticationInProgress(event)UNDERWAY + ASSIGNED — 鑑定士が作業中

基本ハンドラー

TypeScript SDK を使用しない場合、以下は複数の言語での例です。
app.post('/webhooks/legitmark', express.json(), (req, res) => {
  const event = req.body;

  switch (event.event_type) {
    case 'state_change':
      if (event.state.primary === 'COMPLETE') {
        updateAuthResult(event.reference_id, event.state.supplement);
      }
      break;

    case 'media_rejected':
      event.sides.forEach(side => {
        flagImageForReupload(event.reference_id, side.side, side.reason);
      });
      break;

    case 'invalidate_sr':
      cancelItem(event.reference_id, event.invalidation_reason.message);
      break;
  }

  res.status(200).send('OK');
});

ベストプラクティス

Webhook をできるだけ早く確認応答してください。処理ロジックが複雑な場合や外部サービスを呼び出す場合は、タスクをキューに入れてから 200 を返してください。
同じイベントを複数回受信する可能性があります。Payload フィールドから重複排除キーを構築してください:
  • state_changesr_uuid + state.primary + state.supplement(同じ SR が複数のステータス変更を発行します)
  • media_rejectedsr_uuid + event_type
  • invalidate_srsr_uuid + event_type
本番環境では、永続ストア(データベース、Redis)を使用して重複排除を行ってください。
デバッグのために完全な Webhook ペイロードを保存してください。問題が発生した場合、元のデータがあると診断が大幅に早くなります。
認識されない event_type 値を持つ Webhook を拒否しないでください。将来、新しいイベントタイプが追加される可能性があります。すべてのイベントに対して 200 を返してください。

まとめ

Webhook ハンドラーは以下を満たす必要があります:
  • HTTPS エンドポイント を使用し、30 秒以内に 200 を返す
  • 冪等性 を保証する — Payload フィールドを使用して重複排除する(sr_uuid だけでは不十分、1 つの SR が複数のイベントを発行するため)
  • 未知のイベントタイプを受け入れる — エラーにしない(新しいイベントが追加される可能性あり)
  • 複雑なロジックは 非同期で処理 してタイムアウトを回避する