Chat Android v4
Chat Android
Chat
Android
Home
/
Chat
/
Android
This is the new Docs for Chat SDK v4 beta for Android. To see the previous Docs, click here.

Open channel

An open channel is a Twitch-style public chat where users can easily join without permission. Sendbird Chat SDK now supports two operation systems for open channels, which are classic and dynamic partitioning. These two systems offer the same features and functions, except that dynamic partitioning allows open channels to accommodate a massive number of users.

Open channels can be used in short-lived live events, such as streaming, news-feed type messaging to massive audience, or events that don't require a permanent membership.

Note: To learn about differences between open channels and group channels, see Channel types.


Classic vs. Dynamic partitioning

Classic open channels are the original open channels Sendbird has been providing, and a single classic open channel can handle up to 1,000 participants.

Note: Sendbird applications created before December 15, 2020, are using classic open channels. The classic open channels will be deprecated soon, but the classic channels created up until the deprecation date will remain and function the same way. When the deprecation takes place, all Chat SDK users will be automatically migrated to the new dynamic partitioning system. If you wish to convert to dynamic partitioning open channels beforehand, visit this page and contact us on the Sendbird Dashboard.

On the other hand, dynamic partitioning open channels are designed to accommodate much greater number of users than the classic open channels. The dynamic partitioning open channels can have subchannels where you can divide users evenly.


Create a channel

An open channel is ideal for use cases that require a small and static number of channels. To create an open channel from the Sendbird Dashboard, do the following:

  1. On your dashboard, go to Chat > Open channels, and then click Create channel at the top-right corner.

  2. In the dialog box that appears, specify the name, unique URL, cover image, and custom type of a channel.

You can also create a channel on demand or dynamically through the Chat SDK or the Chat API.

OpenChannel.createChannel(OpenChannelCreateParams()) { channel, e ->
    if (e != null) {
        // Handle error.
    }

    // An open channel is successfully created.
    // Through the channel parameter of the onResult() callback method,
    // you can get the open channel's data from the result object
    // that Sendbird server has passed to the callback method.
}

Otherwise, you can create an open channel by passing a configured OpenChannelCreateParams object as an argument to the parameter in the createChannel() method like the following.

val operators = listOf("Jeff")
val params = OpenChannelCreateParams()
    .setName(NAME)
    .setChannelUrl(UNIQUE_CHANNEL_URL)  // For an open channel, you can create a channel by specifying its unique channel URL in an OpenChannelCreateParams object.
    .setCoverImage(FILE)                // Or .setCoverUrl(COVER_URL)
    .setData(DATA)
    .setCustomType(CUSTOM_TYPE)
.setOperatorUserIds(operators)          // Or .setOperators(List<User> operators)

OpenChannel.createChannel(params) { channel, e ->
    if (e != null) {
        // Handle error.
    }

    // An open channel with detailed configuration is successfully created.
    // By using channel.url, channel.data, channel.customType, and so on,
    // you can access the result object from Sendbird server to check your OpenChannelCreateParams configuration.
}

When creating a channel, you can also append additional information like cover image and description by passing several arguments to the corresponding parameters.

val params = OpenChannelCreateParams()
    .setName(NAME)
    .setCoverImage(FILE)
    .setData(DATA)
    .setCustomType(CUSTOM_TYPE)
    .setOperatorUserIds(OPERATOR_USERS)
OpenChannel.createChannel(params, HANDLER)

List of arguments

ArgumentTypeDescription

NAME

string

Specifies the channel topic or the name of the channel.

COVER_IMAGE_OR_URL

object

Specifies the cover image URL of the channel or uploads a file for the cover image.

DATA

string

Specifies additional channel information such as a long description of the channel or JSON formatted string.

OPERATOR_USERS

list

Specifies a list of one or more users to register as operators of the channel. Operators can delete any messages, and also view all messages in the channel without any filtering or throttling.

CUSTOM_TYPE

string

Specifies the custom channel type which is used for channel grouping.

HANDLER

interface

Specifies the OpenChannelCallbackHandler interface which contains the onResult() callback method to receive the response from Sendbird server for a channel creation request.

Using the coverUrl and updateChannel() methods, you can get and update the cover image URL of a channel.

Note: You can also create an open channel using the Chat API which helps you control channel creations.


Enter a channel

