GS2-Chat SDK for Game Engine API Reference

Specifications of models and API references for GS2-Chat SDK for Game Engine

Model

EzRoom

Room

A room represents the scope within which chat messages can be delivered. GS2-Chat rooms do not have the concept of participation. Therefore, to receive messages, it is sufficient to know the room name, and there is no need to join the room or register as a member.

If you wish to limit the number of game players who can view the messages in a room, there are two options. The first is to set a password for the room. Second, you can whitelist the room and limit the game players by setting their user IDs in the whitelist.

Note that if you set a password, even the game administrator will not be able to retrieve messages without knowing the password. This is because this may fall under the secret of communication stipulated in the Constitution of Japan.

If you subscribe to a room, you can receive GS2-Gateway push notifications when new messages are sent to the room. By using this notification function, you will be able to know if there are any new messages without polling the room.

TypeConditionRequiredDefaultValue LimitsDescription
namestring
UUID~ 128 charsRoom name
Room-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
metadatastring~ 1024 charsMetadata
Arbitrary values can be set in the metadata.
Since they do not affect GS2’s behavior, they can be used to store information used in the game.
whiteListUserIdsList<string>[]0 ~ 1000 itemsList of user IDs with access to the room
When set, only the listed users can retrieve and post messages in the room. If empty, access is not restricted by user ID (though a password may still be required).

EzMessage

Message

Messages are data posted to a room.

It has a field called category, which allows classification of messages. For example, a category of 0 is interpreted as a normal text message, while a category of 1 can be processed as a stamp (sticker).

Messages posted will be automatically deleted after the message retention period set in the Chat Namespace’s messageLifeTimeDays setting has elapsed.

TypeConditionRequiredDefaultValue LimitsDescription
namestring
UUID~ 36 charsMessage Name
Maintains a unique name for each message.
Names are automatically generated in UUID (Universally Unique Identifier) format and used to identify each message.
roomNamestring
UUID~ 128 charsRoom name
Room-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
userIdstring
~ 128 charsUser ID
categoryint00 ~ 2147483645Type number when you want to classify message types.
A numeric value used to classify messages. For example, 0 can represent text messages, 1 can represent stamps/stickers, and other values can represent custom message types. The category determines which CategoryModel rules apply to the message.
metadatastring
~ 1024 charsMetadata
Arbitrary values can be set in the metadata.
Since they do not affect GS2’s behavior, they can be used to store information used in the game.
createdAtlong
*
NowDatetime of creation
Unix time, milliseconds
* Set automatically by the server

EzSubscribe

Room Subscription

By subscribing to a room, you will be instantly informed of new Messages for that room. When subscribing, you can specify the category of the message. This feature can be used to subscribe only to Messages that are of high importance to you.

TypeConditionRequiredDefaultValue LimitsDescription
userIdstring
~ 128 charsUser ID
roomNamestring
~ 128 charsRoom name to subscribe to
The name of the chat room to subscribe to. When subscribed, push notifications are sent via GS2-Gateway whenever new messages are posted to this room.
notificationTypesList<EzNotificationType>[]0 ~ 100 itemsList of categories to receive notifications of new Messages
Filters which message categories trigger push notifications. If empty, notifications are sent for all categories. Each entry specifies a category number and optional mobile push notification forwarding.

EzCategoryModel

Category Model

Category Model defines the categories used to classify messages posted in chat rooms. Each category is identified by a numeric value, and you can configure whether posts using player access tokens are allowed or rejected per category. This enables use cases such as system-only announcement categories where only the server can post messages.

TypeConditionRequiredDefaultValue LimitsDescription
categoryint
0 ~ 2147483645Category
A numeric identifier for the message category. Messages posted with this category number will follow the rules defined in this model, such as whether player posts are allowed or rejected.
rejectAccessTokenPostString Enum
enum {
  “Enabled”,
  “Disabled”
}
Reject posts made using player access tokens
When enabled, only server-side API calls (using user ID specification) can post messages in this category. This is useful for system announcements or server-generated messages that should not be posted by players directly.
DefinitionDescription
“Enabled”Reject posts made using player access tokens
“Disabled”Allow posts made using player access tokens

EzNotificationType

Notification Type

