Threads enable users to create a separate conversation from a specific message within a chat group to keep the main chat uncluttered.
This page shows how to use the Agora Chat SDK to send, receive, recall, and retrieve thread messages in your app.
The Agora Chat SDK provides the ChatManager
, ChatMessage
, and ChatThread
classes for thread messages, which allows you to implement the following features:
The following figure shows the workflow of how clients send and receive peer-to-peer messages.
As shown in the figure, the workflow of peer-to-peer messaging is as follows:
Before proceeding, ensure that you meet the following requirements:
This section describes how to call the APIs provided by the Agora Chat SDK to implement thread features.
Sending a thread message is similar to sending a message in a chat group. The difference lies in the isChatThreadMessage
field, as shown in the following code sample:
// Calls `createTxtSendMessage` to create a text message.
// Sets `content` to the content of the text message.
// Sets `chatThreadId` to the ID of a thread that receives the text message.
ChatMessage message = ChatMessage.createTxtSendMessage(content, chatThreadId);
// Sets `ChatType` to `GroupChat` as a thread that belongs to a chat group.
message.setChatType(ChatType.GroupChat);
// Sets `isChatThreadMessage` to `true` to mark this message as a thread message.
message.setisChatThreadMessage(true);
// Calls `setMessageStatusCallback` to listen for the message sending status. You can implement subsequent settings in this callback, for example, displaying a pop-up if the message sending fails.
message.setMessageStatusCallback(new CallBack() {
@Override
public void onSuccess() {
showToast("The message is successfully sent");
dialog.dismiss();
}
@Override
public void onError(int code, String error) {
showToast("Failed to send the message");
}
@Override
public void onProgress(int progress, String status) {
}
});
// Calls `sendMessage` to send the text message.
ChatClient.getInstance().chatManager().sendMessage(message);
For more information about sending a message, see Send Messages.
Once a thread has a new message, all chat group members receive the ChatThreadChangeListener#onChatThreadUpdated
callback. Thread members can also listen for the MessageListener#onMessageReceived
callback to receive thread messages, as shown in the following code sample:
MessageListener msgListener = new MessageListener() {
// The SDK triggers the `onMessageReceived` callback when it receives a message.
// After receiving this callback, the SDK parses the message and displays it.
@Override
public void onMessageReceived(List<ChatMessage> messages) {
for (ChatMessage message : messages) {
if(message.isChatThreadMessage()) {
// You can implement subsequent settings in this callback.
}
}
}
...
};
// Calls `addMessageListener` to add a message listener.
ChatClient.getInstance().chatManager().addMessageListener(msgListener);
// Calls `removeMessageListener` to remove the message listener.
ChatClient.getInstance().chatManager().removeMessageListener(msgListener);
For more information about receiving a message, see Receive Messages.
For details about how to recall a message, refer to Recall Messages.
Once a message is recalled in a thread, all chat group members receive the ChatThreadChangeListener#onChatThreadUpdated
callback. Thread members can also listen for the MessageListener#onMessageRecalled
callback, as shown in the following code sample:
MessageListener msgListener = new MessageListener() {
// The SDK triggers the `onMessageRecalled` callback when it recalls a message.
// After receiving this callback, the SDK parses the message and updates its display.
@Override
public void onMessageRecalled(List<ChatMessage> messages) {
for (ChatMessage message : messages) {
if(message.isChatThreadMessage()) {
// You can implement subsequent settings in this callback.
}
}
}
...
};
Whether to retrieve thread messages from the server or local database depends on your production context.
When you join a thread, messages are displayed in chronological order by default. In this case, Agora recommends that you retrieve the historical messages of the thread from the server. When you recall a thread message, Agora recommend that you insert the recall notification in the local database.
For details about how to retrieve messages from the server, see Retrieve Historical Messages.
By calling getAllConversations
, you can only retrieve the conversations of one-to-one chats or group chats. To retrieve the conversation of a thread, refer to the following code sample:
// Sets the conversation type to group chat as a thread belongs to a chat group.
// Sets `isChatThread` to `true` to mark the conversation as a thread.
ChatConversation conversation = ChatClient.getInstance().chatManager().getConversation(chatThreadId, ChatConversationType.GroupChat, createIfNotExists, isChatThread);
// Retrieves all messages in the specified thread from the memory.
List<ChatMessage> messages = conversation.getAllMessages();
// Retrieves more messages in the specified thread from the local database. The SDK automatically loads and stores the retrieved messages to the memory.
List<ChatMessage> messages = conversation.loadMoreMsgFromDB(startMsgId, pagesize, searchDirection);