Manage system inbox notifications
Overview
AccelByte Gaming Services (AGS) Chat includes a system inbox notifications feature that enables you to send persistent system notifications to players' inboxes. Examples of system inbox notifications you can send include in-game news, in-game mail, redemption codes, penalty notifications, player report notifications, maintenance schedules, current events, and more. You can also delete or unsend any notifications from a player's inbox, if necessary.
This article explains how to manage system inbox notifications in the AGS Admin Portal or with the AGS CLI, and how to integrate them into your game client.
Prerequisites
Administrators must have the following permissions to manage system inbox notifications:
| Permissions | Action | Usage |
|---|---|---|
ADMIN:NAMESPACE:{namespace}:CHAT:INBOX | CREATE, READ, UPDATE, DELETE | To create, query, edit and remove notifications. |
ADMIN:NAMESPACE:{namespace}:CHAT:INBOX | CREATE, READ, UPDATE, DELETE | To create system message. |
To follow the AGS CLI steps, install the AGS CLI and sign in with an account that has the permissions above. See Install and sign in. The examples use a Bash shell.
Access the system messages page
To access the management and configuration options outlined in the following sections, log in to your AGS Admin Portal and go to your game namespace dashboard. Then, go to Multiplayer > Chat > System Messages.
Manage system inbox notifications
The following sections detail the management of system inbox notifications.
Create, save, and send a notification
To create and send a new system inbox notification, follow these steps:
- Admin Portal
- AGS CLI
-
On the System Messages page, click the + Create new.
-
Fill out the Create New Message page with the content, recipient, and notification details of your message.
-
Click Save as Draft to send the message later, or click Send to send the message right away.
-
Create a JSON file with the notification. Any file name works. This example uses
message.json:{
"message": {"title": "<Title>", "body": "<Body>", "gift": {}},
"scope": "USER",
"userIds": ["<UserId>"],
"expiredAt": <ExpiredAt>,
"status": "DRAFT"
}message: the content of the notification.titleandbodymatch the Admin Portal's Content fields, andgiftholds the In-game Gift Payload. Use{}for no gift.scopeanduserIds: to send the notification to specific players, setscopetoUSERand list their user IDs inuserIds. To send it to all players, setscopetoNAMESPACEanduserIdsto[]. The Admin Portal also accepts usernames and emails, but the AGS CLI only accepts user IDs.expiredAt: when the notification expires, as a Unix timestamp in seconds. The Admin Portal takes the number of days instead, and uses 30 days if you leave it blank. It must be in the future. On Linux,date -d '+1 day' +%sprints the timestamp for one day from now.status:DRAFTto save the notification as a draft, orSENTto send it right away.
-
Create the notification. After
@, pass the path to your JSON file:ags chat inbox create-message --namespace <YourNamespace> --json @message.jsonThe command prints the new notification, including its
id.
Unsend a notification
- Admin Portal
- AGS CLI
-
On the System Messages page, find the sent notification you want to unsend listed under the System Messages List section.
-
Next to the sent notification, click the ellipsis menu next to it under the Action column. Then, click Unsend.
-
On the confirmation box, type
UNSENDand click Unsend to confirm.
-
Find the ID of the sent notification:
ags chat inbox list-messages --namespace <YourNamespace> --transient false --status SENT -
Unsend the notification. Replace
<MessageId>with the notification'sid:ags chat inbox unsend-message --namespace <YourNamespace> --inbox <MessageId> --json '{"userIds": []}'An empty
userIdslist removes the notification from every recipient's inbox and marks it as unsent. To remove it from specific players only, list their user IDs instead.
View, edit, and send draft notifications
- Admin Portal
- AGS CLI
-
On the System Messages page, find the draft notification you want to view, edit, or send listed under the System Messages List section.
-
Next to the draft notification, click the View option next to it under the Action column.
-
Review the information and make any desired changes.
-
Click Save as Draft to update the message without sending, or click Send to send the message right away.
-
Find the draft notification and review its settings:
ags chat inbox list-messages --namespace <YourNamespace> --transient false --status DRAFT --format json -
To edit the draft, create a JSON file with the notification's new settings. This example uses
message.json:{
"message": {"title": "<Title>", "body": "<Body>", "gift": {}},
"scope": "USER",
"userIds": ["<UserId>"],
"expiredAt": <ExpiredAt>
}The fields work the same as in Create, save, and send a notification.
warningEvery update overwrites the content, recipients, and expiry time. Include all four fields, even the ones you don't change.
-
Save your changes. Replace
<MessageId>with the draft'sidfrom step 1. After@, pass the path to your JSON file:ags chat inbox update-message --namespace <YourNamespace> --message-id <MessageId> --json @message.json -
To send the draft, run:
ags chat inbox send-message --namespace <YourNamespace> --message-id <MessageId>
Integrate system inbox notification into the game client
The example below shows you how to integrate system inbox notification into the game client:
- Unreal Engine
- Unity
// Create API client, login, and connect to AGS Chat
FApiClientPtr ApiClient = AccelByteOnlineSubsystemPtr->GetApiClient(TEXT("0"));
ApiClient->User.LoginWithUsername(TEXT("user+a@example.com"), TEXT("Password321"),
FVoidHandler::CreateLambda([]()
{
UE_LOG(LogTemp, Log, TEXT("Login User A successful"));
}),
FErrorHandler::CreateLambda([](int Code, FString const& Message)
{
UE_LOG(LogTemp, Log, TEXT("Login User A failed"));
}));
ApiClient->Chat.Connect();
// Set delegate for incoming system message notification
ApiClient->Chat.SetSystemMessageNotifDelegate(
Api::Chat::FSystemMessageNotif::CreateLambda([](const FAccelByteModelsChatSystemMessageNotif&
Notif)
{
UE_LOG(LogTemp, Log, TEXT("Got System Message: %s %s %s"), *Notif.MessageId, *Notif.Message,
*Notif.Category);
}));
// Query system message
{
FAccelByteModelsQuerySystemMessagesResponse Result;
Chat::FQuerySystemMessageResponse OnSuccess = Chat::FQuerySystemMessageResponse::CreateLambda(
[&Result](const FAccelByteModelsQuerySystemMessagesResponse& Response)
{
Result = Response;
});
FErrorHandler OnError = FErrorHandler::CreateLambda([](int32 Code, const FString& Message)
{
UE_LOG(LogTemp, Error, TEXT("Failed query chat system message %d, %s"), Code, *Message);
});
ApiClient->Chat.QuerySystemMessage(OnSuccess, OnError);
}
// Update system message (mark read/unread or keep messages)
{
FAccelByteModelsActionUpdateSystemMessage Action;
Action.ID = TEXT("message-id");
Action.Read = EAccelByteOptionalBool::NO; // mark message as unread
Action.Keep = EAccelByteOptionalBool::YES; // mark message to keep in inbox
Chat::FUpdateSystemMessagesResponse OnSuccess =
Chat::FUpdateSystemMessagesResponse::CreateLambda(
[](const FAccelByteModelsUpdateSystemMessagesResponse& Response)
{
UE_LOG(LogTemp, Log, TEXT("Update system message success"));
});
FErrorHandler OnError = FErrorHandler::CreateLambda([](int32 Code, const FString& Message)
{
UE_LOG(LogTemp, Error, TEXT("Failed update chat system message %d, %s"), Code, *Message);
});
ApiClient->Chat.UpdateSystemMessages({Action}, OnSuccess, OnError);
}
// Delete system message
{
Chat::FDeleteSystemMessagesResponse OnSuccess =
Chat::FDeleteSystemMessagesResponse::CreateLambda(
[](const FAccelByteModelsDeleteSystemMessagesResponse& Response)
{
UE_LOG(LogTemp, Log, TEXT("Delete system message success"));
});
FErrorHandler OnError = FErrorHandler::CreateLambda([](int32 Code, const FString& Message)
{
UE_LOG(LogTemp, Error, TEXT("Failed delete chat system message %d, %s"), Code, *Message);
});
ApiClient->Chat.DeleteSystemMessages({TEXT("message-id")}, OnSuccess, OnError);
}
// Get system message stats
{
FAccelByteGetSystemMessageStatsResponse Result;
Chat::FGetSystemMessageStatsResponse OnSuccess =
Chat::FGetSystemMessageStatsResponse::CreateLambda(
[&Result](const FAccelByteGetSystemMessageStatsResponse& Response)
{
Result = Response;
});
FErrorHandler OnError = FErrorHandler::CreateLambda([](int32 Code, const FString& Message)
{
UE_LOG(LogAccelByteChatTest, Error, TEXT("Failed get system message stats %d,
%s"), Code, *Message);
});
ApiClient->Chat.GetSystemMessageStats(OnSuccess, OnError);
}
// Create API client, login, and connect to Chat
var apiClient = AccelByteSDK.GetClientRegistry().GetApi();
Result<TokenData, OAuthError> loginResult;
apiClient.GetUser().LoginWithEmailV4(userEmailAddress, userPassword, (Result<TokenData, OAuthError> result) =>
{
loginResult = result;
if (result.IsError)
{
// Handle login error
return;
}
apiClient.GetChat().Connect();
});
// Set delegate for incoming system message notification
apiClient.GetChat().NewSystemMessage += notif =>
{
Debug.Log($"Got new system message: {notif.MessageId} {notif.Message} {notif.Category}");
};
// Query system message
var request = new QuerySystemMessageRequest
{
UnreadOnly = true,
Offset = 0,
Limit = 5
};
QuerySystemMessagesResponse querySystemMessagesResponse = null;
apiClient.GetChat().QuerySystemMessage(result =>
{
if (result.IsError)
{
Debug.LogWarning($"Failed to QuerySystemMessage [{result.Error.Code}]:{result.Error.Message}");
return;
}
querySystemMessagesResponse = result.Value;
}, request);
// Update system message (mark read/unread or keep messages)
UpdateSystemMessagesResponse updateSystemMessagesResponse = null;
var action = new ActionUpdateSystemMessage
{
Id = "messageId",
Read = OptionalBoolean.No,
Keep = OptionalBoolean.Yes
};
apiClient.GetChat().UpdateSystemMessages(new HashSet<ActionUpdateSystemMessage> { action }, result =>
{
if (result.IsError)
{
Debug.LogWarning($"Failed to UpdateSystemMessages [{result.Error.Code}]:{result.Error.Message}");
return;
}
updateSystemMessagesResponse = result.Value;
});
// Delete system message
DeleteSystemMessagesResponse response = null;
var messageIds = new HashSet<string>
{
"messageId1",
"messageId2"
};
apiClient.GetChat().DeleteSystemMessages(messageIds, result =>
{
if (result.IsError)
{
Debug.LogWarning($"Failed to DeleteSystemMessages [{result.Error.Code}]:{result.Error.Message}");
return;
}
response = result.Value;
});
// Get system message stats
GetSystemMessageStatsResponse systemMessageStats = null;
apiClient.GetChat().GetSystemMessagesStats(delegate (Result<GetSystemMessageStatsResponse> result)
{
if (result.IsError)
{
Debug.LogWarning($"Failed to GetSystemMessage [{result.Error.Code}]:{result.Error.Message}");
return;
}
systemMessageStats = result.Value;
Debug.Log($"Stats: {systemMessageStats.Unread} {systemMessageStats.OldestUnread}");
});