Quick Start

1. Create a new SendBird application in the Dashboard

The first thing you need to do is to log in to the SendBird Dashboard and create a SendBird application. If you do not yet have an account, you can log in with Google, GitHub, or create a new account.

You should create one application per service, regardless of the platform. For example, an app released in both Android and iOS would require only one application to be created in the Dashboard.

All users within the same SendBird application are able to communicate with each other, across all platforms. This means users using iOS, Android, web clients, etc. can all chat with one another. However, users in different SendBird applications cannot talk to each other.

2. Requirements

SendBird .NET SDK is designed and tested on Mono/.NET 2.0 platform and Xamarin Studio 6.1.1. You can also use our SDK on any platforms which are compatible with Mono/.NET 2.0.

3. Download the latest .NET SDK

WebSocket Library

The SendBird .NET SDK uses websocket-sharp for websocket connections. You must include websocket-sharp.dll as well as SendBird.dll or SendBird.Unity.dll.

You can find websocket-sharp.dll on the same repository as the SendBird .NET SDK.

GitHub repository

Authentication

Initializing with APP_ID

To use its chat features, you must initialize SendBird using the APP_ID assigned to your SendBird application.
Typically, initialization would be implemented in the user login screen.

SendBirdClient.Init(APP_ID);

Connecting with UserID

By default, SendBird requires only a UserID to join a channel. Upon requesting connection, SendBird will query its user database for a matching UserID. If it finds that the UserID has not been registered yet, a new user account will be created. The UserID can be any unique string id, such as an email address or a UID from your database.

This simple authentification procedure might be useful when you are in development or if your service does not require additional security.

Explanation on SendBird's usage of Handlers and callbacks can be found under the Event Handler section.

SendBirdClient.Connect(USER_ID, (User user, SendBirdException e) =>
{
    if(e != null)
    {
        // Error
        return;
    }
});

Connecting with UserID and Access Token

With the SendBird Platform API, you can create a user with an access token, or you can issue an access token for an existing user. Once an access token is issued, you are required to provide the user's token in the login method.

  1. Create a SendBird user account via the Platform API when your user signs up on your service.
  2. Save the access token to your secured persistent store.
  3. Load the access token in your client and pass it to the SendBird login method.
  4. For security reasons, we recommend that you periodically update your access token by issuing a new token to replace the previous one.

You can set restrictions for users without access tokens in your Dashboard settings.
These settings can be found under Security - Access Token Policy.

SendBirdClient.Connect(USER_ID, ACCESS_TOKEN, (User user, SendBirdException e) =>
{
    if(e != null)
    {
        // Error
        return;
    }
});

Disconnecting

You should disconnect from SendBird when your user no longer needs to receive messages from an online state.

Users will still be able to receive Group Channel messages through Push Notifications.

Disconnecting removes all registered handlers and callbacks. That is, it removes all Event Handlers added through SendBirdClient.AddChannelHandler() or SendBirdClient.AddConnectionHandler(). It also flushes all internally cached data, such as the channels that are cached when OpenChannel.GetChannel() or GroupChannel.GetChannel() is called.

SendBirdClient.Disconnect(() => {
    @Override
    public void onDisconnected() {
        // You are disconnected from SendBird.
    }
});

Updating a User Profile and Profile Image

You can update a user's nickname and profile image.

Call UpdateCurrentUserInfo() to update a user's nickname, as well as their profile picture with a URL.

SendBirdClient.Connect(USER_ID, (User user, SendBirdException e) =>
{
    if(e != null)
    {
        // Error
        return;
    }

    SendBirdClient.UpdateCurrentUserInfo(NICKNAME, PROFILE_URL, (SendBirdException e1) =>
    {
        if(e1 != null)
        {
            // Error
            return;
        }
    });
});

Or, you can upload an image directly using UpdateCurrentUserInfoWithProfileImage().

SendBirdClient.Connect(USER_ID, (User user, SendBirdException e) =>
{
    if(e != null)
    {
        // Error
        return;
    }

    SendBirdClient.UpdateCurrentUserInfoWithProfileImage(NICKNAME, FILE_PATH, (SendBirdException e1) =>
    {
        if(e1 != null)
        {
            // Error
            return;
        }
    });
});

Channel Types

You should understand the following terminology before proceeding with the rest of this guide.

Open Channel

An Open Channel is a public chat. In this channel type, anyone can enter and participate in the chat without permission. A single channel can handle thousands of simultaneous users. i.e.) a Twitch-style public chat

Group Channel

A Group Channel is a private chat. A user may join the chat only through an invitation by another user who is already a member of the chatroom.

  • Distinct property : A channel with the Distinct property enabled will always be reused for the same members. If a new member is invited, or if a member leaves the channel, then the Distinct property is disabled automatically.

  • 1-on-1 messaging : 1-on-1 messaging is a private channel between two users. You can enable the Distinct property for the channel in order to reuse a channel for the same members. i.e.) Twitter Direct Messages-style 1-on-1 chatting

  • Group messaging : Group messaging is a private channel among multiple users. You can invite up to hundreds of members into a group channel. i.e.) a WhatsApp-style closed group chat

Open vs. Group Channels

Type Open Channel Group Channel
Access Control Public Invitation required
Class Name OpenChannel GroupChannel
Number of Members Over a few thousand Less than a few hundred
How to Create SendBird Dashboard / Platform API / Client SDK Client SDK / Platform API
Operators Supported N/A
User Ban Supported N/A
User Mute Supported N/A
Freeze Channel Supported N/A
Push Notifications N/A Supported
Unread Counts N/A Supported
Read Receipts N/A Supported
Typing Indicators N/A Supported

Open Channel

An Open Channel is a public chat. In this channel type, anyone can enter and participate in the chat without permission. A single channel can handle thousands of simultaneous users. i.e.) a Twitch-style public chat

Creating an Open Channel

You can create an Open Channel from the SendBird Dashboard.

To create a channel, you must specify a Channel URL, which is a unique identifier. Additionally, you can set a Channel Topic, the name of the channel.

An open channel is ideal for use cases that require a small and static number of channels - for example, when you have a central "Lobby Chat" within a game.

create_channel_dashboard

You can also create a channel via the SDK or the SendBird Platform API. You should do so when your channel needs to be created on demand or dynamically.

