Quick Start

1. Creating a SendBird Application

The first thing you need to do is to sign up in SendBird Dashboard and create a SendBird application.
You should use one application per one service across various platforms.
Users in different applications can't talk to each other.

2-1. Running Web Sample

You will need a local server to run the sample project. In this example, we'll be using Python to run our local server.

  1. Download and install Python if you don't have it.
  2. Clone the project
    $ git clone https://github.com/smilefam/SendBird-JavaScript
    
  3. Open terminal and run Python HTTP Server in project path.
    $ cd basic-sample
    # If you use Python 2
    $ python -m SimpleHTTPServer 8000
    # or Python 3
    $ python -m http.server 8000
    
  4. Try to connect to http://localhost:8000 in a web browser to see the sample project.

2-2. Integrating SendBird with an existing app

Download the Latest SendBird JavaScript SDK

Using Bower

$ bower install sendbird

Using Npm

$ npm install sendbird

Add the SDK File to Your Project

After downloading the SendBird JavaScript SDK JavaScript file, add it to your Project classpath (generally the libs directory).

Then include the JavaScript file on your page:

<script src="lib/SendBird.min.js"></script>

Browser Support

  • MS IE 10+ (IE8/9 support should be available soon.)
  • MS Edge 13+
  • Chrome 16+
  • Firefox 11+
  • Safari 7+
  • Opera 12.1+
  • iOS 7+ Safari
  • Android 4.4+ (Kitkat) Browser

3. Running 3.0 JS SDK in React Native

Now we suppport both iOS and Android on React Native!

  1. Download and install node and npm.
  2. Clone the project
    $ git clone https://github.com/smilefam/SendBird-JavaScript
    
  3. Open terminal and run the following commands in the project path.
    $ cd basic-react-native-sample/SendBirdReactNativeSample
    $ npm install
    $ npm install -g react-native-cli
    
  4. Run the sample app in iOS Simulator
    $ react-native run-ios
    

Authentication

Initializing with APP_ID

Please initialize SendBird using the APP_ID assigned for your SendBird application before trying to login SendBird.

var sb = new SendBird({

    appId: APP_ID

});


Connecting with UserID

SendBird requires only UserId to login in Client SDK by default.
It creates a user account on demand if UserId has not been taken yet.
UserId could be any unique string id such as email, uid in your database.

This simple authentication is useful when you are in development or your service doesn't need additional security.

sb.connect(USER_ID, function(user, error) {});

Connecting with UserID and Access Token

With SendBird Platform API, you can create a user with an access token or issue an access token for an existing user. Once the access token is issued for the user, you should provide the correct access token in login method.

  1. Create a SendBird user account via Platform API when your user signs up your service.
  2. Save the access token to your secured persistent store.
  3. Load the access token in your client and pass it to SendBird login method.
  4. Issue a new access token via Platform API and update it in your persistent store periodically.

You can change Non Access Token User Policy on your dashboard settings.

sb.connect(USER_ID, ACCESS_TOKEN, function(user, error) {});

Updating User Profile

You can update users information after connected to SendBird.

sb.updateCurrentUserInfo(NICKNAME, PROFILE_URL, function(response, error) {
  console.log(response, error);
});

Updating User Profile with Profile Image Upload

You can update users information and uploading profile image to SendBird.

sb.updateCurrentUserInfoWithProfileImage(NICKNAME, PROFILE_FILE, function(response, error) {
  console.log(response, error);
});

Channel Type

There are some terms you should understand before starting this tutorial.

Open Channel

Open channel is a public chat. This is a channel type which anyone can participate without a permission. It can handle thousands of users in one channel. ex) Twitch-style public chat

Group Channel

Group channel is a private chat. The user who wants to join the group channel has to be invited by other user who is already joined the group channel.

  • Distinct Property : Distinct property enabled group channel is always reused for same channel members. If a new member gets invited or the member left from the channel, then the distinct property disabled automatically.
    If you don't set distinct property on the channel, it always create new channel for the same members.

  • 1-on-1 messaging : 1-on-1 messaging is a private channel between two users. You can enable distinct property for the channel to get always same channel for the same users. ex) Twitter-style Direct Message

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

Type Open Channel Group Channel
Access Control Public Invitation required
Class Name OpenChannel GroupChannel
Number of Members Over a few thousands Less than a few hundreds
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

Open channel is a public chat. This is a channel type which anyone can participate without a permission. It can handle thousands of users in one channel. ex) Twitch-style public chat

Creating an Open Channel