A user must enter an open channel to receive messages. The user can enter up to 10 open channels at once, which are valid only within a current connection. So when a user is disconnected from Sendbird server with disconnect() and reconnected to the server with connect(), you should make sure the user re-enters the open channels for them to continue receiving messages.

When a user who is already a participant in an open channel moves the app to the background, the user will be disconnected from Sendbird server. But when the user's app returns to the foreground, the Chat SDK will automatically re-enter the user to the participating channel.

Note: When a user is reconnected by attempts of the SendbirdChat instance from a temporary unstable connection, the Chat SDK will automatically re-enter the user to the participating channel.

OpenChannel.getChannel(CHANNEL_URL) { channel, e ->
    if (e != null) {
        // Handle error.
    }

    // Call the instance method of the result object in the channel parameter
    // of the onResult() callback method.
    channel?.enter { enterError ->
        if (enterError != null) {
            // Handle error.
        }

        // The current user successfully enters the open channel,
        // and can chat with other users in the channel by using APIs.
        ...
    }
}

Exit a channel

If a user exits an open channel, the user can't receive any messages from that channel.

OpenChannel.getChannel(CHANNEL_URL) { channel, e ->
    if (e != null) {
        // Handle error.
    }

    // Call the instance method of the result object in the channel parameter
    // of the onResult() callback method.
    channel?.exit { exitError ->
        if (e != null) {
            // Handle error.
        }

        // The current user successfully exits the open channel.
        ...
    }
}

Freeze and unfreeze a channel

An open channel can be frozen only on the Sendbird Dashboard or using the Chat API as opposed to a group channel which operators of the channel can do that via the Chat SDK.

To freeze, go to your dashboard and do the following: on Chat > Open channels, select an open channel to freeze, and click the Freeze icon at the upper right corner. To unfreeze, click the icon again with the frozen channel selected.

Note: In a frozen channel, participants can't chat with each other but the operators can send a message to the channel.


Delete a channel

Only the operators of an open channel can delete the channel. Otherwise, an error is returned through CompletionHandler.

Note: The following code works properly in the operators' client apps only.

openChannel.delete { e ->
    if (e != null) {
        // Handle error.
    }

    // The channel is successfully deleted.
    ...
}

Retrieve a list of channels

You can retrieve a list of OpenChannel objects using the next() method of an OpenChannelListQuery instance like the following.

val query = OpenChannel.createOpenChannelListQuery()
query.next { channels, e ->
    if (e != null) {
        // Handle error.
    }

    // A list of open channels is successfully retrieved.
    // Through the channels parameter of the onResult() callback method,
    // you can access the data of each open channel from the result list that Sendbird server has passed to the callback method.
}

Retrieve a channel by URL

Since a channel URL is a unique identifier of an open channel, you can use a URL when retrieving a channel object.

OpenChannel.getChannel(CHANNEL_URL) { channel, e ->
    if (e != null) {
        // Handle error.
    }

    // Through the channel parameter of the onResult() callback method,
    // the open channel object identified with CHANNEL_URL is returned by Sendbird server,
    // and you can get the open channel's data from the result object.
}

Note: We recommend that you store a user's channel URLs to handle the lifecycle or state changes of your app, or any other unexpected situations. For example, when a user is disconnected from Sendbird server due to switching to another app temporarily, you can provide a smooth restoration of the user's state using a stored URL to fetch the appropriate channel instance.


Send a message

In an entered channel, a user can send messages of the following types:

Message typeDescription

UserMessage

A text message sent by a user.

FileMessage

A binary file message sent by a user.

In addition to these message types, you can further subclassify a message by specifying its custom type. This custom type takes on the form of String and can be used to search or filter messages. It allows you to append information to your message and customize message categorization.

The following code shows several types of parameters that you can configure to customize text messages by using UserMessageCreateParams. Under the UserMessageCreateParams object, you can assign specific values to message, data and other properties. By assigning arbitrary string to the data property, you can set custom font size, font type or JSON object. To send your messages, you need to pass the UserMessageCreateParams object as an argument to the parameter in the sendUserMessage() method.

Through the onResult() callback method of the sendUserMessage() method, Sendbird server always notifies whether your message has been successfully sent to the channel. When there is a delivery failure due to network issues, an exception is returned through the callback method.

