2.9.1 • Published 16 days ago

@bandyer/bandyer-chat-widget v2.9.1

Weekly downloads
105
License
ISC
Repository
github
Last release
16 days ago

WEB BANDYER SDK

The BandyerSDK is a fast and effective way to offer a live videochat in your web application.

Consuming a library

You can consume the library from NPM:

npm install @bandyer/bandyer-chat-widget

or embed it directly in your HTML getting it from our CDN:

<script src="https://cdn.bandyer.com/sdk/js/chat/X.X.X/bandyer-widget.min.js" type="text/javascript" ></script>

Example embed in HTML page;

<html>
    <head></head>
    <body>
        <script src="https://cdn.bandyer.com/sdk/js/chat/2.9.1/bandyer-widget.min.js" type="text/javascript"></script>
    </body>
</html>

The script attaches in the window object the global variable BandyerSDK from where you can access the library.

Supported browsers

Browsermin versionPlugin requested
Chrome72
Firefox66
Safari12
Edge new79

Versions

The latest version is: 2.9.1 https://cdn.bandyer.com/sdk/js/chat/2.9.1/bandyer-widget.min.js

if you're upgrading from v1.x.x you can find the migration guide here

For the complete list of versions changes visit: CHANGELOG

Screenshots

BandyerSDK

Methods

Properties

NameTypeDescription
versionstringReturn the current version of the widget

Configure

.configure(config)

const Client: Client = await BandyerSDK.configure({
    appId: 'client secret',
    region: 'eu or in',
    environment: 'sandbox or production'
});

This method allows the configuration of the BandyerSDK and it returns a Client object that can be used to connect and use the library. Be sure to keep a reference of this object somewhere in your code because it is impossible to retrieve it again due to security constraints.

The configuration of a new BandyerSDK instance is made by calling the BandyerSDK.configure() method. The available options are the following:

Parameters
ParameterRequiredDefaultDescription
regionyesRegion on witch your account belongs. Allowed parameters are eu, in, us or me
environmentyesAllowed values are: sandbox or production
appIdyesA valid appId associated to your account
hiddennofalseConfigure the widget to start in hidden mode (not visible in the HTML)
layoutnodefault layoutSpecify the custom layout (see more here)
recordingTypeno'none'Wether the recording is disable (none) or starts automatically at the beginning of a call(automatic) or must be started manually(manual). Allowed values are: none, manual or automatic
isAdminnofalseSpecify wether the logged user is admin of the calls initiated from the widget. Admin users are able to start/stop the recording when is manual
callTypenoaudio_videoSpecify the call type. Allowed values are: audio_only, audio_upgradable, audio_video
modenoembedSpecify the widget call mode. Allowed values are: embed or window
languageno'en'Specify the language of the widget Allowed values are: en, it, es or pt
userDetailsProvidernodefault user providerSpecify the data for each user (see more here)
userDetailsFormatternodefault user formatterSpecify how user data is formatted in the UI (see more here)
toolsnoAll tools disabledSpecify the tools to enable during the call (embed and window mode)(See more here)
virtualBackgroundnofalseIt allows to publish the local webcam with blurred or the replaced background by default (embed and window mode). Allowed values are: blur or image
feedbacknofalseSpecify wether to show the view to leave a feedback at the end of the call
Errors
Namedescription
client_already_existsA client exists already, you need to destroy the existing client before creating a new one
invalid_config_errorOne or more parameters have an incorrect type. See the message to know which ones
browser_not_supportedThe current browser is not supported, please check the compatibility table

Call type options:

  • audio_only: the call is only audio and the participants can't use the webcam
  • audio_upgradable: the call begins with only audio but the participants are allowed to enable the video later during the call
  • audio_video: the call begins with audio and video enabled

Mode options:

  • embed: the call is shown in the widget view
  • window: the call is shown in a separated popup window

Hidden options

The widget remains not visible until it receives the following events:

  1. addChat event
  2. incoming call event

Tools option

By default, if no tools are provided (missing field), all the tools are disabled.

List of available tools

NameModeDescription
chatWindow & EmbedSpecify wether to initialize the chat module or not
screen_sharingWindow & EmbedEnable the screen_sharing feature
file_uploadWindow & EmbedEnable the capability to send file
whiteboardWindowIf true enable all the whiteboard tools. Can be an object of whiteboard tools
snapshotWindowEnable the snapshot feature
live_editWindowEnable the live_edit feature
live_pointerWindowEnable to send pointer-events to others participants (always active in reception)

The whiteboard(WB), snapshot(SN) and live_edit(LE) tools are strictly correlated, so use it accordingly as follows:

CombinationReceive live_editCollaborateSnapshot & GalleryOpen whiteboard
SN+ LE + WB
SN
SN + WB (default LE active in reception)
WB (default LE active in reception)
NONE

