Open Channel

Open Channel is a public chat by nature and it can handle a large number of participation online. In this channel type, anyone can enter and participate in the chat without permission. A single channel can handle up to one thousand, simultaneous users like Twitch-style public chat. This default number of participants can increase per request.


Create an open channel with additional information

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

In the dashboard, click OPEN CHANNELS, then click CREATE at the top-left corner. In the dialog box that appears, specify the name, url, cover image, and custom type of a channel. The channel url is a unique identifier.

You can also create a channel on demand or dynamically via the SDK or the SendBird Platform API.

OpenChannel.createChannel(new OpenChannel.OpenChannelCreateHandler() {
    @Override
    public void onResult(OpenChannel openChannel, SendBirdException e) {
        if (e != null) {    // Error.
            return;
        }
    }
});

When creating a channel, you can also append additional information like cover image and description by specifying several arguments.

OpenChannel.createChannel(NAME, COVER_IMAGE_OR_URL, DATA, CUSTOM_TYPE, HANDLER)
  • NAME: the name of a channel, or the channel topic.
  • COVER_IMAGE_OR_URL: the file or URL of the cover image, which you can fetch to render into the UI.
  • DATA: the String field which can be a description of the channel or structured information such as a JSON String for other purposes.
  • CUSTOM_TYPE: the String field that allows you to subclassify your channel.

You can get the cover image URL using getCoverUrl(), and update a channel's cover image by calling updateChannel().


Enter an open 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 if the disconnected user is reconnected to SendBird, the user must re-enter the channels to continue receiving messages.

OpenChannel.getChannel(CHANNEL_URL, new OpenChannel.OpenChannelGetHandler() {
    @Override
    public void onResult(OpenChannel openChannel, SendBirdException e) {
        if (e != null) {    // Error.
            return;
        }

        openChannel.enter(new OpenChannel.OpenChannelEnterHandler() {
            @Override
            public void onResult(SendBirdException e) {
                if (e != null) {    // Error.
                    return;
                }
            }
        });
    }
});

Exit an open channel

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

OpenChannel.getChannel(CHANNEL_URL, new OpenChannel.OpenChannelGetHandler() {
    @Override
    public void onResult(OpenChannel openChannel, SendBirdException e) {
        if (e != null) {    // Error.
            return;
        }

        openChannel.exit(new OpenChannel.OpenChannelExitHandler() {
            @Override
            public void onResult(SendBirdException e) {
                if (e != null) {    // Error.
                    return;
                }
            }
        });
    }
});

Delete an open channel

The operators of an open channel can delete the channel. Otherwise, an error is returned to OpenChannelDeleteHandler.

OpenChannel.delete(new OpenChannelDeleteHandler() {
    @Override
    public void onResult(SendBirdException e) {
        if (e != null) {    // Error.
            return;
        }
    }
});

Retrieve a list of open channels

You can obtain a list of all open channels by creating a OpenChannelListQuery. The next() method returns a list of OpenChannel objects.

OpenChannelListQuery channelListQuery = OpenChannel.createOpenChannelListQuery();
channelListQuery.next(new OpenChannelListQuery.OpenChannelListQueryResultHandler() {
    @Override
    public void onResult(List<OpenChannel> channels, SendBirdException e) {
        if (e != null) {    // Error.
            return;
        }
    }
});

Retrieve an open channel by its URL

Since a channel URL is a unique identifier of an open channel, you can use a URL to retrieve a channel instance. It is important to remember that a user must enter the channel to send or receive messages within it.

Store channel URLs to handle the lifecycle or state changes in your app. For example, if a user disconnects from SendBird by temporarily switching to another app, you can provide a smooth restoration of the user's state using a stored URL to fetch the appropriate channel instance, then re-entering the user into the channel.

OpenChannel.getChannel(CHANNEL_URL, new OpenChannel.OpenChannelGetHandler() {
    @Override
    public void onResult(OpenChannel openChannel, SendBirdException e) {
        if (e != null) {    // Error!
            return;
        }

        // Successfully fetched the channel.
        // Do something with openChannel.
    }
});

Send messages to an open channel

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

  • UserMessage: text message sent by user.
  • FileMessage: binary message sent by user.

You can additionally specify a CUSTOM_TYPE to further subclassify a message. When you send a text message, you can additionally attach arbitrary strings via a data field. You can utilize this field to send structured data such as font sizes, font types, or custom JSON objects.

Delivery failures due to the network issues return an exception. By overriding the onSent() callback in the context of sendUserMessage(), it is possible to display only the messages that are successfully sent.

