npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@bandyer/bandyer-chat-widget

v2.9.4

Published

Bandyer widget chat

Downloads

592

Readme

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.8.0/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

| Browser | min version | Plugin requested | | -------- | :---------: | :--------------: | | Chrome | 72 | | | Firefox | 66 | | | Safari | 12 | | | Edge new | 79 | |

Versions

The latest version is: 2.8.0 https://cdn.bandyer.com/sdk/js/chat/2.8.0/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

| Name | Type | Description | | ------- | :----: | ---------------------------------------- | | version | string | Return 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

| Parameter | Required | Default | Description | | -------------------- | :------: | :--------------------: | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | region | yes | | Region on witch your account belongs. Allowed parameters are eu, in, us or me | | environment | yes | | Allowed values are: sandbox or production | | appId | yes | | A valid appId associated to your account | | hidden | no | false | Configure the widget to start in hidden mode (not visible in the HTML) | | layout | no | default layout | Specify the custom layout (see more here) | | recordingType | no | '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 | | isAdmin | no | false | Specify 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 | | callType | no | audio_video | Specify the call type. Allowed values are: audio_only, audio_upgradable, audio_video | | mode | no | embed | Specify the widget call mode. Allowed values are: embed or window | | language | no | 'en' | Specify the language of the widget Allowed values are: en, it, es or pt | | userDetailsProvider | no | default user provider | Specify the data for each user (see more here) | | userDetailsFormatter | no | default user formatter | Specify how user data is formatted in the UI (see more here) | | tools | no | All tools disabled | Specify the tools to enable during the call (embed and window mode)(See more here) | | virtualBackground | no | false | It allows to publish the local webcam with blurred or the replaced background by default (embed and window mode). Allowed values are: blur or image | | feedback | no | false | Specify wether to show the view to leave a feedback at the end of the call |

Errors

| Name | description | | --------------------- | ------------------------------------------------------------------------------------------------- | | client_already_exists | A client exists already, you need to destroy the existing client before creating a new one | | invalid_config_error | One or more parameters have an incorrect type. See the message to know which ones | | browser_not_supported | The 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

| Name | Mode | Description | | -------------- | :------------: | :------------------------------------------------------------------------------------------------: | | chat | Window & Embed | Specify wether to initialize the chat module or not | | screen_sharing | Window & Embed | Enable the screen_sharing feature | | file_upload | Window & Embed | Enable the capability to send file | | whiteboard | Window | If true enable all the whiteboard tools. Can be an object of whiteboard tools | | snapshot | Window | Enable the snapshot feature | | live_edit | Window | Enable the live_edit feature | | live_pointer | Window | Enable 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:

| Combination | Receive live_edit | Collaborate | Snapshot & Gallery | Open 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

| Name | Description | | ----------- | :--------------------------------------------------------: | | wb_add_file | Allows to add files on the whiteboard | | wb_cursor | Allows to send the cursor events to the other participants | | wb_text | Allows to add text on the whiteboard | | wb_shape | Allows to add shape on the whiteboard | | wb_pen | Allows to using the pen on the whiteboard | | wb_eraser | Allows 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:

| Key | Options | Description | | --------------- | :-----------------------------------------------------: | --------------------------------------------------------- | | header | background, color | Specify the background and color of the header | | headerButton | background, color | Specify the background and color of the header buttons | | body | background, color | Specify the background and color of the body | | launcher | background | Specify the background of the launcher | | messageSent | background, color | Specify the background and color of the messages you sent | | messageReceived | background, color | Specify the background and color messages you received | | dial | background, color | Specify the background and color of the dial view | | call | background, color | Specify the background and color of the call view | | feedback | body: {background, color}, buttons: {background, color} | Specify the theme for the feedback view | | fontFamily | font Family | Font 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

| Name | Type | Description | | ------------ | :--------------------------: | ------------------------------------------------------------------ | | channelsView | channelView | Retrieve the list of channel view | | callView | CallView | Retrieve the current callView | | region | string | Retrieve the region value forwarded in the configuration step | | environment | string | Retrieve the environment value forwarded in the configuration step | | appId | string | Retrieve the appId value forwarded in the configuration step | | userId | string | Retrieve the userId value forwarded in the configuration step |

Events

| Name | Description | | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | | client:access_token:expired | The 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_expire | The session is about to expire, you need to provide a valid accesstoken through the updateAccessToken api | | client:force_disconnect | The user was disabled or deleted via REST api | | channel:message:sent | When a message was sent in a channel | | channel:message:received | When a message was received in a channel | | channel:added | When a channel was added using client api or rest | | channel:removed | When a channel was removed using client api or rest | | call:incoming | When there is an incoming call | | call:status:changed | Triggered when the call change the status. See call status | | user:status:changed | Triggered 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