Whiteboard tools

{
    "tools": {
        "whiteboard": {
            "wb_add_file": true,
            "wb_cursor": true,
            "wb_text": true,
            "wb_shape": true,
            "wb_pen": true,
            "wb_eraser": true
        }
    }
}

The whiteboard tools object is included in the tools parameter

NameDescription
wb_add_fileAllows to add files on the whiteboard
wb_cursorAllows to send the cursor events to the other participants
wb_textAllows to add text on the whiteboard
wb_shapeAllows to add shape on the whiteboard
wb_penAllows to using the pen on the whiteboard
wb_eraserAllows to erase a previous draw on the whiteboard

Custom layout

The widget has custom configurable layout to give the opportunity to match the look and feel you prefer. The layout option is composed by a list of other keys. The table above is the list of the available options:

KeyOptionsDescription
headerbackground, colorSpecify the background and color of the header
headerButtonbackground, colorSpecify the background and color of the header buttons
bodybackground, colorSpecify the background and color of the body
launcherbackgroundSpecify the background of the launcher
messageSentbackground, colorSpecify the background and color of the messages you sent
messageReceivedbackground, colorSpecify the background and color messages you received
dialbackground, colorSpecify the background and color of the dial view
callbackground, colorSpecify the background and color of the call view
feedbackbody: {background, color}, buttons: {background, color}Specify the theme for the feedback view
fontFamilyfont FamilyFont family of the entire widget

Here an example:

BandyerSDK.configure({
    region: 'eu',
    appId: 'wAppId_fake123456',
    environment: 'sandbox',
    layout: {
        body: { background: '#0069B4', color: '#000' },
        dial: { background: '#003762', color: '#fff' },
        call: { background: '#003762', color: '#fff' },
        messageSent: { background: '#003762', color: '#fff' },
        launcher: { background: '#0069B4' },
        header: { background: '#003762', color: '#fff' },
        headerButton: { background: '#0069B4', color: '#fff' },
        feedback: { body: { background: '#0069B4', color: '#fff' }, buttons: { background: '#0069B4', color: '#fff' } },
        fontFamily: '"Segoe UI","Segoe",Tahoma,Helvetica,Arial,sans-serif'
    }
});

User details provider

Since Kaleyra Video solution treats users of a company referring to them only via anonymous identifiers, in order to display users details on sdk integrations (chat widget, Android and iOS SDks) and call links each platform expose a set of client api to customize the user information (display name and avatar).

In order to obtain user display name and image customization on the client call and chat UIs, has now been released a new convenient and centralized way to achieve the same result. We refer to this newly released API as Server side User Details Provider.

Server side User Details Provider

In order to enable this functionality you must specify a valid user_details_provider_url through the company update rest API.

The provider url, if defined, will be used as an endpoint to request the details of the users through a http post request whenever a client needs to display some user details.

As mentioned above, the best use case scenario for the Server side User Details Provider implementation is represented by those integrations that rely on a heterogeneous usage of client sdks (e.g. mobile sdks alongside chat widget implementation) and call links. Using the Server side User Details Provider will result in a more concise (and less error-prone too) way to display users information. Furthermore, it's not will be necessary to implement the Client side user Details Provider APIs for the client SDKs.

Despite what has been mentioned, the Client side user Details Provider will be maintained for those integrations that cannot rely on webhook implementations.

More details about the REST integration of the Server side user Details Provider can be found here.

Client side user Details Provider

The BandyerSDK exposes the Client side user Details Provider API as a custom configurable function that allows customizing the users' information, which later will be displayed in the UI. The userDetailsProvider is optional, but if defined must be a function.

This function takes an array of String (userId) as the only input parameter and must return a Promise that contains an Array of objects, one object for each userId provided as input.

Beware Client side user details Provider has a higher priority over the server side one, so be careful in implementing both the solutions.

Beware of Performance, the userDetailsProvider function is called and waited internally for up to 1200 ms, otherwise it uses the default provider logic. For this reason your logic will be applied only if it is faster than 1200 ms.

Every single object representing a user and must contain a userId key(otherwise the object will be ignored) and optionally other keys that can be used to define the logic used in your custom userDetailFormatter.

Here an example:

yourProviderFunction = function(usersIds) {
    const userObjPromises = [];
    usersIds.forEach(userId => {
        // Your logic here
        const user = yourAsyncFetchFunction(userId);
        // Example of yourAsyncFetchFunction promise return
        /* {
        userId: userId,
        firstName: myFirstName,
        lastName: myLastName,
        image: myImage
    }; */
        usersObjPromises.push(user);
    });
    return Promise.all(userObjPromises);
};