Configuration of categories for receiving new message notifications

TypeConditionRequiredDefaultValue LimitsDescription
categoryint00 ~ 2147483646Categories for which you receive new message notifications
The numeric category identifier to filter notifications. Only messages matching this category will trigger a push notification for the subscription.
enableTransferMobilePushNotificationboolfalseWhether to forward to mobile push notifications when offline
When enabled, if the recipient device is offline at the time of notification, the notification is forwarded to the mobile push notification service. This allows players to be notified of new messages even when the game is not running.

Methods

createRoom

Create a chat room

Creates a new chat room where players can send and receive messages. The namespace settings must allow players to create rooms; otherwise this call will fail.

You can optionally set a password on the room. If a password is set, it must be provided to post or read messages. You can also set a whitelist of user IDs to restrict who can access the room.

Request

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
namestringUUID~ 128 charsRoom name
Room-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
gameSessionGameSessionGameSession
The user ID of the room owner. When set, only the owner can delete the room. Setting an owner is optional.
metadatastring~ 1024 charsMetadata
Arbitrary values can be set in the metadata.
Since they do not affect GS2’s behavior, they can be used to store information used in the game.
passwordstring~ 128 charsPassword required to access the room
When set, the password must be provided to retrieve or post messages. The password value cannot be referenced again after setting. Even game administrators cannot access messages without the password, as this may fall under communication privacy protections.
whiteListUserIdsList<string>[]0 ~ 1000 itemsList of user IDs with access to the room
When set, only the listed users can retrieve and post messages in the room. If empty, access is not restricted by user ID (though a password may still be required).

Result

TypeDescription
itemEzRoomRoom created

Error

Special exceptions are defined in this API. GS2-SDK for GameEngine provides specialized exceptions derived from general exceptions to facilitate handling of errors that may need to be handled in games. Please refer to the documentation here for more information on common error types and handling methods.

TypeBase TypeDescription
NoAccessPrivilegesExceptionBadRequestExceptionThe whitelist configured for the room does not contain any currently logged in user.

Implementation Example

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.
}
    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;
    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

Delete a chat room

Deletes a chat room that the player has created. Only the player who created the room (the owner) can delete it. All messages in the room will also be removed.

Request

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
roomNamestring
UUID~ 128 charsRoom Name
Room-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
gameSessionGameSessionGameSession
The user ID of the room owner. When set, only the owner can delete the room. Setting an owner is optional.

Result

TypeDescription
itemEzRoomRoom deleted

Error

Special exceptions are defined in this API. GS2-SDK for GameEngine provides specialized exceptions derived from general exceptions to facilitate handling of errors that may need to be handled in games. Please refer to the documentation here for more information on common error types and handling methods.

TypeBase TypeDescription
NoAccessPrivilegesExceptionBadRequestExceptionThe whitelist configured for the room does not contain any currently logged in user.

Implementation Example

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.
}
    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;
    }
    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

Get chat room information

Retrieves the information of a specified chat room, such as its metadata and creation date. This does not require a password, even if the room has one set. Use this to display room details (e.g., room name or topic) before the player enters the room.

Request

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
roomNamestring
UUID~ 128 charsRoom Name
Room-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).

Result

TypeDescription
itemEzRoomRoom

Implementation Example

    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).User(
        userId: null
    ).Room(
        roomName: "room-0001",
        password: null
    );
    var item = await domain.ModelAsync();
    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;
    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;
    }
Value change event handling
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).User(
        userId: null
    ).Room(
        roomName: "room-0001",
        password: null
    );
    
    // Start event handling
    var callbackId = domain.Subscribe(
        value => {
            // Called when the value changes
            // The "value" is passed the value after the change.
        }
    );

    // Stop event handling
    domain.Unsubscribe(callbackId);
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).User(
        userId: null
    ).Room(
        roomName: "room-0001",
        password: null
    );
    
    // Start event handling
    var callbackId = domain.Subscribe(
        value => {
            // Called when the value changes
            // The "value" is passed the value after the change.
        }
    );

    // Stop event handling
    domain.Unsubscribe(callbackId);
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    )->User(
        nullptr // userId
    )->Room(
        "room-0001", // roomName
        nullptr // password
    );
    
    // Start event handling
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Chat::Model::FRoom> value) {
            // Called when the value changes
            // The "value" is passed the value after the change.
        }
    );

    // Stop event handling
    Domain->Unsubscribe(CallbackId);