OpenChannel.CreateChannel(NAME, COVER_URL, DATA, (OpenChannel openChannel, SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }
});

You can also append information by passing additional arguments.

OpenChannel.CreateChannel(NAME, COVER_IMAGE_OR_URL, DATA, CUSTOM_TYPE, (OpenChannel openChannel, SendBirdException e) => {
    if(e != null) {
        / Error.
        return;
    }
});
  • NAME : the name of the 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 : a String field to store structured information, such as a JSON String.
  • CUSTOM_TYPE : a String field that allows you to subclassify your channel.

See the Advanced section for more information on cover images and Custom Types.

Getting 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.

You must be connected to SendBird before requesting an Open Channel List.

OpenChannelListQuery mChannelListQuery = OpenChannel.CreateOpenChannelListQuery();
mChannelListQuery.Next((List<OpenChannel> channels, SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }
});

Getting an Open Channel instance with a 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 before being able to send or receive messages within it.

Store channel URLs to handle 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(channelUrl, (OpenChannel openChannel, SendBirdException e) => {
    if (e != null) {
        // Error!
        return;
    }

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

Entering an Open Channel

A user must enter an Open Channel in order to receive messages.

You can enter up to 10 Open Channels at once. Entered Open Channels are valid only within the current connection. If you disconnect or reconnect to SendBird, you must re-enter channels in order to continue receiving messages.

OpenChannel.GetChannel(CHANNEL_URL, (OpenChannel openChannel, SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }

    openChannel.Enter((SendBirdException e) => {
        if (e != null) {
            // Error.
            return;
        }
    });
});

Exiting an Open Channel

To stop receiving messages from an Open Channel, you must exit the channel.

OpenChannel.GetChannel(CHANNEL_URL, (OpenChannel openChannel, SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }

    openChannel.Exit((SendBirdException e) => {
        if (e != null) {
            // Error.
            return;
        }
    });
});

Sending messages

Upon entering a channel, a user will be able to send messages of the following types:

  • UserMessage : a User text message.
  • FileMessage : a User binary message.

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 (e.g., due to network issues) will return an exception. By implementating the callback within sendUserMessage(), it is possible to display only the messages that are successfully sent.

openChannel.SendUserMessage(MESSAGE, DATA, (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.

By sending a raw file, you are uploading it to the SendBird servers. Alternatively, you can choose to send a file hosted in your own servers by passing in a URL that points to the file. In this case, your file will not be hosted in the SendBird servers, and downloads of the file will occur through your own servers instead.

Note that 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. Your file will not be uploaded to the SendBird servers.

// Sending a File Message with a raw file

openChannel.SendFileMessage(FILE_PATH, FILE_NAME, FILE_TYPE, FILE_SIZE, DATA, CUSTOM_TYPE, (FileMessage fileMessage, SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }
});
// Sending File Message with a file URL

channel.SendFileMessageWithURL(FILE_URL, NAME, TYPE, SIZE, DATA, CUSTOM_TYPE, (FileMessage fileMessage, SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }
});

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

Receiving messages

Messages can be received by adding a ChannelHandler.

A received BaseMessage object can be of one of three different types of messages.

  • UserMessage : a User text message.
  • FileMessage : a User binary message.
  • AdminMessage : an Admin message which can be sent by an admin through the Platform API.

UNIQUE_HANDLER_ID is a unique identifier to register multiple concurrent handlers.

SendBirdClient.ChannelHandler ch = new SendBirdClient.ChannelHandler();
ch.OnMessageReceived = (BaseChannel baseChannel, BaseMessage baseMessage) => {
};
SendBirdClient.AddChannelHandler(UNIQUE_HANDLER_ID, ch);

Loading previous messages

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

PreviousMessageListQuery mPrevMessageListQuery = openChannel.CreatePreviousMessageListQuery();
mPrevMessageListQuery.Load(30, true, (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 will load the most recent n messages. Calling Load() on the same query instance will load n messages before that. Therefore, you should store your query instance as a member variable in order to traverse through your entire message history.

An important note is that you must ensure that you have received a callback before calling Load() again.

Loading messages by timestamp

You can query a set number of previous messages starting from the timestamp of the earliest message.

Note that the number of results may be larger than the set limit when there are multiple messages with the same timestamp as the earliest message.

MessageListQuery mMessageListQuery = openChannel.CreateMessageListQuery();
mMessageListQuery.Prev(EARLIEST_MESSAGE_TIMESTAMP, LIMIT, REVERSE_ORDER, (List<BaseMessage> list, SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }
});

Getting a list of participants in a channel

Participants are online users who are currently receiving all messages from the Open Channel.

UserListQuery mQuery = openChannel.CreateParticipantListQuery();
mQuery.Next((List<User> list, SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }
});

Getting participants' online statuses

To stay updated on each participant's connection status, you must obtain a new UserListQuery, which contains the lastest information on each user. To get a UserListQuery for a specific channel, call OpenChannel.CreateParticipantListQuery(). If you wish to get the list of all users of your service (application), call SendBirdClient.CreateUserListQuery().

You can then check each of the users' connection statuses by retrieving user.ConnectionStatus.

If your application needs to keep track of users' connection statuses in real time, we recommend that you receive a new UserListQuery periodically, perhaps in intervals of one minute or more.

ConnectionStatus can return one of 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.

Getting a list of banned or muted users in a channel

You can also create a query to get a list of muted or banned users in an open channel.

This query is only available for users who are registered as operators of the Open Channel.

UserListQuery mQuery = openChannel.CreateBannedUserListQuery(); //or CreateMutedUserListQuery()
mQuery.Next((List<User> list, SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }
});

Deleting messages

Users are able to delete messages. An error is returned if a user tries to delete messages sent by someone else. Channel Operators are able to delete any message in the channel, including those by other users.

Deleting a message fires a MessageDeleted event to all other users in the channel.

channel.DeleteMessage(BASE_MESSAGE, (SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }
});

You can receive a MessageDeleted event using a ChannelHandler.

SendBirdClient.ChannelHandler ch = new SendBirdClient.ChannelHandler();
ch.OnMessageDeleted = (BaseChannel baseChannel, long messageId) => {
};
SendBirdClient.AddChannelHandler(UNIQUE_HANDLER_ID, ch);