BandyerSDK.configure({
    region: 'eu',
    appId: 'wAppId_fake123456',
    environment: 'sandbox',
    userDetailsProvider: yourProviderFunction
});

N.B define a userDetailsProvider without the relative userDetailsFormatter is useless since the displayed result will be the server side information or the userId as it is the default logic of userDetailsFormatter.

Client side user details formatter

The local user details formatter API, if defined is a function that allows to use the information obtained from Client side user Details Provider in order to obtain a displayName to use in the different UIs

The userDetailsFormatter is optional, but if defined, it must be a function.

This function takes as input parameter an Object that represents one user and must return a String that represents how the user identity must be displayed in the UI.

If the return value is not a String or the logic fails, the displayed information will be the remote (if provided) or the userId.

Here an example:

yourFormatterFunction = function(user) {
    /*
    user = {
        userId: userId
        customParam1: the parameter provided in the providerFunction
        customParam2:  another parameter provided in the providerFunction
        displayName: optional parameter if you have defined a provider url for you company 
        }
     */
    return user.customParam1 + ' ' + user.customParam2;
};

BandyerSDK.configure({
    region: 'eu',
    appId: 'wAppId_fake123456',
    environment: 'sandbox',
    userDetailsFormatter: yourFormatterFunction
});

destroyClient

.destroyClient()

await BandyerSDK.destroyClient();

Allows to de-initialize the BandyerSDK, this operation destroys the client reference after which you are able to configure a new Client.

Client type

Methods

Properties

NameTypeDescription
channelsViewchannelViewRetrieve the list of channel view
callViewCallViewRetrieve the current callView
regionstringRetrieve the region value forwarded in the configuration step
environmentstringRetrieve the environment value forwarded in the configuration step
appIdstringRetrieve the appId value forwarded in the configuration step
userIdstringRetrieve the userId value forwarded in the configuration step

Events

NameDescription
client:access_token:expiredThe session expired, for some reason the update token process is failed, you need to re-connect the Client with a new access token
client:access_token:about_to_expireThe session is about to expire, you need to provide a valid accesstoken through the updateAccessToken api
client:force_disconnectThe user was disabled or deleted via REST api
channel:message:sentWhen a message was sent in a channel
channel:message:receivedWhen a message was received in a channel
channel:addedWhen a channel was added using client api or rest
channel:removedWhen a channel was removed using client api or rest
call:incomingWhen there is an incoming call
call:status:changedTriggered when the call change the status. See call status
user:status:changedTriggered when a user change the status(online / offline)

Client life cycle

To connect the Client object you need a valid accessToken, you can obtain a valid access token via rest API

If you want to have a persisted user connected across the calls you need to obtain a valid accessToken token via rest API

In order to maintain the connected state you need to bind two events to the Client object(obtained with Configure):

  • access_token_is_about_to_expire
  • access_token_expired Follow an example of licfecycle implementation:
//configuration step

// access token request

Client.on('client:access_token:is_about_to_expire', async data => {
    // data: {expiresAt: "2022-01-10T11:41:19.000Z"'}
    const accessToken = await yourAsyncFunction(); // async function that allow you to ask a new accessToken to the server
    // Provide the obtained accessToken to the sdk
    const { expiresAt } = await Client.updateAccessToken(accessToken); // return the new expiration date
});
Client.on('client:access_token:expired', async () => {
    // the session expired, for some reason the update token process is failed, you need to re-connect the Client with a new access token
    await Client.disconnect();
    // retrieve a new accessToken
    await Client.connect(userId, accessToken);
});

Client.on('client:force_disconnect', () => {
    // the user was disabled or deleted from a rest api
});
try {
    await Client.connect(userId, accessToken);
} catch (e) {
    console.error('Fail to connect the client', error);
}

Otherwise, you can use a classic call link obtained from the create call rest API

In that case the lifecycle is strictly related to the call, once the call finish the user is automatically disconnected.

try {
    const accessLink = 'https://sandbox.bandyer.com/eu/direct-rest-call-handler/adufj5769cnapmce';
    // remember that the link must match the region and the environment forwarded in the configuration phase
    await Client.joinCallUrl(accessLink);
} catch (e) {
    console.error('Fail to connect the client', error);
}

There is no need to manage and handle the access Token.

Following there are the two method for the connection

Connect

To connect the Client object you need a valid accessToken, you can obtain a valid access token via rest API

The access token must match the userId provided

.connect()

try {
    await Client.connect(userId, accessToken);
} catch (e) {
    console.error('Fail to connect the client', error)
}
Parameters
ParameterRequiredDefaultDescription
userIdyesUser that you want to authenticate
accessTokenyesAccess token corresponding to the user provided
Errors
Namedescription
sdk_version_invalidIf one or more parameter have an incorrect type, see the message to knows which ones
sdk_version_unsupportedThe browser is not supported, please check the compatibility table above
app_id_invalidThe appId used in configuration step is invalid
access_token_expiredThe access token is expired, please retrieve a new one before retry the connection
access_token_invalidhe access token is invalid, please check the token generation
access_token_invalid_signatureThe access token is compromised, please check the token generation
access_token_invalid_userThe access token not belong to the userId forwarded in the connect method
user_not_foundThe user does not exists

