# General Translation Platform: Webhooks
URL: https://generaltranslation.com/ja/docs/platform/dashboard/reference/webhooks.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: Webhook エンドポイントを設定し、署名を検証して、General Translation からの翻訳イベントを処理します。Webhook のリファレンス。

Webhooks は、署名付きの HTTP POST リクエストとして翻訳イベントをバックエンドに送信します。ファイルやジョブが変更されたときに、独自のワークフローを実行するために使用できます。

*注: Webhooks には Team または Enterprise プランが必要です。*

## Webhook を作成する [#create-webhook]

1. **Organization &gt; Developer &gt; Webhooks** に移動します。
2. **Add endpoint** をクリックします。
3. イベントを受信するエンドポイント URL を入力します。URL には HTTPS を使用する必要があります。
4. 購読するイベントタイプを選択します。
5. **Create endpoint** をクリックします。

エンドポイントを作成したら、Webhook 詳細ページを開いて signing secret をコピーします。このシークレットを使用して、受信したリクエストが General Translation から送信されたものであることを検証します。

Organization ごとに作成できる **Webhook エンドポイント** は最大 **5 件** です。

## イベントタイプ [#event-types]

各エンドポイントは、1つ以上のイベントタイプを購読できます。購読設定は webhook 詳細ページから更新できます。

* `translated_file.completed` は、翻訳済みファイルの準備が完了し、ダウンロード可能になったときに発火します。
* `translated_file.edited` は、翻訳済みファイルが翻訳エディターでユーザーによって手動で編集されたときに発火します。
* `translation_job.completed` は、翻訳ジョブが完了したときに発火します。

## ペイロード形式 [#payload-format]

各 webhook 配信は、JSON ボディを含む HTTP POST リクエストです。

```json
{
  "id": "evt_xxx",
  "type": "translated_file.completed",
  "created_at": "2026-04-30T12:00:00.000Z",
  "api_version": "2026-03-06.v1",
  "data": {
    "object": {
      "id": "file_xxx",
      "org_id": "org_xxx",
      "project_id": "project_xxx",
      "branch_id": "branch_xxx",
      "source_file_id": "src_xxx",
      "file_id": "file_xxx",
      "version_id": "ver_xxx",
      "locale": "fr",
      "file_format": "json",
      "data_format": null,
      "completed_at": "2026-04-30T12:00:00.000Z"
    }
  }
}
```

最上位の `id` は、配信の重複を排除するために使える、安定したイベント識別子です。

## 署名を検証する [#verify-signatures]

すべての webhook リクエストには、3 つのヘッダーが含まれます。

* `webhook-id` は、`evt_xxx` のようなイベント ID です。
* `webhook-timestamp` は、リクエストが送信された時刻を示す、秒単位の Unix タイムスタンプです。
* `webhook-signature` は、`v1,<base64-hmac>` 形式の署名です。

