Chat SDKs JavaScript v3
Chat SDKs JavaScript
Chat SDKs
JavaScript
Version 3
Sendbird Chat SDK v3 for JavaScript is no longer supported as a new version is released. Check out our latest Chat SDK v4

Message threading

Copy link

Message threading is a feature that allows users to ask questions, give feedback or add context to a specific message without disrupting the conversation flow. A message thread refers to a collection of messages grouped together, consisting of a parent message and its replies. It can have the following elements:

  • A message can have a thread of replies.
  • A message that has a thread of replies is a parent message.
  • A parent message and its threaded replies are collectively called a message thread.
  • Every message within a thread, whether it's parent or reply, is a threaded message.
  • A message that doesn't have any replies is an unthreaded message.


Benefits

Copy link

Message threading can be widely used to help conversations flow smoothly while keeping users engaged. Message replies in a thread are common among popular messaging platforms, such as Slack and iMessage.

  • Conversation flow: Without message threading, it's hard to specify which message a channel member is responding to. Users would have to explain the context of their response, potentially confusing other channel members and distracting them from reading new messages. Message threads can help everyone stay engaged and carry on their conversation without any interferences.

  • In-depth discussions: By allowing users to reply to each other's messages in a thread, they can have more in-depth conversations on one topic. They're able to ask follow-up questions or provide more detailed explanations to a specific message without interrupting others in the channel. Message threads can encourage users to start topic-specific discussions separate from the main channel conversation.


Limitations

Copy link

Refer to the following limitations before using the message threading feature:

  • Message threading doesn't integrate with SyncManager.
  • SDK only supports 1-depth threads, meaning you can only add reply messages to non-reply messages. You can't add a reply to a reply message.
  • Message threading is limited to text and file messages. You can't send admin messages as replies or add replies to admin messages.

List messages along with their replies

Copy link

You can retrieve messages and their replies in a specific thread.

Load channel messages

Copy link

The load() method of a PreviousMessageListQuery instance returns a list of BaseMessage objects. Using this method, you can retrieve previous messages in a specific channel. If you want to include the replies of the target messages in the results, change the value of properties in the PreviousMessageListQuery instance.

PreviousMessageListQuery

Copy link

The following table lists the properties of this class.

Property nameTypeDescription

limit

int

Specifies the number of results to return per call. Acceptable values are 1 to 100, inclusive. The recommended value for this parameter is 30.

reverse

boolean

Determines whether to sort the retrieved messages in reverse order. If false, the results are in ascending order.

includeThreadInfo

boolean

Determines whether to include the thread information of the messages in the results when the results contain parent messages.

replyType

string

Specifies the type of message to include in the results.
- NONE (default): All messages that are not replies. These message may or may not have replies in its thread.
- ALL: All messages including threaded and non-threaded parent messages as well as its replies.
- ONLY_REPLY_TO_CHANNEL: Messages that are not threaded. It only includes the parent messages and replies that were sent to the channel.

includeParentMessageInfo

boolean

Determines whether to include the information of the parent messages in the result. (Default: false)

includeReplies

boolean

(Deprecated) Determines whether replies are included in the results.

includeParentMessageText

boolean

(Deprecated) Determines whether to include the parent message text in the results when the retrieved messages are replies in a thread. If the type of the parent message is UserMessage, the value is a message property. If it is FileMessage, the value is the name of the uploaded file.

const listQuery = channel.createPreviousMessageListQuery();
listQuery.replyType = REPLY_TYPE;
listQuery.includeThreadInfo = INCLUDE_THREAD_INFO;
listQuery.includeParentMessageInfo = INCLUDE_PARENT_MESSAGE_INFO;

load()

Copy link
// Retrieving previous messages.
listQuery.load(LIMIT, REVERSE, MESSAGE_TYPE_FILTER, (messages, error) => {
    if (error) {
        // Handle error.
    }

    ...
});

List of parameters

Copy link
Parameter nameTypeDescription

LIMIT

number

Specifies the number of results to return per call. Acceptable values are 1 to 100, inclusive. The recommended value for this parameter is 30.

REVERSE

boolean

Determines whether to sort the retrieved messages in reverse order. If false, the results are in ascending order.

