Manage private chats and chat rooms
Overview
AccelByte Gaming Services (AGS) Chat allows you to enable sending and receiving private messages between players and in chat rooms for sessions or parties in your game.
This article walks you through how to:
- Configure a session template to support chat
- Create a new session with a chat room
- Send messages through a session chat room
Parties are managed by AGS Session, so the process for session and party is similar.
In this article, the term "topic" is interchangeable with "chat rooms." Both are a representation of a channel that chat messages can be sent through. Players are automatically subscribed to the chat room when they join the session and removed when they leave.
Prerequisites
To be able to complete all the steps in this article, you will need:
- A familiarity with AGS Lobby, Session, and Chat.
- To have installed the appropriate SDK for your game.
- Access to the appropriate game namespace in the AGS Admin Portal.
Connect to AGS Chat
- OSS
- Unity
Before a player is able to send or receive chat messages, they first need to be authenticated by AGS Identity. This will automatically connect them to Chat with their user account.
If you are using the AGS OSS plugin, you must enable the following config value in the DefaultEngine.ini
file so that users can automatically be connected to AGS Chat after logging in.
[OnlineSubsystemAccelByte]
bAutoChatConnectAfterLoginSuccess=true
Before a player can send or receive chat messages, they first need to be authenticated by AGS Identity. Once the user API client is authenticated, connect the Chat service websocket.
var apiClient = AccelByteSDK.GetClientRegistry().GetApi();
Chat chatService = apiClient.GetChat();
apiClient.GetUser().LoginWithUsernameV3(userEmailAddress, userPassword, (Result<TokenData, OAuthError> result) =>
{
if (result.IsError)
{
// Handle login error
return;
}
chatService.Connected += () =>
{
// Handle successful chat websocket connection
};
chatService.Connect();
});
Send a private message
Players can send a messages directly to other users. You can register the appropriate delegate to listen for when other players are sending a private or direct message.
- Unreal Engine
- OSS
- Unity
// Set up the chat notification delegate. This delegate is called when there are new messages.
ApiClient->Chat.SetChatNotifDelegate(
Api::Chat::FChatNotif::CreateLambda([](const FAccelByteModelsChatNotif& Result)
{
UE_LOG(LogTemp, Log, TEXT("Receive chat! From[%s] content: [%s]"),
*Result.From, *Result.Message);
})
);
// Set up the "added to topic" notification delegate. This is called when a player is added to a topic.
ApiClient->Chat.SetAddToTopicNotifDelegate(
Api::Chat::FAddRemoveFromTopicNotif::CreateLambda([](const
FAccelByteModelsChatUpdateUserTopicNotif& Result)
{
UE_LOG(LogTemp, Log, TEXT("Added to topic [%s] by user [%s]"),
*Result.TopicId, *Result.SenderId);
})
);
// Create a personal topic.
// The target player will receive a notification that they have been added to the topic.
FApiClientPtr ApiClient = FMultiRegistry::GetApiClient(TEXT("0"));
ApiClient->Chat.CreatePersonalTopic(TEXT("target_user_id"),
Api::Chat::FChatActionTopicResponse::CreateLambda(
[](const FAccelByteModelsChatActionTopicResponse& Result)
{
UE_LOG(LogTemp, Log, TEXT("Create personal topic success. Created TopicID:
%s"), *Result.TopicId);
}),
FErrorHandler::CreateLambda([](int32 ErrorCode, FString ErrorMessage)
{
UE_LOG(LogTemp, Error, TEXT("Error code: %d\nError message:%s"), ErrorCode,
*ErrorMessage);
})
);
// After a personal topic has been created, players can send a chat message to the topic.
// The target player will be notified with a chat notification delegate.
FApiClientPtr ApiClient = FMultiRegistry::GetApiClient(TEXT("0"));
ApiClient->Chat.SendChat(TEXT("topic_id"), TEXT("message to send"),
Api::Chat::FSendChatResponse::CreateLambda(
[](const FAccelByteModelsChatSendChatResponse& Result)
{
UE_LOG(LogTemp, Log, TEXT("Send message to topic success."));
}),
FErrorHandler::CreateLambda([](int32 ErrorCode, FString ErrorMessage)
{
UE_LOG(LogTemp, Error, TEXT("Error code: %d\nError message:%s"), ErrorCode,
*ErrorMessage);
})
);
// Listen for the "private message received" notification.
auto ChatPrivateMessageReceivedHandle =
ChatInterface->AddOnChatPrivateMessageReceivedDelegate_Handle(
FOnChatPrivateMessageReceivedDelegate::CreateLambda(
[&ReceivedPrivateMessage](const FUniqueNetId& LocalUserId, const TSharedRef<FChatMessage>& ChatMessage)
{
ReceivedPrivateMessage = ChatMessage->GetBody();
}));
// Bind this delegate to listen if the chat message was successfully sent through the service.
auto ChatRoomMessageSentHandle = ChatInterface->AddOnSendChatCompleteDelegate_Handle(
FOnSendChatCompleteDelegate::CreateLambda([](FString UserId, FString MsgBody, FString RoomId, bool bWasSuccessful)
{
// Handle success or failure here.
}));
TSharedPtr<const FUniqueNetId> LocalUserId;
FString TestPrivateMessage = TEXT("Test Private Message");
// Call SendPrivateChat from the Chat Interface to send the private message.
// You must have acquired the recipientId for the target user.
ChatInterface->SendPrivateChat(LocalUserId.ToSharedRef().Get(), recepientId, TestPrivateMessage);
Coming soon.
Chat rooms are managed at the session level and can be enabled as part of the session template. To configure a session template to be chat enabled, you will need to do so through the API Docs for your environment by following these instructions:
Open the Swagger page for your environment. For example, AccelByte Demo Environment.
Either choose to POST to create a new session template, or PUT to update an existing template. For either option, be sure to set the appropriate values for the request body.
Make sure you have targeted your game namespace and add your request body with
textChat
set totrue
.Execute the request and verify the output indicates it ran successfully.
Sample request Body:
{
"name": "default",
"deployment": "default",
"inactiveTimeout": 60,
"inviteTimeout": 60,
"joinability": "OPEN",
"maxPlayers": 5,
"minPlayers": 1,
"type": "NONE",
"textChat": "true"
}
Create a session chat room
In general, there are no additional steps necessary to create a chat room for a session if it is created using a template that has chat enabled. When using AGS, you will find there are three ways to create a session with a chat room:
Through matchmaking: when a match is found, a game session will be created based on a session template. If the session template has chat enabled, then the session chat room will automatically be created.
A session template: as long as the template has chat enabled, the session chat room will automatically be created.
Creating a session without a session template: This will require you to pass in the required session settings, including setting chat as
true
.
If you need to create a session without a template, then you can use the code sample below to see how to define the session settings prior to calling CreateSession
with chat enabled.
- Unreal Engine
- OSS
- Unity
// This example illustrates how to manually create a party session with a chat room / topic.
FAccelByteModelsV2PartyCreateRequest CreatePartyRequest;
// Set text chat as true or the session.
CreatePartyRequest.TextChat = true;
// Bind this delegate to listen for the player being added to the session chat room / topic.
ApiClient->Chat.SetAddToTopicNotifDelegate(
Api::Chat::FAddToTopicNotif::CreateLambda([](const FAccelByteModelsChatUpdateUserTopicNotif& Result)
{
UE_LOG(LogTemp, Log, TEXT("Added to topic [%s] by user [%s]"), *Result.TopicId, *Result.SenderId);
})
);
// Create the new session with a chat room or topic.
ApiClient->Session.CreateParty(CreatePartyRequest,
THandler<FAccelByteModelsV2PartySession>::CreateLambda(
[](const FAccelByteModelsV2PartySession& Result)
{
UE_LOG(LogTemp, Log, TEXT("Party created"));
}),
FErrorHandler::CreateLambda([](int32 ErrorCode, FString ErrorMessage)
{
UE_LOG(LogTemp, Error, TEXT("Error code: %d\nError message:%s"), ErrorCode, *ErrorMessage);
})
);
// The OSS uses the Session Interface to create and manage parties and sessions.
// Define the session settings for the session you will be creating.
FOnlineSessionSettings NewSessionSettings;
NewSessionSettings.NumPrivateConnections = 4;
NewSessionSettings.Set(SETTING_SESSION_JOIN_TYPE, TEXT("INVITE_ONLY"));
NewSessionSettings.Set(SETTING_SESSION_TYPE, SETTING_SESSION_TYPE_PARTY_SESSION);
NewSessionSettings.Set(SETTING_SESSION_TEMPLATE_NAME, ConfigurationTemplateName);
// Set text chat as true in the session settings.
NewSessionSettings.Set(SETTING_SESSION_TEXTCHAT, true);
// Bind the delegate to listen for the successful creation of the new session.
FName SessionNameResponse = FName(TEXT(""));
auto OnCreateSessionCompleteDelegate = SessionInterface->AddOnCreateSessionCompleteDelegate_Handle(
FOnCreateSessionCompleteDelegate::CreateLambda([&SessionNameResponse](FName SessionName, bool bWasSuccessful)
{
SessionNameResponse = SessionName;
}));
// Bind this delegate to listen for the player being added to the session chat room / topic to acquire information about the room.
FString InTopicId;
auto TopicAddedHandle = ChatInterface->AddOnTopicAddedDelegate_Handle(
FOnTopicAddedDelegate::CreateLambda([&InTopicId](FString ChatTopicName, FString TopicId, FString SenderId)
{
InTopicId = TopicId;
}));
// Create the new session with a chat room / topic.
SessionInterface->CreateSession(LocalUserId.ToSharedRef().Get(), NAME_Session, NewSessionSettings);
// This example illustrates how to manually create a party session with a chat room / topic.
// Make sure that the user's ApiClient is authenticated and their Chat websocket is connected prior to this example.
var apiClient = AccelByteSDK.GetClientRegistry().GetApiClient();
// Bind this delegate to listen for the player being added to the session chat room / topic.
apiClient.GetChat().AddedToTopic += topic =>
{
Debug.Log("Added to topic" + topic.topicId);
};
var createPartyRequest = new SessionV2PartySessionCreateRequest
{
configurationName = configurationTemplateName,
textChat = true // set text chat to true for this session.
};
// Create the new session with a chat room.
Result<SessionV2PartySession> createPartySessionResult = null;
apiClient.GetSession().CreateParty(createPartyRequest, result =>
{
if (!result.IsError)
{
Debug.Log("Party creation success");
}
});
The returned ID (RoomId
/ TopicId
) will have a prefix based on the type of session created:
s.
corresponds to a V2 game session chat room / topicp.
corresponds to V2 party session chat room / topic
Joining a session chat room
When a player joins a session, they will automatically be subscribed to its chat room as a member without additional work.
You can register the appropriate delegate to listen for when other players are added to a chat room.
- Unreal Engine
- OSS
- Unity
// Bind this delegate to listen for the player being added to a session chat room / topic.
ApiClient->Chat.SetAddToTopicNotifDelegate(
Api::Chat::FAddRemoveFromTopicNotif::CreateLambda([](const FAccelByteModelsChatUpdateUserTopicNotif& Result)
{
UE_LOG(LogTemp, Log, TEXT("Added to topic [%s] by user [%s]"), *Result.TopicId, *Result.SenderId);
})
);
FString SessionV2RoomId;
// Bind this delegate to listen for the player being added to a session chat room / topic.
ChatInterface->AddOnChatRoomMemberJoinDelegate_Handle(
FOnChatRoomMemberJoinDelegate::CreateLambda([&SessionV2RoomId](const FUniqueNetId& UserId, const FChatRoomId& RoomId, const FUniqueNetId& MemberId)
{
// The user is automatically added to room / topic on creation or joining a session
const auto RoomType = FOnlineChatAccelByte::GetChatRoomType(RoomId);
if (RoomType == EAccelByteChatRoomType::PARTY_V2)
{
// this is session v2 room
SessionV2RoomId = RoomId;
}
// note: this is triggered for all users
if (UserId == MemberId)
{
// current user has joined the chat room
}
else
{
// another user has joined the chat room
}
}));
// Bind this delegate to listen for the player being added to a session chat room / topic.
apiClient.GetChat().AddedToTopic += topic =>
{
Debug.Log("Added to topic" + topic.topicId);
};
Leaving a session chat room
When a player leaves a session, AGS Session will manage removing them as a member of the chat room, including players who are kicked out of a session.
You can register the appropriate delegate to listen for when a player is removed from a chat room.
- Unreal Engine
- OSS
- Unity
// Bind this delegate to listen for the player being removed from a session chat room / topic.
ApiClient->Chat.SetRemoveFromTopicNotifDelegate(
Api::Chat::FAddRemoveFromTopicNotif::CreateLambda([](const FAccelByteModelsChatUpdateUserTopicNotif& Result)
{
UE_LOG(LogTemp, Log, TEXT("Removed from topic [%s] by user [%s]"), *Result.TopicId, *Result.SenderId);
})
);
// Bind this delegate to listen for the player being removed from a session chat room / topic.
FUniqueNetIdPtr ExitMemberId;
auto MemberExitRoomEventHandle = ChatInterface->AddOnChatRoomMemberExitDelegate_Handle(
FOnChatRoomMemberExitDelegate::CreateLambda([&ExitMemberId](const
FUniqueNetId& UserId, const FChatRoomId& RoomId, const FUniqueNetId& MemberId)
{
ExitMemberId = MemberId.AsShared();
}));
// Bind this delegate to listen for the player being removed from a session chat room / topic.
apiClient.GetChat().RemovedFromTopic += topic =>
{
Debug.Log("Removed from topic " + topic.topicId);
};
Send a session chat message
Once a player is in a chat room, they can start sending messages to the room for other players to receive. Because players can be subscribed to multiple chat rooms, you need to provide the appropriate room/topic ID with the message when requesting to send it to ensure it is delivered to the correct session chat room.
- Unreal Engine
- OSS
- Unity
FApiClientPtr ApiClient = FMultiRegistry::GetApiClient(TEXT("0"));
// Call SendChat from the Chat Interface to send the message.
// You will need to have acquired and stored the ID when the player joins the session chat room / topic.
ApiClient->Chat.SendChat(TEXT("topic_id"), TEXT("message to send"), Api::Chat::FSendChatResponse::CreateLambda(
[](const FAccelByteModelsChatSendChatResponse& Result)
{
UE_LOG(LogTemp, Log, TEXT("Send message to topic success."));
}),
FErrorHandler::CreateLambda([](int32 ErrorCode, FString ErrorMessage)
{
UE_LOG(LogTemp, Error, TEXT("Error code: %d\nError message:%s"), ErrorCode, *ErrorMessage);
})
);
// Bind this delegate to listen if the chat message was successfully sent through the service.
auto ChatRoomMessageSentHandle = ChatInterface->AddOnSendChatCompleteDelegate_Handle(
FOnSendChatCompleteDelegate::CreateLambda([](FString UserId, FString MsgBody, FString RoomId, bool bWasSuccessful)
{
// handle success or failure here
}));
TSharedPtr<const FUniqueNetId> LocalUserId;
// Call SendRoomChat from the Chat Interface to send the message.
// You will need to have acquired the RoomID when the player joins the session chat room, or by calling FOnlineChatAccelByte::GetJoinedRooms to get all joined rooms.
ChatInterface->SendRoomChat(LocalUserId.ToSharedRef().Get(), RoomId, TestRoomMessage);
// Call SendChatMessage after already in a Chat Room / Topic and have the Id stored.
// You will need to have acquired and stored the TopicId when the player joins the session topic.
apiClient.GetChat().SendChatMessage("topicId", "this is chat message", result =>
{
if (!result.IsError)
{
Debug.Log(("Success sending chat message"));
}
});
Receive a session chat message
To listen for chat messages from other players, register the appropriate delegate. It will be called when new messages are available along with the associated room/topic ID the message was sent to.
- Unreal SDK
- Online Subsystem
- Unity SDK
// Bind this delegate to listen for new messages sent from other players.
ApiClient->Chat.SetChatNotifDelegate(
Api::Chat::FChatNotif::CreateLambda([](const FAccelByteModelsChatNotif& Result)
{
UE_LOG(LogTemp, Log, TEXT("Receive chat! From[%s] content: [%s]"), *Result.From, *Result.Message);
})
);
FString ReceivedChatRoomMessage = TEXT("");
// Listen for "chat room message received" notification
auto ChatRoomMessageReceivedHandle = ChatInterface->AddOnChatRoomMessageReceivedDelegate_Handle(
FOnChatRoomMessageReceivedDelegate::CreateLambda(
[&ReceivedChatRoomMessage](const FUniqueNetId& UserId, const FChatRoomId& RoomId, const TSharedRef<FChatMessage> ChatMessage)
{
ReceivedChatRoomMessage = ChatMessage->GetBody();
}));
FString ReceivedPrivateMessage = TEXT("");
// Listen for "private message received" notification
auto ChatRoomMessageReceivedHandle =
ChatInterface->AddOnChatPrivateMessageReceivedDelegate_Handle(
FOnChatPrivateMessageReceivedDelegate::CreateLambda(
[&ReceivedPrivateMessage](const FUniqueNetId& UserId, const TSharedRef<FChatMessage>& ChatMessage)
{
ReceivedPrivateMessage = ChatMessage->GetBody();
}));
// Bind this delegate to listen for new messages sent from other players.
apiClient.GetChat().NewChatMessage += chat =>
{
Debug.Log("Receive new chat " + chat.message + " from user id " + chat.from);
};
Retrieve chat history
The Chat service stores messages in the chat history, which can be accessed by moderators for review or by users to view their own messages. The chat history is managed as follows:
- Messages are organized by topic ID, making it easy to retrieve them based on their topic.
- Messages are recorded every second and are available for retrieval after a 1-second delay.
- By default, chat history is kept for 30 days and is then automatically deleted.
- Users can only access chat history for topics they are a member of.
To retrieve chat history, use the queryChat
WebSocket command with the following parameters:
topicId
: The ID of the topic from which you want to retrieve messages.limit
: The maximum number of messages to retrieve.lastChatCreatedAt
: The earliest timestamp of messages to retrieve, specified in Unix time.