Webhook 受信
Speakeasy は purelovers.com からの Webhook を Tap Gateway で受信し、データ同期やイベント処理を行います。
Webhook エンドポイント
Section titled “Webhook エンドポイント”POST /api/v1/webhooks/pureloversContent-Type: application/jsonX-Webhook-Signature: {HMAC-SHA256 署名}HMAC-SHA256
Section titled “HMAC-SHA256”Webhook ペイロードの改ざんを防止するため、HMAC-SHA256 署名を検証します。
const computedSignature = await crypto.subtle.sign( 'HMAC', await crypto.subtle.importKey( 'raw', new TextEncoder().encode(env.WEBHOOK_SECRET), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign'] ), new TextEncoder().encode(rawBody));
// タイミングセーフ比較(タイミング攻撃防止)const isValid = timingSafeEqual(computedSignature, receivedSignature);イベント種別
Section titled “イベント種別”| イベント | 説明 | 処理内容 |
|---|---|---|
shop.updated | 店舗情報の更新 | 店舗キャッシュの無効化 |
girl.schedule_changed | スタッフスケジュール変更 | チャットルーム通知 |
girl.created | スタッフ追加 | キャスト同期 |
girl.deleted | スタッフ削除 | キャスト同期 |
review.posted | レビュー投稿 | レビュー通知 |
user.updated | ユーザー情報更新 | contact_purelovers 更新 |
イベント処理フロー
Section titled “イベント処理フロー”Webhook ペイロード
Section titled “Webhook ペイロード”{ readonly event: string; // イベント種別 readonly data: unknown; // イベントデータ readonly timestamp: string; // ISO 8601 readonly webhookId: string; // Webhook ID}shop.updated の例
Section titled “shop.updated の例”{ "event": "shop.updated", "data": { "shop_id": "shop123", "name": "店舗名", "updated_fields": ["name", "address"] }, "timestamp": "2024-01-15T10:00:00Z"}user.updated の例
Section titled “user.updated の例”{ "event": "user.updated", "data": { "user_id": "user123", "shop_id": "shop456", "display_name": "田中太郎", "profile_image_url": "https://..." }, "timestamp": "2024-01-15T10:00:00Z"}セキュリティ
Section titled “セキュリティ”| 項目 | 実装 |
|---|---|
| 認証 | HMAC-SHA256 署名検証 |
| タイミング攻撃防止 | 定数時間比較(timingSafeEqual) |
| 共有シークレット | WEBHOOK_SECRET 環境変数 |
| HTTPS | Cloudflare Workers で強制 |
エラーハンドリング
Section titled “エラーハンドリング”| HTTP ステータス | 状況 | 対応 |
|---|---|---|
| 200 | 処理成功 | - |
| 401 | 署名検証失敗 | purelovers 側でリトライ |
| 500 | サーバーエラー | purelovers 側でリトライ |
- purelovers 連携 - セッション発行・データ同期
- Tap Gateway - ゲートウェイアーキテクチャ