MESSAGE_TYPE_FILTER

string

Restricts the search scope only to retrieve messages with the specified message type.

Load messages by timestamp or message ID

Copy link

The getMessagesByTimestamp() and getMessagesByMessageId() methods of a BaseChannel instance returns a list of BaseMessage objects. By using these methods, you can retrieve messages in a specific channel according to a MessageListParams object.

MessageListParams

Copy link

The following table lists the properties of this class.

Property nameTypeDescription

previousResultSize

int

Specifies the number of messages to retrieve that were sent before the specified timestamp or message ID.

nextResultSize

int

Specifies the number of messages to retrieve that were sent after the specified timestamp or message ID.

isInclusive

boolean

Determines whether to include the messages with the matching timestamp or message ID in the results.

reverse

boolean

Determines whether to sort the retrieved messages in reverse order. If false, the results are in ascending order.

includeThreadInfo

boolean

Determines whether to include the thread information of the messages in the results when the results contain parent messages.

replyType

string

Specifies the type of message to include in the results.
- NONE (default): All messages that are not replies. These message may or may not have replies in its thread.
- ALL: All messages including threaded and non-threaded parent messages as well as its replies.
- ONLY_REPLY_TO_CHANNEL: Messages that are not threaded. It only includes the parent messages and replies that were sent to the channel.

includeParentMessageInfo

boolean

Determines whether to include the information of the parent messages in the result. (Default: false)

includeReplies

boolean

(Deprecated) Determines whether replies are included in the results.

includeParentMessageText

boolean

(Deprecated) Determines whether to include the parent message text in the results when the messages are replies in a thread. If the type of the parent message is UserMessage, the value is a message property. If it is FileMessage, the value is the name of the uploaded file.

const params = new sb.MessageListParams();
params.prevResultSize = PREV_RESULT_SIZE;
params.nextResultSize = NEXT_RESULT_SIZE;
params.isInclusive = INCLUSIVE;
params.reverse = REVERSE;
params.replyType = REPLY_TYPE;
params.includeThreadInfo = INCLUDE_THREAD_INFO;
params.includeParentMessageInfo = INCLUDE_PARENT_MESSAGE_INFO;

By timestamp

Copy link

You can retrieve a set number of messages of previous and next messages on both sides of a specific timestamp in a channel by using the getMessagesByTimestamp() method.

channel.getMessagesByTimestamp(TIMESTAMP, params, (messages, error) => {
    if (error) {
        // Handle error.
    }

    // A list of previous and next messages on both sides of a specified timestamp is successfully retrieved.
    // Through the "messages" parameter of the callback function,
    // you can access and display the data of each message from the result list that Sendbird server has passed to the callback function.
    messages.forEach(message => {
        ...
    });

    ...
});

List of arguments

Copy link
ArgumentTypeDescription

TIMESTAMP

long

Specifies the timestamp to be the reference point for messages to retrieve, in Unix milliseconds format. Messages sent before or after the timestamp can be retrieved.

By message ID

Copy link

You can retrieve a set number of previous and next messages on both sides of a specific message ID in a channel by using the getMessagesByMessageId() method.

channel.getMessagesByMessageId(MESSAGE_ID, params, (messages, error) => {
    if (error) {
        // Handle error.
    }

    // A list of previous and next messages on both sides of a specified message ID is successfully retrieved.
    // Through the "messages" parameter of the callback function,
    // you can access and display the data of each message from the result list that Sendbird server has passed to the callback function.
    messages.forEach(message => {
        ...
    });

    ...
});

List of parameters

Copy link
Parameter nameTypeDescription

MESSAGE_ID

long

Specifies the message ID to be the reference point for messages to retrieve. Messages sent before or after the message with the matching message ID can be retrieved.


List replies of a parent message

Copy link

You can retrieve replies of a parent message if you can determine the parent message like the following. First, create a ThreadMessageListParams object and set properties related to the thread where the target replies belong to.

const params = new sb.ThreadedMessageListParams();
params.prevResultSize = PREV_RESULT_SIZE;
params.nextResultSize = NEXT_RESULT_SIZE;
params.isInclusive = INCLUSIVE;
params.reverse = REVERSE;
params.includeParentMessageInfo = INCLUDE_PARENT_MESSAGE_INFO;

