Skip to main content

Thread messages

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 Chat SDK to send, receive, recall, and retrieve thread messages in your app.

Understand the tech

The Chat SDK provides the ChatManager, ChatMessage, and ChatThread classes for thread messages, which allows you to implement the following features:

  • Send a thread message
  • Receive a thread message
  • Recall a thread message
  • Retrieve thread messages

The following figure shows the workflow of how clients send and receive peer-to-peer messages.

Thread Messages

As shown in the figure, the workflow of peer-to-peer messaging is as follows:

  1. Clients retrieve a token from your app server.
  2. Client A and Client B log in to Chat.
  3. Client A sends a message to Client B. The message is sent to the Chat server and the server delivers the message to Client B. When Client B receives the message, the SDK triggers an event. Client B listens for the event and gets the message.

Prerequisites

Before proceeding, ensure that you meet the following requirements:

  • You have initialized the Chat SDK. For details, see SDK quickstart.
  • You understand the call frequency limit of the Chat APIs supported by different pricing plans as described in Limitations.
The thread feature is supported by all types of Pricing Plans and is enabled by default once you have enabled Chat in Agora Console.

Implementation

This section describes how to call the APIs provided by the Chat SDK to implement thread features.

Send a thread message

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:


_25
// Calls `createTxtSendMessage` to create a text message.
_25
// Sets `content` to the content of the text message.
_25
// Sets `chatThreadId` to the ID of a thread that receives the text message.
_25
ChatMessage message = ChatMessage.createTxtSendMessage(content, chatThreadId);
_25
// Sets `ChatType` to `GroupChat` as a thread that belongs to a chat group.
_25
message.setChatType(ChatType.GroupChat);
_25
// Sets `isChatThreadMessage` to `true` to mark this message as a thread message.
_25
message.setisChatThreadMessage(true);
_25
// 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.
_25
message.setMessageStatusCallback(new CallBack() {
_25
@Override
_25
public void onSuccess() {
_25
showToast("The message is successfully sent");
_25
dialog.dismiss();
_25
}
_25
@Override
_25
public void onError(int code, String error) {
_25
showToast("Failed to send the message");
_25
}
_25
@Override
_25
public void onProgress(int progress, String status) {
_25
}
_25
});
_25
// Calls `sendMessage` to send the text message.
_25
ChatClient.getInstance().chatManager().sendMessage(message);

For more information about sending a message, see Send Messages.

Receive a thread message

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:


_17
MessageListener msgListener = new MessageListener() {
_17
// The SDK triggers the `onMessageReceived` callback when it receives a message.
_17
// After receiving this callback, the SDK parses the message and displays it.
_17
@Override
_17
public void onMessageReceived(List<ChatMessage> messages) {
_17
for (ChatMessage message : messages) {
_17
if(message.isChatThreadMessage()) {
_17
// You can implement subsequent settings in this callback.
_17
}
_17
}
_17
}
_17
...
_17
};
_17
// Calls `addMessageListener` to add a message listener.
_17
ChatClient.getInstance().chatManager().addMessageListener(msgListener);
_17
// Calls `removeMessageListener` to remove the message listener.
_17
ChatClient.getInstance().chatManager().removeMessageListener(msgListener);

For more information about receiving a message, see Receive Messages.

Recall a thread message

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:


_13
MessageListener msgListener = new MessageListener() {
_13
// The SDK triggers the `onMessageRecalled` callback when it recalls a message.
_13
// After receiving this callback, the SDK parses the message and updates its display.
_13
@Override
_13
public void onMessageRecalled(List<ChatMessage> messages) {
_13
for (ChatMessage message : messages) {
_13
if(message.isChatThreadMessage()) {
_13
// You can implement subsequent settings in this callback.
_13
}
_13
}
_13
}
_13
...
_13
};

Retrieve thread messages

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.

Retrieve thread messages from the server

For details about how to retrieve messages from the server, see Retrieve Historical Messages.

Retrieve the conversation of a thread from the memory and local database

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:


_7
// Sets the conversation type to group chat as a thread belongs to a chat group.
_7
// Sets `isChatThread` to `true` to mark the conversation as a thread.
_7
ChatConversation conversation = ChatClient.getInstance().chatManager().getConversation(chatThreadId, ChatConversationType.GroupChat, createIfNotExists, isChatThread);
_7
// Retrieves all messages in the specified thread from the memory.
_7
List<ChatMessage> messages = conversation.getAllMessages();
_7
// Retrieves more messages in the specified thread from the local database. The SDK automatically loads and stores the retrieved messages to the memory.
_7
List<ChatMessage> messages = conversation.loadMoreMsgFromDB(startMsgId, pagesize, searchDirection);