val userIdsToMention = listOf("Jeff", "Julia")
val targetLanguages = listOf("fr", "de") // French, German
val params = UserMessageCreateParams(TEXT_MESSAGE)
    .setCustomType(CUSTOM_TYPE)
    .setData(DATA)
    .setMentionType(MentionType.USERS)
    .setMentionedUserIds(userIdsToMention)
    .setMetaArrays(
        listOf(
            MessageMetaArray("itemType", listOf("tablet")),
            MessageMetaArray("quality", listOf("best", "good"))
        )
    )
    .setTranslationTargetLanguages(targetLanguages)
    .setPushNotificationDeliveryOption(PushNotificationDeliveryOption.DEFAULT)

openChannel.sendUserMessage(params) { message, e ->
    if (e != null) {
        // Handle error.
    }

    // A text message with detailed configuration is successfully sent to the channel.
    // By using message.messageId, message.message, message.customType, and so on,
    // you can access the result object from Sendbird server to check your UserMessageCreateParams configuration.
    // The current user can receive messages from other users through the onMessageReceived() method of an event handler.
}

A user can also send binary files through the Chat SDK. The two ways to send a binary file are: sending the file itself, or sending a URL.

Sending a raw file means you're uploading it to Sendbird server where it can be downloaded in client apps. When you upload a file directly to the server, there is a size limit imposed on the file depending on your plan. You can see the limit on your dashboard and adjust it with our sales team.

The other option is to send a file hosted on your server. You can pass the file's URL, which represents its location, as an argument to a parameter. In this case, your file is not hosted on Sendbird server and it can only be downloaded from your own server. When you send a file message with a URL, there is no limit on the file size since it's not directly uploaded to Sendbird server.

Note: You can use sendFileMessages(), which is another method that allows you to send up to 20 file messages per one method call. Refer to our API Reference to learn more about it.

The following code shows several types of parameters that you can configure to customize file messages by using FileMessageCreateParams. Under the FileMessageCreateParams object, you can assign specific values to customType and other properties. To send your messages, you need to pass the FileMessageCreateParams object as an argument to the parameter in the sendFileMessage() method.

Through the onResult() callback method of the sendFileMessage() method, Sendbird server always notifies whether your message has been successfully sent to the channel. When there is a delivery failure due to network issues, an exception is returned through the callback method.

// Create and add a ThumbnailSize object.
// 3 thumbnail images are allowed.
val thumbnailSizes = listOf(
    FileMessage.ThumbnailSize(100, 100),
    FileMessage.ThumbnailSize(200, 200)
)

val userIdsToMention = listOf("Jeff", "Julia")

val params = FileMessageCreateParams()
    .setFile(FILE) // Or .setFileURL(FILE_URL). You can also send a file message with a file URL.
    .setFileName(FILE_NAME)
    .setFileSize(FILE_SIZE)
    .setMimeType(MIME_TYPE)
    .setThumbnailSizes(thumbnailSizes)
    .setCustomType(CUSTOM_TYPE)
    .setMentionType(MentionType.USERS)      // Either USERS or CHANNEL
    .setMentionedUserIds(userIdsToMention)  // Or .setMentionedUsers(LIST_OF_USERS_TO_MENTION)
    .setPushNotificationDeliveryOption(PushNotificationDeliveryOption.DEFAULT) // Either DEFAULT or SUPPRESS

openChannel.sendFileMessage(params) { message, e ->
    if (e != null) {
        // Handle error.
    }

    // A file message with detailed configuration is successfully sent to the channel.
    // By using message.messageId, message.fileName, message.customType, and so on,
    // you can access the result object from Sendbird server to check your FileMessageCreateParams configuration.
    // The current user can receive messages from other users through the onMessageReceived() method of an event handler.
}

Send a critical alert message to iOS devices

A critical alert is a notification that can be sent to iOS devices even when mute or Do Not Disturb is turned on. Critical alert messages can be sent to iOS devices through the sendUserMessage() and sendFileMessage() methods. To do so, create an AppleCriticalAlertOptions instance and set it as an attribute of a UserMessageCreateParams instance. Then pass the created UserMessageCreateParams instance as an argument to a parameter in the sendUserMessage() or sendFileMessage() method.

Note: To learn more about how to set critical alerts, visit Apple critical alerts.

