TicketWave Logo
Webhooks

概要

署名付き HTTP リクエストとして、TicketWave のイベントを自分のアプリケーションで受け取ります。

Webhooks

Webhook とは、TicketWave があなたに送信する HTTP リクエストです。サーバーで何かが起こるたびに — チケットが開かれたり、メンバーがブラックリストに追加されたりすると — TicketWave はあなたが管理する URL に JSON 本文を POST します。

これが Log Channels との違いです。ログチャンネルは人が読むために Discord に embed を書き込みますが、webhook は生のイベントをあなたのコードに渡します。

Webhook は プレミアム 機能です。プレミアムがない場合、エンドポイントは作成できず、イベントも配信されません。

エンドポイントを作成する

エンドポイントページを開く

サーバーダッシュボード → WebhooksEndpoints

エンドポイントを追加する

Add Endpoint をクリックし、次の 2 つの項目を入力します。

FieldDescription
Endpoint URLリクエストを受け取る https:// の URL
Event Typesこのエンドポイントが受け取るイベント

エンドポイントは、チェックした種類のイベントだけを受け取ります。何も選択しないことはできません。少なくとも 1 つ選んでください。

署名シークレットをコピーする

エンドポイントが作成された瞬間に、TicketWave が署名シークレット (whsec_…) を生成します。エンドポイント一覧を開き、目のアイコンで表示してから、アプリケーションの設定にコピーしてください。

シークレットはパスワードのように扱ってください。これを持っている人は、署名チェックを通過する偽のリクエストを作れます。リポジトリには入れず、環境変数に保存してください。

テストイベントを送信する

エンドポイント行にある Send test event ボタン(紙飛行機)を使います。これにより、"test": true を含む本物の、完全に署名されたリクエストが送信されるので、実際のチケットが依存する前に受信側が正しく動くか確認できます。

結果は他の配信と同じように Webhooks の履歴に表示されます。

エンドポイントの要件

RequirementDetail
Schemehttps:// のみ — http:// は拒否されます
Host公開解決可能である必要があります。プライベート、ループバック、リンクローカル、CGNAT のアドレスは拒否されます
Response2xx のステータスなら成功とみなされます
Timeout応答まで 10 秒 あります
Redirects追従しません。3xx は失敗扱いです
Limitサーバーごとに最大 5 個のエンドポイント

ホストチェックは、エンドポイントを保存するときと、各配信の直前の両方で行われます。そのため、後から内部アドレスを解決するようになったドメインには配信されなくなります。

リクエスト

すべての配信は JSON 本文を持つ POST です。

Headers

HeaderExampleMeaning
Content-Typeapplication/json常に JSON
User-AgentTicketWave-Webhooks/1.0.5送信した bot のバージョン
X-TicketWave-Eventticket.createdイベントタイプ
X-TicketWave-Deliverywh_3f2a…この配信の一意な ID
X-TicketWave-Timestamp1786224191Unix 秒、署名の一部
X-TicketWave-Signaturesha256=9f86d0…リクエストの HMAC

Body

すべてのペイロードは同じエンベロープを使います。data だけがイベントタイプごとに異なります。

{
  "event": "ticket.created",
  "timestamp": "2026-08-26T08:23:11.000Z",
  "guild_id": "123456789012345678",
  "data": {
    "ticket_id": "ticket-1042",
    "ticket_num_id": 1042,
    "channel_id": "998877665544332211",
    "category": "🤖 Support",
    "user": { "id": "987654321098765432", "username": "Luna" },
    "created_at": "2026-08-26T08:23:11.000Z"
  }
}

すべての種類の data オブジェクトについては Event Reference を参照してください。

署名の検証

あなたのエンドポイント URL を見つけた人は、そこに POST リクエストを送れます。署名は、それが本物の TicketWave 配信なのか、偽造されたものなのかを見分けるためのものです。

必ず検証してください。 検証していないエンドポイントがシステム内で何かを作成したり閉じたりできるなら、それは開いた扉と同じです。

署名の作り方

TicketWave はタイムスタンプと 生の リクエスト本文をドットで連結し、その結果に対して HMAC-SHA256 をあなたのエンドポイントシークレットで実行します。

signed_payload = X-TicketWave-Timestamp + "." + raw_request_body
signature      = HMAC_SHA256(signed_payload, your_endpoint_secret)

ヘッダーには、そのダイジェストが hex エンコードされ、プレフィックス付きで入ります: sha256=<digest>

受信側で行うこと

生の本文を読み取る。 受け取った正確なバイト列と照合してください。フレームワークが先に JSON をパースしてから再シリアライズすると、キーの順序や空白が変わり、ダイジェストが一致しなくなります。

HMAC を再計算するtimestamp + "." + rawBody に対して、あなたのシークレットを使います。

定数時間で比較する(Node なら crypto.timingSafeEqual)。単純な === はタイミング情報を漏らします。

タイムスタンプを確認する。 直近のものかを見てください。5 分程度の許容幅がよいデフォルトです。タイムスタンプは署名済みペイロードの中にあるため、攻撃者が古いリクエストに新しいタイムスタンプを付けて再送することはできません。

完全な実装は Example Server のページにあります。

リトライ

失敗した配信は自動的に再試行されます。

Attempts3 回(最初の試行 + 2 回の再試行)
Backoff1 秒、その後 5 秒
Retried onネットワークエラー、タイムアウト、408429、および任意の 5xx
Not retried onそれ以外のすべての 4xx — これらは、エンドポイントが意図的にリクエストを拒否したことを意味します

リトライがあるため、エンドポイントは 同じイベントを 2 回 受け取ることがあります。X-TicketWave-Delivery を冪等性キーとして使ってください。処理済みの ID を記録し、重複は無視します。

配信は 順序保証されません。2 つのチケットが同時に作成された場合、リクエストはどちらの順番でも届く可能性があります。順序が重要なら、本文の timestamp フィールドを使ってください。

配信履歴

ダッシュボードの Webhooks ページには、すべての配信がステータス、レスポンスコード、所要時間、試行回数とともに一覧表示されます。行を開くと、送信された正確なリクエストペイロードと、サーバーが返したレスポンスを確認できます。

失敗した配信は、詳細ページから Retry Webhook で再送できます。元のペイロードを同じエンドポイントにもう一度送信し、新しい配信として記録します。

履歴は 30 日間 保存され、その後自動的に削除されます。

トラブルシューティング

ProblemFix
エンドポイントを保存できないURL は https:// で、公開アドレスに解決される必要があります
すべてがレスポンスコードなしで失敗として表示されるリクエストがそもそも届いていません — タイムアウト、DNS 失敗、または接続拒否です
署名が一度も一致しないパース後の本文をハッシュしているか、timestamp + "." のプレフィックスを忘れています
しばらくすると配信が止まるホストが 4xx を返し始めていないか確認してください — これらは再試行されません
イベントが届かないエンドポイントがその種類を購読していないか、サーバーのプレミアムが失われています
重複イベントリトライ時には想定されます — X-TicketWave-Delivery で重複排除してください

次のステップ

How is this guide?