Customer SDK
Introduction
LiveChat Customer SDK is a set of tools that helps you build a custom chat widget. Under the hood, it makes use of the LiveChat Customer Chat API. Customer SDK lets you communicate with LiveChat services directly from the browser environment using JavaScript without the need to develop your backend.
Is it for me?
If you need to customize the LiveChat Widget, using LiveChat Customer SDK is one of the options to do this. If you need a fully customizable solution and you feel brave, dive into LiveChat Customer SDK. We provide methods and events for deep integration with the LiveChat environment.
Keep in mind that interacting with this API requires some development skills.
Customer SDK allows you to create frontend apps, so if you're looking for server-side solutions, you should explore the LiveChat Customer Chat API instead. If you want to dive deeper into the LiveChat Platform, you might find the Platform Overview article handy.
Limitations
If a customer is chatting from a custom widget, private messages will not be available for agents.
About LiveChat Customer SDK
We provide an asynchronous API. Most methods return a Promise
. You can subscribe to the emitted events with the on
and off
methods.
Not familiar with promises? Read this article to learn more.
We authenticate your sessions with the use of
customer-auth package
and expose the created auth
object to the returned SDK instance. In general,
you don't have to worry about it or use the exposed object. If you need to
get the authentication token, you can get it through the SDK like this:
customerSDK.auth.getToken().then(token => {
console.log(token)
})
Questions
If you have any questions, you can start a chat with our 24/7 Support.
How to start
This tutorial is here to help you get started with LiveChat Customer SDK.
Create an application
First, you need to create an application in
Developer Console (select the Web app (frontend,
e.g. JavaScript) type). Then, you will have to give it the access to the customers:own
scope and the correct URI to the Redirect URI whitelist
.
Install Customer SDK
You can use the LiveChat Customer SDK in two different ways:
Using npm
npm install --save @livechat/customer-sdk
Import the SDK in your code:
import * as CustomerSDK from '@livechat/customer-sdk'
Or use the node-style require
call:
const CustomerSDK = require('@livechat/customer-sdk')
Using a script tag - UMD module hosted on unpkg's CDN
<script src="https://unpkg.com/@livechat/customer-sdk@3.1.2"></script>
If you just want to look around and play with the SDK, check out our sample chat widget implementation.
For the time being you need to register your application in the Developers Console
as a "Web app (frontend, eg. JavaScript)" type. Then, you have to pass the configured redirectUri
to the init
, along with the regular required properties (organizationId
and clientId
).
Using the API
To use the API you will first need to create an instance using the init
function.
You will need to provide your organizationId and clientId when creating a Customer SDK instance.
Other optional configuration parameters are also available:
parameters | type | default | description |
---|---|---|---|
organizationId | string | Your Organization ID, you receive this value when creating a new LiveChat account. | |
clientId | string | Your client id, you receive this value when you register your application in the LiveChat Developer Console. | |
autoConnect | boolean | true | Optional; decides whether the SDK should reconnect on its own. |
groupId | number | Optional; the id of the group you wish to connect to. | |
uniqueGroups | boolean | false | Optional; by default, the customer identity is the same for all groups. If you want to create a separate customer identity for each group, set this parameter to true . When set to true , passing a groupId is required. |
region | 'dal' | 'fra' | 'dal' | Optional; the server region your license is at. |
redirectUri | string | Optional; should only be used inside ReactNative, this is the URI which your webview is redirected to after authorization. | |
customerDataProvider | () => CustomerData | Optional; should only be used if you need to send customer data during login. In general, updateCustomer() should be prefered for sending customer data. | |
identityProvider | () => CustomerAuth | Optional; allows for providing own instance of the CustomerAuth object which contains the customer access token handlers. See Custom Identity Provider for more information. | |
page | object | Optional; customer page information. | |
page.url | string | Optional; customer page url. | |
page.title | string | Optional; customer page title. | |
referrer | string | Optional; page referrer. |
CustomerData:
parameters | type | description |
---|---|---|
name | string | Optional |
string | Optional | |
sessionFields | object | Key: value pairs |
CustomerAuth:
parameters | type | description |
---|---|---|
getFreshToken | () => Promise<Token> | Should resolve with freshly requested customer access token. |
getToken | () => Promise<Token> | Should resolve with currently stored customer access token. |
hasToken | () => Promise<boolean> | Should resolve with a boolean value representing if a token has been already acquired. |
invalidate | () => Promise<void> | Should handle token invalidation and/or clearing the locally cached value. |
The init
function will return a Customer SDK instance:
const customerSDK = CustomerSDK.init({
organizationId: ORGANIZATION_ID,
clientId: CLIENT_ID,
})
With customerSDK
, you can attach events:
customerSDK.on('new_event', newEvent => {
console.log(newEvent)
})
Or execute methods:
const chatId = 'OU0V0P0OWT'
customerSDK
.sendEvent({
chatId,
event: {
type: 'message',
text: 'Hi!',
},
})
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
Key Concepts
The LiveChat system includes four basic types of entities - users, chats, threads, and events.
- Chats consist of threads and threads consist of events.
- Threads are parts of chats.
- Users can add events to chats, which then are automatically added to threads.
- Users can participate in many chats at the same time.
Threads are a vital part of the LiveChat architecture. Grouping events in threads allows us to provide the continuous chat experience (i.e. the Customer always has the option to continue the conversation) while still maintaining smaller, logical chunks of events (e.g. for reporting and caching purposes). Handling operations such as loading archival events from the chat history can be challenging, but you won't have to worry about managing threads most of the time. Customer SDK provides wrappers for common tasks and most methods expect to receive chat IDs. You will only get notified about thread metadata if you explicitly ask for it.
You can read more about key concepts of the LiveChat messaging in the Messaging Overview.
User
Agent
{
id: 'ed9d4095-45d6-428d-5093-f8ec7f1f81b9',
type: 'agent',
name: 'Jane Doe',
jobTitle: 'Agent',
avatar: 'https://cdn.livechat-files.com/api/file/avatar.png',
}
Customer
{
id: 'ed9d0195-45d6-428d-5093-f8ec7f1471b9',
type: 'customer',
name: 'Jon Doe',
avatar: 'https://cdn.livechat-files.com/api/file/avatar.png',
fields: {
custom_property: 'BasketValue=10usd',
}
}
Chat
{
id: 'OU0V0P0OWT',
users: [{
id: 'ed9d4095-45d6-428d-5093-f8ec7f1f81b9',
// ... more user properties
}],
lastSeenTimestamps: {
'ed9d4095-45d6-428d-5093-f8ec7f1f81b9': 1503062591000, // might be null
},
threads: ['OU0V0U3IMN'],
}
Event
{
type: 'message',
text: 'hi!',
author: 'ed9d4095-45d6-428d-5093-f8ec7f1f81b9', // assigned by server
id: 'OU0V0U3IMN_1', // assigned by server
timestamp: 1503062591000, // assigned by server
customId: '814.3316641404942', // optional
thread: 'OU0V4R0OXP',
properties: {},
}
Threads
{
id: 'OU0V0U3IMN',
active: true,
order: 3,
users: ['ed9d4095-45d6-428d-5093-f8ec7f1f81b9'],
lastSeenTimestamps: {
'ed9d4095-45d6-428d-5093-f8ec7f1f81b9': 1503062591000, // might be null
},
events: [ /* events */ ],
}
Methods
acceptGreeting
You can use this method to inform that a Customer has seen a greeting. Based on that, the Reports section displays only the greetings seen by Customers instead of all the sent greetings. If a Customer started a chat from a greeting but you didn't execute acceptGreeting
method, the greeting counts as seen in Reports anyway.
As arguments to this method you should use uniqueId
& greetingId
received in the incoming_greeting
or connected
event.
customerSDK
.acceptGreeting({
greetingId: 7,
uniqueId: 'Q10X0W041P',
})
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
Parameters:
parameters | type |
---|---|
greetingId | number |
uniqueId | string |
Errors
GREETING_NOT_FOUND
- a givenuniqueId
couldn't be found on the server
cancelGreeting
Cancels a greeting (an invitation to the chat). For example, Customers could cancel greetings by clicking close icon on the displayed greeting.
customerSDK
.cancelGreeting({
uniqueId: 'Q10X0W041P',
})
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
Parameters:
parameters | type |
---|---|
uniqueId | string |
Errors
GREETING_NOT_FOUND
- givenuniqueId
could not be found on the server
cancelRate
Cancels rate-related thread properties.
customerSDK
.cancelRate({
chatId: 'ON0X0R0L67',
properties: ['score', 'comment'],
})
.then(response => {
console.log(response)
})
.catch(() => {
console.log(error)
})
Errors
MISSING_CHAT_THREAD
- the targeted chat is empty and has no threads.
connect
Starts the connection process to our servers. It is needed when:
- The
autoConnect: false
argument has been passed to theinit
method.
const customerSDK = CustomerSDK.init({
organizationId: ORGANIZATION_ID,
clientId: CLIENT_ID,
autoConnect: false,
})
/* later in the code... */
customerSDK.connect()
- You get disconnected for a reason that suspends reconnection attempts (e.g.
inactivity_timeout
).
customerSDK.on('disconnected', ({ reason }) => {
if (reason === 'inactivity_timeout') {
customerSDK.connect()
}
})
deactivateChat
customerSDK
.deactivateChat({ id: 'ON0X0R0L67' })
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
Parameters:
parameters | type | description |
---|---|---|
id | string | Chat ID in which thread should get closed |
Returned value:
properties | type |
---|---|
success | boolean |
deleteChatProperties
Deletes given chat properties.
customerSDK
.deleteChatProperties({
id: 'ON0X0R0L67',
properties: {
property_namespace: ['sample'],
},
})
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
Parameters:
parameters | type | description |
---|---|---|
id | string | ID of the chat whose properties you want to delete. |
properties | object | Chat properties to delete |
Returned value:
properties | type |
---|---|
success | boolean |
deleteEventProperties
Deletes given event properties.
customerSDK
.deleteEventProperties({
chatId: 'ON0X0R0L67',
threadId: 'OS0C0W0Z1B',
eventId: 'Q50W0A0P0Y',
properties: {
property_namespace: ['sample'],
},
})
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
Parameters:
parameters | type | description |
---|---|---|
chatId | string | ID of the chat whose properties you want to delete. |
threadId | string | ID of the thread whose properties you want to delete. |
eventId | string | ID of the event whose properties you want to delete. |
properties | object | Properties to delete |
Returned value:
properties | type |
---|---|
success | boolean |
deleteThreadProperties
Deletes given chat thread properties.
customerSDK
.deleteThreadProperties({
chatId: 'ON0X0R0L67',
threadId: 'OS0C0W0Z1B',
properties: {
property_namespace: ['sample'],
},
})
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
Parameters:
parameters | type | description |
---|---|---|
chatId | string | ID of the chat whose properties you want to delete. |
threadId | string | ID of the thread whose properties you want to delete. |
properties | object | Properties to delete |
Returned value:
properties | type |
---|---|
success | boolean |
destroy
Clears any stored resources, removes all listeners, and disconnects from the network. After using this method, you won't be able to use the destroyed Customer SDK instance.
customerSDK.destroy()
disconnect
Disconnects from the server.
customerSDK.disconnect()
getChat
Returns the chat data about the requested chat ID together with a single thread's data. If the method is called with the threadId
parameter, then this particular thread is being returned. If no threadId
is given, the latest thread is automatically returned.
customerSDK
.getChat({
chatId: 'ON0X0R0L67',
})
.then(chat => {
const { id, access, users, properties, thread } = chat
console.log({ id, access, users, properties, thread })
})
.catch(error => {
console.log(error)
})
Parameters:
parameters | type | description |
---|---|---|
chatId | string | |
threadId | string | optional |
Returned value:
properties | type | description |
---|---|---|
id | string | Chat ID |
access | object | Chat initial access |
users | object[] | Users objects referenced in the chat |
properties | object | Chat properties |
thread | object |
getChatHistory
Helps loading in historical thread events.
First, call getChatHistory
to access the history
object of a particular chat.
The returned history
object has only one method, next
, which gives you a Promise
with a { done, value }
object.
done
- indicates if there is anything more to loadvalue
- an object with an array of threads, each containing an array of its events
Then, you can keep calling history.next()
multiple times to load previous historical events. They're going to be grouped into threads and might require merging with already loaded events.
This is useful for implementing an infinite scroll or otherwise showing your Customer's archival chats.
Keep in mind, though, that you generally shouldn't call next
while the history is loading - we queue those requests, so the previous one must resolve before we proceed with the next one.
The structure such as our history
object is called an async iterator.
let wholeChatHistoryLoaded = false
const history = customerSDK.getChatHistory({ chatId: 'OU0V0P0OWT' })
history.next().then(result => {
if (result.done) {
wholeChatHistoryLoaded = true
}
const { threads } = result.value
const events = threads
.map(thread => thread.events || [])
.reduce((acc, current) => acc.concat(current), [])
console.log(events)
})
Parameters:
parameters | type | description |
---|---|---|
chatId | string | Chat ID of the requested history object |
getCustomer
Returns the info about the Customer requesting it.
customerSDK
.getCustomer()
.then(customer => {
console.log(customer)
})
.catch(error => {
console.log(error)
})
Returned value:
properties | type | description |
---|---|---|
type | 'customer' | |
id | string | |
name | string | Returned only if set |
string | Returned only if set | |
avatar | string | Returned only if set |
sessionFields | object | |
statistics | object | |
statistics.chatsCount | number | |
statistics.threadsCount | number | |
statistics.visitsCount | number | |
statistics.pageViewsCount | number | |
statistics.greetingsShownCount | number | |
statistics.greetingsAcceptedCount | number |
getForm
Allows you to fetch a form template for a given group and form type.
customerSDK
.getForm({
groupId: 0,
type: 'prechat',
})
.then(response => {
if (response.enabled) {
// prechat form is enabled for this group in the configurator
console.log(response.form)
}
})
.catch(error => {
console.log(error)
})
Parameters:
parameters | type |
---|---|
groupId | number |
type | 'prechat', 'postchat' or 'ticket' |
Returned value:
properties | type | description |
---|---|---|
enabled | boolean | |
form | object | Available only when a given form is enabled |
form.id | string | |
form.fields | object[] |
getPredictedAgent
customerSDK
.getPredictedAgent({
groupId: 0,
})
.then(agent => {
console.log(agent)
})
.catch(error => {
console.log(error)
})
Parameters:
parameters | type | description |
---|---|---|
groupId | number | Optional |
Returned value:
properties | type | description |
---|---|---|
agent | object | |
agent.id | string | |
agent.name | string | |
agent.jobTitle | string | |
agent.type | 'agent' | |
agent.isBot | boolean | |
queue | boolean | True when the current group has reached concurrent chat limit |
Errors
GROUP_OFFLINE
- the requested group is offline, and it was not possible to return a predicted Agent for it.GROUP_UNAVAILABLE
- thrown when manual routing is enabled for the group and a predicted Agent is requested for it. If you callstartChat
orresumeChat
accordingly, you'll end up in the queue.
getUrlInfo
It returns the info on a given URL.
customerSDK
.getUrlInfo({ url: 'https://www.livechat.com' })
.then(urlDetails => {
if (urlDetails.title) {
console.log(`The title of requested URL is: ${urlDetails.title}`)
}
if (urlDetails.description) {
console.log(
`The description of requested URL is: ${urlDetails.description}`,
)
}
if (urlDetails.imageUrl) {
console.log(
`The preview image of requested URL is available under: ${urlDetails.imageUrl}`,
)
if (urlDetails.imageWidth && urlDetails.imageHeight) {
console.log(`Its width is: ${urlDetails.imageWidth}`)
console.log(`Its height is: ${urlDetails.imageHeight}`)
}
}
})
.catch(error => {
console.log(error)
})
Parameters:
parameters | type |
---|---|
url | string |
Returned value:
properties | type | description |
---|---|---|
url | string | |
title | string | Optional |
description | string | Optional |
imageUrl | string | Optional |
imageWidth | number | Optional |
imageHeight | number | Optional |
off
Unsubscribes from emitted events, which are described here.
on
Subscribes to emitted events, which are described here.
once
Subscribes to emitted events, which are described here. Unsubscribes immediately after the callback gets called.
listChats
It returns summaries of the chats a Customer participated in.
customerSDK
.listChats({
pageId: 'MTU5MTEwMTUxNDM5NTk5OTpkZXNj',
limit: 10,
})
.then(({ chatsSummary, totalChats }) => {
console.log(chatsSummary)
console.log(totalChats)
})
.catch(error => {
console.log(error)
})
Parameters:
parameters | type | description |
---|---|---|
pageId | string | Optional; the cursor returned from the previous listChats calls |
limit | number | Optional; the limit of returned results. Default is set to 10 and maximum is 25 |
Returned value:
properties | type | description |
---|---|---|
chatsSummary | object[] | |
chatsSummary[].id | string | Chat ID |
chatsSummary[].active | boolean | |
chatsSummary[].users | object[] | Users objects referenced in the chat |
chatsSummary[].lastEvent | object | Event |
chatsSummary[].lastEventsPerType | object | Map of event types to event objects |
chatsSummary[].lastSeenTimestamps | object | Map of user IDs to optional lastSeenTimestamps |
chatsSummary[].lastThread | string | Thread ID |
totalChats | number |
listGroupStatuses
Returns availability statuses of the requested groups.
customerSDK
.listGroupStatuses({
groupIds: [3, 10],
})
.then(statusMap => {
console.log(`Status of the group 3: ${statusMap[3]}`)
console.log(`Status of the group 10: ${statusMap[10]}`)
})
.catch(error => {
console.log(error)
})
Parameters:
parameters | type | description |
---|---|---|
groupsIds | number[] | Optional; if omitted, statuses of all groups are returned. |
Returned value:
properties | type | description |
---|---|---|
statusMap | object | Map of group numbers to availability statuses |
listThreads
Returns a list of thread objects together with the previous and next page ID cursors that can be used to load more threads.
If you want to load consecutive events, consider using getChatHistory
.
customerSDK
.listThreads({
chatId: 'ON0X0R0L67',
})
.then(response => {
console.log(response.threads)
console.log(response.previousPageId)
console.log(response.nextPageId)
})
.catch(error => {
console.log(error)
})
Parameters:
parameters | type | description |
---|---|---|
chatId | string | |
pageId | string | Optional, the cursor returned from the previous listThreads calls |
sortOrder | 'desc' | 'asc' | Optional, default: 'desc' |
limit | number | Optional, default: 3, can't be used together with minEventsCount |
minEventsCount | number | Optional, can't be used together with limit |
Returned value:
properties | type | description |
---|---|---|
threads | object[] | |
threads[].id | string | Thread ID |
threads[].chatId | string | Chat ID |
threads[].active | boolean | Active state |
threads[].createdAt | string | Thread creation date in RFC 3339 date-time format |
threads[].userIds | string[] | User IDs |
threads[].events | object[] | Events |
threads[].properties | object | Chat properties |
threads[].access | object | |
threads[].queue | object | Optional |
threads[].queue.position | number | Current position in the queue |
threads[].queue.waitTime | number | Estimated waiting time for an agent to be assigned to the chat, in seconds |
threads[].queue.queuedAt | string | RFC 3339 date-time format |
previousPageId | string | |
nextPageId | string |
markEventsAsSeen
Marks events as seen by the current Customer up to the given date.
customerSDK
.markEventsAsSeen({
chatId: 'ON0X0R0L67',
seenUpTo: '2017-10-12T15:19:21.010200Z',
})
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
Parameters:
parameters | type | description |
---|---|---|
chatId | string | ID of the chat in which you want to mark events as seen. |
seenUpTo | string | RFC 3339 date-time format; you should use the event's createdAt value as the argument. |
Returned value:
properties | type |
---|---|
success | boolean |
rateChat
Sends chat rating and a comment for the most recent chat thread.
customerSDK
.rateChat({
chatId: 'ON0X0R0L67',
rating: {
score: 1,
comment: 'Agent helped me a lot!',
},
})
.then(() => {
console.log('Rating has been set')
})
.catch(error => {
console.log(error)
})
Parameters:
parameters | type | description |
---|---|---|
chatId | Destination chat ID | |
rating | ||
rating.score | 0 or 1 | Rating value: 0 for a bad rating and 1 for a good rating |
rating.comment | string | Optional comment |
Returned value:
properties | type |
---|---|
success | boolean |
Errors
MISSING_CHAT_THREAD
- the targeted chat cannot be rated because it has no threads.
resumeChat
Resumes an archived chat.
customerSDK
.resumeChat({
chat: {
id: 'OU0V0P0OWT',
thread: {
events: [],
},
},
})
.then(chat => {
console.log(chat)
})
.catch(error => {
console.log(error)
})
Parameters:
parameters | type | description |
---|---|---|
data.active | boolean | Optional; defaults to true but can be used to create threads that are immediately inactive |
data.continuous | boolean | Optional |
data.chat.id | string | |
data.chat.access | Access | Optional |
data.chat.properties | object | Optional, Default properties docs |
data.chat.thread.events | Event[] | Optional; you can pass initial events which will immediately become part of the created thread. |
data.chat.thread.properties | object | Optional, Default properties docs |
Errors
CHAT_ALREADY_ACTIVE
- the chat is already active and you can't activate it again.GROUPS_OFFLINE
- a group in the targeted chat is offline. It can happen for licenses without continuous chats enabled.
sendEvent
Sends a provided object as an event with a specified type.
const event = {
type: 'message',
// ... other properties specific for the event's type
}
customerSDK
.sendEvent({
chatId: 'ON0X0R0L67',
event,
})
.then(event => {
console.log(event)
})
.catch(error => {
console.log(error)
})
Parameters:
parameters | type | description |
---|---|---|
chatId | string | Destination chat ID |
event | ||
event.type | string | Type of the event; accepts only message, file, filled_form, system_message, and custom event types. |
attachToLastThread | boolean | Optional |
sendRichMessagePostback
Sends information to the server about a user's interaction with a rich message button.
customerSDK
.sendRichMessagePostback({
chatId: 'ON0X0R0L67',
threadId: 'OS0C0W0Z1B',
eventId: 'OS0C0W0Z1B01',
postback: {
id: 'OS0C0W0Z1B01002',
toggled: true,
},
})
.then(() => {
console.log('success')
})
.catch(error => {
console.log(error)
})
Parameters:
parameters | type | default | description |
---|---|---|---|
chatId | string | postback chat ID | |
threadId | string | postback thread ID | |
eventId | string | postback event ID | |
postback | |||
postback.id | string | Postback button ID | |
postback.toggled | boolean | true | Postback toggled |
setCustomerSessionFields
Sends the request to set customer's session fields. They are available for the duration of the session.
customerSDK.setCustomerSessionFields({
sessionFields: {
foo: 'bar',
test: 'qwerty',
},
})
Parameters:
parameters | type |
---|---|
sessionFields | object |
setSneakPeek
You can use it to update the sneak peek in the Agent App. It is sent to the server only if the target chat is active. This method doesn't return a promise.
customerSDK.setSneakPeek({
chatId: 'ON0X0R0L67',
sneakPeekText: 'what is the price for your ',
})
Parameters:
parameters | type | description |
---|---|---|
chatId | string | Target chat ID |
sneakPeekText | string | Message preview broadcasted to the Agent |
startChat
Starts a new chat. For one Customer, you can only start one chat.
In order to activate a previously started chat, use resumeChat
.
customerSDK
.startChat({
chat: {
thread: {
events: [],
},
},
})
.then(chat => {
console.log(chat)
})
.catch(error => {
console.log(error)
})
Parameters:
parameters | type | description |
---|---|---|
active | boolean | Optional, defaults to true but can be used to create threads that are immediately inactive |
continuous | boolean | Optional, starts chat as continuous (online group is not required); default: false. |
chat.access | access | Optional; chat access to set, default: all agents. |
chat.properties | object | Optional, default properties docs |
chat.thread.events | event[] | Optional; initial events that will immediately become a part of the created thread. |
chat.thread.properties | object | Optional, default properties docs |
Errors
CHAT_LIMIT_REACHED
- the maximum limit of chats per Customer has been reached, and it's not possible to start a new one. You should activate one of the existing chats. The limit is 1.GROUPS_OFFLINE
- a group in the target chat is offline. It can happen for licenses, which don't allow Customers to chat during their unavailability.
updateChatProperties
const properties = {
property_namespace: {
sample: 'property',
},
}
customerSDK
.updateChatProperties({ id: 'ON0X0R0L67', properties })
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
Parameters:
parameters | type | description |
---|---|---|
id | string | ID of the chat whose properties you want to update. |
properties | object | Default properties docs |
updateCustomer
Updates the specified Customer properties and fields.
const properties = {
name: 'John Doe',
email: 'john.doe@example.com',
sessionFields: {
custom_property: 'BasketValue=10usd',
any_key_is_ok: 'sample custom field',
},
}
customerSDK.updateCustomer(properties)
Parameters:
parameters | type | description |
---|---|---|
properties | ||
properties.name | string | Optional |
properties.email | string | Optional |
properties.sessionFields | object | Optional; custom fields with string values |
Errors
CUSTOMER_SESSION_FIELDS_LIMIT_REACHED
- total amount of session fields would have been exceeded after requested update
updateCustomerPage
Updates information about the Customer page using the provided page object.
const page = {
url: 'https://platform.text.com/',
title: 'LiveChat for Developers',
}
customerSDK.updateCustomerPage(page)
Parameters:
parameters | type |
---|---|
page | |
page.url | string |
page.title | string |
updateEventProperties
Updates given properties of an event.
const properties = {
property_namespace: {
sample: 'property',
},
}
customerSDK
.updateEventProperties({
chatId: 'ON0X0R0L67',
threadId: 'OS0C0W0Z1B',
eventId: 'Q50W0A0P0Y',
properties,
})
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
Parameters:
parameters | type | description |
---|---|---|
chatId | string | ID of the chat whose properties you want to update. |
threadId | string | ID of the thread whose properties you want to update. |
eventId | string | ID of the event whose properties you want to update. |
properties | object | Default properties docs |
updateThreadProperties
const properties = {
property_namespace: {
sample: 'property',
},
}
customerSDK
.updateThreadProperties({
chatId: 'ON0X0R0L67',
threadId: 'OS0C0W0Z1B',
properties,
})
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
Parameters:
parameters | type | description |
---|---|---|
chatId | string | ID of the chat whose properties you want to update. |
threadId | string | ID of the thread whose properties you want to update. |
properties | object | Default properties docs. |
uploadFile
Returns both a promise
and a cancel
. You can use cancel
to abort a file upload.
It also lets you pass the onProgress
callback function. Keep in mind that the maximum accepted file size is 10 MB.
It returns a URL that expires after 24 hours unless the URL is used in sendEvent
const { promise, cancel } = customerSDK.uploadFile({
file,
onProgress: progress => console.log(`upload progress: ${progress}`),
})
document.getElementById('cancel-upload').onclick = () => {
cancel()
}
promise
.then(response => {
console.log(response.url)
})
.catch(error => {
console.log(error)
})
Parameters:
parameters | type | description |
---|---|---|
file | blob | |
onProgress | function | Receives a progress value |
onProgress parameters:
parameters | type | min | max |
---|---|---|---|
progress | number | 0 | 1 |
Returned value:
properties | type |
---|---|
url | string |
In React Native, instead of passing a blob you need to pass an object of such a shape:
const file = {
uri: uriFromCameraRoll,
type: 'image/jpeg', // optional
name: 'photo.jpg', // optional
}
Events
You can listen for emitted events by subscribing to them using the on method with your custom callback. For example, your function can be executed every time a message is received.
Availability updated
Informs about a changed availability status.
customerSDK.on('availability_updated', ({ availability }) => {
console.log('availability_updated', availability)
})
Payload:
properties | type | description |
---|---|---|
availability | string | 'online' or 'offline' |
Chat deactivated
Informs that thread has been closed.
customerSDK.on('chat_deactivated', payload => {
const { chatId } = payload
console.log('chat_deactivated', { chatId })
})
Payload:
properties | type | description |
---|---|---|
chatId | string | Chat ID |
Chat properties deleted
Informs about deleted chat properties.
customerSDK.on('chat_properties_deleted', payload => {
const { chatId, properties } = payload
console.log('chat_properties_deleted', { chatId, properties })
})
Payload:
properties | type | description |
---|---|---|
chatId | string | Chat ID |
properties | object | Chat properties |
Chat properties updated
Informs about updated chat properties.
customerSDK.on('chat_properties_updated', payload => {
const { chatId, properties } = payload
console.log('chat_properties_updated', { chatId, properties })
})
Payload:
properties | type | description |
---|---|---|
chatId | string | Chat ID |
properties | object | Chat properties |
Chat transferred
Informs that a chat was transferred to a different group or an Agent.
customerSDK.on('chat_transferred', payload => {
const { chatId, threadId, transferredTo } = payload
console.log('chat_transferred', {
chatId,
threadId,
transferredTo,
})
})
Payload:
properties | type | description |
---|---|---|
chatId | string | |
threadId | string | |
reason | string | |
requesterId | string | returned only if reason is equal to 'manual' |
transferredTo | ||
transferredTo.agentIds | string[] | optional |
transferredTo.groupIds | number[] | optional |
queue | optional | |
queue.position | number | Current place in the queue |
queue.waitTime | number | Estimated waiting time for an agent to be assigned to the chat, in seconds |
queue.queuedAt | string | RFC 3339 date-time format |
Connected
Informs that the connection has been established.
customerSDK.on('connected', payload => {
const { customer, availability, greeting } = payload
console.log('connected', { customer, availability, greeting })
})
Payload:
argument | type | description |
---|---|---|
customer | object | Customer object, the same as the response from getCustomer |
availability | string | 'online' or 'offline' |
greeting | greeting | Optional greeting received before the thread started |
Greeting:
argument | type | description |
---|---|---|
id | number | Greeting template identifier |
text | string | Text content of the greeting message |
uniqueId | string | Unique event ID of the greeting |
displayedFirstTime | boolean | |
accepted | boolean | |
agent.id | string | |
agent.name | string | |
agent.avatar | string | |
agent.jobTitle | string | |
agent.isBot | boolean |
Connection recovered
Informs that Customer SDK has recovered from an "unstable" connection state. It's always preceded by the "connection_unstable"
event.
customerSDK.on('connection_recovered', () => {
console.log('connection_recovered')
})
This event doesn't carry any additional payload.
Connection unstable
Informs that Customer SDK has detected that connection quality is poor. It doesn't mean that it has disconnected from the server just yet.
customerSDK.on('connection_unstable', () => {
console.log('connection_unstable')
})
This event doesn't carry any additional payload.
Customer ID
Informs about the ID of the Customer.
customerSDK.on('customer_id', id => {
console.log('customer id is', id)
})
Payload:
argument | type |
---|---|
id | string |
Customer page updated
The Customer moved to another page, for example by following a link on your website.
customerSDK.on('customer_page_updated', payload => {
const { url, title, openedAt } = payload
console.log('customer_page_updated', { url, title, openedAt })
})
Payload:
properties | type | |
---|---|---|
url | string | URL of the Customer current website |
title | string | Title of the Customer current website |
openedAt | string | Date of the last update in RFC 3339 date-time format |
Customer updated
Informs that Customer's data was updated. Each property in payload is available only if it was updated.
customerSDK.on('customer_updated', customer => {
if (customer.name) {
console.log(`Name got updated to: ${customer.name}`)
}
if (customer.email) {
console.log(`Email got updated to: ${customer.email}`)
}
if (customer.avatar) {
console.log(`Avatar got updated to: ${customer.avatar}`)
}
if (customer.fields) {
console.log(`Fields got updated:`)
console.log(customer.fields)
}
})
Payload:
properties | type |
---|---|
name | string |
string | |
avatar | string |
fields | object |
Disconnected
Informs that SDK has disconnected from the server. The event provides the disconnection reason.
customerSDK.on('disconnected', payload => {
const { reason } = payload
console.log('disconnected', { reason })
})
Payload:
properties | type | description |
---|---|---|
reason | string | disconnection reasons |
Event properties deleted
Informs about the event properties that were deleted.
customerSDK.on('event_properties_deleted', payload => {
const { chatId, threadId, eventId, properties } = payload
console.log('event_properties_deleted', {
chatId,
threadId,
eventId,
properties,
})
})
Payload:
properties | type | description |
---|---|---|
chatId | string | Chat ID |
threadId | string | Thread ID |
eventId | string | Event ID |
properties | object | Event properties |
Event properties updated
Informs about the event properties that were updated.
customerSDK.on('event_properties_updated', payload => {
const { chatId, threadId, eventId, properties } = payload
console.log('event_properties_updated', {
chatId,
threadId,
eventId,
properties,
})
})
Payload:
properties | type | description |
---|---|---|
chatId | string | Chat ID |
threadId | string | Thread ID |
eventId | string | Event ID |
properties | object | Event properties |
Event updated
Informs that an event was updated.
customerSDK.on('event_updated', payload => {
const { chatId, threadId, event } = payload
console.log('event_updated', { chatId, threadId, event })
})
Payload:
properties | type | description |
---|---|---|
chatId | string | Chat ID |
threadId | string | Thread ID |
event | object | The entire updated event |
Events marked as seen
Informs that the events were seen by the particular user.
customerSDK.on('events_marked_as_seen', payload => {
const { chatId, userId, seenUpTo } = payload
console.log('events_marked_as_seen', { chatId, userId, seenUpTo })
})
Payload:
properties | type | description |
---|---|---|
chatId | string | Chat ID |
userId | string | User ID |
seenUpTo | string | RFC 3339 date-time format |
Greeting accepted
Informs about a greeting accepted by the Customer.
customerSDK.on('greeting_accepted', payload => {
console.log('greeting_accepted', payload.uniqueId)
})
Payload:
properties | type |
---|---|
uniqueId | string |
Greeting canceled
Informs about a greeting canceled by the Customer. It is also emitted when a new greeting automatically cancels the currently displayed one.
customerSDK.on('greeting_canceled', payload => {
console.log('greeting_canceled', payload.uniqueId)
})
Payload:
properties | type |
---|---|
uniqueId | string |
Incoming chat
Informs about a newly started chat thread. The payload contains the chat data structure and an object describing the new thread. If the chat was started with some initial events, they will be included in the thread object.
customerSDK.on('incoming_chat', payload => {
const { chat } = payload
const { id, access, users, properties, thread } = chat
console.log('incoming_chat', { id, access, users, properties, thread })
})
Payload:
properties | type | description |
---|---|---|
chat.id | string | Chat ID |
chat.access | object | Chat initial access |
chat.users | object[] | Users objects referenced in the chat |
chat.properties | object | Chat properties |
chat.thread | object |
Incoming event
Informs about an incoming event sent to a chat. You should distinguish received events by their types.
customerSDK.on('incoming_event', payload => {
const { chat, event } = payload
switch (event.type) {
case 'message':
console.log('new message - ', event.text)
break
default:
break
}
})
Payload:
properties | type | description |
---|---|---|
type | string | Event type |
... | Other properties |
Incoming greeting
Informs about an incoming greeting.
customerSDK.on('incoming_greeting', payload => {
const { text, agent } = payload
const { name } = agent
console.log(`Received a greeting with "${text}" text content from ${name}.`)
})
Payload:
properties | type | description |
---|---|---|
id | number | Greeting template ID |
text | string | Greeting text content |
uniqueId | string | Greeting unique ID |
displayedFirstTime | boolean | Describes if the greeting was generated for the first time. |
accepted | boolean | Chat properties |
agent | object | Agent user |
Incoming rich message postback
Informs about an incoming rich message postback.
customerSDK.on('incoming_rich_message_postback', payload => {
const { chatId, threadId, eventId, userId, postback } = payload
console.log('incoming_rich_message_postback', {
chatId,
threadId,
eventId,
userId,
postback,
})
})
Payload:
properties | type | description |
---|---|---|
chatId | string | Chat ID of the sent postback |
threadId | string | Thread ID of the sent postback |
eventId | string | Event ID of the sent postback |
userId | number | User who has sent a rich message postback |
postback.id | boolean | ID of the sent postback |
postback.toggled | boolean | Describes if the sent postback was toggled. |
Incoming typing indicator
Informs that one of the chat users is currently typing a message. The message hasn't been sent yet. The push payload contains the typing indicator object.
customerSDK.on('incoming_typing_indicator', payload => {
if (payload.typingIndicator.isTyping) {
console.log(
`user with ${payload.typingIndicator.authorId} id is writing something in ${payload.chatId}`,
)
} else {
console.log(
`user with ${payload.typingIndicator.authorId} id stopped writing in ${payload.chatId}`,
)
}
})
Payload:
properties | type | description |
---|---|---|
chatId | string | Chat ID |
typingIndicator | ||
typingIndicator.authorId | string | User ID |
typingIndicator.isTyping | boolean |
Queue position updated
Informs that the queue position has been updated.
customerSDK.on('queue_position_updated', payload => {
console.log(payload.chatId)
console.log(payload.threadId)
console.log(payload.queue.position)
console.log(payload.queue.waitTime)
})
Payload:
properties | type | description |
---|---|---|
chatId | string | Chat ID |
threadId | string | Thread ID |
queue | ||
queue.position | number | Current place in the queue |
queue.waitTime | number | Estimated waiting time for an agent to be assigned to the chat, in seconds |
Thread properties deleted
Informs about deleted thread properties.
customerSDK.on('thread_properties_deleted', payload => {
const { chatId, threadId, properties } = payload
console.log('thread_properties_deleted', { chatId, threadId, properties })
})
Payload:
properties | type | description |
---|---|---|
chatId | string | Chat ID |
threadId | string | Thread ID |
properties | object | Chat thread properties |
Thread properties updated
Informs about updated thread properties.
customerSDK.on('thread_properties_updated', payload => {
const { chatId, threadId, properties } = payload
console.log('thread_properties_updated', { chatId, threadId, properties })
})
Payload:
properties | type | description |
---|---|---|
chatId | string | Chat ID |
threadId | string | Thread ID |
properties | object | Thread properties |
User added to chat
Informs that a user was added to a chat.
customerSDK.on('user_added_to_chat', payload => {
const { chatId, user, present } = payload
console.log('user_added_to_chat', { chatId, user, present })
})
Payload:
properties | type | description |
---|---|---|
chatId | string | Chat ID |
user | object | User |
present | boolean |
User data
Contains the information about the User data.
customerSDK.on('user_data', user => {
console.log(user)
})
Customer user type:
properties | type | description |
---|---|---|
type | 'customer' | |
id | string | |
name | string | Optional |
string | Optional | |
avatar | string | Optional |
fields | customerFields |
Agent user type:
properties | type |
---|---|
type | 'agent' |
id | string |
name | string |
avatar | string |
jobTitle | string |
User removed from chat
Informs that a user was removed from a chat.
customerSDK.on('user_removed_from_chat', payload => {
const { chatId, userId } = payload
console.log('user_removed_from_chat', { chatId, userId })
})
Payload:
properties | type | description |
---|---|---|
chatId | string | Chat ID |
userId | string | User ID |
Disconnection reasons
Most of the disconnection reasons can be treated as errors. Because of that, you can find their detailed descriptions in this section.
customerSDK.on('disconnected', ({ reason }) => {
switch (reason) {
case 'access_token_expired':
// handle particular disconnection reasons
break
// ...
default:
}
})
Access token expired
Access token lifetime has elapsed. Customer SDK fetches a new token and reconnects to the server on its own. This is emitted to the user for informational purposes, so for example a reconnection bar can be displayed.
Connection lost
Disconnected because of the poor connection quality. Customer SDK will try to reconnect on its own.
Customer banned
The Customer has been banned.
This internally destroys the current instance of Customer SDK, so it won't be possible to reuse it.
Customer temporarily blocked
The Customer tried reconnecting too many times after the "too_many_connections"
error had occurred.
This internally destroys the current instance of Customer SDK, so it won't be possible to reuse it.
Identity mismatch
The identity of the Customer has changed between reconnects. This might happen if cookies can't be persisted in the browser.
This internally destroys the current instance of Customer SDK, so it won't be possible to reuse it.
Inactivity timeout
The Customer didn't chat or change the page in the past 30 minutes. Customer SDK won't try to reconnect on its own after receiving this error. You should implement a reconnect login on your own. Preferably you should only try to reconnect when you detect a clear intention of chatting from your user.
Internal error
Internal error. Customer SDK reconnects on its own.
License expired
The license with the specified ID has expired. You should make sure that there are no unpaid invoices for it.
License not found
The license with the specified ID doesn't exist. You should check the options passed in to Customer SDK and make sure that the license parameter is correct.
This internally destroys the current instance of Customer SDK, so it won't be possible to reuse it.
Misdirected connection
You have connected to a server in the wrong region. Customer SDK reconnects to the correct region on its own, but to avoid this problem altogether, you should provide the correct region
parameter when initializing the SDK. This is emitted to the user for informational purposes, so for example a reconnection bar can be displayed.
Too many connections
The Customer has reached the maximum number of connections. You should avoid opening too many concurrent connections for the same Customer.
This internally destroys the current instance of Customer SDK, so it won't be possible to reuse it.
Too many unauthorized connections
The maximum number of unauthorized connections has been reached. This error can only be received immediately after you try to connect to our servers when there are too many pending (unauthorized) connections. Once you get authorized, you stay that way and the Customer SDK reconnects on its own.
Unsupported version
Connecting to an unsupported version of the Customer Chat API. You should upgrade your Customer SDK version.
This internally destroys the current instance of Customer SDK, so it won't be possible to reuse it.
Users limit reached
The maximum number of Customers connected at the same time has been reached. This can only be received immediately after we try to connect to our servers, because once you get authorized, you stay that way. The limit is different for each plan, and you can check the exact values on our pricing page.
This internally disconnects from the current instance of the Customer SDK. After that, the manual connect()
call will be required, preferably linked to the user's action rather than automated.
Errors
This is the list of standard error codes. You can receive them for all available methods which perform API calls. It means the errors can occur for methods returning Promises. Because we wrap API calls with Promise interface, the errors are available on the thrown Error
objects under the code
property. They can be caught using a regular Promise catch
method.
There are also some per-method error codes, which are not described below. They are mentioned under corresponding methods instead.
Connection lost
All in-flight requests fail with this one when the network connection gets lost.
Customer banned
The Customer has been banned.
Group not found
Can be received in response to any request that accepts a group somewhere in its payload.
Internal
Internal error.
Pending requests limit reached
This is a rate-limiting error. You have sent out too many requests in a too short time period without waiting for them to resolve.
Request timeout
The request has timed out.
Service unavailable
The backend service is under heavy traffic and it had to restrict creation of a new resource.
Validation
Wrong format of request, for example a string
sent in the place of a number
.
Recipes
Chat transcript feature
To implement Chat transcript, you need to set the transcript_email
thread property in the routing
namespace. The value of this property should be set to the email address of the requester.
customerSDK
.updateThreadProperties({
chatId: 'ON0X0R0L67',
threadId: 'OS0C0W0Z1B',
properties: {
routing: {
transcript_email: 'john.doe@example.com',
},
},
})
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
Hard limit error handling
In order to handle hard limit error properly, you can listen for this specific disconnect reason and then react accordingly. In our case, we are showing simple information that our agents are not available at the moment.
customerSDK.on('disconnected', ({ reason }) => {
if (reason === 'users_limit_reached') {
console.log('Our agents are not available at the moment')
}
})
Changelog
[v4.0.2] - 2023-11-02
Added
- Extend init function types with page and referrer.
[v4.0.1] - 2023-09-19
Added
- Additional types and constants for better development experience.
Changed
Switched to using Customer API 3.5:
- Drop support for the
licenseId
parameter in theinit
method. It has been replaced by theorganizationId
.
Removed
sendTicketForm
method. As of June 1 2023 LiveChat tickets are handled by HelpDesk
[v3.1.2] - 2023-02-28
Fixed
- Fixed situations when a value for
urlDetails.imageUrl
available in thegetUrlInfo
method could sometimes return a URL with a duplicated protocol (like "https://https://...")
[v3.1.0] - 2021-10-7
Added
- New optional
config
propertyidentityProvider
, which allows for specifying own custom access token handlers. - Handle new event type
'form'
representing the optional custom forms sent from the server.
[v3.0.0] - 2021-05-25
Fixed
- Chat structures can now have
thread
set tonull
since it's possible for threads to be removed - Prevented additional connections to be created in the case when SDK gets destroyed in the middle of the
login
flow
Changed
- Switched to using Customer API 3.3:
activateChat
method has been renamed toresumeChat
.- In the
deactivateChat
method, thechat_id
parameter was renamed toid
. - In the
updateChatProperties
method, thechat_id
parameter was renamed toid
. - In the
deleteChatProperties
method, thechat_id
parameter was renamed toid
. - In the
getPredictedAgent
method, agent properties are grouped inagent
property and additionalqueue
parameter is returned. - In the
customer_page_updated
event thetimestamp
property has been replaced withopenedAt
. - In the
customer_updated
event customer data is no longer grouped in thecustomer
object but rather all properties are returned at the top level.
- The communication with the server is done now using WebSocket endpoint, without the SockJS overhead.
- Users limit handling changed from destroying the instance to disconnecting.
Added
active
parameter to thestartChat
&resumeChat
methods. It defaults totrue
but can be used to create threads that are immediately inactive.- Greetings can now have a
subtype
property. - Support for
alternative_text
image property in:- image attachments
- rich greetings
- rich messages
cancel
button type in rich messages.- Support for the events of type
"custom"
[v2.0.4] - 2020-10-28
Added
- Updated documentation.
[v2.0.3] - 2020-08-31
Fixed
- Fixed API compatibility issues that could cause misalignment in data shape.
[v2.0.2] - 2020-08-21
Fixed
- Updated the
@livechat/file-upload
dependency to resolve compatibility issues.
[v2.0.1] - 2020-06-24
Fixed
rateChat
andcancelRate
methods are updating properties of the correct thread now.
[v2.0.0] - 2020-06-22
Changed
- The iterator returned from
getChatHistory
no longer returnsusers
. User data needs to be obtained independently, for example by using thegetChat
method. listChats
no longer acceptsoffset
parameter. Instead, it now acceptspageId
to which you can provide a value ofpreviousPageId
ornextPageId
returned from the otherlistChats
calls.- Chat objects returned from
listChats
no longer have thelastThreadOrder
property, but they received a newlastThreadCreatedAt
property instead. - The
threads
objects no longer have theorder
property, but they received a newcreatedAt
property instead. - The
eventsSeenUpToMap
is no longer available on the thread object, it has been moved to chat objects. - The payload of the
chat_transferred
event was changed. It now always has thereason
property. It contains thequeue
property if the chat has been transferred and queued immediately.requesterId
is available whenreason
is equal to"manual"
.
Removed
- The
access_set
event has been removed.chat_transferred
event covers for its use cases. - The
getChatThreads
and thegetChatThreadsSummary
methods have been removed. Newly introducedlistThreads
can be used instead.
Added
- The
listThreads
andgetChat
methods have been added. - The thread objects gained back
userIds
property. - The thread objects got
previousThreadId
andnextThreadId
properties. - The
sendTicketForm
methods accepts a newtimeZone
parameter which influences how times are formatted in a generated ticket. - Queue objects got a new
queuedAt
property. This doesn't apply to the information returned inqueue_position_updated
event.
[v2.0.0-beta.2] - 2020-04-02
Changed
- Renamed methods:
closeThread
todeactivateChat
deleteChatThreadProperties
todeleteThreadProperties
getChatsSummary
tolistChats
getGroupsStatus
tolistGroupStatuses
getUrlDetails
togetUrlInfo
updateChatThreadProperties
toupdateThreadProperties
- Renamed events:
chat_thread_properties_deleted
tothread_properties_deleted
chat_thread_properties_updated
tothread_properties_updated
chat_user_added
touser_added_to_chat
chat_user_removed
touser_removed_from_chat
thread_closed
tochat_deactivated
chat_transferred
event doesn't containtype
andids
properties anymore. InsteadtransferredTo
property is available. It has optionalagentIds
andgroupIds
properties
Added
customer
data available in theconnected
callbackstatistics
property available on the Customer object returned from thegetCustomer
method
[v2.0.0-beta.1] - 2020-03-13
Fixed
- Updated the
@livechat/customer-auth
dependency, which has been previously published with broken dist files.
[v2.0.0-beta.0] - 2020-03-12
Changed
Most methods have been changed to accept parameters by name instead of by position. We found this pattern to be easier to read and maintain in the long run. As an example, a call that previously might have looked like this:
customerSDK.updateChatProperties('ON0X0R0L67', properties)
will now look like this:customerSDK.updateChatProperties({ chatId: 'ON0X0R0L67', properties })
. All methods and their respective parameters are described in the documentation.All data structures have been adjusted: Previously properties like
chat
orthread
could hold a primitive value (usually a string) because they actually contained IDs. This has been confusing and all such properties have been renamed to have anId
suffix now. For example:chat
was renamed tochatId
, andthread
was renamed tothreadId
.updateCustomer
method now returns a Promise. Additionally, customer data is not sent automatically in thelogin
request. If you still need to send customer data during thelogin
request, you will need to provide acustomerDataProvider
in the configuration passed in theinit
call. This provider will be called before sending anylogin
request.connected
event no longer contains any chat information. You should usegetChatsSummary
andgetChatHistory
appropriately to fetch it.getChatHistory
now returns an array of threads instead of an array of events.sendEvent
can no longer activate an existing chat. You should use theactivateChat
method for that purpose.new_event
event has been renamed toincoming_event
.customer_updated
doesn't provide the whole Customer object anymore. You will only receive the data that has actually been changed.Chat summary & incoming chat objects used to contain an array of user IDs. This has been changed to align with the API and you can now expect complete user objects in those objects.
getPredictedAgent
method requires a group argument now.updateLastSeenTimestamp
method has been changed tomarkEventsAsSeen
.sendPostback
method has been changed tosendRichMessagePostback
.
Removed
reconnected
event got removed. You should just use a singleconnected
handler for both initial connection and reconnets.thread_summary
event got removed.sendMessage
method has been removed. You can just usesendEvent
to send any of the supported types of events.user_is_typing
anduser_stopped_typing
events have been removed. You can useincoming_typing_indicator
to receive those informations - it comes with aisTyping
property.user_joined_chat
anduser_left_chat
events have been renamed tochat_user_added
andchat_user_removed
respectively.sendFile
method has been removed. You should use the newuploadFile
method instead.Events of type
"annotation"
don't exist anymore. They were only used for rating events and now those are automatically added to a chat upon rating in a form of system events.
Added
incoming_typing_indicator
event replaceduser_is_typing
anduser_stopped_typing
events.optional
queue
property has been added on thread objects.chat_user_added
andchat_user_removed
events replaceduser_joined_chat
anduser_left_chat
events respectively.getForm
andsendTicketForm
have been added.deleteChatProperties
,deleteChatThreadProperties
anddeleteEventProperties
methods have been added with accompanyingchat_properties_deleted
,chat_thread_properties_deleted
andevent_properties_deleted
events.acceptGreeting
andcancelGreeting
have been added with accompanyingincoming_greeting
,greeting_accepted
andgreeting_canceled
events.getCustomer
method has been added.setCustomerSessionFields
method has been added.cancelRate
method has been added.getGroupsStatus
method has been added.uploadFile
method has been added. It replacessendFile
and doesn't add an event of type"file"
to a chat but rather returns a URL which you can then use to send a"file"
event using thesendEvent
method.queue_position_updated
event has been added.availability_changed
event has been added.event_updated
event has been added.access_set
event has been added.chat_transferred
event has been added.connection_recovered
andconnection_unstable
have been added.All possible errors and disconnection reasons have been documented.
SDK automatically reconnects to the correct region, but it's advised to pass the correct region of your license explicitly to the
init
function.dal
is the default.Users of type
"agent"
got ajobTitle
property.Events of type
"file"
got aname
property.New types of rich message buttons have been added and some of them have additional properties. Buttons of type
"webview"
come with awebviewHeight
and buttons of type"url"
come with atarget
.connected
event payload has a newavailability
property.You can send custom system message events using
sendEvent
.
[v2.0.0-alpha.0] - 2018-08-17
Initial alpha release.