UserMessageFileMessage
// Send a critical alert user message.
val params = UserMessageCreateParams()
    .setAppleCriticalAlertOptions(AppleCriticalAlertOptions("name", 0.7)) // Acceptable values for volume are 0 to 1.0, inclusive.
openChannel.sendUserMessage(params) { message, e ->
    if (e != null) {
        // Handle error.
    }
}

Receive messages through a channel event handler

Messages sent from other participants can be received through the onMessageReceived() method in the channel event handler. A BaseMessage object for each received message is one of the following message types.

Message typeDescription

UserMessage

A text message sent by a user

FileMessage

A binary file message sent by a user

AdminMessage

A text message sent by an admin through the Chat API

The UNIQUE_HANDLER_ID argument is a unique ID to register multiple concurrent handlers.

SendbirdChat.addChannelHandler(
    UNIQUE_HANDLER_ID,
    object : OpenChannelHandler() {
        override fun onMessageReceived(channel: BaseChannel, message: BaseMessage) {
            // You can customize how to display the different types of messages with the result object in the message parameter.
            when (message) {
                is UserMessage -> {}
                is FileMessage -> {}
                is AdminMessage -> {}
            }
        }
    }
)

Reply to a message

Users can reply to a specific message in a channel through either the sendUserMessage() or sendFileMessage() method.

Depending on the type of the message a user intends to reply with, create a UserMessageCreateParams or a FileMessageCreateParams 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

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

// Create a UserMessageCreateParams object.
val params = UserMessageCreateParams()
    .setParentMessageId(PARENT_MESSAGE_ID)

