ウェブフック (Webhook)
Webhook の使い方
アプリが Gency 内で発生するイベントをリアルタイムで受信できるように、ウェブフックを登録できます。
ウェブフックの登録
API センターで 新しい Webhook を作成 をクリックし、次の項目を入力します。
- 名前 (必須、最大100文字): ウェブフックを識別できる名前
- URL (必須、HTTPS のみ許可、最大500文字): イベント発生時に POST リクエストを送るエンドポイント
- 購読イベント : 受信するイベントタイプをチェックボックスで選択
サポートするイベントタイプ
| イベント | 説明 |
|---|---|
product.created | 商品が作成された |
product.deleted | 商品が削除された |
product.pending_review | 検収待ち状態に変更された |
product.in_review | 検収進行中に変更された |
product.review_completed | 検収が完了した |
product.creation_failed | 商品の作成に失敗した |
イベントペイロード
イベント発生時に、登録された URL へ次の形式の POST リクエストが送信されます。event フィールドは共通で、data の内部構造はイベントタイプによって異なります。
product.pending_review / product.in_review / product.review_completed
商品の検収状態が変更されたときに送信されます。
{
"event": "product.review_completed",
"data": {
"products": [
{
"workspaceId": "01HABC...",
"productId": "01HXYZ...",
"projectId": "my-project-01",
"productName": "겨울 패딩 자켓",
"status": "REVIEW_COMPLETE",
"category": "OUTER",
"productType": "FASHION",
"createdId": "01HUSR...",
"createdAt": "2025-01-01T00:00:00+09:00"
}
]
}
}
| フィールド | タイプ | 説明 |
|---|---|---|
products | Array | 状態が変更された商品の一覧 |
products[].workspaceId | String | ワークスペース ID |
products[].productId | String | 商品 ID |
products[].projectId | String | 管理名 |
products[].productName | String | 商品名 |
products[].status | String | 変更された状態 (BEFORE_REVIEW: 検収前, IN_REVIEW: 検収中, REVIEW_COMPLETE: 検収完了, CREATION_FAILED: 生成失敗) |
products[].category | String | カテゴリ |
products[].productType | String | 商品タイプ (FASHION, JEWELRY) |
products[].createdId | String | 作成者 ID |
products[].createdAt | String | 作成日時 (ISO 8601) |
product.created
商品が作成されたときに送信されます。
{
"event": "product.created",
"data": {
"products": [
{
"workspaceId": "01HABC...",
"productId": "01HXYZ...",
"projectId": "my-project-01",
"productName": "겨울 패딩 자켓",
"status": "BEFORE_REVIEW",
"category": "OUTER",
"productType": "FASHION",
"createdId": "01HUSR...",
"createdAt": "2025-01-01T00:00:00+09:00"
}
]
}
}
product.creation_failed
商品の作成に失敗したときに送信されます。
{
"event": "product.creation_failed",
"data": {
"products": [
{
"workspaceId": "01HABC...",
"productId": "01HXYZ...",
"projectId": "my-project-01",
"productName": "겨울 패딩 자켓",
"status": "CREATION_FAILED",
"category": "OUTER",
"productType": "FASHION",
"createdId": "01HUSR...",
"createdAt": "2025-01-01T00:00:00+09:00"
}
]
}
}
ペイロード構造は状態変更イベントと同じです。status が PRODUCT_STATUS_05 (生成失敗) に設定されます。
product.deleted
商品が削除されたときに送信されます。
{
"event": "product.deleted",
"data": {
"products": [
{
"workspaceId": "01HABC...",
"productId": "01HXYZ...",
"productName": "겨울 패딩 자켓"
}
]
}
}
| フィールド | タイプ | 説明 |
|---|---|---|
products | Array | 削除された商品の一覧 |
products[].workspaceId | String | ワークスペース ID |
products[].productId | String | 商品 ID |
products[].productName | String | 商品名 |
リトライポリシー
ウェブフックの送信に失敗すると、システムが自動的にリトライします。初回送信を含めて最大 5回 (初回1回 + リトライ4回) 試行し、指数バックオフ 方式で間隔が広がっていきます。
- 成功基準: HTTP レスポンスコード
200 ~ 299 - 失敗処理: 上記範囲外のレスポンスコード、タイムアウト(30秒)、ネットワークエラーなどはすべて失敗とみなされます。
- 5回のリトライまですべて失敗した場合、その配送は 最終失敗 として処理されます。
- すべての試行に対する配送記録(HTTP ステータスコード、レスポンス時間、エラーメッセージ)は 30日間 保管されます。
ウェブフックの登録制限
マスターあたり最大 10個 のウェブフックを登録できます。削除されたウェブフックは個数に含まれないため、上限に達した場合は使用していないウェブフックを削除すれば新たに登録できます。
署名検証 (任意)
ウェブフック作成時に Signing Secret が自動発行されます (whsec_{32자 랜덤문자열} 形式)。署名検証は必須ではありませんが、偽造されたリクエストを防ぐため、本番環境では検証を推奨します。
各ウェブフックリクエストには次のヘッダーが含まれます。
| ヘッダー | 説明 |
|---|---|
X-Webhook-Signature | sha256={HMAC-SHA256 서명값} |
X-Webhook-Timestamp | リクエスト送信時刻 (Unix timestamp) |
| Content-Type | application/json |
検証方法:
X-Webhook-Timestampヘッダーからタイムスタンプを抽出します。{타임스탬프}.{요청 body}形式で署名対象のメッセージを作成します。- Signing Secret をキーとして使用し、HMAC-SHA256 署名を計算します。
- 計算された署名と
X-Webhook-Signatureヘッダーの値を比較します。
// 검증 예시 (Java)
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
public boolean verifyWebhook(String payload, String timestamp, String signature, String secret) {
String message = timestamp + "." + payload;
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secret.getBytes(), "HmacSHA256"));
byte[] hash = mac.doFinal(message.getBytes());
StringBuilder hex = new StringBuilder();
for (byte b : hash) {
hex.append(String.format("%02x", b));
}
String expected = "sha256=" + hex.toString();
return MessageDigest.isEqual(expected.getBytes(), signature.getBytes());
}
Secret 再発行
Secret 再発行 ボタンをクリックすると新しい Signing Secret が発行されます。既存のシークレットは即座に無効化されるため、新しいシークレットをサーバーに反映してから使用する必要があります。
状態管理
ウェブフックは次の状態を持つことができます。
| 状態 | 説明 |
|---|---|
ACTIVE | イベント発生時に正常に送信されます |
INACTIVE | イベント送信が一時停止されます |
一時的にウェブフックの受信を停止したい場合は無効化でき、削除すると完全に除去されます。