getMessage

Get a specific message by name

Retrieves a single message from a chat room by specifying its message name (ID). Use this to display the details of a specific message, such as when the player taps on a notification.

If the room has a password, it must be provided.

Request

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
roomNamestring
~ 128 charsRoom Name
Room-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
messageNamestring
UUID~ 36 charsMessage Name
Maintains a unique name for each message.
Names are automatically generated in UUID (Universally Unique Identifier) format and used to identify each message.
gameSessionGameSessionGameSession
passwordstring~ 128 charsPassword

Result

TypeDescription
itemEzMessageMessage

Error

Special exceptions are defined in this API. GS2-SDK for GameEngine provides specialized exceptions derived from general exceptions to facilitate handling of errors that may need to be handled in games. Please refer to the documentation here for more information on common error types and handling methods.

TypeBase TypeDescription
NoAccessPrivilegesExceptionBadRequestExceptionThe whitelist configured for the room does not contain any currently logged in user.
PasswordRequiredExceptionBadRequestExceptionA password must be set to access the room.
PasswordIncorrectExceptionBadRequestExceptionThe password set for the room does not match the password specified.

Implementation Example

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 set to access the room.
} catch(Gs2.Gs2Chat.Exception.PasswordIncorrectException e) {
    // The password set for the room does not match the password specified.
}
    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;
    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 set 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;
    }
Value change event handling
try {
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Room(
        roomName: "room-0001",
        password: null
    ).Message(
        messageName: "message-0001"
    );
    
    // Start event handling
    var callbackId = domain.Subscribe(
        value => {
            // Called when the value changes
            // The "value" is passed the value after the change.
        }
    );

    // Stop event handling
    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 set to access the room.
} catch(Gs2.Gs2Chat.Exception.PasswordIncorrectException e) {
    // The password set for the room does not match the password specified.
}
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Room(
        roomName: "room-0001",
        password: null
    ).Message(
        messageName: "message-0001"
    );
    
    // Start event handling
    var callbackId = domain.Subscribe(
        value => {
            // Called when the value changes
            // The "value" is passed the value after the change.
        }
    );

    // Stop event handling
    domain.Unsubscribe(callbackId);
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Room(
        "room-0001", // roomName
        nullptr // password
    )->Message(
        "message-0001" // messageName
    );
    
    // Start event handling
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Chat::Model::FMessage> value) {
            // Called when the value changes
            // The "value" is passed the value after the change.
        }
    );

    // Stop event handling
    Domain->Unsubscribe(CallbackId);

listLatestMessages

Get the latest messages in a chat room

Retrieves the most recent messages in a chat room, in reverse chronological order (newest first). Use this when you want to show the latest conversation when a player first opens the chat screen.

If the room has a password, it must be provided.

Request

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
roomNamestring
UUID~ 128 charsRoom name
Room-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
gameSessionGameSession
GameSession
limitint301 ~ 1000Number of data items to retrieve
passwordstring~ 128 charsPassword required to access the room
When set, the password must be provided to retrieve or post messages. The password value cannot be referenced again after setting. Even game administrators cannot access messages without the password, as this may fall under communication privacy protections.

Result

TypeDescription
itemsList<EzMessage>List of Message
nextPageTokenstringPage token to retrieve the rest of the listing

Error

Special exceptions are defined in this API. GS2-SDK for GameEngine provides specialized exceptions derived from general exceptions to facilitate handling of errors that may need to be handled in games. Please refer to the documentation here for more information on common error types and handling methods.

TypeBase TypeDescription
NoAccessPrivilegesExceptionBadRequestExceptionThe whitelist configured for the room does not contain any currently logged in user.
PasswordRequiredExceptionBadRequestExceptionA password must be set to access the room.
PasswordIncorrectExceptionBadRequestExceptionThe password set for the room does not match the password specified.

Implementation Example

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 set to access the room.
} catch(Gs2.Gs2Chat.Exception.PasswordIncorrectException e) {
    // The password set for the room does not match the password specified.
}
    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;
        }
    }
    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