| Parameter | Required | Default | Description | | ----------- | :------: | :-----: | ----------------------------------------------- | | userId | yes | | User that you want to authenticate | | accessToken | yes | | Access token corresponding to the user provided |

Errors

| Name | description | | ------------------------------ | ------------------------------------------------------------------------------------ | | sdk_version_invalid | If one or more parameter have an incorrect type, see the message to knows which ones | | sdk_version_unsupported | The browser is not supported, please check the compatibility table above | | app_id_invalid | The appId used in configuration step is invalid | | access_token_expired | The access token is expired, please retrieve a new one before retry the connection | | access_token_invalid | he access token is invalid, please check the token generation | | access_token_invalid_signature | The access token is compromised, please check the token generation | | access_token_invalid_user | The access token not belong to the userId forwarded in the connect method | | user_not_found | The 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

| Name | Type | Description | | ---- | :----: | ---------------------- | | url | string | Valid url for the call |

Errors

| Name | description | | ------------------- | ----------------------------------------------------------------------------------------- | | sdk_version_invalid | If one or more parameter have an incorrect type, see the message to knows which ones | | sdk_version_invalid | If one or more parameter have an incorrect type, see the message to knows which ones | | invalid_access_link | The access link is not a valid url | | invalid_access_link | The access link is not valid, the room is inactive or the user does not belong to the URL | | app_id_invalid | The appId used in configuration step is invalid | | user_not_found | The 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

| Parameter | Required | Default | Description | | ----------- | :------: | :-----: | ----------------------------------------------- | | accessToken | yes | | Access token corresponding to the user provided |

Errors

| Name | description | | ------------------------------ | ---------------------------------------------------------------------------------- | | access_token_expired | The access token is expired, please retrieve a new one before retry the connection | | access_token_invalid | he access token is invalid, please check the token generation | | access_token_invalid_signature | The access token is compromised, please check the token generation | | access_token_invalid_user | The 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

| Name | Type | Description | | ------ | :----: | ------------------------------- | | userId | String | User that you want to chat with |

Errors

| Name | description | | -------------------- | ----------------------------------------------------------------------------------------- | | validation_error | One of the arguments is invalid or the chat module is not initialized | | authentication_error | The Client is not authenticated | | create_channel_oto | An 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

| Name | Type | Description | | ------ | :----: | ------------------------------------------------------ | | userId | String | Other participants of the chat that you want to remove |

Errors

| Name | description | | -------------------- | --------------------------------------------------------------------------------------- | | validation_error | One of the arguments is invalid or the chat module is not initialized | | authentication_error | The Client is not authenticated | | delete_channel | An 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

| Name | Type | Description | | ------ | :----: | ------------------------------------------------------ | | userId | String | Other participants of the chat that you want to remove |

Errors

| Name | description | | ----------------- | --------------------------------------------------------------------- | | validation_error | One of the arguments is invalid or the chat module is not initialized | | channel_not_found | The 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

| Name | Type | Description | | ------------ | :------: | ---------------------------------------------------------------------------- | | participants | string[] | List of users with whom you want to start a call (at most one at the moment) | | options | Object | Call options |

Options

| Name | Default | Type | Description | | ------------- | ----------------------- | :-----: | ----------------------------------------------------------- | | callType | inherit from the config | string | Can be 'audio_only', 'audio_upgradable', 'audio_video' | | recording | inherit from the config | boolean | Allow to define if the call start with recording | | recordingType | inherit from the config | string | Can be 'manual' or 'automatic' | | isAdmin | inherit from the config | boolean | Allow 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

| Name | description | | -------------------------- | ----------------------------------------------------------------------------- | | validation_error | One of the arguments is invalid | | another_call_in_progress | The user is already in call | | current_user_not_available | The connected user is in disconnection phase | | current_user_busy | The connect user is busy on another device | | all_users_busy | All the users are busy | | no_plus_user | Should be at least one plus user in the call | | room_create_error | A generic error has occurred please check the error message to know the cause | | internal_server_error | A 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

| Name | Type | Description | | ---- | :----: | ---------------------- | | url | string | Valid url for the call |

Errors