この署名は、[Standard Webhooks](https://www.standardwebhooks.com/) の規約に従っています。

リクエストを検証するには:

1. `{webhook-id}.{webhook-timestamp}.{raw request body}` を連結します。
2. `whsec_` プレフィックスを取り除いてから secret を Base64 デコードし、署名キーを取得します。
3. デコードした署名キーを使って、連結した文字列の HMAC-SHA256 を計算します。
4. 結果を Base64 エンコードします。
5. `v1,` プレフィックスの後ろにある署名値と比較します。
6. リプレイ攻撃を防ぐため、タイムスタンプが現在時刻から 5 分以内であることを確認します。

### 例: Node.js

```js
import crypto from "crypto";

function verifyWebhook(payload, headers, secret) {
  const msgId = headers["webhook-id"];
  const timestamp = headers["webhook-timestamp"];
  const signature = headers["webhook-signature"];

  const now = Math.floor(Date.now() / 1000);
  if (Math.abs(now - parseInt(timestamp)) > 300) {
    throw new Error("Timestamp too old");
  }

  const signingKey = Buffer.from(secret.replace("whsec_", ""), "base64");
  const signedContent = `${msgId}.${timestamp}.${payload}`;
  const expected = crypto
    .createHmac("sha256", signingKey)
    .update(signedContent)
    .digest("base64");

  const received = signature.split(",")[1];
  if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received))) {
    throw new Error("Invalid signature");
  }

  return JSON.parse(payload);
}
```

ご利用の言語向けの[Standard Webhooks](https://www.standardwebhooks.com/)ライブラリを使うこともでき、検証は自動的に行われます。

## 再試行と配信を扱う [#handle-retries-delivery]

webhook では **at-least-once delivery** が使われます。

エンドポイントが 10 秒以内に `2xx` レスポンスを返さない場合、配信は指数バックオフで **最大 10 回** まで再試行されます。

ダッシュボードの **Organization &gt; Developer &gt; Webhook Events** から、失敗した配信を手動で再試行できます。リストでイベントを選択し、**配信試行** の下にある行にカーソルを合わせて **Retry** をクリックします。

失敗した試行を展開して、**Error** フィールドを確認します。`2xx` 以外のレスポンスでは、エラーに HTTP ステータスが含まれ、エンドポイントのレスポンス body のサニタイズ済みの抜粋が含まれる場合があります。General Translation はレスポンスから最大 4,096 バイトを読み取り、診断用に最大 500 文字を保存します。

## イベントと配信試行を表示する [#view-events]

1. **Organization &gt; Developer &gt; Webhook Events** に移動します。
2. Organization でトリガーされたイベントの一覧からイベントを選択します。
3. そのイベントの **配信試行**を確認します。

各試行には、ステータス、エンドポイント URL、タイムスタンプが表示されます。結果が記録されている試行を展開すると、**Automatic** または **Manual** のいずれか、往復レイテンシー、接続エラーやタイムアウトなどの転送失敗に関する **Error** の概要を確認できます。結果が記録されていない保留中の試行は展開できません。

自動再試行は **Automatic** 配信として表示されます。ダッシュボード から開始した再試行は **Manual** として表示されます。

## 重複するイベントを処理する [#handle-duplicate-events]

イベント配信は少なくとも1回は行われるため、エンドポイントで同じイベントを複数回受信することがあります。重複を除外するには、ペイロード内の `id` フィールドを使用してください。

```js
app.post("/webhooks/gt", (req, res) => {
  const eventId = req.body.id;

  if (alreadyProcessed(eventId)) {
    return res.status(200).send("OK");
  }

  // イベントを処理する...
  markProcessed(eventId);
  res.status(200).send("OK");
});
```

## エンドポイントを管理する [#manage-endpoints]

**Organization &gt; Developer &gt; Webhooks** では、次の操作を行えます。

* エンドポイントを削除せずに有効化または無効化する
* 購読中のイベントタイプを更新する
* signing secret を表示する
* エンドポイントを削除する

**Organization &gt; Developer &gt; Webhook Events** では、配信履歴を表示し、各配信試行の詳細を確認し、失敗した配信を再試行できます。

## ベストプラクティス [#best-practices]

* まず `2xx` レスポンスをすぐに返し、その後でイベントを非同期に処理します。
* ペイロードを信頼する前に、`webhook-signature` ヘッダーを検証します。
* 処理済みのイベント ID を保存し、重複するものはスキップします。
* 本番環境の webhook エンドポイントでは HTTPS を使用します。
* 継続的な配信失敗がないか、**Webhooks &gt; Events** を監視します。

## 権限 [#permissions]

Webhookエンドポイントを管理し、配信を再試行するには、`org:webhooks:write` 権限が必要です。

イベントと配信試行を閲覧するには、`org:webhooks:read` 権限が必要です。

デフォルトでは、**Admin** ロールと **Developer** ロールに両方の権限が付与されています (詳しくは、[ロールと権限](/docs/platform/dashboard/reference/roles-and-permissions)を参照してください) 。

## Sitemap

See the full [sitemap](https://generaltranslation.com/sitemap.md) for all pages.