Get messages in a chat room (from a specific time)

Retrieves messages posted at or after the specified startAt time, in chronological order (oldest first). Use this when you want to fetch messages since the player last checked, for example after reconnecting or opening the chat screen.

Only messages within the retention period configured in the namespace settings can be retrieved. If the room has a password, it must be provided.

Request

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
roomNamestring
UUID~ 128 charsRoom name
Room-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
gameSessionGameSession
GameSession
startAtlongThe absolute time 1 hour prior to the current timeStart time for message retrieval
Unix time, milliseconds
limitint301 ~ 1000Number of data items to retrieve
passwordstring~ 128 charsPassword required to access the room
When set, the password must be provided to retrieve or post messages. The password value cannot be referenced again after setting. Even game administrators cannot access messages without the password, as this may fall under communication privacy protections.

Result

TypeDescription
itemsList<EzMessage>List of Message

Error

Special exceptions are defined in this API. GS2-SDK for GameEngine provides specialized exceptions derived from general exceptions to facilitate handling of errors that may need to be handled in games. Please refer to the documentation here for more information on common error types and handling methods.

TypeBase TypeDescription
NoAccessPrivilegesExceptionBadRequestExceptionThe whitelist configured for the room does not contain any currently logged in user.
PasswordRequiredExceptionBadRequestExceptionA password must be set to access the room.
PasswordIncorrectExceptionBadRequestExceptionThe password set for the room does not match the password specified.

Implementation Example

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 set to access the room.
} catch(Gs2.Gs2Chat.Exception.PasswordIncorrectException e) {
    // The password set for the room does not match the password specified.
}
    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;
        }
    }
    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());
    }
Value change event handling
try {
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Room(
        roomName: "room-0001",
        password: null
    );
    
    // Start event handling
    var callbackId = domain.SubscribeMessages(
        () => {
            // Called when an element of the list changes.
        }
    );

    // Stop event handling
    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 set to access the room.
} catch(Gs2.Gs2Chat.Exception.PasswordIncorrectException e) {
    // The password set for the room does not match the password specified.
}
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Room(
        roomName: "room-0001",
        password: null
    );
    
    // Start event handling
    var callbackId = domain.SubscribeMessages(
        () => {
            // Called when an element of the list changes.
        }
    );

    // Stop event handling
    domain.UnsubscribeMessages(callbackId);
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    )->Room(
        "room-0001", // roomName
        nullptr // password
    );
    
    // Start event handling
    const auto CallbackId = Domain->SubscribeMessages(
        []() {
            // Called when an element of the list changes.
        }
    );

    // Stop event handling
    Domain->UnsubscribeMessages(CallbackId);

post

Post a message to a chat room

Sends a message to the specified chat room. You can attach a category number to classify the message type (e.g., 0 for text, 1 for stamps/stickers). The message content is stored in metadata as a free-format string — you can use it for text, JSON, or any data your game needs. If the room has a password, it must be provided to post.

Request

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
roomNamestring
~ 128 charsRoom Name
Room-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
gameSessionGameSession
GameSession
categoryint00 ~ 2147483645Type number when you want to classify message types.
A numeric value used to classify messages. For example, 0 can represent text messages, 1 can represent stamps/stickers, and other values can represent custom message types. The category determines which CategoryModel rules apply to the message.
metadatastring
~ 1024 charsMetadata
Arbitrary values can be set in the metadata.
Since they do not affect GS2’s behavior, they can be used to store information used in the game.
passwordstring~ 128 charsPassword

Result

TypeDescription
itemEzMessagePosted message

Error

Special exceptions are defined in this API. GS2-SDK for GameEngine provides specialized exceptions derived from general exceptions to facilitate handling of errors that may need to be handled in games. Please refer to the documentation here for more information on common error types and handling methods.

TypeBase TypeDescription
NoAccessPrivilegesExceptionBadRequestExceptionThe whitelist configured for the room does not contain any currently logged in user.
PasswordRequiredExceptionBadRequestExceptionA password must be set to access the room.
PasswordIncorrectExceptionBadRequestExceptionThe password set for the room does not match the password specified.

