# シグナリング通知メタデータ拡張機能

## 概要

シグナリング通知メタデータ拡張機能(以降メタデータ拡張機能)は、
Sora に API 経由で変更できるメタデータを接続ごとに保持する機能です。

- メタデータは新規参加者にシグナリング通知経由で共有されます
- メタデータを API 経由で変更した際に変更をプッシュで通知することもできるようになります

## 目的

接続ごとに持たせたメタデータを API 経由で変更し、
既存参加者にはプッシュで通知、新規参加者には参加時に通知するような仕組みを提供することです。

## シグナリング通知メタデータの課題

今までのシグナリング通知メタデータは、接続時に指定した値を認証成功時の払い出しで上書きするといったものでした。
そのため **接続ごとの状態変更** を管理するために別の仕組みを用意する必要がありました。

メタデータ拡張を利用することで、接続ごとの状態、
例えば「忙しい」といったプレゼンス情報を Sora で管理し、他の接続に通知できるようになります。

## メタデータ拡張機能を利用することで実現できること

- 参加者のプレゼンス状態を変更した際に既存参加者にはプッシュで共有し、新規参加者にはシグナリング通知で共有できるようになる
- マイクミュート状態を既存参加者にはプッシュで共有し、新規参加者にはシグナリング通知で共有できるようになる
- 画面共有中の配信者を既存参加者にはプッシュで共有し、新規参加者にはシグナリング通知で共有できるようになる

今まで別の場所で保持していた変更可能な状態を Sora 側で持つことができます。

## メタデータ拡張機能の有効 / 無効について

メタデータ拡張機能はデフォルトで無効になっています。

### sora.conf の指定

メタデータ拡張機能を有効にするには設定を有効にする必要があります。

```ini
signaling_notify_metadata_ext = true
```

### 有効にした際の変更点

- API 経由で connection.created 時に共有される `metadata` が key / value 形式で指定できるようになります
- シグナリング通知時に送られる `metadata` は API でのみ反映され、接続時や認証時の `signaling_notify_metadata` は反映されません
- シグナリング通知時に送られる `metadata` の初期値は `{}` で空オブジェクトです
- 接続時に指定していた `signaling_notify_metadata` は `authn_metadata` を利用してください- 指定しない場合は `authn_metadata` はシグナリング通知時に含まれません
- 認証成功時に払い出していた `signaling_notify_metadata` は `authz_metadata` を利用してください- 指定しない場合は `authz_metadata` はシグナリング通知時に含まれません

## メタデータ拡張機能の特徴

- API 実行時に `"push": true` を指定することで、メタデータの変更と通知を同時に行えます- 通知は `"type": "push"` で行われます
- API 経由以外では変更できません

## メタデータ拡張機能の制限

> **重要**
>
> 1 接続が保持できるメタデータ拡張のサイズは最大 32 KiB (32768 バイト) です。

メタデータのサイズはエンコード済みの JSON 、つまり文字列としてサイズを計算します。

例えば `{"a":"b"}` の場合は 9 バイトで、 `{"a":"b","c":1200}` は 18 バイトです。

## メタデータ拡張の初期値

メタデータ拡張機能の初期値を認証ウェブフックの成功時に払い出すことができます。

```javascript
{
   "allowed": true,
   "signaling_notify_metadata_ext": {
      "abc": 10
   }
}
```

払い出す値は JSON Object である必要があります。

## 利用方法

**開発ツールを利用します**

> **注意**
>
> シグナリング通知メタデータ拡張 API が有効になるのはイベントウェブフックの `connection.created` が通知されてからです。

1. シグナリング通知メタデータ拡張機能を有効にしましょう- `sora.conf` の `signaling_notify_metadata_ext = true` を設定します
2. まず１つ目の接続をしてみましょう- 開発ツールを開いて、右上の debug にチェックを入れて connect を押してください
   - `channel_id` はデフォルトの `sora` のままで問題ありません
   - `connection_id` を `PPD3R008XH0S11CG535JFKQFH0` とします
3. この時点で、まだ `PPD3R008XH0S11CG535JFKQFH0` の `metadata` は `{}` です
4. `PPD3R008XH0S11CG535JFKQFH0` のメタデータに新しいアイテムを追加してみましょう

   - HTTP API の `PutSignalingNotifyMetadataItem` を利用します
   - key を "abc" とし value を 10 としてアイテムを追加します
   - ついでにプッシュ通知も行うように push を true にします


   ```
   $ curl -sS \
       -X POST \
       http://127.0.0.1:3000/ \
       -H "x-sora-target: Sora_20201124.PutSignalingNotifyMetadataItem" \
       --json '{"channel_id":"sora","connection_id":"PPD3R008XH0S11CG535JFKQFH0","key":"abc","value":10,"push":true}' \
       | jq .
   {
       "abc": 10
   }
   ```
5. 項目に値が入っているか確認してみましょう


   ```
   $ curl -sS \
       -X POST \
       http://127.0.0.1:3000/ \
       -H "x-sora-target: Sora_20201124.GetSignalingNotifyMetadata" \
       --json '{"channel_id":"sora","connection_id":"PPD3R008XH0S11CG535JFKQFH0"}' \
       | jq .
   {
       "abc": 10
   }
   ```
6. 新しい接続に追加したアイテムが反映されているメタデータが通知されるか確認してみましょう- 別のタブを開いて、debug にチェックを入れて connect して Notify タブを見てみて下さい
   - `data` の中に `connection_id: PPD3R008XH0S11CG535JFKQFH0` があり、その `metadata` が先程作成した値であれば成功です
