Skip to main content

BlendVision Chatroom JavaScript SDK

BlendVision Chatroom provides real-time messaging, admin-controlled bans, message deletion, and pinned announcements.

Installing

Setup

1. Get your chatroom token

Integrator could get chatroom token and refresh token with BlendVision API.

2. Add dependency

via NPM (js)

npm install @blendvision/chatroom-javascript-sdk@latest --save

Configure BlendVision JavaScript SDK

1. Initialize the Chatroom

The init() method initializes the settings required for BlendVision Chatroom.

Therefore, we suggest integrator to call the init() method on app startup, preferably in the index.js file.

import { Chatroom } from '@blendvision/chatroom-javascript-sdk';
import { ChatroomConfig } from '@blendvision/chatroom-javascript-sdk/type';
const chatToken = 'YOUR_CHATROOM_TOKEN';
const refreshToken = 'YOUR_CHATROOM_REFRESH_TOKEN';
Chatroom.init({ chatToken, refreshToken }).then(
(data: ChatroomConfig) => {
console.log('Initialization completed successfully', data);
},
(error) => {
console.log('Initialization failed with error:', error);
}
);

Parameters

ParametersRequiredDescription
chatTokenRequiredThe chatroom token is required for accessing and managing chatroom-related APIs.
Additionally, this token has a validity period of 24 hours. Please considering your application's use case, it may be necessary to pass refresh token or integrate a refresh token mechanism to ensure continuous access.
refreshTokenOptionalFor the chatroom expected to last longer than 24 hours, please provide a refresh token to ensure a smooth user experience. Alternatively, the integrator should handle the token refresh mechanism.
optionskeepaliveOptionalThe interval, in seconds, between keepalive pings sent to the server to ensure the connection remains active.
The default is 60 seconds, set to 0 to disable.
reconnectPeriodOptionalThe interval, in milliseconds, between reconnection attempts if the connection is lost.
The default is 1000 milliseconds (1 second). Setting this to 0 disables automatic reconnections.
connectTimeoutOptionalThe maximum time, in milliseconds, the client will wait for a CONNACK response from the broker after sending a connection request.
The default is 30 * 1000 milliseconds (30 seconds).
serverBatchIntervalOptionalThe interval, in milliseconds, applies to custom messages with a counter. Messages are accumulated up to this interval before being sent to the server.
The default interval is 5000 milliseconds (5 seconds).
clientBatchIntervalOptionalThe interval, in milliseconds, applies to custom messages with a counter as well.
To prevent the user from experiencing delays, the user's own messages can be updated faster than the server setting, minimizing the perceived delay in replies. This mechanism also helps protect your front-end from updating too frequently.
The default is 2000 milliseconds (2 seconds).

Responses

The response data type for the API call is structured as follows:

interface User {
id: string;
deviceId: string;
customName: string;
isAdmin: boolean;
}

interface BlockedUser {
blockedUser: User;
actionTaker: string;
}

interface TextMessage {
id: string;
text: string;
sender: User;
}

interface PinnedMessage {
textMessage: TextMessage;
actionTaker: string;
}

interface ViewerInfo {
enabled: boolean;
count: number;
version: number;
updatedAt: string;
}

interface CustomCounter {
key: string;
value: number;
version: number;
updatedAt: string;
disabled: boolean;
}

interface ChatroomType {
id: string;
muted: boolean;
blockedUsers: BlockedUser[];
pinnedMessages: PinnedMessage[];
viewerInfo: ViewerInfo;
customCounters: CustomCounter[];
createdAt: string;
updatedAt: string;
}

interface ChatroomConfig {
user: User;
chatroom: ChatroomType;
}

2. Handle Received Messages with register()

import { Chatroom } from '@blendvision/chatroom-javascript-sdk';
import { ReceivedMessage, ReceivedMessageText } from '@blendvision/chatroom-javascript-sdk/type';
import { IConnackPacket, IDisconnectPacket, ErrorWithReasonCode } from 'mqtt';

Chatroom.register({
// Connection Status
onConnect: (packet: IConnackPacket) => {
console.log('The chatroom is successfully connected', packet);
},
onDisconnect: (packet: IDisconnectPacket) => {
console.log('The chatroom is disconnected', packet);
},
onReconnect: () => {
console.log('The chatroom is reconnecting');
},
onError: (error: Error | ErrorWithReasonCode) => {
console.log('The chatroom failed to connect', error);
},
// Interaction Message
onTextReceived: (textMessage: ReceivedMessageText) => {
console.log('onTextReceived', textMessage);
},
onMuteReceived: (message: ReceivedMessage) => {
console.log('onMuteReceived', 'The chatroom is muted by', message.user.customName);
},
});