channel.sendUserMessage(MESSAGE, DATA, CUSTOM_TYPE, new BaseChannel.SendUserMessageHandler() {
    @Override
    public void onSent(UserMessage userMessage, SendBirdException e) {
        if (e != null) {    // Error.
            return;
        }
    }
});

A user can also send any binary file through SendBird. There are two ways in which you can send a binary file: by sending the file itself, or by sending a URL.

Sending a raw file means that you upload it to SendBird server. Alternatively, you can choose to send a file hosted in your own server by passing in a URL that points to the file. In this case, the file isn't hosted in SendBird server, and downloaded through your own server instead.

Note: If you upload your file directly, a size limit is imposed per file. This limit depends on your plan, and can be viewed from your Dashboard. No file size limit is imposed if you send a file message via a URL. Then the file isn't uploaded to SendBird server.

// Sending file message with raw file
channel.sendFileMessage(FILE, NAME, TYPE, SIZE, DATA, CUSTOM_TYPE, new BaseChannel.SendFileMessageHandler() {
    @Override
    public void onSent(FileMessage fileMessage, SendBirdException e) {
        if (e != null) {    // Error.
            return;
        }
    }
});

// Sending file message with file URL
channel.sendFileMessage(FILE_URL, NAME, TYPE, SIZE, DATA, CUSTOM_TYPE, new BaseChannel.SendFileMessageHandler() {
    @Override
    public void onSent(FileMessage fileMessage, SendBirdException e) {
        if (e != null) {    // Error.
            return;
        }
    }
});

Note: To send metadata along with a file, you can populate the DATA field.


Receive messages through a channel event handler

Messages can be received through a onMessageReceived() of a channel event handler. A received BaseMessage object is one of the following three message types.

  • UserMessage: text message sent by user.
  • FileMessage: binary message sent by user.
  • AdminMessage: message sent by an admin through the Platform API.

UNIQUE_HANDLER_ID is a unique identifier to register multiple concurrent handlers.

SendBird.addChannelHandler(UNIQUE_HANDLER_ID, new SendBird.ChannelHandler() {
    @Override
    public void onMessageReceived(BaseChannel baseChannel, BaseMessage baseMessage) {
        if (baseMessage instanceof UserMessage) {
            // The received message is a UserMessage.
        } else if (baseMessage instanceof FileMessage) {
            // The received message is a FileMessage.
        } else if (baseMessage instanceof AdminMessage) {
            // The received message is an AdminMessage.
        }
    }
});

Load previous messages in an open channel

You can load previous messages by creating a PreviousMessageListQuery instance and calling load(). You can display the past messages in your UI once they have loaded.

PreviousMessageListQuery prevMessageListQuery = openChannel.createPreviousMessageListQuery();
prevMessageListQuery.load(30, true, new PreviousMessageListQuery.MessageListQueryResult() {
    @Override
    public void onResult(List<BaseMessage> messages, SendBirdException e) {
        if (e != null) {    // Error.
            return;
        }
    }
});

Past messages are queried in fixed numbers (30 in the above code). A new PreviousMessageListQuery instance loads the most recent n messages. load() on the same query instance returns n messages before that. So if you store your query instance as a member variable, you can traverse through your entire message history.

Note: You must receive your first onResult() callback before invoking load() again.


Load messages by timestamp or message ID in an open channel

You can retrieve a list of messages starting from a specific timestamp. To load messages sent prior to a specified timestamp, use getPreviousMessagesByTimestamp().

openChannel.getPreviousMessagesByTimestamp(TIMESTAMP, IS_INCLUSIVE, PREV_RESULT_SIZE, REVERSE, MESSAGE_TYPE, CUSTOM_TYPE, new BaseChannel.GetMessagesHandler() {
    @Override
    public void onResult(List<BaseMessage> list, SendBirdException e) {
        if (e != null) {    // Error.
            return;
        }

        // A list of messages sent before timestamp is successfully retrieved.
    }
});
  • TIMESTAMP: the reference timestamp.
  • IS_INCLUSIVE: whether to include messages sent exactly at TIMESTAMP.
  • PREV_RESULT_SIZE: the number of messages to load. 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.
  • REVERSE: whether to reverse the results.
  • MESSAGE_TYPE: a BaseChannel.MessageTypeFilter object. The values are limited to MessageTypeFilter.ALL, MessageTypeFilter.USER, MessageTypeFilter.FILE, or MessageTypeFilter.ADMIN.
  • CUSTOM_TYPE: the custom type of the messages to be returned.