| Name | description | | --------------------------- | ----------------------------------------------------------------------------- | | validation_error | One of the arguments is invalid | | another_call_in_progress | The user is already in call | | current_user_not_available | The connected user is in disconnection phase | | current_user_busy | The connect user is busy on another device | | all_users_busy | All the users are busy | | invalid_url | The given URL is invalid | | invalid_token | The call token is invalid or disabled | | user_not_associated_to_link | The user does not belong to the link | | join_url_mtm | At the moment the client does not support the many to many calls | | no_plus_user | Should be at least one plus user in the call | | room_create_error | A generic error has occurred please check the error message to know the cause | | internal_server_error | A 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
});

| Name | description | | --------------------- | ------------------------------------------------------------------------------- | | invalid_call_status | The call cannot be already in an ended status | | user_not_in_dialing | The other participants is in disconnection phase | | dial_stop_error | Generic dial stop error, please refer to the message in order to know the cause | | dial_decline_error | Generic dial stop error, please refer to the message in order to know the cause | | internal_server_error | A 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:

| Name | Type | Description | | -------- | :----------------------: | --------------------------------------------------------- | | textArea | String | Allow to get and set the textArea field on the channel UI | | channel | Channel | Retrieve 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

| Name | Type | Description | | -------------- | :------------------------: | ------------------------------------------------------------------ | | channelId | String | Retrieve the unique channelId, it can be use also in our rest apis | | participants | String[] | Retrieve the userIds of the participants | | unreadMessages | number | Retrieve the count of the unread messages | | messages | Message[] | Array of messages in the channel |

Events

| Name | Description | | --------------------- | ------------------------------------------------------------------------- | | channel:message:added | Notify 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

| Name | Type | Description | | -------------- | :------: | --------------------------------------------------------------------- | | messageToFetch | number | Number of messages to fetch | | anchor | String[] | Starting messageId from witch start to fetch | | direction | string | Use 'backwards' to retrieve past messages , use 'afterward' otherwise |

Errors

| Name | description | | -------------------- | ----------------------------------------------------------- | | channel_not_exists | When the request is performed after the channel was deleted | | message_anchor_error | Invalid 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

| Name | Type | Description | | ------- | :----: | ---------------------------------- | | message | string | text message that you want to send |

Errors

| Name | description | | ------------------ | ----------------------------------------------------------- | | channel_not_exists | When the request is performed after the channel was deleted | | message_not_saved | Error in storing the message, please retry |

Message type

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

Property

| Name | Type | Description | | ------------ | :----------------------: | -------------------------------- | | messageId | String | Retrieve the unique messageId | | channel | Channel | Retrieve the logical channel | | sender | string | UserId of the sender | | text | String | Text of the message | | creationDate | String(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

| Name | Type | Description | | ---- | :----------------: | ---------------------------------------------------- | | call | Call | Allow to retrieve the logical call | | tone | Object | Allow 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

| Name | Type | Description | | ---- | :------------------------------: | ----------------------------------- | | 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

| Name | Type | Description | | -------------- | :------------: | ---------------------------------------------------------------------------------------------------------------------------- | | roomId | String | RoomId of the call, can be used in out rest api to retrieve information | | options | Object | Contains call information about his initialization and status | | creationDate | string(ISO) | Creation date of the call | | participants | string[] | Array of userId that participate to the call | | direction | string | 'incoming' or 'outgoing' | | status | string | can be 'dialing', 'connecting' 'connected' or 'ended' | | recordingState | String | 'started' if the recording was started, 'stopped' otherwise | | endReason | string or null | Filled if the call is in the end state, should be 'declined', 'canceled', 'answered_of_another_device', 'hang_up', 'timeout' |

Options object

| Name | Type | Description | | ------------- | :----: | ------------------------------------------------------ | | callType | String | Can be 'audio_video', 'audio_upgradable', 'audio_only' | | recordingType | String | Can be 'none', 'automatic' or 'manual' | | live | String | If the call trigger the incoming call event or hook |

Events

| Name | Description | | ----------------------- | ---------------------------------------- | | status:changed | Triggered when a call change his status | | recording:state:changed | Triggered 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

| Name | description | | --------------------- | ------------------------------------------------------------------------------------------------- | | invalid_call_status | In order to answer a call, this one should have an incoming direction an must be in dialing state | | callee_not_available | The other participants is in disconnection phase | | dial_answer_error | Generic error, please refer to the message in order to know the cause | | internal_server_error | A 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 value | new value | change | | --------- | ------------- | ----------------------------------------------------------- | | record | recordingType | Parameter key | | tools | tools | Not specifying tools now means that the user will have none | | language | language | The 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();