Connection Status

You could check the Packet type here. If there is a connection error, the reason code could be found here.

Interaction Message

The basic interaction message type is:

interface User {
id: string;
deviceId: string;
customName: string;
isAdmin?: boolean;
}

enum InteractionType {
Text = 'INTERACTION_TYPE_TEXT',
Custom = 'INTERACTION_TYPE_CUSTOM',
CustomCounterUpdate = 'INTERACTION_TYPE_CUSTOM_COUNTER_UPDATE',
Mute = 'INTERACTION_TYPE_MUTE',
Unmute = 'INTERACTION_TYPE_UNMUTE',
Pin = 'INTERACTION_TYPE_PIN_MESSAGE',
Unpin = 'INTERACTION_TYPE_UNPIN_MESSAGE',
Block = 'INTERACTION_TYPE_BLOCK_USER',
Unblock = 'INTERACTION_TYPE_UNBLOCK_USER',
Delete = 'INTERACTION_TYPE_DELETE_MESSAGE',
ViewerInfoEnabled = 'INTERACTION_TYPE_VIEWER_INFO_ENABLED',
ViewerInfoDisabled = 'INTERACTION_TYPE_VIEWER_INFO_DISABLED',
ViewerInfoUpdate = 'INTERACTION_TYPE_VIEWER_INFO_UPDATE',
Broadcast = 'INTERACTION_TYPE_BROADCAST_UPDATE',
}

interface ReceivedMessage {
id: string;
type: InteractionType;
user: User;
sentAt: string; // Timestamp indicating when the message was received by the SDK.
receivedAt: string; // Timestamp indicating when the message reached the server.
}

Text Message

FunctionInteraction TypeDescription
onTextReceivedINTERACTION_TYPE_TEXTThe text message
interface ReceivedMessageText extends ReceivedMessage {
type: InteractionType.Text;
text: string;
}

Custom Message

FunctionInteraction TypeDescription
onCustomReceivedINTERACTION_TYPE_CUSTOMThe custom message
interface ReceivedMessageCustom extends ReceivedMessage {
type: InteractionType.Custom;
value: string; // usually structure in JSON format
}

Custom Counter Message

The message would be sent with the batch setting by default, and the batching interval could be adjusted [here].

FunctionInteraction TypeDescription
onCustomCounterReceivedINTERACTION_TYPE_CUSTOMThe custom counter message
interface ReceivedMessageCustomCounter extends ReceivedMessage {
type: InteractionType.Custom;
key: string; // the key that set up when create chatroom
value: string; // usually structure in JSON format, would be empty string if no value provided
}

Custom Counter Update

The actual value of the counter would be updated by this function.

Since the admin could update the counter via chatroom custom counter API here, the SDK would receive the update event by this function.

FunctionInteraction TypeDescription
onCustomCounterUpdateReceivedINTERACTION_TYPE_CUSTOM_COUNTER_UPDATEUpdate the custom counter's value or disabled.
interface ReceivedMessageCustomCounterUpdate extends ReceivedMessage {
type: InteractionType.CustomCounterUpdate;
key: string; // Indicate the key of counter
value: string; // Indicate the actual amount of counter
version: number;
updatedAt: string;
disabled: boolean; // Would be true if the counter key has been removed
}

Mute the Chatroom

FunctionInteraction TypeDescription
onMuteReceivedINTERACTION_TYPE_MUTESince the chatroom is muted, viewers can not send message.
onUnmuteReceivedINTERACTION_TYPE_UNMUTEThe chatroom is unmuted.

No extra information would be sent with the mute/unmute message.

Pin/Unpin a message

FunctionInteraction TypeDescription
onPinMessageReceivedINTERACTION_TYPE_PIN_MESSAGEThe message is pinned.
onUnpinMessageReceivedINTERACTION_TYPE_UNPIN_MESSAGEThe message is unpinned.
interface User {
id: string;
deviceId: string;
customName: string;
isAdmin?: boolean;
}

interface ReceivedMessagePin extends ReceivedMessage {
type: InteractionType.Pin | InteractionType.Unpin;
pinUnpinMessage: {
textMessage: {
id: string;
text: string;
sender: User;
};
actionTaker: string;
};
}

