> For the complete documentation index, see [llms.txt](/llms.txt)

# GS2-Chat SDK for Game Engine API リファレンス

ゲームエンジン向け GS2-Chat SDK の モデルの仕様 と API のリファレンス



## モデル

### EzRoom

ルーム<br>

ルームはチャットのメッセージを届けられる範囲を表しています。<br>
GS2-Chat のルームには参加という概念はありません。<br>
そのため、メッセージを受信するにはルームの名前を知っているだけでよく、ルームへの参加やメンバー登録は必要ありません。<br>

ルームのメッセージを閲覧できるゲームプレイヤーを限定したい場合は2つの方法があります。<br>
1つ目はルームにパスワードを設定することです。<br>
2つ目はルームに設定可能なホワイトリストでゲームプレイヤーのユーザーIDを設定することで限定ができます。<br>

パスワードを設定した場合、パスワードを知らなければゲームの管理者でもメッセージの取得が出来なくなることに注意してください。<br>
これは日本国憲法で定められた`通信の秘密`に該当する可能性があるためです。<br>

ルームを購読すると、ルームに対して新しいメッセージが送信された際に GS2-Gateway のプッシュ通知を受けることが可能です。<br>
この通知機能を利用することで、ルームに対してポーリングすることなく新しいメッセージの有無を知ることが可能となります。

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| name | string |  | ✓ | UUID |  ~ 128文字 | ルーム名<br>ルーム固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| metadata | string |  |  |  |  ~ 1024文字 | メタデータ<br>メタデータには任意の値を設定できます。<br>これらの値は GS2 の動作には影響しないため、ゲーム内で利用する情報の保存先として使用できます。 |
| whiteListUserIds | List&lt;string&gt; |  |  | [] | 0 ~ 1000 items | ルームにアクセス可能なユーザーIDリスト<br>設定すると、リストに含まれるユーザーのみがルームのメッセージを取得・投稿できるようになります。空の場合、ユーザーIDによるアクセス制限は適用されません（ただしパスワードは別途必要な場合があります）。 |

**関連するメソッド:**
createRoom - チャットルームを作成する
deleteRoom - チャットルームを削除する
getRoom - チャットルームの情報を取得する


---

### EzMessage

メッセージ<br>

メッセージはルームに投稿されたデータです。<br>

カテゴリというフィールドを持ちますので、メッセージの分類が可能です。<br>
たとえば、カテゴリが 0 の場合は通常のテキストメッセージとして解釈し、1 の場合はスタンプ（ステッカー）として処理するようにクライアントを実行することができます。<br>

投稿されたメッセージは投稿後、Chat Namespace の messageLifeTimeDays で設定したメッセージ保持期間が経過すると自動的に削除されます。

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| name | string |  | ✓ | UUID |  ~ 36文字 | メッセージ名<br>メッセージの一意な名前を保持します。<br>名前はUUID（Universally Unique Identifier）フォーマットで自動的に生成され、各メッセージを識別するために使用されます。 |
| roomName | string |  | ✓ | UUID |  ~ 128文字 | ルーム名<br>ルーム固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| userId | string |  | ✓ |  |  ~ 128文字 | ユーザーID |
| category | int |  |  | 0 | 0 ~ 2147483645 | メッセージ分類用カテゴリ番号<br>メッセージを分類するための数値です。例えば、0 は通常のテキストメッセージ、1 はスタンプ（ステッカー）、その他の値はカスタムメッセージタイプとして使用できます。カテゴリーにより、メッセージに適用される CategoryModel のルールが決まります。 |
| metadata | string |  | ✓ |  |  ~ 1024文字 | メタデータ<br>メタデータには任意の値を設定できます。<br>これらの値は GS2 の動作には影響しないため、ゲーム内で利用する情報の保存先として使用できます。 |
| createdAt | long |  | ※ | 現在時刻 |  | 作成日時<br>UNIX 時間・ミリ秒<br>※ サーバーが自動で設定 |

**関連するメソッド:**
getMessage - メッセージ名を指定してメッセージを1件取得する
listLatestMessages - チャットルームの最新メッセージを取得する
listMessages - チャットルームのメッセージを取得する（指定時刻以降）
post - チャットルームにメッセージを投稿する


---

### EzSubscribe

ルーム購読<br>

