GS2-Inbox

Present box feature

This system enables a mechanism for messages and gifts to be delivered to players from the system and management.

Messages

read management

Messages have a read status.
You can choose to keep read messages in the list or remove them from the list.

Attach Reward

Rewards can be attached to messages.
Instead of marking a message as read, you can receive the reward attached to the message.

Expiration Date

Messages can have an expiration date.
Messages that reach their expiration date will be automatically deleted, regardless of whether they are unread or have been read.

It will be deleted even if you did not receive the attached reward.

Global Message

Global Message is defined as master data. Registering master data allows you to configure data and behaviors available to microservices. The types of master data include the following.

  • GlobalMessage: Message definition delivered to all players

Master data can be registered via the management console. Additionally, you can set up workflows to reflect data from GitHub or register via CI using GS2-Deploy.

Script Triggers

By configuring receiveMessageScript, readMessageScript, and deleteMessageScript in the namespace, you can execute custom scripts before and after message reception, opening, and deletion. Scripts can be set to execute synchronously or asynchronously. Asynchronous execution enables external integrations using GS2-Script or Amazon EventBridge.

The main configurable event triggers and script configuration names are as follows:

  • receiveMessageScript (Completion notification: receiveMessageDone): Before and after message receipt
  • readMessageScript (Completion notification: readMessageDone): Before and after message opening
  • deleteMessageScript (Completion notification: deleteMessageDone): Before and after message deletion

Push Notifications

The main push notifications and their configuration names are as follows:

  • receiveNotification: Notify when a message is received

You can also specify settings to forward notifications to mobile push notifications when the notification device is offline, ensuring reliable delivery.

Example implementation

Sending messages

Sending messages cannot be handled by the SDK for the game engine.

Get list of received messages

    var items = await gs2.Inbox.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).MessagesAsync(
    ).ToListAsync();
    const auto It = Gs2->Inbox->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->Messages(
    );
    TArray<Gs2::UE5::Inbox::Model::FEzMessagePtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

Get list of unread messages only

    var items = await gs2.Inbox.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).MessagesAsync(
        isRead: false
    ).ToListAsync();
    const auto It = Gs2->Inbox->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->Messages(
        false // isRead
    );
    TArray<Gs2::UE5::Inbox::Model::FEzMessagePtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

Get a list of only read messages

    var items = await gs2.Inbox.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).MessagesAsync(
        isRead: true
    ).ToListAsync();
    const auto It = Gs2->Inbox->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->Messages(
        true // isRead
    );
    TArray<Gs2::UE5::Inbox::Model::FEzMessagePtr> Result;
    for (auto Item : *It)
    {
        if (Item.IsError())
        {
            return false;
        }
        Result.Add(Item.Current());
    }

Read a message

    var result = await gs2.Inbox.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Message(
        messageName: "message-0001"
    ).ReadAsync(
    );
    const auto Future = Gs2->Inbox->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->Message(
        "message-0001" // messageName
    )->Read(
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError()) return false;

Delete a message

    var result = await gs2.Inbox.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).Message(
        messageName: "message-0001"
    ).DeleteAsync(
    );
    const auto Future = Gs2->Inbox->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->Message(
        "message-0001" // messageName
    )->Delete(
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError()) return false;

Receive global messages

If there are messages in the global message that you have not yet received, Copy the messages to own inbox.

    var result = await gs2.Inbox.Namespace(
        namespaceName: "namespace-0001"
    ).Me(
        gameSession: GameSession
    ).ReceiveGlobalMessageAsync(
    );
    const auto Future = Gs2->Inbox->Namespace(
        "namespace-0001" // namespaceName
    )->Me(
        AccessToken
    )->Message(
        "message-0001" // messageName
    )->Read(
    );
    Future->StartSynchronousTask();
    if (Future->GetTask().IsError()) return false;

Frequently Asked Questions

Can I read messages in bulk?

No, you cannot read messages in bulk. However, you can call the read API in parallel.
When reading multiple messages with rewards attached in parallel, you should carefully consider whether the reward-granting process may exceed the limits defined by each microservice.

For example, GS2-Inventory defines that the quantity of the same item a player owns can be updated no more than three times per second. Reading 10 messages with the same item attached in parallel may exceed this limit.

In principle, no results are lost even if this limit is exceeded. However, after calling the read API, the reward-granting process, which runs asynchronously, may take some time to complete.

Detailed Reference