You can create an Open Channel in SendBird Dashboard.
You should set "Channel Topic", a name of the channel and "Channel URL", a unique identifier of the channel. This is useful when you have a small and static number of channels such as "Lobby Chat" in games.

create_channel_dashboard

You can also create your channels via SendBird Platform API.
You should use it when your channels need to be created on demand or dynamically.


sb.OpenChannel.createChannel(NAME, COVER_URL, DATA, function (channel, error) {
    if (error) {
        console.error(error);
        return;
    }
    console.log(channel);
});

Getting a list of Open Channels

You can get a list of Open Channels with OpenChannel class.
It returns a list of OpenChannel objects.

  • You must be connected to SendBird before requesting Open channel list.
var openChannelListQuery = sb.OpenChannel.createOpenChannelListQuery();

openChannelListQuery.next(function (response, error) {
    if (error) {
        console.log(error);
        return;
    }

    console.log(response);
});

Entering an Open Channel

You must enter open channels to receive messages from the channels.

You can enter open channels up to 10 channels at once.

Entered open channels are valid only within current connection. You must re-enter the channels if you disconnect and connect to SendBird.

sb.OpenChannel.getChannel(CHANNEL_URL, function (channel, error) {
    if (error) {
        console.error(error);
        return;
    }

    channel.enter(function(response, error){
        if (error) {
            console.error(error);
            return;
        }
    });
});

Exiting from an Open Channel

To stop getting messages from open channels, you should exit from the channels.

sb.OpenChannel.getChannel(CHANNEL_URL, function (channel, error) {
    if (error) {
        console.error(error);
        return;
    }

    channel.exit(function(response, error){
        if (error) {
            console.error(error);
            return;
        }
    });
});

Loading Previous Messages

Before entering to the channel, getting previous messages in the channel is typically needed to render previous messages in chat UI.

var messageListQuery = channel.createPreviousMessageListQuery();

messageListQuery.load(20, true, function(messageList, error){
    if (error) {
        console.error(error);
        return;
    }
    console.log(messageList);
});

Sending Messages

After entering to a channel, a user can send various types of messages.
When you send text messages, you can also attach arbitrary strings via data field.
You can utilize this field to send some structured data such as a font size, a font type, or custom object json.

When some deliveries fail due to network issues, it will returns an exception for the message. In UI, you could display only messages appeared as 'sent' only if sending message is succeeded.

channel.sendUserMessage(MESSAGE, DATA, function(message, error){
    if (error) {
        console.error(error);
        return;
    }
    console.log(message);
});

A user can also send any binary files to SendBird.

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.

To send meta data with a file, you can use custom data.

channel.sendFileMessage(FILE, FILE_NAME, FILE_TYPE, FILE_SIZE, CUSTOM_DATA, function(message, error){
    if (error) {
        console.error(error);
        return;
    }
    console.log(message);
});

Receiving Messages

After entering to a channel, all messages can be received by adding ChannelHandler.
You can cast a BaseMessage object among three types of messages.

  • UserMessage: User text message.
  • FileMessage: User binary message.
  • AdminMessage: Admin message which could be sent via Platform API by admin.

UNIQUE_HANDLER_ID is an identifier for multiple channel handlers registration.

var ChannelHandler = new sb.ChannelHandler();

ChannelHandler.onMessageReceived = function(channel, message){
    console.log(channel, message);
};

sb.addChannelHandler(UNIQUE_HANDLER_ID, ChannelHandler);

Loading Messages by Timestamp

When a user scrolls up a screen to see previous messages, you can query previous messages starting from the timestamp of the earliest message.

Note that the number of messages could be larger than the limit you set when there are messages having same timestamps on edge.

var messageListQuery = channel.createMessageListQuery();

messageListQuery.prev(EARLIEST_MESSAGE_TIMESTAMP, LIMIT, REVERSE_ORDER, function(messageList, error){
    if (error) {
        console.error(error);
        return;
    }
    console.log(messageList);
});

Getting a list of Participants in a Channel

Participants are online users who are currently receiving all messages from the open channel.


var participantListQuery = channel.createParticipantListQuery();

participantListQuery.next(function (participantList, error) {
    if (error) {
        console.error(error);
        return;
    }
    console.log(participantList);
});

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 registerd as operators of the open channel.


var UserListQuery = testData.openChannel.createBannedUserListQuery();  //or createMutedUserListQuery()

UserListQuery.next(function (userList, error) {
    if (error) {
        console.error(error);
        return;
    }

    console.log(userList);
});

Deleting Messages

User can delete a message. It gives an error if the user try to delete messages which are sent by others.
Channel operators can delete any messages on the channel.
It also fires a message deleted events to other users on the channel.