ルームを購読することで、そのルームに対する新着メッセージの存在を即座に知ることが出来るようになります。<br>
購読する際にはメッセージのカテゴリを指定できます。<br>
この機能をうまく利用すれば重要度の高いメッセージのみ受信するような設定も可能です。

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| userId | string |  | ✓ |  |  ~ 128文字 | ユーザーID |
| roomName | string |  | ✓ |  |  ~ 128文字 | 購読するルーム名<br>購読するチャットルームの名前です。購読すると、このルームに新しいメッセージが投稿されるたびに GS2-Gateway 経由でプッシュ通知が送信されます。 |
| notificationTypes | [List&lt;EzNotificationType&gt;](#eznotificationtype) |  |  | [] | 0 ~ 100 items | 新着メッセージ通知を受け取るカテゴリリスト<br>プッシュ通知をトリガーするメッセージカテゴリーをフィルタリングします。空の場合、すべてのカテゴリーで通知が送信されます。各エントリーはカテゴリー番号とオプションのモバイルプッシュ通知転送を指定します。 |

**関連するメソッド:**
listSubscribeRooms - プレイヤーが購読中のルーム一覧を取得する
subscribe - チャットルームを購読する
unsubscribe - チャットルームの購読を解除する
updateSubscribeSetting - 購読中のルームの通知設定を変更する


---

### EzCategoryModel

メッセージカテゴリーモデル<br>

メッセージカテゴリーモデルは、チャットルームに投稿されるメッセージを分類するためのカテゴリーを定義します。<br>
各カテゴリーは数値で識別され、カテゴリーごとにプレイヤーのアクセストークンを使った投稿を許可するか拒否するかを設定できます。<br>
これにより、サーバーのみが投稿可能なシステムアナウンスカテゴリーなどのユースケースを実現できます。

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| category | int |  | ✓ |  | 0 ~ 2147483645 | カテゴリー<br>メッセージカテゴリーの数値識別子です。このカテゴリー番号で投稿されたメッセージは、プレイヤーの投稿を許可するかなど、このモデルで定義されたルールに従います。 |
| rejectAccessTokenPost | 文字列列挙型<br>enum {<br>&nbsp;&nbsp;"Enabled",<br>&nbsp;&nbsp;"Disabled"<br>}<br> |  |  |  |  | プレイヤーのアクセストークンを利用した投稿を拒否する<br>有効にすると、このカテゴリーではサーバーサイドの API 呼び出し（ユーザーID指定）のみがメッセージを投稿できます。プレイヤーが直接投稿すべきでないシステムアナウンスやサーバー生成メッセージに有用です。"Enabled": アクセストークンを利用した投稿を拒否する / "Disabled": アクセストークンを利用した投稿を許可する /  |

**関連するメソッド:**
getCategoryModel - カテゴリ番号を指定してメッセージカテゴリ定義を取得する
listCategoryModels - メッセージカテゴリモデルの一覧を取得する


---

### EzNotificationType

通知タイプ<br>

新着メッセージ通知を受け取るカテゴリの設定

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| category | int |  |  | 0 | 0 ~ 2147483646 | 新着メッセージ通知を受け取るカテゴリ<br>通知をフィルタリングするためのカテゴリーの数値識別子です。このカテゴリーに一致するメッセージのみが、購読に対するプッシュ通知をトリガーします。 |
| enableTransferMobilePushNotification | bool |  |  | false |  | オフラインだった時にモバイルプッシュ通知に転送するか<br>有効にすると、通知時に受信先デバイスがオフラインだった場合、モバイルプッシュ通知サービスに転送されます。これにより、ゲームが実行されていない場合でもプレイヤーに新着メッセージを通知できます。 |

**関連するメソッド:**
subscribe - チャットルームを購読する
updateSubscribeSetting - 購読中のルームの通知設定を変更する


**関連するモデル:**
EzSubscribe - ルーム購読



---

## メソッド

### createRoom

チャットルームを作成する<br>

プレイヤーがメッセージをやり取りできる新しいチャットルームを作成します。<br>
ネームスペースの設定でプレイヤーによるルーム作成が許可されている必要があります。許可されていない場合は失敗します。<br>

ルームにパスワードを設定することもできます。パスワードを設定した場合、メッセージの投稿・取得にはパスワードの入力が必要です。<br>
ホワイトリストにユーザーIDを設定して、アクセスできるプレイヤーを制限することも可能です。

#### Request

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128文字 | ネームスペース名<br>ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| name | string |  | | UUID |  ~ 128文字 | ルーム名<br>ルーム固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| gameSession | GameSession | | |  |  | GameSession<br>ルームのオーナーのユーザーIDです。設定すると、オーナーのみがルームを削除できるようになります。オーナーの設定は任意です。 |
| metadata | string |  | |  |  ~ 1024文字 | メタデータ<br>メタデータには任意の値を設定できます。<br>これらの値は GS2 の動作には影響しないため、ゲーム内で利用する情報の保存先として使用できます。 |
| password | string |  | |  |  ~ 128文字 | ルームにアクセスするために必要となるパスワード<br>設定すると、メッセージの取得・投稿時にパスワードの入力が必要になります。設定したパスワードは二度と参照できません。通信の秘密に該当する可能性があるため、ゲーム管理者でもパスワードを知らなければメッセージにアクセスできなくなります。 |
| whiteListUserIds | List&lt;string&gt; |  | | [] | 0 ~ 1000 items | ルームにアクセス可能なユーザーIDリスト<br>設定すると、リストに含まれるユーザーのみがルームのメッセージを取得・投稿できるようになります。空の場合、ユーザーIDによるアクセス制限は適用されません（ただしパスワードは別途必要な場合があります）。 |

#### Result

|  | 型 | 説明 |
| --- | --- | --- |
| item | [EzRoom](#ezroom) | 作成したルーム|

#### Error

このAPIには特別な例外が定義されています。<br>
GS2-SDK for Game Engine ではゲーム内でハンドリングが必要そうなエラーは一般的な例外から派生した特殊化した例外を用意することでハンドリングしやすくしています。<br>
一般的なエラーの種類や、ハンドリング方法は [こちら]() のドキュメントを参考にしてください。

| 型 | 基底クラス | 説明 |
| --- | --- | --- |
| NoAccessPrivilegesException | BadRequestException | ルームに設定されたホワイトリストにログイン中のユーザーが含まれていません |

#### 実装例




**Unity (UniTask)**
```csharp

try {
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var result = await domain.CreateRoomAsync(
        name: "room-0001",
        metadata: null,
        password: null,
        whiteListUserIds: null
    );
    var item = await result.ModelAsync();
} catch(Gs2.Gs2Chat.Exception.NoAccessPrivilegesException e) {
    // The whitelist configured for the room does not contain any currently logged in user.
}

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var future = domain.CreateRoomFuture(
        name: "room-0001",
        metadata: null,
        password: null,
        whiteListUserIds: null
    );
    yield return future;
    if (future.Error != null)
    {
        if (future.Error is Gs2.Gs2Chat.Exception.NoAccessPrivilegesException)
        {
            // The whitelist configured for the room does not contain any currently logged in user.
        }
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.ModelFuture();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    );
    const auto Future = Domain->CreateRoom(
        "room-0001" // name
        // metadata
        // password
        // whiteListUserIds
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        auto e = Future->GetTask().Error();
        if (e->IsChildOf(Gs2::Chat::Error::FNoAccessPrivilegesError::Class))
        {
            // The whitelist configured for the room does not contain any currently logged in user.
        }
        return false;
    }

    // obtain changed values / result values
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();

```


---

### deleteRoom

チャットルームを削除する<br>

プレイヤーが作成したチャットルームを削除します。<br>
ルームを作成したプレイヤー（オーナー）のみが削除できます。<br>
ルーム内のすべてのメッセージも一緒に削除されます。

#### Request

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128文字 | ネームスペース名<br>ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| roomName | string |  | ✓| UUID |  ~ 128文字 | ルーム名<br>ルーム固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| gameSession | GameSession | | |  |  | GameSession |

#### Result

|  | 型 | 説明 |
| --- | --- | --- |
| item | [EzRoom](#ezroom) | 削除したルーム|

#### Error

このAPIには特別な例外が定義されています。<br>
GS2-SDK for Game Engine ではゲーム内でハンドリングが必要そうなエラーは一般的な例外から派生した特殊化した例外を用意することでハンドリングしやすくしています。<br>
一般的なエラーの種類や、ハンドリング方法は [こちら]() のドキュメントを参考にしてください。

| 型 | 基底クラス | 説明 |
| --- | --- | --- |
| NoAccessPrivilegesException | BadRequestException | ルームに設定されたホワイトリストにログイン中のユーザーが含まれていません |

#### 実装例




**Unity (UniTask)**
```csharp

try {
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Room(
        roomName: "room-0001",
        password: null
    );
    var result = await domain.DeleteRoomAsync(
    );
} catch(Gs2.Gs2Chat.Exception.NoAccessPrivilegesException e) {
    // The whitelist configured for the room does not contain any currently logged in user.
}

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Room(
        roomName: "room-0001",
        password: null
    );
    var future = domain.DeleteRoomFuture(
    );
    yield return future;
    if (future.Error != null)
    {
        if (future.Error is Gs2.Gs2Chat.Exception.NoAccessPrivilegesException)
        {
            // The whitelist configured for the room does not contain any currently logged in user.
        }
        onError.Invoke(future.Error, null);
        yield break;
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Room(
        "room-0001", // roomName
        nullptr // password
    );
    const auto Future = Domain->DeleteRoom(
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        auto e = Future->GetTask().Error();
        if (e->IsChildOf(Gs2::Chat::Error::FNoAccessPrivilegesError::Class))
        {
            // The whitelist configured for the room does not contain any currently logged in user.
        }
        return false;
    }
    const auto Result = Future->GetTask().Result();

```


---

### getRoom

チャットルームの情報を取得する<br>

指定したチャットルームのメタデータや作成日時などの情報を取得します。<br>
ルームにパスワードが設定されていても、パスワードなしで取得できます。<br>
プレイヤーがルームを閲覧する前に、ルームの詳細（ルーム名やトピックなど）を表示する際に使います。

#### Request

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128文字 | ネームスペース名<br>ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| roomName | string |  | ✓| UUID |  ~ 128文字 | ルーム名<br>ルーム固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |

#### Result

|  | 型 | 説明 |
| --- | --- | --- |
| item | [EzRoom](#ezroom) | ルーム|

#### 実装例




**Unity (UniTask)**
```csharp
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).User(
        userId: null
    ).Room(
        roomName: "room-0001",
        password: null
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).User(
        userId: null
    ).Room(
        roomName: "room-0001",
        password: null
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    )->User(
        nullptr // userId
    )->Room(
        "room-0001", // roomName
        nullptr // password
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```


##### 値の変更イベントハンドリング




**Unity (UniTask)**
```csharp
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).User(
        userId: null
    ).Room(
        roomName: "room-0001",
        password: null
    );
    
    // イベントハンドリングを開始
    var callbackId = domain.Subscribe(
        value => {
            // 値が変化した時に呼び出される
            // value には変更後の値が渡ってくる
        }
    );

    // イベントハンドリングを停止
    domain.Unsubscribe(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).User(
        userId: null
    ).Room(
        roomName: "room-0001",
        password: null
    );
    
    // イベントハンドリングを開始
    var callbackId = domain.Subscribe(
        value => {
            // 値が変化した時に呼び出される
            // value には変更後の値が渡ってくる
        }
    );

    // イベントハンドリングを停止
    domain.Unsubscribe(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    )->User(
        nullptr // userId
    )->Room(
        "room-0001", // roomName
        nullptr // password
    );
    
    // イベントハンドリングを開始
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Chat::Model::FRoom> value) {
            // 値が変化した時に呼び出される
            // value には変更後の値が渡ってくる
        }
    );

    // イベントハンドリングを停止
    Domain->Unsubscribe(CallbackId);

```


{{% alert title="Warning" color="warning" %}}このイベントはSDKがもつローカルキャッシュの値が変更された時に呼び出されます。

ローカルキャッシュは SDK が持つ API の実行、または GS2-Gateway の通知を有効にした GS2-Distributor 経由でのスタンプシートの実行、または GS2-Gateway の通知を有効にした GS2-JobQueue の実行によって変化したもののみが対象となります。

そのため、これらの方法以外で値が変更されてもコールバックは呼び出されません。
{{% /alert %}}

---

### getMessage

メッセージ名を指定してメッセージを1件取得する<br>

メッセージ名（ID）を指定して、チャットルーム内のメッセージを1件取得します。<br>
通知をタップしたときなど、特定のメッセージの詳細を表示する際に使います。<br>

ルームにパスワードが設定されている場合は、パスワードの入力が必要です。

#### Request

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128文字 | ネームスペース名<br>ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| roomName | string |  | ✓|  |  ~ 128文字 | ルーム名<br>ルーム固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| messageName | string |  | ✓| UUID |  ~ 36文字 | メッセージ名<br>メッセージの一意な名前を保持します。<br>名前はUUID（Universally Unique Identifier）フォーマットで自動的に生成され、各メッセージを識別するために使用されます。 |
| gameSession | GameSession | | |  |  | GameSession |
| password | string |  | |  |  ~ 128文字 | パスワード |

#### Result

|  | 型 | 説明 |
| --- | --- | --- |
| item | [EzMessage](#ezmessage) | メッセージ|

#### Error

このAPIには特別な例外が定義されています。<br>
GS2-SDK for Game Engine ではゲーム内でハンドリングが必要そうなエラーは一般的な例外から派生した特殊化した例外を用意することでハンドリングしやすくしています。<br>
一般的なエラーの種類や、ハンドリング方法は [こちら]() のドキュメントを参考にしてください。

| 型 | 基底クラス | 説明 |
| --- | --- | --- |
| NoAccessPrivilegesException | BadRequestException | ルームに設定されたホワイトリストにログイン中のユーザーが含まれていません |
| PasswordRequiredException | BadRequestException | ルームにアクセスするためにはパスワードの指定が必要です |
| PasswordIncorrectException | BadRequestException | ルームに設定されたパスワードと指定されたパスワードが一致しません |

#### 実装例




**Unity (UniTask)**
```csharp

try {
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Room(
        roomName: "room-0001",
        password: null
    ).Message(
        messageName: "message-0001"
    );
    var item = await domain.ModelAsync();
} catch(Gs2.Gs2Chat.Exception.NoAccessPrivilegesException e) {
    // The whitelist configured for the room does not contain any currently logged in user.
} catch(Gs2.Gs2Chat.Exception.PasswordRequiredException e) {
    // A password must be specified to access the room.
} catch(Gs2.Gs2Chat.Exception.PasswordIncorrectException e) {
    // The password set for the room does not match the password specified.
}

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Room(
        roomName: "room-0001",
        password: null
    ).Message(
        messageName: "message-0001"
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Room(
        "room-0001", // roomName
        nullptr // password
    )->Message(
        "message-0001" // messageName
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        auto e = Future->GetTask().Error();
        if (e->IsChildOf(Gs2::Chat::Error::FNoAccessPrivilegesError::Class))
        {
            // The whitelist configured for the room does not contain any currently logged in user.
        }
        if (e->IsChildOf(Gs2::Chat::Error::FPasswordRequiredError::Class))
        {
            // A password must be specified to access the room.
        }
        if (e->IsChildOf(Gs2::Chat::Error::FPasswordIncorrectError::Class))
        {
            // The password set for the room does not match the password specified.
        }
        return false;
    }

```


##### 値の変更イベントハンドリング




**Unity (UniTask)**
```csharp

try {
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Room(
        roomName: "room-0001",
        password: null
    ).Message(
        messageName: "message-0001"
    );
    
    // イベントハンドリングを開始
    var callbackId = domain.Subscribe(
        value => {
            // 値が変化した時に呼び出される
            // value には変更後の値が渡ってくる
        }
    );

    // イベントハンドリングを停止
    domain.Unsubscribe(callbackId);
} catch(Gs2.Gs2Chat.Exception.NoAccessPrivilegesException e) {
    // The whitelist configured for the room does not contain any currently logged in user.
} catch(Gs2.Gs2Chat.Exception.PasswordRequiredException e) {
    // A password must be specified to access the room.
} catch(Gs2.Gs2Chat.Exception.PasswordIncorrectException e) {
    // The password set for the room does not match the password specified.
}

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Room(
        roomName: "room-0001",
        password: null
    ).Message(
        messageName: "message-0001"
    );
    
    // イベントハンドリングを開始
    var callbackId = domain.Subscribe(
        value => {
            // 値が変化した時に呼び出される
            // value には変更後の値が渡ってくる
        }
    );

    // イベントハンドリングを停止
    domain.Unsubscribe(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Room(
        "room-0001", // roomName
        nullptr // password
    )->Message(
        "message-0001" // messageName
    );
    
    // イベントハンドリングを開始
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Chat::Model::FMessage> value) {
            // 値が変化した時に呼び出される
            // value には変更後の値が渡ってくる
        }
    );

    // イベントハンドリングを停止
    Domain->Unsubscribe(CallbackId);

```


{{% alert title="Warning" color="warning" %}}このイベントはSDKがもつローカルキャッシュの値が変更された時に呼び出されます。

ローカルキャッシュは SDK が持つ API の実行、または GS2-Gateway の通知を有効にした GS2-Distributor 経由でのスタンプシートの実行、または GS2-Gateway の通知を有効にした GS2-JobQueue の実行によって変化したもののみが対象となります。

そのため、これらの方法以外で値が変更されてもコールバックは呼び出されません。
{{% /alert %}}

---

### listLatestMessages

チャットルームの最新メッセージを取得する<br>

チャットルーム内の最新のメッセージを、新しい順に取得します。<br>
プレイヤーがチャット画面を開いたときに直近のやり取りを表示する際に使います。<br>

ルームにパスワードが設定されている場合は、パスワードの入力が必要です。

#### Request

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128文字 | ネームスペース名<br>ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| roomName | string |  | ✓| UUID |  ~ 128文字 | ルーム名<br>ルーム固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| gameSession | GameSession | | ✓|  |  | GameSession |
| limit | int |  | | 30 | 1 ~ 1000 | データの取得件数 |
| password | string |  | |  |  ~ 128文字 | ルームにアクセスするために必要となるパスワード<br>設定すると、メッセージの取得・投稿時にパスワードの入力が必要になります。設定したパスワードは二度と参照できません。通信の秘密に該当する可能性があるため、ゲーム管理者でもパスワードを知らなければメッセージにアクセスできなくなります。 |

#### Result

|  | 型 | 説明 |
| --- | --- | --- |
| items | [List&lt;EzMessage&gt;](#ezmessage) | メッセージのリスト|
| nextPageToken | string | リストの続きを取得するためのページトークン|

#### Error

このAPIには特別な例外が定義されています。<br>
GS2-SDK for Game Engine ではゲーム内でハンドリングが必要そうなエラーは一般的な例外から派生した特殊化した例外を用意することでハンドリングしやすくしています。<br>
一般的なエラーの種類や、ハンドリング方法は [こちら]() のドキュメントを参考にしてください。

| 型 | 基底クラス | 説明 |
| --- | --- | --- |
| NoAccessPrivilegesException | BadRequestException | ルームに設定されたホワイトリストにログイン中のユーザーが含まれていません |
| PasswordRequiredException | BadRequestException | ルームにアクセスするためにはパスワードの指定が必要です |
| PasswordIncorrectException | BadRequestException | ルームに設定されたパスワードと指定されたパスワードが一致しません |

#### 実装例




**Unity (UniTask)**
```csharp

try {
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Room(
        roomName: "room-0001",
        password: null
    );
    var items = await domain.LatestMessagesAsync(
    ).ToListAsync();
} catch(Gs2.Gs2Chat.Exception.NoAccessPrivilegesException e) {
    // The whitelist configured for the room does not contain any currently logged in user.
} catch(Gs2.Gs2Chat.Exception.PasswordRequiredException e) {
    // A password must be specified to access the room.
} catch(Gs2.Gs2Chat.Exception.PasswordIncorrectException e) {
    // The password set for the room does not match the password specified.
}

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Room(
        roomName: "room-0001",
        password: null
    );
    var it = domain.LatestMessages(
    );
    List<EzMessage> items = new List<EzMessage>();
    while (it.HasNext())
    {
        yield return it.Next();
        if (it.Error != null)
        {
            onError.Invoke(it.Error, null);
            break;
        }
        if (it.Current != null)
        {
            items.Add(it.Current);
        }
        else
        {
            break;
        }
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Room(
        "room-0001", // roomName
        nullptr // password
    );
    const auto It = Domain->LatestMessages(
    );
    TArray<Gs2::UE5::Chat::Model::FEzMessagePtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

```


---

### listMessages

チャットルームのメッセージを取得する（指定時刻以降）<br>

`startAt` に指定した時刻以降に投稿されたメッセージを、古い順に取得します。<br>
前回の確認以降の新着メッセージを取得したいとき（再接続時やチャット画面を開いたときなど）に使います。<br>

ネームスペースの設定で指定された保持期間内のメッセージのみ取得できます。<br>
ルームにパスワードが設定されている場合は、パスワードの入力が必要です。

#### Request

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128文字 | ネームスペース名<br>ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| roomName | string |  | ✓| UUID |  ~ 128文字 | ルーム名<br>ルーム固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| gameSession | GameSession | | ✓|  |  | GameSession |
| startAt | long |  | | 現在時刻から1時間前の絶対時刻 |  | メッセージの取得を開始する時刻<br>UNIX 時間・ミリ秒 |
| limit | int |  | | 30 | 1 ~ 1000 | データの取得件数 |
| password | string |  | |  |  ~ 128文字 | ルームにアクセスするために必要となるパスワード<br>設定すると、メッセージの取得・投稿時にパスワードの入力が必要になります。設定したパスワードは二度と参照できません。通信の秘密に該当する可能性があるため、ゲーム管理者でもパスワードを知らなければメッセージにアクセスできなくなります。 |

#### Result

|  | 型 | 説明 |
| --- | --- | --- |
| items | [List&lt;EzMessage&gt;](#ezmessage) | メッセージのリスト|

#### Error

このAPIには特別な例外が定義されています。<br>
GS2-SDK for Game Engine ではゲーム内でハンドリングが必要そうなエラーは一般的な例外から派生した特殊化した例外を用意することでハンドリングしやすくしています。<br>
一般的なエラーの種類や、ハンドリング方法は [こちら]() のドキュメントを参考にしてください。

| 型 | 基底クラス | 説明 |
| --- | --- | --- |
| NoAccessPrivilegesException | BadRequestException | ルームに設定されたホワイトリストにログイン中のユーザーが含まれていません |
| PasswordRequiredException | BadRequestException | ルームにアクセスするためにはパスワードの指定が必要です |
| PasswordIncorrectException | BadRequestException | ルームに設定されたパスワードと指定されたパスワードが一致しません |

#### 実装例




**Unity (UniTask)**
```csharp

try {
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Room(
        roomName: "room-0001",
        password: null
    );
    var items = await domain.MessagesAsync(
    ).ToListAsync();
} catch(Gs2.Gs2Chat.Exception.NoAccessPrivilegesException e) {
    // The whitelist configured for the room does not contain any currently logged in user.
} catch(Gs2.Gs2Chat.Exception.PasswordRequiredException e) {
    // A password must be specified to access the room.
} catch(Gs2.Gs2Chat.Exception.PasswordIncorrectException e) {
    // The password set for the room does not match the password specified.
}

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Room(
        roomName: "room-0001",
        password: null
    );
    var it = domain.Messages(
    );
    List<EzMessage> items = new List<EzMessage>();
    while (it.HasNext())
    {
        yield return it.Next();
        if (it.Error != null)
        {
            onError.Invoke(it.Error, null);
            break;
        }
        if (it.Current != null)
        {
            items.Add(it.Current);
        }
        else
        {
            break;
        }
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Room(
        "room-0001", // roomName
        nullptr // password
    );
    const auto It = Domain->Messages(
    );
    TArray<Gs2::UE5::Chat::Model::FEzMessagePtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

```


##### 値の変更イベントハンドリング




**Unity (UniTask)**
```csharp

try {
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Room(
        roomName: "room-0001",
        password: null
    );
    
    // イベントハンドリングを開始
    var callbackId = domain.SubscribeMessages(
        () => {
            // リストの要素が変化した時に呼び出される
        }
    );

    // イベントハンドリングを停止
    domain.UnsubscribeMessages(callbackId);
} catch(Gs2.Gs2Chat.Exception.NoAccessPrivilegesException e) {
    // The whitelist configured for the room does not contain any currently logged in user.
} catch(Gs2.Gs2Chat.Exception.PasswordRequiredException e) {
    // A password must be specified to access the room.
} catch(Gs2.Gs2Chat.Exception.PasswordIncorrectException e) {
    // The password set for the room does not match the password specified.
}

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Room(
        roomName: "room-0001",
        password: null
    );
    
    // イベントハンドリングを開始
    var callbackId = domain.SubscribeMessages(
        () => {
            // リストの要素が変化した時に呼び出される
        }
    );

    // イベントハンドリングを停止
    domain.UnsubscribeMessages(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Room(
        "room-0001", // roomName
        nullptr // password
    );
    
    // イベントハンドリングを開始
    const auto CallbackId = Domain->SubscribeMessages(
        []() {
            // リストの要素が変化した時に呼び出される
        }
    );

    // イベントハンドリングを停止
    Domain->UnsubscribeMessages(CallbackId);

```


{{% alert title="Warning" color="warning" %}}このイベントはSDKがもつローカルキャッシュの値が変更された時に呼び出されます。

ローカルキャッシュは SDK が持つ API の実行、または GS2-Gateway の通知を有効にした GS2-Distributor 経由でのスタンプシートの実行、または GS2-Gateway の通知を有効にした GS2-JobQueue の実行によって変化したもののみが対象となります。

そのため、これらの方法以外で値が変更されてもコールバックは呼び出されません。
{{% /alert %}}

---

### post

チャットルームにメッセージを投稿する<br>

指定したチャットルームにメッセージを送信します。<br>
`カテゴリ` の数値を付けることで、メッセージの種類を区別できます（例: 0 はテキスト、1 はスタンプ）。<br>
メッセージの内容は `metadata` に自由な形式の文字列として保存されます。テキスト、JSON など、ゲームに合わせたデータを格納できます。<br>
ルームにパスワードが設定されている場合は、パスワードの入力が必要です。

#### Request

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128文字 | ネームスペース名<br>ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| roomName | string |  | ✓|  |  ~ 128文字 | ルーム名<br>ルーム固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| gameSession | GameSession | | ✓|  |  | GameSession |
| category | int |  | | 0 | 0 ~ 2147483645 | メッセージ分類用カテゴリ番号<br>メッセージを分類するための数値です。例えば、0 は通常のテキストメッセージ、1 はスタンプ（ステッカー）、その他の値はカスタムメッセージタイプとして使用できます。カテゴリーにより、メッセージに適用される CategoryModel のルールが決まります。 |
| metadata | string |  | ✓|  |  ~ 1024文字 | メタデータ<br>メタデータには任意の値を設定できます。<br>これらの値は GS2 の動作には影響しないため、ゲーム内で利用する情報の保存先として使用できます。 |
| password | string |  | |  |  ~ 128文字 | パスワード |

#### Result

|  | 型 | 説明 |
| --- | --- | --- |
| item | [EzMessage](#ezmessage) | 投稿したメッセージ|

#### Error

このAPIには特別な例外が定義されています。<br>
GS2-SDK for Game Engine ではゲーム内でハンドリングが必要そうなエラーは一般的な例外から派生した特殊化した例外を用意することでハンドリングしやすくしています。<br>
一般的なエラーの種類や、ハンドリング方法は [こちら]() のドキュメントを参考にしてください。

| 型 | 基底クラス | 説明 |
| --- | --- | --- |
| NoAccessPrivilegesException | BadRequestException | ルームに設定されたホワイトリストにログイン中のユーザーが含まれていません |
| PasswordRequiredException | BadRequestException | ルームにアクセスするためにはパスワードの指定が必要です |
| PasswordIncorrectException | BadRequestException | ルームに設定されたパスワードと指定されたパスワードが一致しません |

#### 実装例




**Unity (UniTask)**
```csharp

try {
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Room(
        roomName: "room-0001",
        password: null
    );
    var result = await domain.PostAsync(
        metadata: "MESSAGE_0001",
        category: null
    );
    var item = await result.ModelAsync();
} catch(Gs2.Gs2Chat.Exception.NoAccessPrivilegesException e) {
    // The whitelist configured for the room does not contain any currently logged in user.
} catch(Gs2.Gs2Chat.Exception.PasswordRequiredException e) {
    // A password must be specified to access the room.
} catch(Gs2.Gs2Chat.Exception.PasswordIncorrectException e) {
    // The password set for the room does not match the password specified.
}

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Room(
        roomName: "room-0001",
        password: null
    );
    var future = domain.PostFuture(
        metadata: "MESSAGE_0001",
        category: null
    );
    yield return future;
    if (future.Error != null)
    {
        if (future.Error is Gs2.Gs2Chat.Exception.NoAccessPrivilegesException)
        {
            // The whitelist configured for the room does not contain any currently logged in user.
        }
        if (future.Error is Gs2.Gs2Chat.Exception.PasswordRequiredException)
        {
            // A password must be specified to access the room.
        }
        if (future.Error is Gs2.Gs2Chat.Exception.PasswordIncorrectException)
        {
            // The password set for the room does not match the password specified.
        }
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.ModelFuture();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Room(
        "room-0001", // roomName
        nullptr // password
    );
    const auto Future = Domain->Post(
        "MESSAGE_0001" // metadata
        // category
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        auto e = Future->GetTask().Error();
        if (e->IsChildOf(Gs2::Chat::Error::FNoAccessPrivilegesError::Class))
        {
            // The whitelist configured for the room does not contain any currently logged in user.
        }
        if (e->IsChildOf(Gs2::Chat::Error::FPasswordRequiredError::Class))
        {
            // A password must be specified to access the room.
        }
        if (e->IsChildOf(Gs2::Chat::Error::FPasswordIncorrectError::Class))
        {
            // The password set for the room does not match the password specified.
        }
        return false;
    }

    // obtain changed values / result values
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();

```


---

### listSubscribeRooms

プレイヤーが購読中のルーム一覧を取得する<br>

新着メッセージ通知を受け取るために購読しているチャットルームの一覧を取得します。<br>
チャットUIで「購読中のルーム」リストを表示し、プレイヤーが気になるルームにすぐアクセスできるようにする際に使います。

#### Request

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128文字 | ネームスペース名<br>ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| gameSession | GameSession | | ✓|  |  | GameSession |
| pageToken | string |  | |  |  ~ 1024文字 | データの取得を開始する位置を指定するトークン |
| limit | int |  | | 30 | 1 ~ 1000 | データの取得件数 |

#### Result

|  | 型 | 説明 |
| --- | --- | --- |
| items | [List&lt;EzSubscribe&gt;](#ezsubscribe) | ルーム購読のリスト|
| nextPageToken | string | リストの続きを取得するためのページトークン|

#### 実装例




**Unity (UniTask)**
```csharp
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var items = await domain.SubscribesAsync(
    ).ToListAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var it = domain.Subscribes(
    );
    List<EzSubscribe> items = new List<EzSubscribe>();
    while (it.HasNext())
    {
        yield return it.Next();
        if (it.Error != null)
        {
            onError.Invoke(it.Error, null);
            break;
        }
        if (it.Current != null)
        {
            items.Add(it.Current);
        }
        else
        {
            break;
        }
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    );
    const auto It = Domain->Subscribes(
    );
    TArray<Gs2::UE5::Chat::Model::FEzSubscribePtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

```


##### 値の変更イベントハンドリング




**Unity (UniTask)**
```csharp
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    
    // イベントハンドリングを開始
    var callbackId = domain.SubscribeSubscribes(
        () => {
            // リストの要素が変化した時に呼び出される
        }
    );

    // イベントハンドリングを停止
    domain.UnsubscribeSubscribes(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    
    // イベントハンドリングを開始
    var callbackId = domain.SubscribeSubscribes(
        () => {
            // リストの要素が変化した時に呼び出される
        }
    );

    // イベントハンドリングを停止
    domain.UnsubscribeSubscribes(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    );
    
    // イベントハンドリングを開始
    const auto CallbackId = Domain->SubscribeSubscribes(
        []() {
            // リストの要素が変化した時に呼び出される
        }
    );

    // イベントハンドリングを停止
    Domain->UnsubscribeSubscribes(CallbackId);

```


{{% alert title="Warning" color="warning" %}}このイベントはSDKがもつローカルキャッシュの値が変更された時に呼び出されます。

ローカルキャッシュは SDK が持つ API の実行、または GS2-Gateway の通知を有効にした GS2-Distributor 経由でのスタンプシートの実行、または GS2-Gateway の通知を有効にした GS2-JobQueue の実行によって変化したもののみが対象となります。

そのため、これらの方法以外で値が変更されてもコールバックは呼び出されません。
{{% /alert %}}

---

### subscribe

チャットルームを購読する<br>

チャットルームを購読して、新しいメッセージが投稿されたときに通知を受け取れるようにします。<br>
カテゴリの条件を設定することで、どのメッセージで通知を受け取るかをフィルタリングできます。<br>
たとえば「カテゴリ1（スタンプ）のときだけ通知する」「すべてのカテゴリで通知する」といった設定が可能です。<br>
通知を受けたときにプレイヤーがオフラインの場合、モバイルプッシュ通知として転送することもできます（ネームスペースの設定に依存）。

#### Request

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128文字 | ネームスペース名<br>ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| roomName | string |  | ✓|  |  ~ 128文字 | 購読するルーム名<br>購読するチャットルームの名前です。購読すると、このルームに新しいメッセージが投稿されるたびに GS2-Gateway 経由でプッシュ通知が送信されます。 |
| gameSession | GameSession | | ✓|  |  | GameSession |
| notificationTypes | [List&lt;EzNotificationType&gt;](#eznotificationtype) |  | | [] | 0 ~ 100 items | 新着メッセージ通知を受け取るカテゴリリスト<br>プッシュ通知をトリガーするメッセージカテゴリーをフィルタリングします。空の場合、すべてのカテゴリーで通知が送信されます。各エントリーはカテゴリー番号とオプションのモバイルプッシュ通知転送を指定します。 |

#### Result

|  | 型 | 説明 |
| --- | --- | --- |
| item | [EzSubscribe](#ezsubscribe) | ルーム購読|

#### 実装例




**Unity (UniTask)**
```csharp
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Subscribe(
        roomName: "room-0001"
    );
    var result = await domain.SubscribeAsync(
        notificationTypes: new List<Gs2.Unity.Gs2Chat.Model.EzNotificationType> {
            new Gs2.Unity.Gs2Chat.Model.EzNotificationType {
            },
        }
    );
    var item = await result.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Subscribe(
        roomName: "room-0001"
    );
    var future = domain.SubscribeFuture(
        notificationTypes: new List<Gs2.Unity.Gs2Chat.Model.EzNotificationType> {
            new Gs2.Unity.Gs2Chat.Model.EzNotificationType {
            },
        }
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.ModelFuture();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Subscribe(
        "room-0001" // roomName
    );
    const auto Future = Domain->Subscribe(
        []
        {
            auto v = MakeShared<TArray<TSharedPtr<Gs2::UE5::Chat::Model::FEzNotificationType>>>();
            v->Add(
                MakeShared<Gs2::UE5::Chat::Model::FEzNotificationType>());
            return v;
        }() // notificationTypes
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

    // obtain changed values / result values
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();

```


---

### unsubscribe

チャットルームの購読を解除する<br>

指定したチャットルームの新着メッセージ通知の受け取りを停止します。<br>
グループから抜けたときや、設定画面で通知をオフにしたときなど、プレイヤーがルーム購読を解除する際に使います。

#### Request

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128文字 | ネームスペース名<br>ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| roomName | string |  | ✓|  |  ~ 128文字 | ルーム購読を解除するルーム名<br>購読を解除するチャットルームの名前です。 |
| gameSession | GameSession | | ✓|  |  | GameSession |

#### Result

|  | 型 | 説明 |
| --- | --- | --- |
| item | [EzSubscribe](#ezsubscribe) | 解除したルーム購読|

#### 実装例




**Unity (UniTask)**
```csharp
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Subscribe(
        roomName: "room-0001"
    );
    var result = await domain.UnsubscribeAsync(
    );

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Subscribe(
        roomName: "room-0001"
    );
    var future = domain.UnsubscribeFuture(
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Subscribe(
        "room-0001" // roomName
    );
    const auto Future = Domain->Unsubscribe(
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }
    const auto Result = Future->GetTask().Result();

```


---

### updateSubscribeSetting

購読中のルームの通知設定を変更する<br>

すでに購読しているルームで、どのカテゴリのメッセージで通知を受け取るかを変更します。<br>
たとえば、最初はすべてのカテゴリで購読していたものを、設定画面から「スタンプのみ」に変更するといった使い方ができます。

#### Request

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128文字 | ネームスペース名<br>ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| roomName | string |  | ✓|  |  ~ 128文字 | 購読中のルーム名<br>通知設定を変更する対象の購読中チャットルーム名です。 |
| gameSession | GameSession | | ✓|  |  | GameSession |
| notificationTypes | [List&lt;EzNotificationType&gt;](#eznotificationtype) |  | | [] | 0 ~ 100 items | 新着メッセージ通知を受け取るカテゴリリスト<br>プッシュ通知をトリガーするメッセージカテゴリーをフィルタリングします。空の場合、すべてのカテゴリーで通知が送信されます。各エントリーはカテゴリー番号とオプションのモバイルプッシュ通知転送を指定します。 |

#### Result

|  | 型 | 説明 |
| --- | --- | --- |
| item | [EzSubscribe](#ezsubscribe) | 更新したルーム購読|

#### 実装例




**Unity (UniTask)**
```csharp
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Subscribe(
        roomName: "room-0001"
    );
    var result = await domain.UpdateSubscribeSettingAsync(
        notificationTypes: new List<Gs2.Unity.Gs2Chat.Model.EzNotificationType> {
            new Gs2.Unity.Gs2Chat.Model.EzNotificationType() {},
        }
    );
    var item = await result.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Subscribe(
        roomName: "room-0001"
    );
    var future = domain.UpdateSubscribeSettingFuture(
        notificationTypes: new List<Gs2.Unity.Gs2Chat.Model.EzNotificationType> {
            new Gs2.Unity.Gs2Chat.Model.EzNotificationType() {},
        }
    );
    yield return future;
    if (future.Error != null)
    {
        onError.Invoke(future.Error, null);
        yield break;
    }
    var future2 = future.Result.ModelFuture();
    yield return future2;
    if (future2.Error != null)
    {
        onError.Invoke(future2.Error, null);
        yield break;
    }
    var result = future2.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Subscribe(
        "room-0001" // roomName
    );
    const auto Future = Domain->UpdateSubscribeSetting(
        []
        {
            auto v = MakeShared<TArray<TSharedPtr<Gs2::UE5::Chat::Model::FEzNotificationType>>>();
            v->Add(
                MakeShared<Gs2::UE5::Chat::Model::FEzNotificationType>() {});
            return v;
        }() // notificationTypes
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

    // obtain changed values / result values
    const auto Future2 = Future->GetTask().Result()->Model();
    Future2->StartSynchronousTask();
    if (Future2->GetTask().IsError())
    {
        return Future2->GetTask().Error();
    }
    const auto Result = Future2->GetTask().Result();

```


---

### getCategoryModel

カテゴリ番号を指定してメッセージカテゴリ定義を取得する<br>

カテゴリ番号を指定して、メッセージカテゴリ定義を1件取得します。<br>
取得できる情報には、プレイヤーがこのカテゴリへの投稿を制限されているかどうかが含まれます。<br>
（サーバー側のシステムメッセージ専用カテゴリなどに利用できます）。

#### Request

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128文字 | ネームスペース名<br>ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |
| category | int |  | ✓|  | 0 ~ 2147483645 | カテゴリー<br>メッセージカテゴリーの数値識別子です。このカテゴリー番号で投稿されたメッセージは、プレイヤーの投稿を許可するかなど、このモデルで定義されたルールに従います。 |

#### Result

|  | 型 | 説明 |
| --- | --- | --- |
| item | [EzCategoryModel](#ezcategorymodel) | メッセージカテゴリーモデル|

#### 実装例




**Unity (UniTask)**
```csharp
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).CategoryModel(
        category: 0
    );
    var item = await domain.ModelAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).CategoryModel(
        category: 0
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    )->CategoryModel(
        0 // category
    );
    const auto Future = Domain->Model();
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError())
    {
        return false;
    }

```


##### 値の変更イベントハンドリング




**Unity (UniTask)**
```csharp
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).CategoryModel(
        category: 0
    );
    
    // イベントハンドリングを開始
    var callbackId = domain.Subscribe(
        value => {
            // 値が変化した時に呼び出される
            // value には変更後の値が渡ってくる
        }
    );

    // イベントハンドリングを停止
    domain.Unsubscribe(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).CategoryModel(
        category: 0
    );
    
    // イベントハンドリングを開始
    var callbackId = domain.Subscribe(
        value => {
            // 値が変化した時に呼び出される
            // value には変更後の値が渡ってくる
        }
    );

    // イベントハンドリングを停止
    domain.Unsubscribe(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    )->CategoryModel(
        0 // category
    );
    
    // イベントハンドリングを開始
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Chat::Model::FCategoryModel> value) {
            // 値が変化した時に呼び出される
            // value には変更後の値が渡ってくる
        }
    );

    // イベントハンドリングを停止
    Domain->Unsubscribe(CallbackId);

```


{{% alert title="Warning" color="warning" %}}このイベントはSDKがもつローカルキャッシュの値が変更された時に呼び出されます。

ローカルキャッシュは SDK が持つ API の実行、または GS2-Gateway の通知を有効にした GS2-Distributor 経由でのスタンプシートの実行、または GS2-Gateway の通知を有効にした GS2-JobQueue の実行によって変化したもののみが対象となります。

そのため、これらの方法以外で値が変更されてもコールバックは呼び出されません。
{{% /alert %}}

---

### listCategoryModels

メッセージカテゴリモデルの一覧を取得する<br>

このネームスペースに登録されているすべてのメッセージカテゴリモデルを取得します。<br>
カテゴリを使うとメッセージの種類を分類できます。たとえば、カテゴリ0を通常テキスト、カテゴリ1をスタンプに割り当てるといった使い方です。<br>
カテゴリごとに投稿権限を制御することもできます（例: システムアナウンスはサーバーからのみ投稿可能）。<br>
チャットUIでカテゴリ選択を表示したり、利用可能なメッセージタイプを確認する際に使います。

#### Request

|  | 型 | 有効化条件 | 必須 | デフォルト | 値の制限 | 説明 |
| --- | --- | --- | --- | --- | --- | --- |
| namespaceName | string |  | ✓|  |  ~ 128文字 | ネームスペース名<br>ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。 |

#### Result

|  | 型 | 説明 |
| --- | --- | --- |
| items | [List&lt;EzCategoryModel&gt;](#ezcategorymodel) | メッセージカテゴリーモデルのリスト|

#### 実装例




**Unity (UniTask)**
```csharp
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    );
    var items = await domain.CategoryModelsAsync(
    ).ToListAsync();

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    );
    var it = domain.CategoryModels(
    );
    List<EzCategoryModel> items = new List<EzCategoryModel>();
    while (it.HasNext())
    {
        yield return it.Next();
        if (it.Error != null)
        {
            onError.Invoke(it.Error, null);
            break;
        }
        if (it.Current != null)
        {
            items.Add(it.Current);
        }
        else
        {
            break;
        }
    }

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    );
    const auto It = Domain->CategoryModels(
    );
    TArray<Gs2::UE5::Chat::Model::FEzCategoryModelPtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

```


##### 値の変更イベントハンドリング




**Unity (UniTask)**
```csharp
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    );
    
    // イベントハンドリングを開始
    var callbackId = domain.SubscribeCategoryModels(
        () => {
            // リストの要素が変化した時に呼び出される
        }
    );

    // イベントハンドリングを停止
    domain.UnsubscribeCategoryModels(callbackId);

```

**Unity (Vanilla)**
```cs
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    );
    
    // イベントハンドリングを開始
    var callbackId = domain.SubscribeCategoryModels(
        () => {
            // リストの要素が変化した時に呼び出される
        }
    );

    // イベントハンドリングを停止
    domain.UnsubscribeCategoryModels(callbackId);

```

**Unreal Engine 5**
```cpp
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    );
    
    // イベントハンドリングを開始
    const auto CallbackId = Domain->SubscribeCategoryModels(
        []() {
            // リストの要素が変化した時に呼び出される
        }
    );

    // イベントハンドリングを停止
    Domain->UnsubscribeCategoryModels(CallbackId);

```


{{% alert title="Warning" color="warning" %}}このイベントはSDKがもつローカルキャッシュの値が変更された時に呼び出されます。

ローカルキャッシュは SDK が持つ API の実行、または GS2-Gateway の通知を有効にした GS2-Distributor 経由でのスタンプシートの実行、または GS2-Gateway の通知を有効にした GS2-JobQueue の実行によって変化したもののみが対象となります。

そのため、これらの方法以外で値が変更されてもコールバックは呼び出されません。
{{% /alert %}}

---

## イベントハンドラ

### OnPostNotification

購読しているルームに新しい投稿があったときの通知

 | 名前 | 型 | 説明 |
| --- | --- | --- |
| namespaceName | string |ネームスペース名<br>ネームスペース固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。|
| roomName | string |ルーム名<br>ルーム固有の名前。英数字および -(ハイフン) _(アンダースコア) .(ピリオド)で指定します。|
| userId | string |ユーザーID|
| category | int |メッセージ分類用カテゴリ番号<br>メッセージを分類するための数値です。例えば、0 は通常のテキストメッセージ、1 はスタンプ（ステッカー）、その他の値はカスタムメッセージタイプとして使用できます。カテゴリーにより、メッセージに適用される CategoryModel のルールが決まります。|
| createdAt | long |作成日時<br>UNIX 時間・ミリ秒<br>※ サーバーが自動で設定|

#### 実装例





**Unity (UniTask)**
```csharp

    gs2.Chat.OnPostNotification += notification =>
    {
        var namespaceName = notification.NamespaceName;
        var roomName = notification.RoomName;
        var userId = notification.UserId;
        var category = notification.Category;
        var createdAt = notification.CreatedAt;
    };
```

**Unity (Vanilla)**
```cs

    gs2.Chat.OnPostNotification += notification =>
    {
        var namespaceName = notification.NamespaceName;
        var roomName = notification.RoomName;
        var userId = notification.UserId;
        var category = notification.Category;
        var createdAt = notification.CreatedAt;
    };
```

**Unreal Engine 5**
```cpp

    Gs2->Chat->OnPostNotification().AddLambda([](const auto Notification)
    {
        const auto NamespaceName = Notification->NamespaceNameValue;
        const auto RoomName = Notification->RoomNameValue;
        const auto UserId = Notification->UserIdValue;
        const auto Category = Notification->CategoryValue;
        const auto CreatedAt = Notification->CreatedAtValue;
    });
```


---