Open Channel - Advanced

Admin messages

You can send Admin messages to users in a channel using the SendBird Dashboard or the Platform API.

To do so using the Dashboard, navigate to the Open Channels tab. Inside the message box, you should see an option to send an Admin message. Admin messages should not be longer than 1000 characters.

If you are currently developing under the Free Plan and therefore cannot access the Moderation Tools from the Dashboard, you must send Admin messages through the Platform API.

Channel cover images

When creating a channel, you can add a cover image by specifying an image URL or file.

OpenChannel.CreateChannel(NAME, COVER_IMAGE_OR_URL, DATA, (OpenChannel openChannel, SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }
});

You can fetch the cover image URL using the CoverUrl property. You can also update a channel's cover image by calling UpdateChannel().

Custom channel types

When creating a channel, you can additionally specify a Custom Type to further subclassify your channels. This custom type takes on the form of a String, and can be handy in searching or filtering channels.

DATA and CUSTOM_TYPE are both String fields that allow you to append information to your channels. The intended use case is for CUSTOM_TYPE to contain information that can subclassify the channel (e.g., distinguishing "School" and "Work" channels). However, both these fields can be flexibly utilized.

OpenChannel.CreateChannel(NAME, COVER_IMAGE_OR_URL, DATA, CUSTOM_TYPE, (OpenChannel openChannel, SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }
});

The CustomType property contains the channel's Custom Type.

Custom message types

Likewise, you can specify a Custom Type for messages in order to categorize them into more specific groups. This custom type takes on the form of a String, and can be useful in searching or filtering messages.

DATA and CUSTOM_TYPE are both String fields that allow you to append information to your messages. The intended use case is for CUSTOM_TYPE to contain information that can subclassify the message (e.g., distinguishing "FILE_IMAGE" and "FILE_AUDIO" type messages). However, both these fields can be flexibly utilized.

To embed a Custom Type into a message, simply pass a String parameter to channel.SendUserMessage() or channel.SendFileMessage().

openChannel.SendUserMessage(MESSAGE, DATA, CUSTOM_TYPE, (UserMessage userMessage, SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }
});

The CustomType property contains the message's Custom Type.

Message auto-translation

This feature is not available under the Free plan. Contact sales@sendbird.com if you wish to implement this functionality.

SendBird makes it possible for messages to be sent in different languages through its auto-translation feature.
Pass in a List of language codes to SendUserMessage() to request translated messages in the corresponding languages.

List<string> targetLangs = new List<string>();
targetLangs.Add("es");
targetLangs.Add("ko");

openChannel.SendUserMessage(MESSAGE, DATA, CUSTOM_TYPE, targetLangs, (UserMessage userMessage, SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }
});

You can obtain translations of a message through the Translations property. This contains a Dictionary containing the language codes and translations.

SendBirdClient.ChannelHandler ch = new SendBirdClient.ChannelHandler();
ch.OnMessageReceived = (BaseChannel baseChannel, BaseMessage baseMessage) => {
    // Received a chat message.
    // ((UserMessage)baseMessage).Translations["es"];
    // ((UserMessage)baseMessage).Translations["ko"];
};
SendBirdClient.AddChannelHandler(UNIQUE_HANDLER_ID, ch);

Reference the table below for supported languages and their language codes.

Language Code English Name Language Code English Name
af Afrikaans tlh-Qaak Klingon (pIqaD)
ar Arabic ko Korean
bs-Latn Bosnian (Latin) lv Latvian
bg Bulgarian lt Lithuanian
ca Catalan ms Malay
zh-CHS Chinese Simplified mt Maltese
zh-CHT Chinese Traditional no Norwegian
hr Croatian fa Persian
cs Czech pl Polish
da Danish pt Portuguese
nl Dutch otq Querétaro Otomi
en English ro Romanian
et Estonian ru Russian
fi Finnish sr-Cyrl Serbian (Cyrillic)
fr French sr-Latn Serbian (Latin)
de German sk Slovak
el Greek sl Slovenian
ht Haitian Creole es Spanish
he Hebrew sv Swedish
hi Hindi th Thai
mww Hmong Daw tr Turkish
hu Hungarian uk Ukrainian
id Indonesian ur Urdu
it Italian vi Vietnamese
ja Japanese cy Welsh
sw Kiswahili yua Yucatec Maya
tlh Klingon - -

You search for specific channels by adding a keyword to your OpenChannelListQuery.
There are two types of keywords: a Name Keyword and a URL Keyword.

Adding a Name Keyword to a query will return the list of Open Channels that have the keyword included in their names.

channelListQuery = OpenChannel.CreateOpenChannelListQuery();
channelListQuery.NameKeyword = "NameKeyword";

channelListQuery.Next((List<OpenChannel> channels, SendBirdException e) => {
    if (e != null) {
        // Error!
        return;
    }
    // Returns a List of channels that have "NameKeyword" in their names.
});

Adding a URL Keyword to a query will return the Open Channel whose URL exactly matches the given keyword.

channelListQuery = OpenChannel.CreateOpenChannelListQuery();
channelListQuery.UrlKeyword = "UrlKeyword";

channelListQuery.Next((List<OpenChannel> channels, SendBirdException e) => {
    if (e != null) {
        // Error!
        return;
    }
    // Returns a List of channels that have "NameKeyword" in their names.
});

Group Channel

A Group Channel is a private chat. A user may join the chat only through an invitation by another user who is already a member of the chatroom. A Group Channel can consist of one to hundreds of members. Creating a channel with two members allows 1-to-1 messaging.

A user will automatically receive all messages from the group channels that they are a member of.

Creating a Group Channel

A Group Channel can be created on demand by a user through the SendBird SDK.

Distinct property : A channel with the Distinct property enabled will always be reused for the same members. If a new member is invited, or if a member leaves the channel, then the distinct property is disabled automatically. For example, in the case that a Group Channel with 3 members, A, B, and C, already exists, attempting to create a new channel with the same members will just return a reference to the existing channel.

Consequently, we recommend that you enable the Distinct property in 1-to-1 messaging channels in order to reuse the same channel when a user chooses to directly message a friend. If the property is disabled, the user will create a new channel even if they have had previous conversations with the friend, and therefore will not be able to see or access previously sent messages or data.