Implementation Example

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 set to access the room.
} catch(Gs2.Gs2Chat.Exception.PasswordIncorrectException e) {
    // The password set for the room does not match the password specified.
}
    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 set 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;
    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 set 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

Get a list of rooms the player is subscribed to

Retrieves the list of chat rooms that the player has subscribed to for new-message notifications. Use this to show a “subscribed rooms” list in the chat UI, so the player can quickly jump to rooms they care about.

Request

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
gameSessionGameSession
GameSession
pageTokenstring~ 1024 charsToken specifying the position from which to start acquiring data
limitint301 ~ 1000Number of data items to retrieve

Result

TypeDescription
itemsList<EzSubscribe>List of Room Subscriptions
nextPageTokenstringPage token to retrieve the rest of the listing

Implementation Example

    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    var items = await domain.SubscribesAsync(
    ).ToListAsync();
    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;
        }
    }
    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());
    }
Value change event handling
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    
    // Start event handling
    var callbackId = domain.SubscribeSubscribes(
        () => {
            // Called when an element of the list changes.
        }
    );

    // Stop event handling
    domain.UnsubscribeSubscribes(callbackId);
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    );
    
    // Start event handling
    var callbackId = domain.SubscribeSubscribes(
        () => {
            // Called when an element of the list changes.
        }
    );

    // Stop event handling
    domain.UnsubscribeSubscribes(callbackId);
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        GameSession
    );
    
    // Start event handling
    const auto CallbackId = Domain->SubscribeSubscribes(
        []() {
            // Called when an element of the list changes.
        }
    );

    // Stop event handling
    Domain->UnsubscribeSubscribes(CallbackId);

subscribe

Subscribe to a chat room

Subscribes the player to a chat room so they receive notifications when new messages are posted. You can filter which messages trigger notifications by setting category conditions. For example, you could set it to “only notify for category 1 (stamps)” or “notify for all categories.” If the player is offline when a notification arrives, it can be forwarded as a mobile push notification (depending on namespace settings).

Request

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
roomNamestring
~ 128 charsRoom name to subscribe to
The name of the chat room to subscribe to. When subscribed, push notifications are sent via GS2-Gateway whenever new messages are posted to this room.
gameSessionGameSession
GameSession
notificationTypesList<EzNotificationType>[]0 ~ 100 itemsList of categories to receive notifications of new Messages
Filters which message categories trigger push notifications. If empty, notifications are sent for all categories. Each entry specifies a category number and optional mobile push notification forwarding.

Result

TypeDescription
itemEzSubscribeRoom Subscription

Implementation Example

    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();
    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;
    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

Unsubscribe from a chat room

Stops receiving new-message notifications for the specified chat room. Use this when the player no longer wants to follow a room, such as when they leave a group or turn off notifications from a settings screen.

Request

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
roomNamestring
~ 128 charsRoom name to subscribe to
The name of the chat room to subscribe to. When subscribed, push notifications are sent via GS2-Gateway whenever new messages are posted to this room.
gameSessionGameSession
GameSession

Result

TypeDescription
itemEzSubscribeUnsubscribed room subscription

Implementation Example

    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Subscribe(
        roomName: "room-0001"
    );
    var result = await domain.UnsubscribeAsync(
    );
    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;
    }
    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

Update notification settings for a subscribed room

Changes which message categories trigger notifications for a room the player is already subscribed to. For example, the player might initially subscribe to all categories, then later change it to “stamps only” from a settings screen.

Request

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
roomNamestring
~ 128 charsRoom name to subscribe to
The name of the chat room to subscribe to. When subscribed, push notifications are sent via GS2-Gateway whenever new messages are posted to this room.
gameSessionGameSession
GameSession
notificationTypesList<EzNotificationType>[]0 ~ 100 itemsList of categories to receive notifications of new Messages
Filters which message categories trigger push notifications. If empty, notifications are sent for all categories. Each entry specifies a category number and optional mobile push notification forwarding.

Result

TypeDescription
itemEzSubscribeRenewed Subscriptions

Implementation Example

    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();
    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;
    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

Get a message category definition by number

Retrieves a single message category definition by specifying its category number. The returned information includes whether players are restricted from posting to this category (useful for categories reserved for server-side system messages).