channel.deleteMessage(testData.fileMessage, function(response, error){
    if (error) {
        console.error(error);
        return;
    }
});

You can receive a MessageDeleted event in the channel handler.

var ChannelHandler = new sb.ChannelHandler();

ChannelHandler.onMessageDeleted = function (channel, messageId) {
    console.log('ChannelHandler.onMessageDeleted: ', channel, messageId);
};

sb.addChannelHandler(UNIQUE_HANDLER_ID, ChannelHandler);

Group Channel

Group channel is a private chat. The user who wants to join the group channel has to be invited by another user who is already joined the channel.

  • User will automatically receive all messages from the group channels where the user belongs.

Creating Group Channels

Group channel is created in client SDK on demand.

Distinct Property : Distinct property enabled group channel is always reused for same channel members. If a new member gets invited or the member left from the channel, then the distinct property disabled automatically.
If you don't set distinct property on the channel, it always create new channel for the same members.

var userIds = ['unique_user_id1', 'unique_user_id2'];
// distinct is false 
sb.GroupChannel.createChannelWithUserIds(userIds, false, name, cover_url, data, function(channel, error) {
    if (error) {
        console.error(error);
        return;
    }

    console.log(channel);
});

You can also create your channels via SendBird Platform API.
You should use it when you want to control channel creations and member invitations in server side.

Inviting Users to an existing Channel

Only members on the channel will be able to invite other users to the channel.

groupChannel.inviteWithUserIds(userIds, function(response, error) {
    if (error) {
        console.error(error);
        return;
    }
});

Leaving a Group Channel

After leaving from a channel, you are no longer a member of the channel so you won't receive any messages from the channel.

groupChannel.leave(function(response, error) {
    if (error) {
        console.error(error);
        return;
    }
});

Getting a list of My Group Channels

You can get a list of Group Channels with GroupChannel.createMyGroupChannelListQuery.
It returns a list of GroupChannel objects. You can also set an option to include empty channels.

var channelListQuery = sb.GroupChannel.createMyGroupChannelListQuery();
channelListQuery.includeEmpty = true;
channelListQuery.limit = 20; // pagination limit could be set up to 100

if (channelListQuery.hasNext) {
    channelListQuery.next(function(channelList, error){
        if (error) {
            console.error(error);
            return;
        }

        console.log(channelList);
    });
}

Sending Messages

After joining to a channel, a user can send various types of messages.
When you send text messages, you can also attach arbitrary strings via data field.
You can utilize this field to send some structured data such as a font size, a font type, or custom object json.
In addtion to data field, also you can set your own custom type of messages by using customType field.
This field could be used to express certain groups of messages you want to see in the statistics page of SendBird Dashboard.
(The statistics page will support breakdowns based on customType shortly)

When some deliveries fail due to network issues, it will returns an exception for the message. In UI, you could display only messages appeared as 'sent' only if sending message is succeeded.

channel.sendUserMessage(MESSAGE, DATA, CUSTOM_TYPE, function(message, error){
    if (error) {
        console.error(error);
        return;
    }
    console.log(message);
});

A user can also send any binary files to SendBird.

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.

To send meta data with a file, you can use custom data and customType.

channel.sendFileMessage(FILE, FILE_NAME, FILE_TYPE, FILE_SIZE, CUSTOM_DATA, CUSTOM_TYPE, function(message, error){
    if (error) {
        console.error(error);
        return;
    }
    console.log(message);
});

Receiving Messages

After entering to a channel, all messages can be received by adding ChannelHandler.
You can cast a BaseMessage object among three types of messages.

  • UserMessage: User text message.
  • FileMessage: User binary message.
  • AdminMessage: Admin message which could be sent via platform API by admin.

UNIQUE_HANDLER_ID is an identifier for multiple channel handlers registration.

var ChannelHandler = new sb.ChannelHandler();

ChannelHandler.onMessageReceived = function(channel, message){
    console.log(channel, message);
};

sb.addChannelHandler(UNIQUE_HANDLER_ID, ChannelHandler);

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

sb.removeChannelHandler(UNIQUE_HANDLER_ID);

Loading Previous Messages

Before entering to the channel, getting previous messages in the channel is typically needed to render previous messages in chat UI.

var messageListQuery = channel.createPreviousMessageListQuery();

messageListQuery.load(20, true, function(messageList, error){
    if (error) {
        console.error(error);
        return;
    }
    console.log(messageList);
});

Group Channel - Advance

Getting/Updating a list of all members