GroupChannel.CreateChannelWithUserIds(userIds, false, (GroupChannel groupChannel, SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }
});

You can also append information by passing additional arguments.

GroupChannel.CreateChannel(USER_IDS, IS_DISTINCT, NAME, COVER_IMAGE_OR_URL, DATA, CUSTOM_TYPE, (GroupChannel groupChannel, SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }
});
  • NAME : the name of the 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 : a String field to store structured information, such as a JSON String.
  • CUSTOM_TYPE : a String field that allows you to subclassify your channel.

See the Advanced section for more information on cover images and Custom Types.

You can also create channels via the SendBird Platform API. You should utilize the Platform API when you wish to control channel creations and member invitations on the server-side.

Getting a Group Channel instance with a URL

Since a channel URL is a unique identifier of a Group Channel, you can use a URL to retrieve a channel instance.

Store channel URLs to handle 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.

GroupChannel.GetChannel(channelUrl, (GroupChannel groupChannel, SendBirdException e) => {
    if (e != null) {
        // Error!
        return;
    }

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

Inviting users to an existing channel

Only members of the channel are able to invite new users into the channel.

You can choose whether the newly invited user is able to access past messages in the channel. In your Dashboard Settings - Messages section, there is an option to show channel history. If this option is enabled, new users will be able to view all messages sent before they have joined the channel. If not, new users will only be able to see messages sent after they had been invited.

Show channel history is enabled by default.

groupChannel.InviteWithUserIds(userIds, (SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }
});

Leaving a Group Channel

Users will no longer receive messages from channels they have left.

groupChannel.Leave((SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }
});

Getting a list of my Group Channels

You can obtain a list of all Open Channels by creating a GroupChannelListQuery.
The Next() method returns a list of GroupChannel objects.

You can also set an option to include empty channels with mQuery.IncludeEmpty = true. Empty channels are channels that have been created but contain no sent messages. By default, empty channels are not shown.

GroupChannelListQuery mQuery = GroupChannel.CreateMyGroupChannelListQuery();
mQuery.IncludeEmpty = true;
mQuery.Next((List<GroupChannel> list, SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }
});

Querying Group Channels by User IDs

It is possible to filter a channel search by user IDs. This can be done by calling SetUserIdsExactFilter(List<string> userIds) or SetUserIdsIncludeFilter(List<string> userIds, QueryType queryType).