Connect with access link

BandyerSDK can optionally be connected using a call url link. The session that will be created using the call url link as access link will last only for the duration of the joined call.

All the sdk feature will be restricted on the call represented by the call link url.

In addition, the only chat accessibile will be the chat related to the current call specified by the call link url.

At the end of the call the BandyerSDK will be automatically disconnected and all persisted data will be cleared as well.

Note that if BandyerSDK is already connected via access token, connecting via access link with the same user or with another user is not allowed. The current access link session must be ended before connecting again.

.joinCallURL(url)

try {
    const call: CallView = await Client.joinCallURL(url);
} catch (e) {
    console.error('Fail to connect the client', error);
}
Parameters
NameTypeDescription
urlstringValid url for the call
Errors
Namedescription
sdk_version_invalidIf one or more parameter have an incorrect type, see the message to knows which ones
sdk_version_invalidIf one or more parameter have an incorrect type, see the message to knows which ones
invalid_access_linkThe access link is not a valid url
invalid_access_linkThe access link is not valid, the room is inactive or the user does not belong to the URL
app_id_invalidThe appId used in configuration step is invalid
user_not_foundThe user does not exists

Disconnect

.disconnect()

await Client.disconnect();

Update access token

Allow to refresh the session, you can obtain a valid access token via rest API

.updateAccessToken()

await updateAccessToken(accessToken);
Parameters
ParameterRequiredDefaultDescription
accessTokenyesAccess token corresponding to the user provided
Errors
Namedescription
access_token_expiredThe access token is expired, please retrieve a new one before retry the connection
access_token_invalidhe access token is invalid, please check the token generation
access_token_invalid_signatureThe access token is compromised, please check the token generation
access_token_invalid_userThe access token not belong to the userId forwarded in the connect method

Client: Chat API and types

If the Client was created with the chat module enabled it can perform some chat operation, also expose some real time events.

Events

// when a message was sent in a channel
Client.on('channel:message:sent', ({message: Message}) => {
  // your logic
})

// when a message was received in a channel
Client.on('channel:message:received', ({message: Message}) => {
  // your logic
})


// when a channel was added using api/ rest
Client.on('channel:added', ({channel: Channel}) => {
  // your logic
})

// when a channel was removed using api/ rest
Client.on('channel:removed', ({channelId: string, participants: string[] }) => {
  // your logic
})

Add channel

To create a chat channel another user of your platform, you need to call the .addChannel() method. The addChannel method expect a valid user alias (it must be a user already created). Once the method is called, the widget will return a channelView

.addChannel(userId)

const channelView: channelView = await Client.addChannel('usr_fr55ga3');
Parameters
NameTypeDescription
userIdStringUser that you want to chat with
Errors
Namedescription
validation_errorOne of the arguments is invalid or the chat module is not initialized
authentication_errorThe Client is not authenticated
create_channel_otoAn error has occurred during the creation phase, please refer to the message in the error

Remove channel

To remove a chat channel you need to call the .removeChannel() method. The removeChannel will remove the chat between the user authenticated and the user specified as input of the method. All the messages between them will be deleted permanently.

.removeChannel(userId)

await Client.removeChannel('usr_fr55ga3');
Parameters
NameTypeDescription
userIdStringOther participants of the chat that you want to remove
Errors
Namedescription
validation_errorOne of the arguments is invalid or the chat module is not initialized
authentication_errorThe Client is not authenticated
delete_channelAn error has occurred during the remove phase, please refer to the message in the error

Get channel view

Allow to retrieve a specific channel view with a user

..getChannelView(userId)

Client.getChannelView(userId);
Parameters
NameTypeDescription
userIdStringOther participants of the chat that you want to remove
Errors
Namedescription
validation_errorOne of the arguments is invalid or the chat module is not initialized
channel_not_foundThe channel does not exists

Select channels view

Allow to show the main view of the Client, if you are in a call view or in a channel view this method allow to change the current view to the list of channels

.selectChannelsView()

Client.selectChannelsView();

Client: Call API and types

The client expose apis and events in order to manage a call lifecycle

Events

// triggered when a call is created (status equal to dialing)
Client.on('call:incoming', ({ call: Call }) => {
    // yuor logic
});

// triggered when the call change the status (connecting, connected, ended)
Client.on('call:status:changed', ({ call: Call, status }) => {
    // yuor logic, note if the status was ended, the call object can have a endReason
});