GroupChannel has members attributes and you can use it to get a list of members.
Members are automatically updated when you are online. If you disconnect from SendBird and connect it again, you should refresh the channel to update with latest information.

var members = groupChannel.members;

Typing Indicators

You can send typing events with startTyping and endTyping.

groupChannel.startTyping();
groupChannel.endTyping();

You can receive a TypingStatusUpdate event in the channel handler.

var ChannelHandler = new sb.ChannelHandler();

ChannelHandler.onTypingStatusUpdated = function(channel){
    console.log(channel);
};

sb.addChannelHandler(UNIQUE_HANDLER_ID, ChannelHandler);

Read Receipts

Users can send markAsRead events when users read messages.

groupChannel.markAsRead();

You can receive a ReadReceiptUpdate event in the channel handler.

var ChannelHandler = new sb.ChannelHandler();

ChannelHandler.onReadReceiptUpdated = function(channel){
    console.log(channel);
};

sb.addChannelHandler(UNIQUE_HANDLER_ID, ChannelHandler);

You can get updated receipt counts when you get ReadReceiptUpdate events

  var unreadCount = channel.getReadReceipt(msg);

Deleting Messages

A user can delete a message. It gives an error if the user tries to delete messages which are sent by others.
It also fires a message deleted events to other users on the channel.

channel.deleteMessage(BASE_MESSAGE, function(response, error){
    if (error) {
        console.error(error);;
    }
});

You can receive a MessageDeleted event in the channel handler.

var ChannelHandler = new sb.ChannelHandler();

ChannelHandler.onMessageDeleted = function(channel, messageId){
    console.log(channel, messageId);
};

sb.addChannelHandler(UNIQUE_HANDLER_ID, ChannelHandler);

Channel MetaData (beta)

You can save any key/value pair information into each channel with meta data.

If the value is integer and needs atomic increasing/decreasing operations, you should use meta counters instead.

With meta data/counters, you could save some additional information such as the number of likes, background colors, long description.

Meta Data

Create

var data = {
    key1: value,
    key2: value
};

channel.createMetaData(data, function(response, error) {
    if (error) {
        console.error(error);
        return;
    }
    console.log(response);    
});

Update

var data = {
    key1: value,
    key2: value
};
var isUpsert = true;

channel.updateMetaCounters(data, isUpsert, function(response, error) {
    if (error) {
        console.error(error);
        return;
    }
    console.log(response);    
});

Get

var keys = ['key1', 'key2'];
channel.getMetaData(keys, function(response, error) {
    if (error) {
        console.error(error);
        return;
    }
    console.log(response);    
});

Meta Counters

Create

var counters = {
    key1: 1,
    key2: 2
};

channel.createMetaCounters(counters, function(response, error) {
    if (error) {
        console.error(error);
        return;
    }
    console.log(response);
});

Increase

var counters = {
    key1: 1,
    key2: 2
};

channel.increaseMetaCounters(counters, function(response, error) {
    if (error) {
        console.error(error);
        return;
    }
    console.log(response);
});

Decrease

var counters = {
    key1: 3,
    key2: 2
};

channel.decreaseMetaCounters(counters, function(response, error) {
    if (error) {
        console.error(error);
        return;
    }
    console.log(response);
});

Get

var keys = ['key1', 'key2'];

channel.getMetaCounters(keys, function(response, error) {
    if (error) {
        console.error(error);
        return;
    }
    console.log(response);
});

Event Handler

Channel Handler

You can register multiple channel handlers to receive various events and messages from SendBird.

Typically you should register the event handler in each activity.

var ChannelHandler = new sb.ChannelHandler();

ChannelHandler.onMessageReceived = function (channel, message) {
  console.log('ChannelHandler.onMessageReceived: ', channel, message);
};

ChannelHandler.onMessageDeleted = function (channel, messageId) {
  console.log('ChannelHandler.onMessageDeleted: ', channel, messageId);
};

ChannelHandler.onReadReceiptUpdated = function (channel) {
  console.log('ChannelHandler.onReadReceiptUpdated: ', channel);
};

ChannelHandler.onTypingStatusUpdated = function (channel) {
  console.log('ChannelHandler.onTypingStatusUpdated: ', channel);
};

ChannelHandler.onUserJoined = function (channel, user) {
  console.log('ChannelHandler.onUserJoined: ', channel, user);
};

ChannelHandler.onUserLeft = function (channel, user) {
  console.log('ChannelHandler.onUserLeft: ', channel, user);
};

ChannelHandler.onUserEntered = function (channel, user) {
  console.log('ChannelHandler.onUserEntered: ', channel, user);
};