Note: To load messages sent after a specified timestamp, call getNextMessagesByTimestamp() in a similar fashion. To load results on either side of the reference timestamp, use getPreviousAndNextMessagesByTimestamp().

You can also retrieve a set number of messages starting from a specific message ID. To load messages sent prior to the specified message ID, use getPreviousMessagesById().

openChannel.getPreviousMessagesById(MESSAGE_ID, IS_INCLUSIVE, PREV_RESULT_SIZE, REVERSE, MESSAGE_TYPE, CUSTOM_TYPE, new BaseChannel.GetMessagesHandler() {
    @Override
    public void onResult(List<BaseMessage> list, SendBirdException e) {
        if (e != null) {        // Error.
            return;
        }

        // A list of messages, the IDs of which are prior to the specified message ID, is successfully retrieved.
    }
});
  • MESSAGE_ID: the reference message ID.
  • IS_INCLUSIVE: whether to include messages sent exactly at MESSAGE_ID.
  • PREV_RESULT_SIZE: the number of messages to load. Note that the actual number of results may be larger than the set value when there are multiple messages with the same message ID the earliest message.
  • REVERSE: whether to reverse the results.
  • MESSAGE_TYPE: a BaseChannel.MessageTypeFilter object. The values are limited to MessageTypeFilter.ALL, MessageTypeFilter.USER, MessageTypeFilter.FILE, or MessageTypeFilter.ADMIN.
  • CUSTOM_TYPE: the custom type of the messages to be returned.

Note: To load messages sent after a specified message ID, call getNextMessagesById() in a similar fashion. To load results on either side of the reference message ID, use getPreviousAndNextMessagesById().


Update a message in an open channel

Users can update any of their own text and file messages sent. 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.

// In case of UserMessage
channel.updateUserMessage(MESSAGE_ID, BODY, DATA, CUSTOM_TYPE, new BaseChannel.UpdateUserMessageHandler() {
    @Override
    public void onUpdated(UserMessage userMessage, SendBirdException e) {
        if (e != null) {    // Error.
            return;
        }
    }
});

// In case of FileMessage
channel.updateFileMessage(MESSAGE_ID, DATA, CUSTOM_TYPE, new BaseChannel.UpdateFileMessageHandler() {
    @Override
    public void onUpdated(FileMessage fileMessage, SendBirdException e) {
        if (e != null) {    // Error.
            return;
        }
    }
});

A onMessageUpdated() of a channel event handler will be invoked after the message is updated, and all participants of the channel will be notified.

SendBird.addChannelHandler(UNIQUE_HANDLER_ID, new SendBird.ChannelHandler() {
    ...

    @Override
    public void onMessageUpdated(BaseChannel baseChannel, BaseMessage message) {

    }
    ...

});

Delete a message from an open channel

Users can delete any messages which were 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.

channel.deleteMessage(BASE_MESSAGE, new BaseChannel.DeleteMessageHandler() {
    @Override
    public void onResult(SendBirdException e) {
        if (e != null) {    // Error.
            return;
        }
    }
});

A onMessageDeleted() of a channel event handler will be invoked after the message is deleted, and the result also notified to all other participants in the channel.

SendBird.addChannelHandler(UNIQUE_HANDLER_ID, new SendBird.ChannelHandler() {
    ...

    @Override
    public void onMessageDeleted(BaseChannel baseChannel, long messageId) {

    }
    ...

});

Retrieve a list of participants in an open channel

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

ParticipantListQuery participantListQuery = openChannel.createParticipantListQuery();
participantListQuery.next(new UserListQuery.UserListQueryResultHandler() {
    @Override
    public void onResult(List<User> list, SendBirdException e) {
        if (e != null) {    // Error.
            return;
        }
    }
});

Retrieve participant online status in an open channel

To retrieve current connection status of each participant, you should create a new ParticipantListQuery to see the latest and updated information on each user. To do like the Retrieve a list of participants in an open channel section above, get a ParticipantListQuery for the channel and call channel.createParticipantListQuery(). If you want to see a list of all users in your application, call SendBird.createApplicationUserListQuery() instead.

By using user.getConnectionStatus() at each User object in the returned list, you can check user's current connection status. The getConnectionStatus() returns one of the following three values:

  • User.ConnectionStatus.NON_AVAILABLE: user's status information cannot be reached.
  • User.ConnectionStatus.OFFLINE: user is disconnected from SendBird.
  • User.ConnectionStatus.ONLINE: user is connected to SendBird.