Create call

.createCall(users, options)

Create a call with arbitrary call options with the users specified in the array (Only one user at the moment)

This method return a callView that is a UI representation of the call, this object contains also the call(logical)

const callView: CallView = Client.createCall(['usr_fr55ga3'], { call_type: 'audio_video' });

Note: If the widget is in hidden mode, the createCall method mode will display the widget.

Parameters
NameTypeDescription
participantsstring[]List of users with whom you want to start a call (at most one at the moment)
optionsObjectCall options
Options
NameDefaultTypeDescription
callTypeinherit from the configstringCan be 'audio_only', 'audio_upgradable', 'audio_video'
recordinginherit from the configbooleanAllow to define if the call start with recording
recordingTypeinherit from the configstringCan be 'manual' or 'automatic'
isAdmininherit from the configbooleanAllow the user to control the manual recording capabilities

N.B. if the call is {recording: true, recordingType: 'manual', isAdmin: false} create a call with the recording capability but no-one is able to start the recording. In order to do that create this type of call with isAdmin: true

Errors

Namedescription
validation_errorOne of the arguments is invalid
another_call_in_progressThe user is already in call
current_user_not_availableThe connected user is in disconnection phase
current_user_busyThe connect user is busy on another device
all_users_busyAll the users are busy
no_plus_userShould be at least one plus user in the call
room_create_errorA generic error has occurred please check the error message to know the cause
internal_server_errorA server problem is occurred please retry or contact for support

Join call URL

.joinCallURL(url)

Join a call URL retrieved from the rest api integration Documentation can be found here

This method return a callView that is a UI representation of the call, this object contains also the call(logical)

const call: CallView = Client.joinCallUrl('https://sandbox.bandyer.com/region/direct-rest-call-handler/token');

Note: If the widget is in hidden mode, the joinCallURL method mode will display the widget.

Parameters
NameTypeDescription
urlstringValid url for the call

Errors

Namedescription
validation_errorOne of the arguments is invalid
another_call_in_progressThe user is already in call
current_user_not_availableThe connected user is in disconnection phase
current_user_busyThe connect user is busy on another device
all_users_busyAll the users are busy
invalid_urlThe given URL is invalid
invalid_tokenThe call token is invalid or disabled
user_not_associated_to_linkThe user does not belong to the link
join_url_mtmAt the moment the client does not support the many to many calls
no_plus_userShould be at least one plus user in the call
room_create_errorA generic error has occurred please check the error message to know the cause
internal_server_errorA server problem is occurred please retry or contact for support

Client : User API and events

The client expose apis and events to keep track of the other users status and life cycle

Events:

// triggered when a user in you company change you status(online, offline)
Client.on('user:status:changed', (data: { userId: string, status: string }) => {
    // yuor logic
});
Namedescription
invalid_call_statusThe call cannot be already in an ended status
user_not_in_dialingThe other participants is in disconnection phase
dial_stop_errorGeneric dial stop error, please refer to the message in order to know the cause
dial_decline_errorGeneric dial stop error, please refer to the message in order to know the cause
internal_server_errorA server problem is occurred please retry or contact for support

getOnlineUsers

.getOnlineUsers()

Allow to retrieve the current list of online users

const users: string[] = Client.getOnlineUsers();

Client : UI API

Show widget

.showWidget()

Allow to render the UI component when the Client was created with hidden:true

Client.showWidget();

Hide widget

.hideWidget()

Allow to remove the UI component when the Client was created with hidden:false

Client.hideWIdget();

Open widget

.openWidget()

Allow to expand the widget component

Client.openWidget();

Close widget

.closeWidget()

Allow to minimize the widget component

Client.closeWidget();

Toggle widget

.toggleWidget()

Allow expanding or minimize the widget component based on the status

Client.toggleWidget();

Channel view type

A channel view type is a UI representation of the logical Channel. On this object you can perform all the UI api's

Methods

Property:

NameTypeDescription
textAreaStringAllow to get and set the textArea field on the channel UI
channelChannelRetrieve the logical channel

Select

.select()

This method allow to change the currentView to the channel one

// channelView received from an event or retrieved from the channelView() method

channelView.select();

Channel type

A channel is a logical representation of the chat On this object you can perform all the logical operation like retrieve messages, send message, get unreadMessages and participants

Methods

Property

NameTypeDescription
channelIdStringRetrieve the unique channelId, it can be use also in our rest apis
participantsString[]Retrieve the userIds of the participants
unreadMessagesnumberRetrieve the count of the unread messages
messagesMessage[]Array of messages in the channel

Events

NameDescription
channel:message:addedNotify when in the current channel a message (sent or received) was added
Channel.on('channel:message:added', (message: Message) => {
    // your logic
});

Fetch messages