ChannelHandler.onUserExited = function (channel, user) {
  console.log('ChannelHandler.onUserExited: ', channel, user);
};

ChannelHandler.onUserMuted = function (channel, user) {
  console.log('ChannelHandler.onUserMuted: ', channel, user);
};

ChannelHandler.onUserUnmuted = function (channel, user) {
  console.log('ChannelHandler.onUserUnmuted: ', channel, user);
};

ChannelHandler.onUserBanned = function (channel, user) {
  console.log('ChannelHandler.onUserBanned: ', channel, user);
};

ChannelHandler.onUserUnbanned = function (channel, user) {
  console.log('ChannelHandler.onUserUnbanned: ', channel, user);
};

ChannelHandler.onChannelFrozen = function (channel) {
  console.log('ChannelHandler.onChannelFrozen: ', channel);
};

ChannelHandler.onChannelUnfrozen = function (channel) {
  console.log('ChannelHandler.onChannelUnfrozen: ', channel);
};

ChannelHandler.onChannelChanged = function (channel) {
  console.log('ChannelHandler.onChannelChanged: ', channel);
};

ChannelHandler.onChannelDeleted = function (channel) {
  console.log('ChannelHandler.onChannelDeleted: ', channel);
};

sb.addChannelHandler(UNIQUE_HANDLER_ID, ChannelHandler);

You should remove the channel handler where the activity is no longer valid.

sb.removeChannelHandler(UNIQUE_HANDLER_ID);

Connection Handler

You can register multiple connection handlers to detect connection status changes.

Typically you should register the connection handler in each activity.

var ConnectionHandler = new sb.ConnectionHandler();

ConnectionHandler.onReconnectStarted = function(){
};

ConnectionHandler.onReconnectSucceeded = function(){
};

ConnectionHandler.onReconnectFailed = function(){
};

You should remove the connection handler where the activity is no longer valid.

sb.removeConnectionHandler(UNIQUE_HANDLER_ID);

Miscellaneous

Client SDK generated Error Codes

Error Value Description
INVALID_INITIALIZATION 800100 Initialization failed
CONNECTION_REQUIRED 800101 Connection required
INVALID_PARAMETER 800110 Invalid parameters
NETWORK_ERROR 800120 Network error
NETWORK_ROUTING_ERROR 800121 Routing error
MALFORMED_DATA 800130 Malformed data
MALFORMED_ERROR_DATA 800140 Malformed error
WRONG_CHANNEL_TYPE 800150 Wrong channel type
MARK_AS_READ_RATE_LIMIT_EXCEEDED 800160 Mark as read rate limit exceeded
QUERY_IN_PROGRESS 800170 Query is in progress
ACK_TIMEOUT 800180 Ack command timed out
LOGIN_TIMEOUT 800190 Login timed out
WEBSOCKET_CONNECTION_CLOSED 800200 Connection closed
WEBSOCKET_CONNECTION_FAILED 800210 Connection failed
REQUEST_FAILED 800220 Request failed

Server-generated Error Codes

These errors are not defined in the js 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.15

Fixed a bug that created non-integer file size field.

v3.0.14

Fixed a reconnection bug happening after calling disconnect() and connect() in serial.
Added "custom_type" field to message/file object.
Added "user_id"/"nickanme" filters to GroupChannelList.
Fixed wrong message_id, data field of FileMessage object.

v3.0.11

Fixed a Keep-Alive bug now and it should be much faster in React Native/NodeJS.
Now calling "connect()" multiple times in a row triggers "disconnect()" internally to avoid having multiple websocket connections
New License File

v3.0.10

Fixed a bug that increases unread message counts even when a user gets its own messages
Clear out old ws object's event handlers after disconnect to prevent a user from getting messages from another user who logged in on the same device.

v3.0.9

Minor bugfix for IE, Safari, Opera.

v3.0.8

sendFileMessage bugfix.

v3.0.7

Added features like filtered user list, open channel keyword search, push preference setting, etc.
messageListQuery bugfix.

v3.0.6

npm dependencies bugfix.

v3.0.5

NodeJS Keepalive bugfix.
React Native android bugfix.

v3.0.4

createPreviousMessageListQuery bugfix.
npm bundle bugfix.

v3.0.3(Sep 5, 2016)

npm release. (only for React Native)

v3.0.2(Sep 2, 2016)

Reconnect bugfix.
getMetaCounters, getMetaData bugfix.

v3.0.1(Aug 24, 2016)

blockUserWithUserId bugfix.

v3.0.0(Aug 12, 2016)

First release.