Given an example where a user (with the ID "User") is part of two Group Channels:

  • channelA: { "User", John", "Jay" }
  • channelB: { "User", John", "Jay", "Jin" }

An ExactFilter returns the list of channels containing exactly the queried userIDs.

GroupChannelListQuery filteredQuery = GroupChannel.CreateMyGroupChannelListQuery();
List<string> userIds = new List<string>();
userIds.Add("John");
userIds.Add("Jay");

filteredQuery.setUserIdsExactFilter(userIds);
filteredQuery.Next(
...
    // returns channelA only.
)

An IncludeFilter returns channels where the userIDs are included. This method can return one of two different results, based on the paramater queryType.

GroupChannelListQuery filteredQuery = GroupChannel.CreateMyGroupChannelListQuery();
List<String> userIds = new List<string>();
userIds.Add("John");
userIds.Add("Jay");
userIds.Add("Jin");

filteredQuery.SetUserIdsIncludeFilter(userIds, GroupChannelListQuery.QueryType.AND);
filteredQuery.Next(
...
    // returns channels that include the ids { John, Jay, Jin } as a subset.

    // i.e. returns channelB only.
)

filteredQuery.SetUserIdsIncludeFilter(userIds, GroupChannelListQuery.QueryType.OR);
filteredQuery.Next(
...
    // returns channels that include { John }, plus channels that include { Jay }, 
    // plus channels that include { Jin }.

    // i.e. returns both channelA, channelB.
)

Sending messages

Upon entering a channel, a user will be able to send messages of the following types:

  • UserMessage : a User text message.
  • FileMessage : a User binary message.

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 size, font type, or a custom JSON object.

Delivery failures (e.g., due to network issues) will return an exception. By implementing the callback within sendUserMessage()`, it is possible to display only the messages that are successfully sent.

channel.SendUserMessage(MESSAGE, DATA, (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.

By sending a raw file, you are uploading it to the SendBird servers. Alternatively, you can choose to send a file hosted in your own servers by passing in a URL that points to the file. In this case, your file will not be hosted in the SendBird servers, and downloads of the file will occur through your own servers instead.

Note that 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. Your file will not be uploaded to the SendBird servers.

// Sending a File Message with a raw file

channel.SendFileMessage(FILE, FILE_NAME, FILE_TYPE, FILE_SIZE, CUSTOM_DATA, CUSTOM_TYPE, (FileMessage fileMessage, SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }
});
// Sending File Message with a file URL

channel.SendFileMessageWithURL(FILE_URL, FILE_NAME, FILE_TYPE, FILE_SIZE, CUSTOM_DATA, CUSTOM_TYPE, (FileMessage fileMessage, SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }
});

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

Receiving messages

Messages can be received by adding a ChannelHandler.

A received BaseMessage object can be of one of three different types of messages.

  • UserMessage : a User text message.
  • FileMessage : a User binary message.
  • AdminMessage : an Admin message which can be sent by an admin through the Platform API.

UNIQUE_HANDLER_ID is a unique identifier to register multiple concurrent handlers.

SendBirdClient.ChannelHandler ch = new SendBirdClient.ChannelHandler();
ch.OnMessageReceived = (BaseChannel baseChannel, BaseMessage baseMessage) => {
    // Received a chat message.
};
SendBirdClient.AddChannelHandler(UNIQUE_HANDLER_ID, ch);

You should remove the channel handler when the UI is no longer valid.

SendBirdClient.RemoveChannelHandler(UNIQUE_HANDLER_ID);

Loading previous messages

You can load previous messages by creating a PreviousMessageListQuery instance and calling Load(). You will be able to display these messages in your UI once they have loaded.

Whether a user can load messages prior to joining the channel depends on your settings. In your Dashboard Settings - Messages section, there is an option to show channel history. If this option is enabled, new users will be able to view all messages sent before they have joined the channel. If not, new users will only be able to see messages sent after they had been invited.

PreviousMessageListQuery mPrevMessageListQuery = groupChannel.CreatePreviousMessageListQuery();
mPrevMessageListQuery.Load(30, true, (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 will load the most recent n messages. Calling Load() on the same query instance will load n messages before that. Therefore, you should store your query instance as a member variable in order to traverse through your entire message history.

An important note is that you must ensure that you have received a callback before calling Load() again.

Deleting messages

Users are able to delete messages. An error is returned if a user tries to delete messages sent by someone else. Channel Operators are able to delete any message in the channel, including those by other users.

Deleting a message fires a MessageDeleted event to all other users in the channel.

channel.DeleteMessage(BASE_MESSAGE, (SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }
});

You can receive a MessageDeleted event using a Channel Handler.

SendBirdClient.ChannelHandler ch = new SendBirdClient.ChannelHandler();
ch.OnMessageDeleted = (BaseChannel baseChannel, long messageId) => {
};
SendBirdClient.AddChannelHandler(UNIQUE_HANDLER_ID, ch);

Group Channel - Advanced

Getting a list of all channel members

You can obtain a list of members in a Group Channel by retrieving channel.Members.

List<User> members = groupChannel.Members;

Members are automatically updated when you are online. If you disconnect from SendBird and reconnect, you should Refresh() the channel to be updated with the latest information.

groupChannel.Refresh((SendBirdException e) => {
    if (e != null) {
        //Error.
        return;
    }
});

Getting members' online statuses

To stay updated on each member's connection status, call channel.Refresh() before accessing channel.Members.
You can then check each of the users' connection statuses by accessing user.ConnectionStatus.

If your application needs to keep track of users' connection statuses in real time, we recommend that you Refresh() your channel instance periodically, perhaps in intervals of one minute or more.

ConnectionStatus can return one of three values:

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

Typing indicators

You can send typing events by invoking StartTyping() and EndTyping().

groupChannel.StartTyping();
groupChannel.EndTyping();

You can receive a TypingStatusUpdate event from a Channel Handler.

SendBirdClient.ChannelHandler ch = new SendBirdClient.ChannelHandler();
ch.OnTypingStatusUpdated = (GroupChannel groupChannel) => {
    if (currentGroupChannel.Url.Equals(groupChannel.Url)) {
        List<User> members = groupChannel.TypingMembers;
        // Refresh typing status.
    }
};
SendBirdClient.AddChannelHandler(UNIQUE_HANDLER_ID, ch);

Read Receipts

A user can indicate that they have read messages in a channel by calling MarkAsRead().

groupChannel.MarkAsRead();

You can receive a ReadReceiptUpdate event from a Channel Handler.

SendBirdClient.ChannelHandler ch = new SendBirdClient.ChannelHandler();
ch.OnReadReceiptUpdated = (GroupChannel groupChannel) => {
    if (currentGroupChannel.Url.Equals(groupChannel.Url)) {
        foreach (BaseMessage msg in yourMessages) {
            int unreadCount = groupChannel.GetReadReceipt(msg);
            if (unreadCount <= 0) {
                // All members have read.
            } else {
                // Some members haven't read.
            }
        }
    }
};
SendBirdClient.AddChannelHandler(UNIQUE_HANDLER_ID, ch);

GetReadReceipt(message) returns the number of members in the channel who have not read the message.

int unreadCount = groupChannel.GetReadReceipt(message);

Admin messages

You can send Admin messages to users in a channel using the SendBird Dashboard or the Platform API.

To do so using the Dashboard, navigate to the Open Channels tab. Inside the message box, you should see an option to send an Admin message. Admin messages should not be longer than 1000 characters.

If you are currently developing under the Free Plan and therefore cannot access the Moderation Tools from the Dashboard, you must send Admin messages through the Platform API.

Channel cover images

When creating a channel, you can add a cover image by specifying an image URL or file.

GroupChannel.CreateChannel(NAME, COVER_IMAGE_OR_URL, DATA, (OpenChannel openChannel, SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }
});

You can fetch the cover image URL using the CoverUrl property. You can also update a channel's cover image by calling UpdateChannel().

Custom channel types

When creating a channel, you can additionally specify a Custom Type to further subclassify your channels. This custom type takes on the form of a String, and can be handy in searching or filtering channels.

DATA and CUSTOM_TYPE are both String fields that allow you to append information to your channels. The intended use case is for CUSTOM_TYPE to contain information that can subclassify the channel (e.g., distinguishing "School" and "Work" channels). However, both these fields can be flexibly utilized.

GroupChannel.CreateChannel(NAME, COVER_IMAGE_OR_URL, DATA, CUSTOM_TYPE, (OpenChannel openChannel, SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }
});

The CustomType property contains the channel's Custom Type.

Custom message types

Likewise, you can specify a Custom Type for messages in order to categorize them into more specific groups. This custom type takes on the form of a String, and can be useful in searching or filtering messages.

DATA and CUSTOM_TYPE are both String fields that allow you to append information to your messages. The intended use case is for CUSTOM_TYPE to contain information that can subclassify the message (e.g., distinguishing "FILE_IMAGE" and "FILE_AUDIO" type messages). However, both these fields can be flexibly utilized.

To embed a Custom Type into a message, simply pass a String parameter to channel.SendUserMessage() or channel.SendFileMessage().

groupChannel.SendUserMessage(MESSAGE, DATA, CUSTOM_TYPE, (UserMessage userMessage, SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }
});

The CustomType property contains the message's Custom Type.

Message auto-translation

This feature is not available under the Free plan. Contact sales@sendbird.com if you wish to implement this functionality.

SendBird makes it possible for messages to be sent in different languages through its auto-translation feature.
Pass in a List of language codes to SendUserMessage() to request translated messages in the corresponding languages.

List<string> targetLangs = new List<string>();
targetLangs.Add("es");
targetLangs.Add("ko");

openChannel.SendUserMessage(MESSAGE, DATA, CUSTOM_TYPE, targetLangs, (UserMessage userMessage, SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }
});

You can obtain translations of a message through the Translations property. This contains a Dictionary containing the language codes and translations.

SendBirdClient.ChannelHandler ch = new SendBirdClient.ChannelHandler();
ch.OnMessageReceived = (BaseChannel baseChannel, BaseMessage baseMessage) => {
    // Received a chat message.
    // ((UserMessage)baseMessage).Translations["es"];
    // ((UserMessage)baseMessage).Translations["ko"];
};
SendBirdClient.AddChannelHandler(UNIQUE_HANDLER_ID, ch);

Reference the table below for supported languages and their language codes.

Language Code English Name Language Code English Name
af Afrikaans tlh-Qaak Klingon (pIqaD)
ar Arabic ko Korean
bs-Latn Bosnian (Latin) lv Latvian
bg Bulgarian lt Lithuanian
ca Catalan ms Malay
zh-CHS Chinese Simplified mt Maltese
zh-CHT Chinese Traditional no Norwegian
hr Croatian fa Persian
cs Czech pl Polish
da Danish pt Portuguese
nl Dutch otq Querétaro Otomi
en English ro Romanian
et Estonian ru Russian
fi Finnish sr-Cyrl Serbian (Cyrillic)
fr French sr-Latn Serbian (Latin)
de German sk Slovak
el Greek sl Slovenian
ht Haitian Creole es Spanish
he Hebrew sv Swedish
hi Hindi th Thai
mww Hmong Daw tr Turkish
hu Hungarian uk Ukrainian
id Indonesian ur Urdu
it Italian vi Vietnamese
ja Japanese cy Welsh
sw Kiswahili yua Yucatec Maya
tlh Klingon - -

Channel Metadata

With MetaData and MetaCounter, you can store additional information within a channel.

MetaData allows you to store a Dictionary of String key-value pairs in a channel instance.
If your aim is to store an integer with atomic increasing/decreasing operations, you should use a MetaCounter instead.

Use cases for MetaData/Counters could include tracking the number of likes, the background color, or a long description of the channel, which can each be fetched and rendered into the UI.

MetaData

MetaData is a Dictionary that is stored within a channel. Its uses are very flexible, allowing you to customize a channel to fit you and your users' needs.

Create

Storing MetaData into a channel simply requires creation of a Dictionary, then passing it as an argument when calling CreateMetaData(). You can store multiple key-value pairs in the map.

Dictionary<string, string> data = new Dictionary<string, string>();
data.Add("key1", "value1");
data.Add("key2", "value2");
channel.CreateMetaData(data, (Dictionary<string, string> map, SendBirdException e) =>
{
    if (e != null) {
        // Error.
        return;
    }
});

Update

The process for updating MetaData is identical to creation. Values will be updated for existing keys, while new key-value pairs will be added.

Dictionary<string, string> data = new Dictionary<string, string>();
data.Add("key1", "valueToUpdate");
data.Add("key2", "valueToUpdate");
channel.UpdateMetaData(data, (Dictionary<string, string> map, SendBirdException e) =>
{
    if (e != null) {
        // Error.
        return;
    }
});

Get

Getting stored MetaData requires creating a List of keys to pass as an argument to GetMetaData(). The callback will return a Dictionary<String, String> containing the corresponding key-value pairs.

List<string> keys = new List<string>();
keys.Add("key1");
keys.Add("key2");
channel.GetMetaData(keys, (Dictionary<string, string> map, SendBirdException e) =>
{
    if (e != null) {
        // Error.
        return;
    }
});

MetaCounter

A MetaCounter is a Dictionary that is stored within a channel instance. Its primary uses are to track and update discrete indicators within a channel.

Create

Storing a MetaCounter into a channel simply requires creation of a Dictionary, then passing it as an argument when calling CreateMetaCounter(). You can store multiple key-value pairs in the map.

Dictionary<string, int> counters = new Dictionary<string, int>();
counters.Add("key1", 1);
counters.Add("key2", 2);
channel.CreateMetaCounters(counters, (Dictionary<string, int> map, SendBirdException e) =>
{
    if (e != null) {
        // Error.
        return;
    }
});

Get

Retrieving stored MetaCounters requires creating a List of keys to pass as an argument to GetMetaCounters(). The callback will return a Dictionary<String, Integer> containing the corresponding key-value pairs.

List<string> keys = new List<string>();
keys.add("key1");
keys.add("key2");
channel.GetMetaCounters(keys, (Dictionary<string, int> map, SendBirdException e) =>
{
    if (e != null) {
        // Error.
        return;
    }
});

Increase

The increase and decrease operations work similarly to getting MetaCounters, as described above. Create a List of keys to pass to IncreaseMetaCounters(), which increments the corresponding MetaCounters by 1.

Dictionary<string, int> counters = new Dictionary<string, int>();
counters.Add("key1", 2); // Increases by 2.
counters.Add("key2", 3); // Increases by 3.
channel.IncreaseMetaCounters(counters, (Dictionary<string, int> map, SendBirdException e) =>
{
    if (e != null) {
        // Error.
        return;
    }
});

Decrease

Likewise, pass a List of keys to DecreaseMetaCounters(), which decrements the MetaCounters by 1.

Dictionary<string, int> counters = new Dictionary<string, int>();
counters.Add("key1", 3); // Decreases by 3.
counters.Add("key2", 4); // Decreases by 4.
channel.DecreaseMetaCounters(counters, (Dictionary<string, int> map, SendBirdException e) =>
{
    if (e != null) {
        // Error.
        return;
    }
});

Event Handler

Event Handlers are crucial components of the SendBird SDK that allow a client to react to server-side events. These handlers contain callback methods that can be overridden to respond to specific chat-related events passed from the server. For example, ChannelHandler.onMessageReceived(BaseChannel, BaseMessage) is triggered whenever a message is received. The specifics of each received message is contained within the BaseChannel and BaseMessage arguments passed in the triggering callback.

By providing its own Event Handlers, the SendBird SDK allows a client to respond to asynchronous events without worrying about the plethora of issues surrounding client-server communication and multithreading. A chat application especially involves rapid exchanges of data that must take place in near real-time across potentially thousands of users. Therefore, the SDK optimizes communication and threading to ensure data integrity between users and servers. Add Event Handlers and implement the necessary callback methods to track events occuring within channels or a user's own device.

Channel Handler

Register a ChannelHandler to receive information whenever events occur within a channel.

You can register multiple Channel Handlers. UNIQUE_HANDLER_ID is a unique identifier that should be given to each handler. Typically, Event Handlers would be registered in each activity in order to stay up to date with changes in the channel, as well as notify the channel of the user's own activity.


SendBirdClient.ChannelHandler ch = new SendBirdClient.ChannelHandler();

ch.OnMessageReceived = (BaseChannel baseChannel, BaseMessage baseMessage) => {
    // Received a chat message.
};

ch.OnMessageDeleted = (BaseChannel baseChannel, long messageId) => {
  // When a message has been deleted.
};

ch.OnChannelChanged = (BaseChannel baseChannel) => {
  // When a channel property has been changed.
};

ch.OnChannelDeleted = (string channelUrl, BaseChannel.ChannelType channelType) => {
  // When a channel has been deleted.
};

ch.OnReadReceiptUpdated = (GroupChannel groupChannel) => {
    // When read receipt has been updated.
};

ch.OnTypingStatusUpdated = (GroupChannel groupChannel) => {
    // When typing status has been updated.
};

ch.OnUserJoined = (GroupChannel groupChannel, User user) => {
  // When a new member joined the group channel.
};

ch.OnUserLeft(GroupChannel groupChannel, User user) => {
  // When a member left the group channel.
};

ch.OnUserEntered = (OpenChannel openChannel, User user) => {
  // When a new user entered the open channel.
};

ch.OnUserExited = (OpenChannel openChannel, User user) => {
  // When a new user left the open channel.
};

ch.OnUserMuted = (OpenChannel openChannel, User user) => {
  // When a user is muted on the open channel.
};

ch.OnUserUnmuted = (OpenChannel openChannel, User user) => {
  // When a user is unmuted on the open channel.
};

ch.OnUserBanned = (OpenChannel openChannel, User user) => {
  // When a user is banned on the open channel.
};

ch.OnUserUnbanned = (OpenChannel openChannel, User user) => {
  // When a user is unbanned on the open channel.
};

ch.OnChannelFrozen(OpenChannel openChannel) => {
  // When the open channel is frozen.
};

ch.OnChannelUnfrozen(OpenChannel openChannel) => {
  // When the open channel is unfrozen.
};


SendBirdClient.AddChannelHandler(UNIQUE_HANDLER_ID, ch);

OnChannelChanged() is called whenever a one of the following channel properties have been changed :

  • Push preference
  • Last message (except in cases where the message is a silent Admin message)
  • Unread message count
  • Name, cover image, data, Custom Type
  • Operators (only applicable to Open Channels)
  • Distinct property (only applicable to Group Channels)

You should remove the ChannelHandler where the activity is no longer valid.

SendBirdClient.RemoveChannelHandler(UNIQUE_HANDLER_ID);

Connection Handler

Register a ConnectionHandler to detect changes in the user's own connection status.

You can register multiple Connection Handlers. UNIQUE_HANDLER_ID is a unique identifier that should be given to each handler. Typically, Connection Handlers would be registered in each activity in order to monitor the state of the user's connection with the SendBird servers.

SendBirdClient.ConnectionHandler ch = new SendBirdClient.ConnectionHandler ();

ch.OnReconnectFailed = () => {
    // Auto reconnecting failed. You should call `connect` to reconnect to SendBird.
};

ch.OnReconnectStarted = () => {
    // Network has been disconnected. Auto reconnecting starts.
};

ch.OnReconnectSucceeded = () => {
    // Auto reconnecting succeeded.
};

SendBirdClient.AddConnectionHandler(UNIQUE_HANDLER_ID, ch);

You should remove the Connection Handler when the activity is no longer valid.

SendBirdClient.RemoveConnectionHandler(UNIQUE_HANDLER_ID);

Push Notifications

You can set up Push Notifications so that users can receive messages even when they are offline.

To set a user's connection status to offline, call SendBirdClient.Disconnect(). It is recommended that you call Disconnect() just before your app goes into the background.

Push notifications are only supported in Group Channels. The SDK does not provide an option for users to receive push notifications from Open Channels.

Android

Please visit our Android Push Notification page for more details.

iOS

Please visit our iOS Push Notification page for more details.

Registering or unregistering a push token

SendBirdClient.RegisterFCMPushTokenForCurrentUser(token, (SendBirdClient.PushTokenRegistrationStatus status, SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }

    if (status == SendBirdClient.PushTokenRegistrationStatus.PENDING) {
        // Try registration after connection is established.
    }
});

You should call SendBirdClient.Connect() in order to complete the token registration process, which is currently in a pending state.

SendBirdClient.Connect(userId, (User user, SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }

    if (SendBirdClient.GetPendingPushToken() == null) return;

    SendBirdClient.RegisterFCMPushTokenForCurrentUser(SendBirdClient.GetPendingPushToken(), (SendBirdClient.PushTokenRegistrationStatus status, SendBirdException e1) => {
        if (e1 != null) {
            // Error.
            return;
        }
    });
});

Offline users will now receive Push notifications which each contain information about the message. Parse these in order to display the messages for a user.

SendBird also sends an additional payload with a sendbird key.

Android

The message property is a basic string. e.g.) "Sender: Message".
The payload property is a JSON string with full information on the request.

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    String message = remoteMessage.getData().get("message");
    JsonElement payload = new JsonParser().parse(remoteMessage.getData().get("sendbird"));
    sendNotification(message, payload);
}

private void sendNotification(String message, JsonElement payload) {  
  // Your own way to show notifications to users.
}

iOS

SendBird APNS Push notifications are sent with the following options.

  • alert : "{Sender Nickname}: {Text Message}"
  • sound : default
  • badge : total unread message count of each user
  • (You can disable "badge" count in SendBird Dashboard if you want)

You could parse the payload in "didReceiveRemoteNotification" and use it to handle user reactions.

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler{

    NSString *alertMsg = [[userInfo objectForKey:@"aps"] objectForKey:@"alert"];
    NSDictionary *payload = [userInfo objectForKey:@"sendbird"];
      // Your custom way to parse data
    completionHandler(UIBackgroundFetchResultNewData);
}

Payload

Here is a format of each payload.

{
  "category": "messaging:offline_notification",
  "message": string,           // User input message
  "data": string,              // User custom data
  "mentioned": [string, ],     // Mentioned User IDs
  "unread_message_count": int, // Total unread message count of messaging channels
  "channel": {
    "channel_url": string,     // Group Channel URL
    "name": string,            // Group Channel name 
  },
  "channel_type": string,      // messaging, group_messaging, chat
  "sender": {
    "id": string,              // Sender's unique ID
    "name": string,            // Sender's nickname
  },
  "recipient": {
    "id": string,              // Recipient's unique ID
    "name": string,            // Recipient's nickname
  },
  files: []  // If a message is a file link, this array represents files
}

Notification Preference

If you have a setting for the push notification in your app, it can be turned on or off.

public void SetPushNotification(bool enable) {
    if (enable)
    {
        SendBirdClient.RegisterFCMPushTokenForCurrentUser(fcmRegToken, (SendBirdClient.PushTokenRegistrationStatus status, SendBirdException e) => {
            if (e != null) {
                // Error.
                return;
            }
        });
    }
    else 
    {
        // If you want to unregister the current device only, invoke this method.
        SendBirdClient.UnregisterFCMPushTokenForCurrentUser(fcmRegToken, (SendBirdException e) => {
            if (e != null) {
                // Error.
                return;
            }
        });

        // If you want to unregister the all devices of the user, invoke this method.
        SendBirdClient.UnregisterPushTokenAllForCurrentUser((SendBirdException e) => {
            if (e != null) {
                // Error.
                return;
            }
        });
    }
}

You can also set push notification on/off setting for a specific group channel.

// If you want to turn push notification for this channel on, set this true.
groupChannel.SetPushPreference(TRUE_OR_FALSE, (SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }
});

If you want to snooze alarms (notifications) for some periods, SetDoNotDisturb is here for you.

// The current logged-in user doesn't receive push notifications during the specified time.
SendBirdClient.SetDoNotDisturb(TRUE_OR_FALSE, START_HOUR, START_MIN, END_HOUR, END_MIN, "America/Los_Angeles", (SendBirdException e) => {
    if (e != null) {
        // Error.
        return;
    }
});

Miscellaneous

Client SDK generated Error Codes

Errors on SendBird are defined as below.

Error Value Description
ERR_INVALID_INITIALIZATION 800100 Initialization failed
ERR_INVALID_PARAMETER 800110 Invalid parameters
ERR_NETWORK 800120 Routing error
ERR_NETWORK_ROUTING_ERROR 800121 Routing error
ERR_MALFORMED_DATA 800130 Malformed data
ERR_MALFORMED_ERROR_DATA 800140 Malformed error data
ERR_WRONG_CHANNEL_TYPE 800150 Wrong channel type
ERR_MARK_AS_READ_RATE_LIMIT_EXCEEDED 800160 Mark as read rate limit exceeded
ERR_QUERY_IN_PROGRESS 800170 Query is in progress
ERR_ACK_TIMEOUT 800180 Command ack timed out
ERR_LOGIN_TIMEOUT 800190 Login timed out
ERR_WEBSOCKET_CONNECTION_CLOSED 800200 Connection closed
ERR_WEBSOCKET_CONNECTION_FAILED 800210 Connection failed
ERR_REQUEST_FAILED 800220 Request failed

Server-generated Error Codes

These errors are not defined in the header file.

Code Description
400100 Parameter Error - String value is required
400101 Parameter Error - Number value is required
400102 Parameter Error - List value is required
400103 Parameter Error - Json value is required
400104 Parameter Error - Boolean value is required
400105 Parameter Error - Not all the required fields are arrived
400106 Parameter Error - Value must be a positive number
400107 Parameter Error - Value must be a negative number
400108 User doesn't have an access to channels or messages
400110 Parameter Error - Length of value is not valid
400111 Parameter Error - Unknown
400112 Parameter Error - Should provide two different values
400151 Parameter Error - Not allowed characters
400201 Object(Channel/User/Message) not found
400202 Unique constraint violation
400300 User Authentication Error - Deactivated user
400301 User Authentication Error - Deleted user or user not found
400302 User Authentication Error - Invalid access token
400303 User Authentication Error - Unexpected error
400304 User Authentication Error - Application not found
400305 User Authentication Error - User id is too long
400306 User Authentication Error - Plan quota exceeded
400307 User Authentication Error - Requests from authorized domain
400601 The push token registration failure
400602 The push token removal failure
400910 Requests are rate-limited
400920 Tried to access non-allowed features under your plan
500901 Unexpected errors
900010 Try to send messages without login
900020 Try to send messages to group channels not belong to the user
900021 Try to send messages after getting deactivated
900030 Try to send messages to the channels when the guest policy is read-only on dashboard
900041 The user is muted on this channel
900050 User cannot send messages to frozen channels
900060 Message is blocked by profanity filter
900070 Try to send messages to deleted channels
900080 You cannot send messages on 1-on-1 group channel when receiver is blocked
900081 You cannot send messages on 1-on-1 group channel when receiver is deactivated
900100 Try to enter the banned channel
900200 You are blocked because you sent too many messages in short period

Change Log

v3.0.6 (Apr, 17, 2017)

  • Fixed message deletion issue on Unity 3d.

v3.0.5 (Jan, 20, 2017)

  • Speed up initial loading on some platforms.

v3.0.4 (Jan, 17, 2017)

  • Improved stability.
  • Fixed read receipt reset issue.

v3.0.3 (Dec 14, 2016)

  • Improved stability.

v3.0.2 (Dec 9, 2016)

  • Improved performance.
  • Improved stability.
  • Added user IDs filters and query type to GroupChannelListQuery.
  • Added channel custom type for OpenChannel and GroupChannel.
  • Fixed to call ChannelHandler.onChannelChanged when unread message count or last message has been updated.
  • Fixed to update last message of group channel when UserMessage or FileMessage is successfully sent.
  • Added custom type to messages.
  • Added group channel list search by member nicknames and user IDs.
  • Added creating and updating channel cover image with binary file.

v3.0.1 (Nov 21, 2016)

  • Faster connection time.
  • Improved stability.

v3.0.0 (Nov 4, 2016)

  • First release.