.fetchMessages(messageToFetch, anchor, direction)

This method allow to retrieve the channel messages programmatically

// channelView received from an event or retrieved from the channelView() method

const messagesObejct: { messages: Message[], anchor: string } = channelView.fetchMessages(
    messageToFetch,
    anchor,
    direction
);
Parameters
NameTypeDescription
messageToFetchnumberNumber of messages to fetch
anchorString[]Starting messageId from witch start to fetch
directionstringUse 'backwards' to retrieve past messages , use 'afterward' otherwise
Errors
Namedescription
channel_not_existsWhen the request is performed after the channel was deleted
message_anchor_errorInvalid anchor

Send message

.sendMessage(message)

This method allow to send a message programmatically

// channelView received from an event or retrieved from the channelView() method

const message: Message = channelView.sendMessage(text);
Parameters
NameTypeDescription
messagestringtext message that you want to send
Errors
Namedescription
channel_not_existsWhen the request is performed after the channel was deleted
message_not_savedError in storing the message, please retry

Message type

A message is a logical representation of a single message in a Channel

Property

NameTypeDescription
messageIdStringRetrieve the unique messageId
channelChannelRetrieve the logical channel
senderstringUserId of the sender
textStringText of the message
creationDateString(ISO)ISO Date of the message creation

Call view type

A call view type is a UI representation of the logical Call. On this object you can perform all the UI operation

Methods

Properties

NameTypeDescription
callCallAllow to retrieve the logical call
toneObjectAllow to manage the audios of the callView (ex ring)

Select method

.select()

This method allow to change the currentView to the call one

// callView received from an event or retrieved from the callView getter on the client object

callView.select();

Tone property

NameTypeDescription
ring{play: function, stop: function}Allow to play or stop the ring tone
// Example of how to use a ring tone

Client.on('call:incoming', ({ call }) => {
    Client.callView.tone.ring.stop(); // this avoid that the ring tone start
    // do what you want
    // ...
    Client.callView.tone.ring.play(); // if needed you can play the ring tone
});

Call type

A call is a logical representation of the room created On this object you can perform all the logical operation like answer, end, get status, participants, options etc

Methods

Properties

NameTypeDescription
roomIdStringRoomId of the call, can be used in out rest api to retrieve information
optionsObjectContains call information about his initialization and status
creationDatestring(ISO)Creation date of the call
participantsstring[]Array of userId that participate to the call
directionstring'incoming' or 'outgoing'
statusstringcan be 'dialing', 'connecting' 'connected' or 'ended'
recordingStateString'started' if the recording was started, 'stopped' otherwise
endReasonstring or nullFilled if the call is in the end state, should be 'declined', 'canceled', 'answered_of_another_device', 'hang_up', 'timeout'

Options object

NameTypeDescription
callTypeStringCan be 'audio_video', 'audio_upgradable', 'audio_only'
recordingTypeStringCan be 'none', 'automatic' or 'manual'
liveStringIf the call trigger the incoming call event or hook

Events

NameDescription
status:changedTriggered when a call change his status
recording:state:changedTriggered when the recordingState change

A call have some events that allow to retrieve real time information

// Triggered  when a call change his status
Call.on('status:changed', (status: string) => {
    // your logic
});

// Triggered  when the recording state was changed
Call.on('recording:state:changed', ({ recordingState: string }) => {
    // your logic
});

Answer

.answer()

This method allow to answer an incoming call in dialing state

// call received from an event or retrieved from the callView.call getter

await call.answer();
Errors
Namedescription
invalid_call_statusIn order to answer a call, this one should have an incoming direction an must be in dialing state
callee_not_availableThe other participants is in disconnection phase
dial_answer_errorGeneric error, please refer to the message in order to know the cause
internal_server_errorA server problem is occurred please retry or contact for support

End

.end()

This method allow to end a call

It automatically performs the correct behaviour(decline, cancel or hangUp) based on the call status

// call received from an event or retrieved from the callView.call getter

await call.end();

Migration from v1.x.x to v2.x.x

Library changes

The library name has been changed from BandyerChat to BandyerSDK so now you can find the library once loaded from the CDN in window.BandyerSDk.

Initialize the BandyerSDK

The BandyerChat.create() function has been renamed to BandyerSDK.configure() to better represent its purpose.

The BandyerSDK.configure() function will now return a client which exposes all the apis previosuly exposed on the BandyerChat object.

The client object will also expose a new distinct client.connect() function that connects the SDK.

The BandyerChat.logout() function has been replaced by the client.disconnect() function exposed on the client object and by the BandyerSDK.destroyClient() that can be used to reconfigure the SDK.

Migrate BandyerChat.create to BandyerSDK.configure

console.log(BandyerChat.version());

const client = await BandyerChat.create({ userAlias, environment, appId, mode, layout });

