---
lang: ja
path: user-guide/webhook/specification
labels: ユーザーガイド/Webhook/仕様
metaTitle: 仕様 | Webhook ｜ ユーザーガイド ｜ SkyWay（スカイウェイ）
---

## 検証リクエスト

検証リクエストは Webhook 機能にイベント送信先となるユーザーのサーバーのエンドポイントを設定するにあたって、Webhook 機能とユーザーのサーバーの双方でお互いが正当であることを確かめるための仕組みです。

ユーザーのサーバーは Webhook 機能から送信される検証リクエストに対して適切なレスポンスを返す必要があります。

検証リクエストは SkyWay コンソールで Webhook の設定を行うと送信されます。

そのため、SkyWay コンソールの操作前にユーザーのサーバーを Webhook 機能からアクセスできるように公開する必要があります。

検証リクエストのフォーマットは次の通りです。

| **項目**                     | **値**                                            |
| ---------------------------- | ------------------------------------------------- |
| HTTP メソッド                | `POST`                                            |

| **項目**                     | **値**                                            |
| ---------------------------- | ------------------------------------------------- |
| ヘッダー                     |                                                   |
| `Content-Type`               | `application/json`                                |
| `X-SkyWay-Request-Timestamp` | `文字列(秒)`                                      |
| `X-SkyWay-Signature`         | `文字列(16進数)`                                  |
| `User-Agent`                 | `SkyWay-Webhook/1.0.0 (+https://skyway.ntt.com/)` |

| **項目**                     | **値**                                            |
| ---------------------------- | ------------------------------------------------- |
| ボディ                       |                                                   |
| `type`                       | `WEBHOOK_URL_VERIFICATION`                        |
| `appId`                      | `文字列(uuid)`                                    |
| `timestamp`                  | `文字列(UTC/ISO 8601 形式)`                       |
| `data`                       | `{ "challenge": <uuid> }`                         |
| `schemaVersion`              | `1`                                               |

**必須**

ユーザーのサーバーは次のフォーマットのレスポンスを 3 秒以内に行う必要があります。

| **項目**         | **値** | 補足                                                                            |
| ---------------- | ------ | ------------------------------------------------------------------------------- |
| ステータスコード | 2xx    | 200 OK を推奨                                                                   |
| ボディ           | 文字列 | プレーンテキストで `challenge` と 完全一致 する文字列（UTF-8 エンコーディング） |
| ヘッダー         | 任意   | 無視される                                                                      |

ユーザーのサーバーから適切なレスポンスが返されない場合（タイムアウト、エラーステータス、challenge の不一致など）、SkyWay Console での Webhook 設定が失敗します。この場合、サーバー側の実装を修正した後、再度 SkyWay Console から設定を行ってください。

**推奨**

署名を生成し、両者が一致するかどうかを確認することで検証リクエストの送信元が本物の SkyWay の Webhook 機能であることを確かめることができます。これを署名の検証と呼びます。

検証リクエストの送信元が本物の SkyWay の Webhook 機能であることを確かめるために、`X-SkyWay-Signature` ヘッダーの値と、リクエストのボディを使って生成した署名が一致することを確認してください。
これにより、検証リクエストの送信元が本物の SkyWay の Webhook 機能であることを確認できます。