ThreadMessageListParams

Copy link
Property nameTypeDescription

previousResultSize

int

Specifies the number of messages to retrieve that were sent before the specified timestamp.

nextResultSize

int

Specifies the number of messages to retrieve that were sent after the specified timestamp.

isInclusive

boolean

Determines whether to include the messages with the matching timestamp in the results.

reverse

boolean

Determines whether to sort the retrieved messages in reverse order. If false, the results are in ascending order.

includeParentMessageInfo

boolean

Determines whether to include the information of the parent messages in the result. (Default: false)

includeParentMessageText

boolean

(Deprecated) Determines whether to include the parent message text in the results when the messages are replies in a thread. If the type of the parent message is UserMessage, the value is a message property. If it is FileMessage, the value is the name of the uploaded file.

With the timestamp of the parent message, you can retrieve its replies by passing a TreadedMessageListParams object as an argument to the parameter in the getThreadedMessagesByTimestamp() method.

parentMessage.getThreadedMessagesByTimestamp(TIMESTAMP, params, ({ parentMessage, threadedReplies }, error) => {
    if (error) {
        // Handle error.
    }

    // A list of replies of the specified parent message timestamp is successfully retrieved.
    ...
});

List of parameters

Copy link
Parameter nameTypeDescription

TIMESTAMP

long

Specifies the timestamp to be the reference point of the retrieval, in Unix milliseconds format.


View a single message

Copy link

You can retrieve a specific message by creating and passing the MessageRetrievalParams object to the getMessage() method as a parameter.

const params = new sb.MessageRetrievalParams();
params.messageId = MESSAGE_ID;
params.channelType = CHANNEL_TYPE;  // 'open', 'group', or 'base'
params.channelUrl = CHANNEL_URL;

MessageRetrievalParams

Copy link
Property nameDescription

messageId

Type: long

Specifies the unique ID of the message to retrieve.

channelType

Type: String

Specifies the type of the channel.

channelUrl

Type: String

Specifies the URL of the channel to retrieve the message.

sb.BaseMessage.getMessage(params, (message, error) => {
    if (error) {
        // Handle error.
    }

    // The specified message is successfully retrieved.
    ...
});

Reply to a message

Copy link

You can reply to a specific message in a channel through the sendUserMessage() or sendFileMessage() method. To do so, you should create a UserMessageParams or a FileMessageParams object and then specify the parentMessageId property of the object. Sending reply messages works the same way as sending regular messages to a channel except replies have an additional parentMessageId property.

Reply with a text message

Copy link

When replying to a message through the sendUserMessage() method, specify and pass a UserMessageParams object as an argument to a parameter in the method.

const params = new sb.UserMessageParams();
params.parentMessageId = PARENT_MESSAGE_ID;

UserMessageParams

Copy link
Property nameTypeDescription

parentMessageId

long

Specifies the unique ID of a parent message. A parent message is a message that has a thread of replies. If the message sent through the sendUserMessage() method is a parent message, the value of this property is 0. If the message is a reply to a parent message, the value is the message ID of the parent message.

channel.sendUserMessage(params, (message, error) => {
    if (error) {
        // Handle error.
    }

    // A reply to a specific message in the form of a text message is successfully sent.
    ...
});

Reply with a file message

Copy link

When replying with a file message through the sendFileMessage() method, specify and pass a FileMessageParams object as an argument to a parameter in the method.

const params = new sb.FileMessageParams();
params.file = FILE;
params.parentMessageId = PARENT_MESSAGE_ID;

FileMessageParams

Copy link
ArgumentTypeDescription

FILE

string

Specifies the URL of the file to be attached to the message

PARENT_MESSAGE_ID

long

Specifies the unique ID of a parent message. A parent message is a message that has a thread of replies. If the message sent through the sendUserMessage() method is a parent message, the value of this property is 0. If the message is a reply to a parent message, the value is the message ID of the parent message.

channel.sendFileMessage(params, (message, error) => {
    if (error) {
        // Handle error.
    }

    // A reply to a specific message in the form of a file message is successfully sent.
    ...
});

List changelogs

Copy link