// the SDK is connected
// put here your logic

await BandyerChat.logout();

becomes

console.log(BandyerSDK.version);

const client = BandyerSDK.configure({ region, environment, appId, mode, layout, tools });

// note that the client is not globally expose, if you want you can global store the object with window.bandyerClient =client

client.on('client:access_token:is_about_to_expire', async () => {
    const accessToken = await getAccessToken(userId); // your async function to obtain a valid accessToken
    await client.updateAccessToken(accessToken);
});

// the SDK is configured

// your async function to obtain a valid accessToken
const accessToken = await getAccessToken(userId);

// userAlias parameters is now called userId
await client.connect(userId, accessToken);

// the SDK is connected
// put here your logic

await client.disconnect(); // replacement of the old BandyerChat.logout() function

BandyerSDK.destroyClient(); // destroys the client allowing a new configuration

Configuration parameters changes

old valuenew valuechange
recordrecordingTypeParameter key
toolstoolsNot specifying tools now means that the user will have none
languagelanguageThe current default is en

Migrate Chat methods

const chatsList = await BandyerChat.getChats();

await BandyerChat.addChat(userId);

BandyerChat.selectChat(userId);

BandyerChat.composeMessage(userId, 'How are you?', false);

BandyerChat.composeMessage(userId, 'How are you?', true);

const unreadMessagesList = await BandyerChat.getUnreadMessages();

await BandyerChat.removeChat(userId);

becomes

const chatsList = Client.channelsView; // array of channelViews instead of getChats()

const channelView = await Client.addChannel(userId);

channelView.select();

channelView.textArea = 'How are you'; // same as composeMessage with send = false

const message = await channelView.channel.sendMessage('How are you'); // same as composeMessage with send = true

channelView.channel.unreadMessages; // get unreadMessages on singleChannels instead of getUnreadMessages()

await Client.removeChannel(userId);

Migrate Chat events

Client.on('chat_loaded', callback);
Client.on('message_received', callback);
Client.on('message_sent', callback);

becomes

// see the documentation in order to know the payload in the callback
Client.on('channel:added', callback);
Client.on('channel:removed', callback);
Client.on('channel:message:received', callback);
Client.on('channel:message:sent', callback);

Migrate Call methods

const call = await BandyerChat.createCall([userId], option);
// const call = await BandyerChat.joinCallUrl(url);
call.hangUp();

becomes

const callView = await client.createCall([userId], option);
// const callView = await Client.joinCallUrl(url);

callView.call.end(); //take care about the call object changes

Migrate Call events

Client.on('incoming_call', call => {
    /* call =  {
  		"event": "incoming_call",
  		"callAlias": "room_027b9312e9a5",
  		"callDirection": "outgoing",
  		"callParticipants": ["user1", "user2"],
  		"callOptions": {
    		"record": false,
			"creationDate": "2021-04-13T08:31:03.916Z",
		   "callType": "audio_video", 
    		"live": true
  		}
	}*/
});

Client.on('call_dial_answered', call => {
    // your logic
});

Client.on('call_dial_declined', call => {
    // your logic
});

Client.on('call_dial_stopped', call => {
    // your logic
});

Client.on('call_started', call => {
    // your logic
});

Client.on('call_ended', call => {
    // your logic
});

becomes

Client.on('call:incoming', (call: Call) => {
    // call is a calltype object (see documentation to know properties and methods)

    call.on('status:changed', (status: string) => {
        // status can be  'dialing', 'connecting' 'connected' or 'ended'
    });

    call.answer();
    //call.end();
});

Client.on('call:status:changed', (call: Call, status: string) => {
    // call is a calltype object (see documentation to know properties and methods)
    // status can be  'dialing', 'connecting' 'connected' or 'ended'
    // if the call status is ended the call object have and endReason getter
});

Migrate User methods

const user = await BandyerChat.getUser(userId);

console.log(user.status);

const users = await BandyerChat.getUsersStatusList();

users.forEach(user => {
    console.log(user.status);
});

becomes

const users = Client.getOnlineUsers();

users.forEach(user => {
    console.log('the user', user, 'is online');
});

// if a user is not in the list above the status is offline

Migrate User events

Client.on('user_connected', callback);

Client.on('user_disconnect', callback);

becomes

Client.on('user:status:changed', ({ userId, status }) => {
    console.log('the user', userId, 'went', status);
});

Migrate Widget methods

BandyerChat.showWidget();
BandyerChat.hideWidget();
BandyerChat.toggleWidget();
BandyerChat.closeWidget();
BandyerChat.openWidget();

becomes

Client.showWidget();
Client.hideWidget();
Client.toggleWidget();
Client.closeWidget();
Client.openWidget();
2.9.1

16 days ago

2.9.0