Block/Unblock User

FunctionInteraction TypeDescription
onBlockUserReceivedINTERACTION_TYPE_BLOCK_USERThe end user is blocked.
onUnblockUserReceivedINTERACTION_TYPE_UNBLOCK_USERThe end user is unblocked.
interface User {
id: string;
deviceId: string;
customName: string;
isAdmin?: boolean;
}

interface ReceivedMessageBlockUnblock extends ReceivedMessage {
type: InteractionType.Block | InteractionType.Unblock;
blockUnblockMessage: {
user: User;
actionTaker: string;
};
}

Delete Message

FunctionInteraction TypeDescription
onDeleteMessageReceivedINTERACTION_TYPE_DELETE_MESSAGEThe message is deleted.
interface ReceivedMessageDelete extends ReceivedMessage {
type: InteractionType.Delete;
deletedMessage: {
id: string;
actionTaker: string;
};
}

Viewer Info

FunctionInteraction TypeDescription
onViewerInfoReceivedINTERACTION_TYPE_VIEWER_INFO_ENABLEDShow concurrent end user count update to viewer.
onViewerInfoReceivedINTERACTION_TYPE_VIEWER_INFO_DISABLEDHide concurrent end user count update to viewer.
onViewerInfoReceivedINTERACTION_TYPE_VIEWER_INFO_UPDATEIf viewerInfo is enabled, both admin and end user will receive viewer info updates. Otherwise, only admin will receive them.
interface ViewerInfoMessage extends ReceivedMessage {
type: InteractionType.Update | InteractionType.Enabled | InteractionType.Disabled;
viewerInfo: {
enabled: boolean; // Indicates whether viewer information is enabled. Default value is false.
count: number; // Represents the number of viewers.
updatedAt: string;
version: number; // The version number of the viewer information. A larger number represents a newer version.
};
}

Broadcast

FunctionInteraction TypeDescription
onBroadcastReceivedINTERACTION_TYPE_BROADCAST_UPDATEWhen received the concurrent viewer (unique viewer identified by id) update and total viewer update.
interface Metrics {
count: number;
updatedAt: string;
}

interface ReceivedMessageBroadcast extends ReceivedMessage {
type: InteractionType.Broadcast;
viewerMetrics: {
concurrent: Metrics;
total: Metrics;
};
}

3. General Action's API

The actions could be called from all end users.

Text Message

const textMessage = {
text: 'Here is a message',
};

Chatroom.sendTextMessage(textMessage).then(
() => {
console.log('Message sent successfully');
},
(error) => {
console.log('Message sending failed with error:', error);
}
);
ParameterRequiredDescription
textRequiredString. The maximum length of text message is 1000.

Custom Message

const customMessage = {
value: 'ANY CUSTOM VALUE YOU MAY HAVE',
};

Chatroom.sendCustomMessage(customMessage).then(
() => {
console.log('Message sent successfully');
},
(error) => {
console.log('Message sending failed with error:', error);
}
);
ParameterRequiredDescription
valueRequiredString. The custom value to send with chatroom service.

Custom Counter Message

const customCounterMessage = {
key: 'like',
value: 'ANY CUSTOM VALUE YOU MAY HAVE',
};

Chatroom.sendCustomCounterMessage(customCounterMessage).then(
() => {
console.log('Message sent successfully');
},
(error) => {
console.log('Message sending failed with error:', error);
}
);
ParameterRequiredDescription
keyRequiredString. The key of increment count set when creating chatroom.
valueOptionalThe custom value to bring with the counter. Usually structure in JSON String.

Retrieve Chat Message History

The default without any query parameters will retrieve 100 messages from the latest to the oldest, and it can continue to retrieve the next 100 messages by providing the beforeAt query parameter which can assign the receivedAt value of the first message from the previous response. If the response returns an empty array, means no more message in the condition.

Only the INTERACTION_TYPE_TEXT, INTERACTION_TYPE_CUSTOM would be listed.

Example 1

interface ReceivedHistoryMessage = ReceivedTextMessage | ReceivedCustomMessage

Chatroom.getChatMessages().then(
(data: ReceivedHistoryMessage[])=>{
console.log('Messages:', data)
// Will get the latest 100 messages by default.
},
(error)=>{
console.log('Get messages failed with error:', error);
}
);

Example 2

function getYesterdayISOString() {
const currentDate = new Date();
currentDate.setDate(currentDate.getDate() - 1);
return currentDate.toISOString();
}

