# Thread messages (/en/realtime-media/im/build/build-groups-rooms-and-threads/threading/thread-messages/web)

> For AI agents: see the complete documentation index at [llms.txt](/llms.txt).

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 allows you to implement the following features:

## Prerequisites

Before proceeding, ensure that you meet the following requirements:

* You have initialized the Chat SDK. For details, see [SDK quickstart](../../../get-started-sdk).
* You understand the call frequency limit of the Chat APIs supported by different pricing plans as described in [Limitations](../../limitations).

<CalloutContainer type="info">
  <CalloutDescription>
    The thread feature is supported by all types of [Pricing Plans](../../../reference/pricing-plan-details) and is enabled by default once you have enabled Chat in [Agora Console](https://console.agora.io/).
  </CalloutDescription>
</CalloutContainer>

## Implementation

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

### Send a thread message

Send a thread message is similar to send a message in a chat group. The difference lies in the `isChatThread` field, as shown in the following code sample:

```javascript
function sendTextMessage() {
    let option = {
        chatType: 'groupChat',     // Sets `chatType` to `groupChat` as a thread belongs to a chat group.
        type: 'txt',               // Sets `type` to `txt` to create and send a text message.
        to: chatThreadId,          // Sets `to` to the thread ID.
        msg: 'message content',    // Sets `msg` to the content of the text message.
        isChatThread:true,         // Sets `isChatThread` to `true` to mark this message as a thread message.
    }
    // Calls `create` to create a text message.
    let msg = WebIM.message.create(option);
    // Calls `send` to send the text message.
    conn.send(msg).then(() => {
        console.log('send private text Success');
    }).catch((e) => {
        console.log("Send private text error");
    })
};
```

For more information about sending a message, see [Send Messages](../../build-core-messaging/messages/send-receive-messages#send-a-text-message).

### Receive a thread message

Once a thread has a new message, all chat group members receive the `onChatThreadChange` callback triggered by the `update` event. Thread members can also listen for the `onTextMessage` callback to receive thread messages, as shown in the following code sample:

```javascript
// The SDK triggers the `onTextMessage` callback when it receives a message.
// After receiving this callback, the SDK parses the message and displays it.
connection.addEventHandler('THREADMESSAGE',{
  onTextMessage:(message) =>{
      if(message.chatThread && JSON.stringify(message.chatThread)!=='{}'){
        console.log(message)
        // You can implement subsequent settings in this callback.
      }
  },
});
```

For more information about receiving a message, see [Receive Messages](../../build-core-messaging/messages/send-receive-messages#receive-a-message).

### Recall a thread message

Once a message is recalled in a thread, all chat group members receive the `onChatThreadChange` callback triggered by the `update` event. Thread members can also listen for the `onRecallMessage` callback, as shown in the following code sample:

```javascript
let option = {
  mid: 'msgId',           // The ID of the message to be recalled.
  to: 'chatThreadId',           // The username of the message receiver.
  chatType: 'groupChat'   // Sets `chatType` to `groupChat` as a thread belongs to a chat group.
  isChatThread: true      // Sets `isChatThread` to `true` to mark this message as a thread message.
};
// Calls `recallMessage` to recall a message.
connection.recallMessage(option).then((res) => {
  console.log('success', res)
}).catch((error) => {
  // Occurs when the message fails to be recalled within the default time limit of two minutes.
  console.log('fail', error)
})
// The SDK triggers the `onRecallMessage` callback when it recalls a message.
// After receiving this callback, the SDK parses the message and updates its display.
conn.addEventHandler('MESSAGES',{
   onRecallMessage: (msg) => {
       // You can implement subsequent settings in this callback.
        console.log('Message recall succeeds.'，msg)
   },
})
```

For more information about recalling a message, see [Recall Messages](../../build-core-messaging/messages/send-receive-messages#recall-a-message).

### Retrieve messages of a thread from the server

You can call `ChatManager#FetchHistoryMessagesFromServer` to retrieve messages of a thread from the server. The only difference between retrieving messages of a thread from the server and retrieving group messages is that a thread ID needs to be passed in for the former and a group ID is required for the latter.

```javascript
let options = {
  // The thread ID.
  targetId: "threadId",
  // The number of thread messages that you expect to get on each page. The value range is [1,50], with `20` as the default.
  pageSize: 20,
  // The starting message ID for retrieving. If you set this parameter to `-1`, `null`, or an empty string, the SDK retrieves messages from the latest one.
  cursor: -1,
  // The chat type is set to `groupChat` as a thread belongs to a group chat.
  chatType: "groupChat",
  // The message search direction: (Default): `up`: The SDK retrieves messages in the descending order of the time when the server receives the messages. `down`: The SDK retrieves messages in the ascending order of the time when the server receives the messages.
  searchDirection: "up",
};
conn
  .getHistoryMessages(options)
  .then((res) => {
    // Succeed in getting historical messages.
    console.log(res);
  })
  .catch((e) => {
    // Fail to get historical messages.
  });
```

    
  
      
  
      
  
      
  
      
  