23 days ago

2.8.0

26 days ago

2.7.5

1 month ago

2.7.4

2 months ago

2.7.0

8 months ago

2.7.2

8 months ago

2.7.1

8 months ago

2.6.1

8 months ago

2.6.0

10 months ago

2.7.3

8 months ago

2.5.5

10 months ago

2.5.0

1 year ago

2.5.2

1 year ago

2.5.1

1 year ago

2.5.4

1 year ago

2.5.3

1 year ago

2.4.0

1 year ago

2.3.1

1 year ago

2.3.0

1 year ago

2.2.0

2 years ago

2.1.2-beta.1

2 years ago

2.1.2-beta.0

2 years ago

1.45.2

2 years ago

2.1.2-beta.2

2 years ago

2.1.4

2 years ago

2.1.3

2 years ago

2.1.5

2 years ago

2.0.0

2 years ago

2.0.0-beta.1

2 years ago

2.0.0-beta.0

2 years ago

2.0.1-beta.0

2 years ago

2.1.2

2 years ago

2.1.1

2 years ago

2.1.0

2 years ago

1.45.1

2 years ago

1.44.0

2 years ago

1.44.2

2 years ago

1.44.1

2 years ago

1.45.0

2 years ago

1.43.0

3 years ago

1.42.0

3 years ago

1.41.7

3 years ago

1.41.6

3 years ago

1.42.0-beta.0

3 years ago

1.41.5

3 years ago

1.41.3

3 years ago

1.41.4

3 years ago

1.41.1

3 years ago

1.41.0

3 years ago

1.41.2

3 years ago

1.40.0

3 years ago

1.39.7

3 years ago

1.39.6

3 years ago

1.39.5

3 years ago

1.39.4

3 years ago

1.39.3

3 years ago

1.39.1

3 years ago

1.39.2

3 years ago

1.39.0

3 years ago

1.38.2

3 years ago

1.38.1

3 years ago

1.38.0

3 years ago

1.37.1

3 years ago

1.37.0

3 years ago

1.36.1

3 years ago

1.36.0

4 years ago

1.35.1

4 years ago

1.35.0

4 years ago

1.34.2

4 years ago

1.34.1

4 years ago

1.34.0

4 years ago

1.33.5

4 years ago

1.33.4

4 years ago

1.33.3

4 years ago

1.33.2

4 years ago

1.33.1

4 years ago

1.33.0

4 years ago

1.32.2

4 years ago

1.32.1

4 years ago

1.32.0

4 years ago

1.31.4

4 years ago

1.31.3

4 years ago

1.31.2

4 years ago

1.31.1

4 years ago

1.31.0

4 years ago

1.30.0

4 years ago

1.29.0

4 years ago

1.28.0

4 years ago

1.27.1

4 years ago

1.27.0

4 years ago

1.26.3

4 years ago

1.26.2

4 years ago

1.26.1

4 years ago

1.26.0

4 years ago

1.25.0

4 years ago

1.22.2

4 years ago

1.23.2

4 years ago

1.24.2

4 years ago

1.24.1

4 years ago

1.24.0

4 years ago

1.23.1

4 years ago

1.23.0

4 years ago

1.22.1

4 years ago

1.22.0

4 years ago

1.21.0

4 years ago

1.20.1

4 years ago

1.20.0

4 years ago

1.19.6

4 years ago

1.18.1

4 years ago

1.17.2

4 years ago

1.19.5

4 years ago

1.19.4

4 years ago

1.19.3

4 years ago

1.19.3-rc.0

4 years ago

1.19.2

4 years ago

1.19.2-rc.0

4 years ago

1.19.1

4 years ago

1.19.0

4 years ago

1.18.0

5 years ago

1.17.1

5 years ago

1.17.0

5 years ago

1.16.2

5 years ago

1.16.1

5 years ago

1.16.0

5 years ago

1.15.0

5 years ago

1.14.3

5 years ago

1.14.2

5 years ago

1.14.1

5 years ago

1.14.0

5 years ago

1.13.7

5 years ago

1.13.6

5 years ago

1.13.5

5 years ago

1.13.4

5 years ago

1.13.3

5 years ago

1.13.2

5 years ago

1.13.1

5 years ago

1.13.0

5 years ago

1.12.0

5 years ago

1.11.0

5 years ago

1.10.0

5 years ago

1.9.2

5 years ago

1.9.1

5 years ago

1.9.0

5 years ago

1.9.0-rc1

5 years ago

1.0.2

6 years ago

0.1.7

6 years ago

1.0.1

6 years ago

1.0.0

6 years ago

0.1.6

6 years ago

0.1.5

6 years ago

0.1.4

6 years ago

0.1.3

6 years ago

0.1.2

6 years ago

0.1.1

6 years ago