Note: If your application needs to keep track of users' connection statuses in real time, we recommend receiving a new ApplicationUserListQuery periodically, perhaps in intervals of one minute or more.


Retrieve a list of operators in an open channel

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, new OpenChannel.OpenChannelGetHandler() {
    @Override
    public void onResult(OpenChannel openChannel, SendBirdException e) {
        if (e != null) {    // Error!
            return;
        }
        // Retrieving a list of operators.
        for (User operator : openChannel.getOperators()) {
            ...
        }
    }
});

Retrieve a list of banned or muted users in an open channel

You can also 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.

// In case of retrieving banned users 
BannedUserListQuery bannedUserListQuery = openChannel.createBannedUserListQuery(); 
bannedUserListQuery.next(new UserListQuery.UserListQueryResultHandler() {
    @Override
    public void onResult(List<User> list, SendBirdException e) {
        if (e != null) {    // Error.
            return;
        }
    }
});

// In case of retrieving muted users 
MutedUserListQuery mutedUserListQuery = openChannel.createMutedUserListQuery();
mutedUserListQuery.next(new UserListQuery.UserListQueryResultHandler() {
    @Override
    public void onResult(List<User> list, SendBirdException e) {
        if (e != null) {    // Error.
            return;
        }
    }
});

Ban and unban a participant in an open channel

Operators of an open channel can remove any participants that behave inappropriately in the channel by using our Ban function. Users that are banned from a channel can participate in the channel again after the time period set by the operators. Operators can ban and unban participants in open channels using the following code.

OpenChannel.getChannel(CHANNEL_URL, new OpenChannel.OpenChannelGetHandler() {
    @Override
    public void onResult(OpenChannel openChannel, SendBirdException e) {
        if (e != null) {    // Error!
            return;
        }

        // Banning and unbanning a participant
        if(openChannel.isOperator(SendBird.getCurrentUser())) {
            openChannel.banUser(USER, SECONDS, new OpenChannel.OpenChannelBanHandler() {
                @Override
                public void onResult(SendBirdException e) {
                    if (e != null) {    // Error!
                        return;
                    }

                    // Custom implementation for what to do after banning.
                }
            });

            openChannel.unbanUser(USER, new OpenChannel.OpenChannelUnbanHandler() {
                @Override
                public void onResult(SendBirdException e) {
                    if (e != null) {    // Error!
                        return;
                    }

                    // Custom implementation for what to do after unbanning.
                }
            });
        }
    }        
});

Note: You can also use banUserWithUserId() and unbanUserWithUserId() methods, instead of banUser() and unbanUser() methods, as they have the same functionalities. Please see our API reference on banUserWithUserId() and unbanUserWithUserID().


Mute and unmute a participant in an open channel

Operators of an open channel can prohibit selected participants from sending messages using our Mute function. Muted participants will remain in the channel and view the messages, but will not be allowed to send any messages until the operators unmute them. Operators can mute and unmute participants in open channels using the following code:

OpenChannel.getChannel(CHANNEL_URL, new OpenChannel.OpenChannelGetHandler() {
    @Override
    public void onResult(OpenChannel openChannel, SendBirdException e) {
        if (e != null) {    // Error!
            return;
        }

        // Muting and unmuting a participant
        if(openChannel.isOperator(SendBird.getCurrentUser())) {
            openChannel.muteUser(USER, new OpenChannel.OpenChannelMuteHandler() {
                @Override
                public void onResult(SendBirdException e) {
                    if (e != null) {    // Error!
                        return;
                    }

                    // Custom implementation for what to do after muting.
                }
            });

            openChannel.unmuteUser(USER, new OpenChannel.OpenChannelUnmuteHandler() {
                @Override
                public void onResult(SendBirdException e) {
                    if (e != null) {    // Error!
                        return;
                    }

                    // Custom implementation for what to do after unmuting.
                }
            });
        }
    }
});

Note: You can also use muteUserWithUserId() and unmuteUserWithUserId() methods, instead of muteUser() and unmuteUser() methods, as they have same functionalities. Please see our API reference on muteUserWithUserId() and unmuteUserWithUserID().


Freeze and unfreeze an open channel

Currently, you can only freeze and unfreeze an open channel by using the SendBird Dashboard or the Platform API as opposed to the group channel. You can take the following steps to freeze an open channel using the SendBird Dashboard: Open Channels > open channel > Freeze icon at the upper right corner. To unfreeze the open channel, click the icon again.