const params = {
afterAt: getYesterdayISOString(),
limit: 50,
fromOldest: true,
};

Chatroom.getChatMessages({ afterAt, limit, fromOldest }).then(
(data: ReceivedHistoryMessage[]) => {
console.log('Messages:', data);
// Will get the oldest 50 messages after yesterday time.
},
(error) => {
console.log('Get messages failed with error:', error);
}
);
ParameterRequiredDescription
beforeAtOptionalList the messages before the time, default is current time. Will list from the latest in the chatroom if not provided.
limitOptionalNumber. The number of messages to retrieve. The default is 100.
afterAtOptionalList the messages after the time. Will list from the latest until the time by default. If it requires to list from the setting time, please set the fromOldest to true.
fromOldestOptionalBoolean. Indicate the list direction between interval. The default is false, will list messages from latest to oldest.

Further explanation of the parameters:

  • Assume there are chat messages existing in a chatroom, and have set the after_at and before_at boundary to list as follows:
m1 m2 m3 m4 m5 m6 m7 m8 m9 m10
^ ^
after_at before_at

a. from_oldest=false, limit=2 => [m6, m7]

b. from_oldest=true, limit=2 => [m3, m4]

  • Assume there are chat messages existing in a chatroom, and haven't set the after_at and before_at boundary to list as follows:
m1 m2 m3 m4 m5 m6 m7 m8 m9 m10

a. from_oldest=false, limit=2 => [m9, m10]

b. from_oldest=true, limit=2 => [m1, m2]

4. Admin Action's API

The actions could be called from admin only.

Mute & Unmute the Chatroom

The admin could mute & unmute the chatroom. End user message would be limited, only admin could send message when the chatroom is muted.

// Mute the chat room. `onMuteReceived` would receive interaction message upon success.
Chatroom.mute();

// Unmute the chat room. `onUnmuteReceived` would receive interaction message upon success.
Chatroom.unmute();

Block & Unblock a User

The admin could block/unblock a certain end user. If an end user is blocked, it's future message would be hidden to other end users, and added 'blocked' label when sending to admin.

// Block a user. `onBlockUserReceived` would receive interaction message upon success.
const userForBlock = {
id: 'USER_ID_FOR_BLOCK',
deviceId: 'USER_DEVICE_ID_FOR_BLOCK',
customName: 'USER_CUSTOM_NAME_FOR_BLOCK',
};
Chatroom.blockUser(userForBlock);

// Unblock a user. `onUnblockUserReceived` would receive interaction message upon success.
const id = 'USER_ID_FOR_UNBLOCK';
Chatroom.unblockUser({ id });

Delete a Message

The admin could delete specific message within the chatroom. If a message is deleted, admin would receive the id of it.

// Delete a message. `onDeleteMessageReceived` would receive interaction message upon success.
const messageForDelete = {
id: 'MESSAGE_FOR_DELETE_ID',
sentAt: 'MESSAGE_FOR_DELETE_SENT_AT', //optional. would improve the message delete time.
receivedAt: 'MESSAGE_FOR_DELETE_RECEIVED_AT', //optional. would improve the message delete time.
};
Chatroom.deleteMsg(messageForDelete);

Pin & Unpin a Message

The admin could pin/unpin a specific message within the chatroom.

// Pin a message. `onPinMessageReceived` would receive interaction message upon success.
const messageForPin = {
id:'MESSAGE_ID';
text:'MESSAGE_TEXT';
sender:{
id:'MESSAGE_SENDER_ID';
deviceId:'MESSAGE_SENDER_DEVICE_ID';
customName:'MESSAGE_SENDER_CUSTOM_NAME';
};
}
Chatroom.pinMessage(messageForPin);

// Unpin a message. `onUnpinMessageReceived` would receive interaction message upon success.
const id = 'UNPIN_MESSAGE_ID';
Chatroom.unpinMessage({ id });

Show & Hide Viewer Info

Modify the visibility of viewer info in the chatroom.

If true, the admin and the end user could receive the viewer info update, otherwise only the admin could receive it.

// Update viewer info. `onUpdateViewerInfoReceived` would receive interaction message upon success.
const viewerInfo = {
enabled: false,
};
Chatroom.updateViewerInfo(viewerInfo);

Update a User

The admin could update their custom name by the function.

// Update a user.
const customName = 'Bella';
Chatroom.updateUser({ customName });