openChannel.sendUserMessage(params) { message, e ->
    if (e != null) {
        // Handle error.
    }

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

List of arguments

ArgumentTypeDescription

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.

Reply with a file message

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

// Create a FileMessageCreateParams object.
val params = FileMessageCreateParams()
    .setParentMessageId(PARENT_MESSAGE_ID)

openChannel.sendFileMessage(params) { message, e ->
    if (e != null) {
        // Handle error.
    }

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

List of arguments

ArgumentTypeDescription

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 sendFileMessage() 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.


Mention other participants in a message

When a participant wants to call the attention of other participants in an open channel where push notifications are not allowed by default, they can mention those participants in a message. To do so, you should:

  1. Specify a list of the user IDs to mention.

  2. Add the list to either UserMessageCreateParams or FileMessageCreateParams which may contain options for further action.

  3. Pass the params to either sendUserMessage() or sendFileMessage().

  4. Then only up to 10 participants mentioned in the message will be notified.

val userIdsToMention = listOf("Harry", "Jay", "Jin")
val params = UserMessageCreateParams(MESSAGE)
    .setMentionedUserIds(userIdsToMention)

openChannel.sendUserMessage(params) { message, e ->
    if (e != null) {
        // Handle error.
    }

    ...
}

Load previous messages

Using the load() method of a PreviousMessageListQuery instance which returns a list of BaseMessage objects, you can retrieve a set number of previous messages in an open channel. With a returned list, you can display the past messages in your UI once they have loaded.

// There should only be one single instance per channel view.
val query = openChannel.createPreviousMessageListQuery()
query.customTypeFilter = CUSTOM_TYPE

// Retrieve previous messages.
query.load(LIMIT, REVERSE) { messages, e ->
    if (e != null) {
        // Handle error.
    }

    ...
}

List of arguments

ArgumentTypeDescription

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 true, returns a list of messages which the latest comes at first and the earliest at last. the results are sorted in reverse order. If false, returns a list of messages which the earliest comes at first and the latest at last.

A limit parameter determines how many messages should be included in a returned list. A PreviousMessageListQuery instance itself does pagination of a result set based on the value of the limit parameter, and internally manages a token to retrieve the next page in the result set.

Each time the load() method is called, the instance retrieves a set number of messages in the next page and then updates the value of the token to complete the current call and prepare a next call.

If you create a new PreviousMessageListQuery instance and call the load() method, a set number of the most recent messages are retrieved because its token has nothing to do with the previously created instance. So we recommend that you create a single query instance and store it as a member variable for traversing through the entire message history.

Note: Before calling the load() method again, you must receive a success callback through onResult() first.


Load messages by timestamp or message ID

You can retrieve a set number of previous and next messages on both sides of a specific timestamp in an open channel. You can do the same using a message ID as well.

By timestamp

Use the getMessagesByTimestamp() method to retrieve a set number of previous and next messages on both sides of a specific timestamp.

The following code shows several types of parameters that you can configure to customize a message query by using MessageListParams. Under the MessageListParams object, you can assign values to previousResultSize, messageType, customType, and other properties. To retrieve messages in a channel, you need to pass the MessageListParams object as an argument to the parameter in the getMessagesByTimestamp() method.

val params = MessageListParams().apply {
    this.isInclusive = IS_INCLUSIVE
    this.previousResultSize = PREVIOUS_RESULT_SIZE
    this.nextResultSize = NEXT_RESULT_SIZE
    this.reverse = REVERSE
    this.messageType = MESSAGE_TYPE
    this.customType = CUSTOM_TYPE
}

openChannel.getMessagesByTimestamp(TIMESTAMP, params) { messages, e ->
    if (e != null) {
        // 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 onResult() callback method,
    // you can access and display the data of each message from the result list
    // that Sendbird server has passed to the callback method.
}

List of arguments

ArgumentTypeDescription

TIMESTAMP

long

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

IS_INCLUSIVE

boolean

Determines whether to include the messages sent exactly on TIMESTAMP.

PREV_RESULT_SIZE

int

Specifies the number of messages to retrieve, which are sent previously before a specified timestamp. Note that the actual number of results may be larger than the set value when there are multiple messages with the same timestamp as the earliest message.

NEXT_RESULT_SIZE

int

Specifies the number of messages to retrieve, which are sent later after a specified timestamp. Note that the actual number of results may be larger than the set value when there are multiple messages with the same timestamp as the latest message.

REVERSE

boolean

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

MESSAGE_TYPE

enum

Specifies the message type to filter the messages with the corresponding type. Acceptable values are MessageTypeFilter.ALL, MessageTypeFilter.USER, MessageTypeFilter.FILE, and MessageTypeFilter.ADMIN.

CUSTOM_TYPE

string

Specifies the custom message type to filter the messages with the corresponding custom type.

By message ID

You can also retrieve a set number of previous and next messages on both sides of a specific message ID in an open channel, using the getMessagesByMessageId() method and MessageListParams object.

val params = MessageListParams().apply {
    this.isInclusive = IS_INCLUSIVE
    this.previousResultSize = PREVIOUS_RESULT_SIZE
    this.nextResultSize = NEXT_RESULT_SIZE
    this.reverse = REVERSE
    this.messageType = MESSAGE_TYPE
    this.customType = CUSTOM_TYPE
}

openChannel.getMessagesByMessageId(MESSAGE_ID, params) { messages, e ->
    if (e != null) {
        // 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 onResult() callback method,
    // you can access and display the data of each message from the result list
    // that Sendbird server has passed to the callback method.
}

List of arguments

ArgumentTypeDescription

MESSAGE_ID

long

Specifies the unique ID of the message to be the reference point of a retrieval.

IS_INCLUSIVE

boolean

Determines whether to include the message identified with a specified message ID.

PREV_RESULT_SIZE

int

Specifies the number of messages to retrieve, which are sent previously before a specified message ID.

NEXT_RESULT_SIZE

int

Specifies the number of messages to retrieve, which are sent later after a specified timestamp.

REVERSE

boolean

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

MESSAGE_TYPE

enum

Specifies the message type to filter the messages with the corresponding type. Acceptable values are MessageTypeFilter.ALL, MessageTypeFilter.USER, MessageTypeFilter.FILE, and MessageTypeFilter.ADMIN.

CUSTOM_TYPE

string

Specifies the custom message type to filter the messages with the corresponding custom type.


List messages along with their replies by timestamp or message ID

You can retrieve messages and their replies in a specific thread through one of the load(), getMessagesByTimestamp(), or getMessagesByMessageId() methods.

First, messages in an open channel must be retrieved. The load() method of a PreviousMessageListQuery instance returns a list of BaseMessage objects. By using this method, you can retrieve previous messages in a specific channel.

val query = openChannel.createPreviousMessageListQuery()
query.limit = LIMIT
query.reverse = REVERSE
query.replyType = ReplyType.ALL
query.messagePayloadFilter = MessagePayloadFilter.Builder()
    .setIncludeParentMessageInfo(true)
    .setIncludeThreadInfo(true)
    .build()

// This retrieves previous messages in a channel.
query.load { messages, e ->
    if (e != null) {
        // Handle error.
    }

    ...
}

List of arguments

ArgumentTypeDescription

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.

ReplyType

enum

Specifies the type of message to include in the results.
- NONE (default): All messages that aren't 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 aren't threaded. It only includes the parent messages and replies that were sent to the channel.

MessagePayloadFilter

Builder

Determines whether to include information about message threads and their parent messages through the following setters:

INCLUDE_THREAD_INFO: Determines whether to include the thread information of the messages in the results when the results contain parent messages. (Default: false)

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

By timestamp

The getMessagesByTimestamp() method of a BaseChannel instance retrieves a list of BaseMessage objects.

When using the method above, you can also pass a MessageListParams object as an argument to the parameter in the getMessagesByTimestamp() method.

val params = MessageListParams().apply {
    this.isInclusive = IS_INCLUSIVE
    this.previousResultSize = PREVIOUS_RESULT_SIZE
    this.nextResultSize = NEXT_RESULT_SIZE
    this.reverse = REVERSE
    this.messageType = MESSAGE_TYPE
    this.customType = CUSTOM_TYPE
    this.replyType = ReplyType.ALL
}

openChannel.getMessagesByTimestamp(TIMESTAMP, params) { messages, e ->
    if (e != null) {
        // 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 onResult() callback method,
    // you can access and display the data of each message from the result list
    // that Sendbird server has passed to the callback method.
}

List of arguments

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.

PREV_RESULT_SIZE

int

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

NEXT_RESULT_SIZE

int

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

INCLUSIVE

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.

INCLUDE_THREAD_INFO

boolean

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

ReplyType

enum

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.

INCLUDE_PARENT_MESSAGE_INFO

boolean

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

By message ID

The getMessagesByMessageId() method of a BaseChannel instance retrieves a set number of previous and next messages on both sides of a specific message ID in a channel.

openChannel.getMessagesByMessageId(MESSAGE_ID, params) { messages, e ->
    if (e != null) {
        // 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 onResult() callback method,
    // you can access and display the data of each message from the result list that Sendbird server has passed to the callback method.
}

List of arguments

ArgumentTypeDescription

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

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

val params = ThreadMessageListParams().apply {
    this.previousResultSize = PREVIOUS_RESULT_SIZE
    this.nextResultSize = NEXT_RESULT_SIZE
    this.isInclusive = INCLUSIVE
    this.reverse = REVERSE
    this.includeParentMessageInfo = INCLUDE_PARENT_MESSAGE_INFO
}

// Pass the params as an argument to the parameter in the getThreadedMessagesByTimestamp() method.
parentMessage.getThreadedMessagesByTimestamp(TIMESTAMP, params) { parentMessage, messages, e ->
    if (e != null) {
        // Handle error.
    }

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

List of arguments

Parameter nameTypeDescription

TIMESTAMP

long

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

PREVIOUS_RESULT_SIZE

int

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

NEXT_RESULT_SIZE

int

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

INCLUSIVE

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.

INCLUDE_PARENT_MESSAGE_INFO

boolean

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


Retrieve a message

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

val params = MessageRetrievalParams(CHANNEL_URL, CHANNEL_TYPE, MESSAGE_ID)

// Pass the params as an argument to the parameter in the getMessage() method.
BaseMessage.getMessage(params) { message, e ->
    if (e != null) {
        // Handle error.
    }

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

List of arguments

ArgumentTypeDescription

CHANNEL_URL

String

Specifies the URL of the channel to retrieve the message.

CHANNEL_TYPE

BaseChannel.ChannelType

Specifies the type of the channel.

MESSAGE_ID

long

Specifies the unique ID of the message to retrieve.


Update a message

A user can update any of their own text and file messages sent using UserMessageUpdateParams and FileMessageUpdateParams. An error is returned if a user attempts to update another user's messages. In addition, channel operators can update any messages sent in the channel.

User messageFile message
val params = UserMessageUpdateParams()
    .setMessage(NEW_TEXT_MESSAGE)
    .setCustomType(NEW_CUSTOM_TYPE)
    .setData(NEW_DATA)

// The MESSAGE_ID argument below indicates the unique message ID of a UserMessage object to update.
openChannel.updateUserMessage(MESSAGE_ID, params) { message, e ->
    if (e != null) {
        // Handle error.
    }

    // The message is successfully updated.
    // Through the message parameter of the onResult() callback method,
    // you could check if the update operation has been performed correctly.
}

If a message is updated, the onMessageUpdated() method in the channel event handler will be invoked on all channel participants' devices except the one that updated the message.

SendbirdChat.addChannelHandler(
    UNIQUE_HANDLER_ID,
    object : OpenChannelHandler() {
        override fun onMessageUpdated(channel: BaseChannel, message: BaseMessage) {
            ...
        }
        ...
    }
)

Delete a message

A user can delete any messages sent by themselves. An error is returned if a user attempts to delete the messages of other participants. Also channel operators can delete any messages in the channel.

// The BASE_MESSAGE argument below indicates a BaseMessage object to delete.
openChannel.deleteMessage(BASE_MESSAGE) { e ->
    if (e != null) {
        // Handle error.
    }

    // The message is successfully deleted from the channel.
    ...
}

If a message is deleted, the onMessageDeleted() method in the channel event handler will be invoked on all channel participants' devices including the one that deleted the message.

SendbirdChat.addChannelHandler(
    UNIQUE_HANDLER_ID,
    object : OpenChannelHandler() {
        override fun onMessageDeleted(channel: BaseChannel, messageId: Long) {
            ...
        }
        ...
    }
)

Copy a message

A user can copy and send their own message in the same channel or to another channel.

User messageFile message
openChannel.copyUserMessage(TARGET_CHANNEL, MESSAGE_TO_COPY) { message, e ->
    if (e != null) {
        // Handle error.
    }

    // The message is successfully copied to the target channel.
}

List of arguments

ArgumentTypeDescription

TARGET_CHANNEL

object

Specifies a target channel to send a copied message to.

MESSAGE_TO_COPY

object

Specifies a message to copy.

HANDLER

interface

Specifies the handler interface which contains the onResult() callback method to receive the response from Sendbird server for a message copy request.


Retrieve a list of participants

You can retrieve a list of participants who are currently online and receiving all messages from an open channel.

val query = openChannel.createParticipantListQuery()
query.next { users, e ->
    if (e != null) {
        // Handle error.
    }

    ...
}

Retrieve the latest information on participants

To retrieve the latest and updated information on each online participant in an open channel, you need another ParticipantListQuery instance for the channel. Like the Retrieve a list of participants section above, create a query instance using channel.createParticipantListQuery(), and then call its next() method consecutively to retrieve the latest.

You can also retrieve the latest and updated information on users at the application level. Like the Retrieve a list of users section, create a new ApplicationUserListQuery instance using SendbirdChat.createApplicationUserListQuery(), and then call its next() method consecutively to retrieve the latest.

When retrieving the online (connection) status of a user, by calling user.connectionStatus at each User object in a returned list, you can get the user's current connection status. The connectionStatus method returns one of the following two values:

getConnectionStatus()

ValueDescription

User.ConnectionStatus.OFFLINE

The user isn't connected to Sendbird server.

User.ConnectionStatus.ONLINE

The user is connected to Sendbird server.

Note: If you need to keep track of the connection status of some users in real time, we recommend that you call periodically the next() method of an ApplicationUserListQuery instance with its userIdsFilter filter specified, perhaps in intervals of one minute or more.


Retrieve a list of operators

You can follow the simple implementation below to retrieve a list of operators who monitor and control the activities in an open channel.

OpenChannel.getChannel(CHANNEL_URL) { channel, e ->
    if (e != null) {
        // Handle error.
    }

    // Retrieve a list of operators.
    channel.operators.forEach { operator ->
        ...
    }
}

Register operators

You can register participants as operators of an open channel.

openChannel.addOperators(USER_IDS) { e ->
    if (e != null) {
        // Handle error.
    }

    // The participants are successfully registered as operators of the channel.
    ...
}

Cancel the registration of operators

You can cancel the registration of operators from an open channel but leave them as participants.

openChannel.removeOperators(USER_IDS) { e ->
    if (e != null) {
        // Handle error.
    }

    // The cancel operation is succeeded,
    // and you could display some message to those who are not operators anymore.
    ...
}

If you want to cancel the registration of all operators in a channel at once, use the following code.

openChannel.removeAllOperators { e ->
    if (e != null) {
        // Handle error.
    }

    // The cancel operation has succeeded,
    // and you could display some message to those who are not operators anymore.
    ...
}

Retrieve a list of banned or muted users

You can create a query to get a list of banned or muted users in an open channel. This query is only available for users who are registered as operators of an open channel.

// Retrieve banned users.
val query = channel.createBannedUserListQuery()
query.next { users, e ->
    if (e != null) {
        // Handle error.
    }

    ...
}

// Retrieve muted users.
val query = channel.createMutedUserListQuery()
query.next { users, e ->
    if (e != null) {
        // Handle error.
    }

    ...
}

Ban and unban a user

Operators of an open channel can remove any users that behave inappropriately in the channel by using our Ban feature. Banned users are immediately expelled from a channel and allowed to participate in the channel again after the time period set by the operators. Operators can ban and unban users from open channels using the following code.

OpenChannel.getChannel(CHANNEL_URL) { channel, e ->
    if (e != null) {
        // Handle error.
    }

    if (channel == null) return@getChannel
    if (channel.isOperator(SendbirdChat.currentUser)) {
        // Ban a user.
        openChannel.banUser(USER, SECONDS) { e ->
            if (e != null) {
                // Handle error.
            }

            // The user is successfully banned from the channel.
            // You could notify the user of being banned by displaying a prompt.
            ...
        }

        // Unban a user.
        openChannel.unbanUser(USER) { e ->
            if (e != null) {
                // Handle error.
            }

            // The user is successfully unbanned for the channel.
            // You could notify the user of being unbanned by displaying a prompt.
            ...
        }
    }
}

Note: You can also pass the unique ID of a participant as a parameter instead of USER to ban or unban them.


Mute and unmute a user

Operators of an open channel can prohibit the selected users from sending messages using our Mute feature. Muted users remain in the channel and are allowed to view the messages, but can't send any messages until the operators unmute them. Operators can mute and unmute users in open channels using the following code:

OpenChannel.getChannel(CHANNEL_URL) { channel, e ->
    if (e != null) {
        // Handle error.
    }

    if (channel == null) return@getChannel
    if (channel.isOperator(SendbirdChat.currentUser)) {
        // Ban a user.
        openChannel.muteUser(USER) { e ->
            if (e != null) {
                // Handle error.
            }

            // The user is successfully muted in the channel.
            // You could notify the user of being muted by displaying a prompt.
            ...
        }

        // Unban a user.
        openChannel.unmuteUser(USER) { e ->
            if (e != null) {
                // Handle error.
            }

            // The user is successfully unmuted in the channel.
            // You could notify the user of being unmuted by displaying a prompt.
            ...
        }
    }
}

Note: You can also pass the unique ID of a participant as a parameter instead of USER to mute or unmute them.


Report a message, a user, or a channel

In an open channel, a user can report suspicious or harassing messages as well as the other users who use abusive language. The user can also report channels if there are any inappropriate content or activity within the channel. Based on this feature and our report API, you can build your own in-app system for managing objectionable content and subject.

// Report a message.
openChannel.reportMessage(MESSAGE_TO_REPORT, REPORT_CATEGORY, DESCRIPTION) { e ->
    if (e != null) {
        // Handle error.
    }

    ...
}

// Report a user.
openChannel.reportUser(OFFENDING_USER, REPORT_CATEGORY, DESCRIPTION) { e ->
    if (e != null) {
        // Handle error.
    }

    ...
}

// Report a channel.
openChannel.report(REPORT_CATEGORY, DESCRIPTION) { e ->
    if (e != null) {
        // Handle error.
    }

    ...
}

List of arguments

ArgumentTypeDescription

MESSAGE_TO_REPORT

object

Specifies the message to report for its suspicious, harassing, or inappropriate content.

OFFENDING_USER

object

Specifies the user who uses offensive or abusive language such as sending explicit messages or inappropriate comments.

REPORT_CATEGORY

enum

Specifies a report category which indicates the reason for reporting. Acceptable values are ReportCategory.SUSPICIOUS, ReportCategory.HARASSING, ReportCategory.INAPPROPRIATE, and ReportCategory.SPAM.

DESCRIPTION

string

Specifies additional information to include in the report.