Skip to main content
// Send message in a thread
const msg = new CometChat.TextMessage("UID", "Reply", CometChat.RECEIVER_TYPE.USER);
msg.setParentMessageId(100);
await CometChat.sendMessage(msg);

// Fetch thread messages
const threadRequest = new CometChat.MessagesRequestBuilder()
  .setParentMessageId(100).setLimit(30).build();
const messages = await threadRequest.fetchPrevious();

// Exclude thread replies from main conversation
const mainRequest = new CometChat.MessagesRequestBuilder()
  .setUID("UID").setLimit(30).hideReplies(true).build();
Threaded messages (or threads) are messages started from a particular parent message. Each thread is attached to a parent message.

Send Message in a Thread

Any message type (Text, Media, or Custom) can be sent in a thread. Set the parentMessageId using setParentMessageId() to indicate which thread the message belongs to.
let receiverId = "UID",
  receiverType: string = CometChat.RECEIVER_TYPE.USER,
  textMessage: CometChat.TextMessage = new CometChat.TextMessage(receiverId, "Hello", receiverType),
  messageId: number = 100;

textMessage.setParentMessageId(messageId);

CometChat.sendMessage(textMessage).then(
  (message: CometChat.TextMessage) => {
      console.log('Message sent successfully', message);
  }, (error: CometChat.CometChatException) => {
      console.log('Message sending failed', error);
  }
);
The above snippet sends “Hello” in the thread with parentMessageId 100. Media and Custom messages can also be sent in threads using setParentMessageId().

Receiving Real-Time Messages

Use MessageListener to receive real-time thread messages. Check if the received message belongs to the active thread using getParentMessageId().
const listenerID: string = "UNIQUE_LISTENER_ID";
const activeThreadId: number = 100;

CometChat.addMessageListener(
  listenerID,
  new CometChat.MessageListener({
      onTextMessageReceived: (textMessage: CometChat.TextMessage) => {
          if (textMessage.getParentMessageId() == activeThreadId) {
              console.log("Text message received for active thread.", textMessage);
          }
      },
      onMediaMessageReceived: (mediaMessage: CometChat.MediaMessage) => {
          if (mediaMessage.getParentMessageId() == activeThreadId) {
              console.log("Media message received for active thread.", mediaMessage);
          }
      },
      onCustomMessageReceived: (customMessage: CometChat.CustomMessage) => {
          if (customMessage.getParentMessageId() == activeThreadId) {
              console.log("Custom message received for active thread.", customMessage);
          }
      }
  })
);

Fetch all the messages for any particular thread.

Use MessagesRequestBuilder with setParentMessageId() to fetch messages belonging to a specific thread. Call fetchPrevious() to get messages (max 100 per request).
let limit: number = 30,
  parentMessageId: number = 1,
  messagesRequest: CometChat.MessagesRequest = new CometChat.MessagesRequestBuilder()
      .setLimit(limit)
      .setParentMessageId(parentMessageId)
      .build();

messagesRequest.fetchPrevious().then(
  (messages: CometChat.BaseMessage[]) => {
      console.log("Messages for thread fetched successfully", messages);
  }, (error: CometChat.CometChatException) => {
      console.log("Message fetching failed with error:", error);
  }
);
The fetchPrevious() method returns an array of BaseMessage objects representing thread replies.

Avoid Threaded Messages in User/Group Conversations

Use hideReplies(true) to exclude threaded messages when fetching messages for a conversation.
let UID: string = "UID",
  limit: number = 30,
  messagesRequest: CometChat.MessagesRequest = new CometChat.MessagesRequestBuilder()
      .setUID(UID)
      .setLimit(limit)
      .hideReplies(true)
      .build();

messagesRequest.fetchPrevious().then(
  (messages: CometChat.BaseMessage[]) => {
      console.log("Messages fetched successfully", messages);
  }, (error: CometChat.CometChatException) => {
      console.log("Message fetching failed with error:", error);
  }
);
The response is an array of BaseMessage objects, excluding any messages that are replies within a thread. Only top-level messages in the conversation are returned.
Always remove message listeners when they’re no longer needed (e.g., on component unmount or page navigation). Failing to remove listeners can cause memory leaks and duplicate event handling.
CometChat.removeMessageListener("UNIQUE_LISTENER_ID");

Next Steps

Send Messages

Send text, media, and custom messages to users and groups

Receive Messages

Listen for incoming messages in real-time and fetch missed messages

Reactions

Add emoji reactions to messages

Message Filtering

Advanced message filtering with RequestBuilder