Request

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
categoryint
0 ~ 2147483645Category
A numeric identifier for the message category. Messages posted with this category number will follow the rules defined in this model, such as whether player posts are allowed or rejected.

Result

TypeDescription
itemEzCategoryModelCategory Model

Implementation Example

    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).CategoryModel(
        category: 0
    );
    var item = await domain.ModelAsync();
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).CategoryModel(
        category: 0
    );
    var future = domain.ModelFuture();
    yield return future;
    var item = future.Result;
    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;
    }
Value change event handling
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).CategoryModel(
        category: 0
    );
    
    // Start event handling
    var callbackId = domain.Subscribe(
        value => {
            // Called when the value changes
            // The "value" is passed the value after the change.
        }
    );

    // Stop event handling
    domain.Unsubscribe(callbackId);
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    ).CategoryModel(
        category: 0
    );
    
    // Start event handling
    var callbackId = domain.Subscribe(
        value => {
            // Called when the value changes
            // The "value" is passed the value after the change.
        }
    );

    // Stop event handling
    domain.Unsubscribe(callbackId);
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    )->CategoryModel(
        0 // category
    );
    
    // Start event handling
    const auto CallbackId = Domain->Subscribe(
        [](TSharedPtr<Gs2::Chat::Model::FCategoryModel> value) {
            // Called when the value changes
            // The "value" is passed the value after the change.
        }
    );

    // Stop event handling
    Domain->Unsubscribe(CallbackId);

listCategoryModels

Get a list of message category definitions

Retrieves all message category definitions registered in this namespace. Categories let you classify messages by type — for example, category 0 for normal text and category 1 for stamps/stickers. You can also control posting permissions per category (e.g., allow only the server to post system announcements). Use this to build a category selector or to check available message types in the chat UI.

Request

TypeConditionRequiredDefaultValue LimitsDescription
namespaceNamestring
~ 128 charsNamespace name
Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).

Result

TypeDescription
itemsList<EzCategoryModel>List of Category Models

Implementation Example

    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    );
    var items = await domain.CategoryModelsAsync(
    ).ToListAsync();
    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;
        }
    }
    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());
    }
Value change event handling
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    );
    
    // Start event handling
    var callbackId = domain.SubscribeCategoryModels(
        () => {
            // Called when an element of the list changes.
        }
    );

    // Stop event handling
    domain.UnsubscribeCategoryModels(callbackId);
    var domain = gs2.Chat.Namespace(
        namespaceName: "namespace-0001"
    );
    
    // Start event handling
    var callbackId = domain.SubscribeCategoryModels(
        () => {
            // Called when an element of the list changes.
        }
    );

    // Stop event handling
    domain.UnsubscribeCategoryModels(callbackId);
    const auto Domain = Gs2->Chat->Namespace(
        "namespace-0001" // namespaceName
    );
    
    // Start event handling
    const auto CallbackId = Domain->SubscribeCategoryModels(
        []() {
            // Called when an element of the list changes.
        }
    );

    // Stop event handling
    Domain->UnsubscribeCategoryModels(CallbackId);

Event Handler

OnPostNotification

Push notification sent when a new message is posted to a subscribed room

NameTypeDescription
namespaceNamestringNamespace name
Namespace-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
roomNamestringRoom name
Room-specific name. Specified using alphanumeric characters, hyphens (-), underscores (_), and periods (.).
userIdstringUser ID
categoryintType number when you want to classify message types.
A numeric value used to classify messages. For example, 0 can represent text messages, 1 can represent stamps/stickers, and other values can represent custom message types. The category determines which CategoryModel rules apply to the message.
createdAtlongDatetime of creation
Unix time, milliseconds
* Set automatically by the server

Implementation Example

    gs2.Chat.OnPostNotification += notification =>
    {
        var namespaceName = notification.NamespaceName;
        var roomName = notification.RoomName;
        var userId = notification.UserId;
        var category = notification.Category;
        var createdAt = notification.CreatedAt;
    };
    gs2.Chat.OnPostNotification += notification =>
    {
        var namespaceName = notification.NamespaceName;
        var roomName = notification.RoomName;
        var userId = notification.UserId;
        var category = notification.Category;
        var createdAt = notification.CreatedAt;
    };
    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;
    });