詳細な検証方法については[署名の検証](/ja/docs/user-guide/webhook/development-guide/#2) をご参照ください。

## Webhook リクエスト

Webhook 機能からユーザーのサーバーにイベントを送信するリクエストのフォーマットは次の通りです。

| **項目**                     | **値**                                            |
| ---------------------------- | ------------------------------------------------- |
| HTTP メソッド                | `POST`                                            |
| ヘッダー                     |                                                   |
| `Content-Type`               | `application/json`                                |
| `X-SkyWay-Request-Timestamp` | `文字列(秒)`                                      |
| `X-SkyWay-Signature`         | `文字列(16進数)`                                  |
| `User-Agent`                 | `SkyWay-Webhook/1.0.0 (+https://skyway.ntt.com/)` |
| ボディ                       |                                                   |
| `type`                       | `文字列`                                          |
| `appId`                      | `文字列(uuid)`                                    |
| `timestamp`                  | `文字列`                                          |
| `data`                       | `文字列(JSONオブジェクト)`                        |
| `schemaVersion`              | `1`                                               |

**必須**

ユーザーのサーバは次のフォーマットのレスポンスを 3 秒以内に行う必要があります。

制限時間内にレスポンスが行われない場合、Webhook 機能はリクエストをリトライします。

| **項目**         | **値** | 補足                                                     |
| ---------------- | ------ | -------------------------------------------------------- |
| ステータスコード | 2xx    | 200 OK を推奨                                            |
| ボディ           | 任意   | 無視される。サイズが 1KiB を越えるとレスポンスに失敗する |
| ヘッダー         | 任意   | 無視される                                               |

**推奨**

検証リクエストと同様に送信元が本物の SkyWay の Webhook 機能であることを確かめるために、`X-SkyWay-Signature` ヘッダーの値と、リクエストのボディを使って生成した署名が一致することを確認してください。

また、リプレイ攻撃を防止するためにタイムスタンプを検証できます。

## 通知イベント

### Room のイベント

Room のイベントの type 名には「ROOM_」という接頭辞が付きます。

#### Room の作成

Room が作成された時に通知されるイベントです。

```ts
{
  type: "ROOM_CREATED";
  appId: string;
  data: {
    room: {
      id: string;
      name?: string;
      metadata?: string;
    };
  };
  timestamp: string;
}
```

#### Room のクローズ

Room がクローズされた時に通知されるイベントです。

type は `ROOM_CLOSED` で、type 以外 `ROOM_CREATED` と同じ形式です。

#### Member の入室

Room に入室した時に通知されるイベントです。

```ts
{
  type: "ROOM_MEMBER_JOINED";
  appId: string;
  data: {
    room: {
      id: string;
      name?: string;
      metadata?: string;
    };
    member: {
      id: string;
      name?: string;
      metadata?: string;
    };
  };
  timestamp: string;
}
```

#### Member の退室

Room から退室した時に通知されるイベントです。

```ts
{
  type: "ROOM_MEMBER_LEFT";
  appId: string;
  data: {
    room: {
      id: string;
      name?: string;
      metadata?: string;
      members: {
        id: string;
        name?: string;
      }[];
    };
    member: {
      id: string;
      name?: string;
      metadata?: string;
    };
  };
  timestamp: string;
}
```

#### Stream の Publish

Publication が Publish された時に通知されるイベントです。

```ts
{
  type: "ROOM_STREAM_PUBLISHED";
  appId: string;
  data: {
    room: {
      id: string;
      name?: string;
      metadata?: string;
    };
    publication: {
      id: string;
      publisher: {
        id: string;
        name?: string;
      };
      contentType: "AUDIO" | "VIDEO" | "DATA";
      type: "P2P" | "SFU";
      isEnabled: boolean;
      metadata?: string;
    };
  };
  timestamp: string;
}
```

#### Stream の Unpublish

Publication が Unpublish された時に通知されるイベントです。

type は `ROOM_STREAM_UNPUBLISHED` で、type 以外 `ROOM_STREAM_PUBLISHED` と同じ形式です。

#### Publication の Subscribe

Publication が Person に Subscribe された時に通知されるイベントです（Bot は通知対象外）。

```ts
{
  type: "ROOM_PUBLICATION_SUBSCRIBED";
  appId: string;
  data: {
    room: {
      id: string;
      name?: string;
      metadata?: string;
    };
    subscription: {
      id: string;
      publicationId: string;
      subscriber: {
        id: string;
        name?: string;
      };
    };
  };
  timestamp: string;
}
```

#### Publication の Unsubscribe

Publication が Person から Unsubscribe された時に通知されるイベントです（Bot は通知対象外）。

type は `ROOM_PUBLICATION_UNSUBSCRIBED` で、type 以外 `ROOM_PUBLICATION_SUBSCRIBED` と同じ形式です。

### 録音・録画のイベント

録音・録画のイベントの type 名には「RECORDING_」という接頭辞が付きます。

**録音・録画の開始**

録音・録画ファイルの作成を開始した時に次のような形式で通知されるイベントです。

[録音・録画可能な時間の制限](/ja/docs/user-guide/commons/quotas-and-limits/#106)の、録音・録画の最小時間を満たしたファイルのみがイベント通知の対象となります。

録音・録画を開始したファイルの状態の変化を追跡するために  `data.file.path` を識別子として利用できます。

```jsx
{
  type: "RECORDING_FILE_STARTED";
  appId: string;
  data: {
    session: {
      id: string;
      roomId: string;
    };
    file: {
      name: string;
      path: string;
      status: "RECORDING" | "SUCCEEDED" | "FAILED";
      errors: {
        detail: string;
        occurredAt: string;
      }[];
      type: "AUDIO" | "VIDEO" | "AUDIO_AND_VIDEO";
      createdAt: string;
      codecs: string[];
      duration: number;
      publisher: {
        name?: string;
        id: string;
      };
      publications: {
        id: string;
        publisher: {
          name?: string;
          id: string;
        };
        contentType: "AUDIO" | "VIDEO";
      }[];
    };
  };
  timestamp: string;
}
```

**録音・録画の完了**

録音・録画が正常に完了した時に通知されるイベントです。

type は `RECORDING_FILE_SUCCEEDED` で、type 以外 `RECORDING_FILE_STARTED` と同じ形式です。

**録音・録画の強制終了**

回復不能なエラーによって録音・録画が強制的に終了された時に通知されるイベントです。

type は `RECORDING_FILE_FAILED` で、type 以外 `RECORDING_FILE_STARTED` と同じ形式です。

録音・録画が強制終了された際の対処法については [エラーとなった場合の録音・録画ファイルの取得](/ja/docs/user-guide/recording/recording-development-guide/#192) を参考にしてください。

**録音・録画のエラーが発生**

すべてのエラーの発生時に通知されるイベントです。

type は `RECORDING_FILE_ERROR_OCCURRED` で、type 以外 `RECORDING_FILE_STARTED` と同じ形式です。

## Webhook の詳細仕様

### Webhook 機能のイベント通知のリトライについて

ユーザーのサーバーが一時的にイベントの通知ができない状況に対応するために Webhook 機能はイベント通知のリトライを行います。リトライの仕様は次の通りです。

- リトライ対象のステータスコード
  - 429
  - 500~599
- 最大試行時間: 3 日 (259200 秒)

最大試行時間の間にバックオフリトライします。

### 注意事項

**通知順序**

概ねイベントの発生時刻の通り通知されますが、完全な順序保証はされていません。

**重複通知**

ごく稀に内容の重複したイベントが通知されることがあります。

通知が重複することで致命的な事態が生じないように必要に応じて[対策](/ja/docs/user-guide/webhook/development-guide/#43)を講じる必要があります。

**イベント通知の欠損**

Webhook 機能はほとんどのケースにおいて Webhook リクエストを送信しますが、ごく稀に Webhook リクエストが欠損する可能性があります。
全てのイベント情報が、Webhook リクエストとして必ず送信される保証は無い点にご留意ください。
