GS2-Inbox

プレゼントボックス機能

システムや運営からプレイヤーにメッセージやプレゼントを届ける仕組みを実現します。

メッセージ

既読管理

メッセージは既読状態をもちます。
既読状態のメッセージをリストに残すか、リストから削除するかを設定が可能です。

報酬の添付

メッセージには報酬を添付することが可能です。
既読フラグを立てる代わりに、メッセージに添付された報酬を受け取ることができます。

有効期限

メッセージには有効期限を設定できます。
有効期限を迎えたメッセージは、未読状態、開封後の既読状態にかかわらず、自動的に削除されます。

添付された報酬を受け取っていなかったとしても削除されます。

グローバルメッセージ

Global Message はマスターデータとして定義します。
マスターデータを登録することでマイクロサービスで利用可能なデータや振る舞いを設定できます。

マスターデータの種類には以下があります。

  • GlobalMessage: 全プレイヤーに配信するメッセージ定義

マスターデータの登録はマネージメントコンソールから登録する他、GitHubからデータを反映したり、GS2-Deployを使ってCIから登録するようなワークフローを組むことが可能です。

スクリプトトリガー

ネームスペースに receiveMessageScriptreadMessageScriptdeleteMessageScript を設定すると、メッセージ受信、開封、削除時の前後でカスタムスクリプトを実行できます。スクリプトは同期・非同期の実行方式を選択でき、非同期では GS2-Script や Amazon EventBridge を利用した外部連携も可能です。

設定できる主なイベントトリガーとスクリプト設定名は以下の通りです。

  • receiveMessageScript(完了通知: receiveMessageDone): メッセージ受信の前後
  • readMessageScript(完了通知: readMessageDone): メッセージ開封の前後
  • deleteMessageScript(完了通知: deleteMessageDone): メッセージ削除の前後

プッシュ通知

設定できる主なプッシュ通知と設定名は以下の通りです。

  • receiveNotification: メッセージ受信時に通知

通知端末がオフラインの場合にモバイルプッシュ通知へ転送する設定も指定でき、確実な配信を実現できます。

実装例

メッセージを送信

メッセージを送信はゲームエンジン用の SDK では処理できません。

受信したメッセージ一覧を取得

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

未読のメッセージのみの一覧を取得

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

既読のメッセージのみの一覧を取得

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

メッセージを開封

    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;

メッセージを削除

    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;

グローバルメッセージを受信

グローバルメッセージの中でまだ受け取っていないメッセージがある場合、 自分の受信ボックスにメッセージをコピーします。

    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;

よくある質問

メッセージの一括開封はできますか?

できませんが、あなたは開封APIを並列で呼び出すことが可能です。
並列で報酬が設定されているメッセージを開封する場合、報酬付与処理が各マイクロサービスの定義するリミットに達しないかを十分配慮するべきでしょう。

例えば、GS2-Inventory には同一のアイテムの所持数量の更新は1秒間に3回までと定義されています。
同じアイテムが添付された10のメッセージを並列で開封するとこの制限を超えることがあります。

このリミットを超過しても、原則として結果が失われることはありません。
しかし、開封APIを呼び出した後、非同期で動作する報酬付与処理の完了まで時間を要する可能性があります。

詳細なリファレンス