You can retrieve message changelogs.

Load message changelogs

Copy link

Each message changelog has distinct properties such as a timestamp of when a message was updated and a unique ID of a deleted message. Based on these two properties, you can retrieve message changelogs in two different ways: either by timestamp or by token. Both getMessageChangeLogsSinceToken() and getMessageChangeLogsSinceTimestamp() methods require a parameter MessageChangeLogsParams object to determine what messages to return.

const params = new sb.MessageChangeLogsParams();
params.replyType = REPLY_TYPE;
params.includeThreadInfo = INCLUDE_THREAD_INFO;
params.includeParentMessageInfo = INCLUDE_PARENT_MESSAGE_INFO;

MessageChangeLogsParams

Copy link

The following table lists the properties of this class.

PropertyTypeDescription

includeThreadInfo

boolean

Determines whether to include the thread information of the messages in the results when the results contain parent messages.

replyType

string

Specifies the type of message to include in the results.
- NONE (default): All messages that are not replies. These message may or may not have replies in its thread.
- ALL: All messages including threaded and non-threaded parent messages as well as its replies.
- ONLY_REPLY_TO_CHANNEL: Messages that are not threaded. It only includes the parent messages and replies that were sent to the channel.

includeParentMessageInfo

boolean

Determines whether to include the information of the parent messages in the result. (Default: false)

includeReplies

boolean

(Deprecated) Determines whether replies are included in the results.

includeParentMessageText

boolean

(Deprecated) Determines whether to include the parent message text in the results when the messages are replies in a thread. If the type of the parent message is UserMessage, the value is a message property. If it is FileMessage, the value is the name of the uploaded file.

By timestamp

Copy link

You can retrieve the message changelogs by specifying a timestamp. The results will include changelogs that were created after the specified timestamp.

channel.getMessageChangeLogsSinceTimestamp(TIMESTAMP, params, ({ updatedMessages, deletedMessageIds, hasMore, token }, error) => {
    if (error) {
        // Handle error.
    }

    // A list of message changelogs created after the specified timestamp is successfully retrieved.
    ...
});

List of parameters

Copy link
Parameter nameTypeDescription

TIMESTAMP

long

Specifies the timestamp to be the reference point for changelogs to retrieve, in Unix milliseconds format.

By token

Copy link

You can also retrieve message changelogs by specifying a token. The token is an opaque string that marks the starting point of the next page in the result set and it is included in the callback of the previous call. Based on the token, the next page will start with changelogs that were created after the specified token.

channel.getMessageChangeLogsSinceToken(TOKEN, params, ({ updatedMessages, deletedMessageIds, hasMore, token }, error) => {
    if (error) {
        // Handle error.
    }

    // A list of message changelogs created after the specified token is successfully retrieved.
    ...
});

Event handler

Copy link

Once a reply is created or deleted from a thread, the onThreadInfoUpdated() event handler is invoked. The method returns a ThreadInfoUpdateEvent object that has the latest information about the thread. This object needs to be applied to the parent message object.

Note: Like other messages, when a reply is created in a channel, the onMessageReceived() method of the channel event handler in client apps will be called.

handler.onThreadInfoUpdated = (channel, threadInfoUpdateEvent) => {
    // Look for a message that has threadInfoUpdateEvent.targetMessageId.
    // Apply the event to the message.
    message.applyThreadInfoUpdateEvent(threadInfoUpdateEvent);
};

List of parameters

Copy link
Parameter nameDescription

channel

Type: BaseChannel

Specifies the channel that has the message thread.

threadInfoUpdateEvent

Type: ThreadInfoUpdateEvent

Specifies a ThreadInfoUpdateEvent object that has the latest information about the thread.

If a reply message is created, onMessageReceived will be called with that reply message. A user will have to find the parent message with the parentMessageID property in that message object.

If the parent message is not in the message view stack and the user wants to get the parent message object, they can do so by calling BaseMessage.getMessage(params, handler) to retrieve the parent message object.

Once the reply message has been created, the onThreadInfoUpdated() event handler will be called since the thread info has been changed. To update thread information, the user should find the matching parent message with targetMessageID and use the parentMessage.applyThreadInfoUpdateEvent() method.