Agent App SDK
Introduction
Agent App Widgets are web applications loaded inside the LiveChat Agent App user interface. Read about their possible locations in the App locations guide. The Agent App SDK is currently the primary way to develop your own widgets and can be used in a basic or advanced way.
Use cases
Widgets are primary elements of the Agent App user interface. You can use them to:
- embed and display static content, for example, knowledge base articles, conversation prompts, or context information.
- embed your SaaS service or web app as part of the agents' workspace.
- query external services with visitor's email or LiveChat group ID (CRM, marketing automation, etc.).
- create a store with in-app purchases to sell additional services or features of your app.
- query LiveChat APIs to do basically anything with the visitor, agent, or chat.
Before you start
From a technical point of view, widgets are regular web applications. For that reason, you need to have some knowledge of HTML, CSS, and JavaScript to build your own widget.
Bear in mind that widgets are front-end elements of the LiveChat Agent App. If your intention is to build a server-side app, we encourage you to check out the Messaging APIs.
Getting started
Follow the intructions to create a basic LiveChat Widget. Before you start, make sure you have an account.
- Go to the Apps section in Developer Console.
- Click Create new app + and give your app a name.
- Decide which product you want to build your app for.
- Go to Building blocks and add a new LiveChat Widgets block.
- Enter the Widget source URL, which is the address of your application. If it's not ready yet, you can use our sample apps to play around.
- Choose the widget placement. It allows you to decide where exactly in the LiveChat App you want to display your integration. Currently, the possible locations are: the Details section, Message Box, App Settings, Fullscreen Apps (main menu). Read more about app locations.
- Additionally, you can configure your app's short decription and add an icon for better visibility in the LiveChat App. You can do that in the Display details tab.
- Go to the Private installation tab and install the app on your account.
After the successful installation, you'll see the widget in your LiveChat App.
Sample apps
If you'd like to experiment with some of the already existing apps, make sure to check out the repository we've prepared. Once installed, these widgets will be displayed in the right sidebar of the Agent App.
- Tag Master: allows user to create, view, and delete tags and canned responses in easy and predictable way.
- Progress: creates reports based on data from chats.
- Supervisor: helps to monitor the weekly progress of your agents, as well as their availability.
Installing the SDK
You can download the SDK directly from NPM as an ES6 or CommonJS module.
Install the SDK from NPM...
INSTALL THE SDK FORM NPM
npm install @livechat/agent-app-sdk
...then import the ES6 module...
IMPORT THE ES6 MODULE
import * as LiveChat from "@livechat/agent-app-sdk";
...or require the CommonJS.
REQUIRE THE COMMONJS
const LiveChat = require("@livechat/agent-app-sdk");
You can also use the UMD build of the SDK directly in the browser.
You can also use the UMD build:
USE UMD BUILD
<script src="https://unpkg.com/@livechat/agent-app-sdk@1.6.3/dist/agentapp.umd.min.js"></script>
<script>
LiveChat.createDetailsWidget().then(function(widget) {
// do something with widget
});
</script>
Basic use
The specific usage of the Agent App SDK depends on the type of widget you want to create. The currently available widget types are the following:
All widgets created with the Agent App SDK share a common interface, which lets you listen for the events happening in the Agent App.
Supposing that widget
is a widget instance:
function handleEvent(event) {
// perform logic when event happens,
// you can also use the data attached to the event
}
// Subscribe to event
widget.on("event", handleEvent);
// Unsubscribe from event
widget.off("event", handleEvent);
Each widget type offers a different set of events that you can listen for.
Details widgets
If you want to use your app in the Details section, you should use the createDetailsWidget
function. It returns a promise resolving to a details widget instance.
DETAILS WIDGETS
import { createDetailsWidget } from "@livechat/agent-app-sdk";
createDetailsWidget().then(widget => {
// build your logic around the widget
});
Events
customer_profile
Emitted when an agent opens a conversation within Chats or Archives, or when an agents selects the customer profile in the Customers sections. The handler will get the customer profile object as an argument.
Listen for the customer profile changes:
CUSTOMER_PROFILE
widget.on("customer_profile", profile => {
// read the new profile
});
The customer profile object will have the following shape:
Property | Description |
---|---|
id | Unique ID of a visitor |
name | Visitor name (if provided) |
email | Visitor email (if provided) |
chat | Object with three properties: chat_id (unique chat id), groupID (unique group id), and id (unique thread id); this object may be empty when a visitor is not currently chatting |
source | String representing the source of an event; possible values: chats , customers , archives |
geolocation | Object containing detailed information about customer's geolocation |
customVariables | Object containing custom variables for given customer/chat (if provided) |
customer_details_section_button_click
Emitted when you click a button located in a section in Customer Details. The handler gets the following payload:
Property | Description |
---|---|
buttonId | The id of the button taken from the section definition |
React to button clicks within Customer Details widgets
CUSTOMER_DETAILS_SECTION_BUTTON_CLICK
widget.on("customer_details_section_button_click", ({ buttonId }) => {
// perform an action when the button is clicked
});
Methods
Get the customer profile
If you want to access the current customer profile, you should use the getCustomerProfile
method.
Get the current customer profile
GET THE CURRENT CUSTOMER PROFILE
const profile = widget.getCustomerProfile();
The returned profile will be an object identical to the one emitted by the customer_profile
event. It can also be null
if no profile was recorded.
Append text to the message box
You can add any text to the current chat message box by using the putMessage
method. The method returns a promise.
Append text to the message box
APPEND TEXT TO THE MESSAGE BOX
widget.putMessage("this text will be appended").then(() => {
// the text should be appended now
});
Modify Customer Details widget's state
If you configured a Customer Details widget, you can modify its section state using the modifySection
method. The method accepts the section state definition as its only parameter, and returns a promise.
You can look up the component types to see how to create the state definition.
The title
of a given section has to match the one specified in the initial state. Otherwise, the section won't change. Also, the Agent App ignores the commands without valid section definitions. Make sure that the definition you're sending is correct.
Modify the Customer Details widget's state
MODIFY CUSTOMER DETAILS WIDGET STATE
widget
.modifySection({
title: "My widget",
components: [
{
type: "title",
data: {
value: "The title will be modified"
}
}
]
})
.then(() => {
// the widget should be modified now
});
MessageBox
The createMessageBoxWidget
function creates a widget instance to be used in MessageBox.
MESSAGEBOX
import { createMessageBoxWidget } from ‘@livechat/agent-app-sdk’;
createMessageBoxWidget().then(widget => {
// do something with the widget
});
Methods
Set a message to be stored by MessageBox
SET A MESSAGE TO BE STORED BY MESSAGEBOX
putMessage(msg: IRichMessage ): Promise<void>
Calling this method does not automatically send the message right away. The message is sent once an agent clicks the Send button. The message accepts the rich message type, which must implement the IRichMessage
interface.
Set a message to be stored by MessageBox
SET A MESSAGE TO BE STORED BY MESSAGEBOX
const richMessage = {
template_id: "cards",
elements: [
{
title: "My cat photo",
image: {
url: "https://example.org/imgs/john-the-cat.jpg"
}
}
]
};
widget.putMessage(richMessage);
Rich Message object format
custom_id
,properties
andelements
are optionalelements
may contain 1-10 element objects- all
elements
properties are optional:title
,subtitle
,image
, andbuttons
- property
url
onimage
is required - optional
image
properties:name
,content_type
,size
,width
, andheight
buttons
may contain 1-11 button objects (1-13 if using API version 3.3 and above)template_id
describes how the event should be presented in an appelements.buttons.postback_id
describes the action sent via thesend_rich_message_postback
method- multiple buttons (even from different elements) can contain the same
postback_id
; callingsend_rich_message_postback
with this id will add a user to all these buttons at once. elements.buttons.user_ids
describes users who sent the postback with"toggled": true
Fullscreen widgets
If you want to connect a Fullscreen widget to the LiveChat Agent App, you should use the createFullscreenWidget
function. It returns a promise resolving to a Fullscreen widget instance.
FULLSCREEN WIDGETS
import { createFullscreenWidget } from "@livechat/agent-app-sdk";
createFullscreenWidget().then(widget => {
// build your logic around the widget
});
Events
page_data
Emitted when the widget is initialized. The handler will get the main window page data object as an argument.
Listen for the page data changes:
PAGE_DATA
widget.on("page_data", pageData => {
// read the page data
});
Methods
Set notification badge
If you want to notify Agents there’s something important inside the widget, use the setNotificationBadge
method.
SET NOTIFICATION BADGE
widget.setNotificationBadge(26);
It displays a notification badge on top of your app’s icon:
If you want to remove the badge, invoke the method with the null
parameter.
REMOVE NOTIFICATION BADGE
widget.setNotificationBadge(null);
Make sure Agents can dismiss the notification to avoid cluttered UI.
Navigate to pathname
Navigates LiveChat App to a given pathname.
NAVIGATE TO PATHNAME
widget.navigate('/archives/?rate=rated_good');
Set Reports filters
Updates "Reports" section filters to a given filters
object.
SET REPORTS FILTERS
widget.setReportsFilters({ tag: ['chatbot'] });
Get page data
Gets the most recently recorded main window page data and returns the IPageData
object (identical to the one emitted by the page_data
event). If no data was recorded, it returns null
.
GET PAGE DATA
widget.getPageData();
Settings widgets
If you want to connect a Settings widget to the LiveChat App, you should use the createSettingsWidget
function. It returns a promise resolving to a Settings widget instance.
SETTINGS WIDGETS
import { createSettingsWidget } from "@livechat/agent-app-sdk";
createSettingsWidget().then(widget => {
// build your logic around the widget
});
Events
page_data
Emitted when the widget is initialized. The handler will get the main window page data object as an argument.
Listen for the page data changes:
PAGE_DATA
widget.on("page_data", pageData => {
// read the page data
});
Methods
Get page data
Gets the most recently recorded main window page data and returns the IPageData
object (identical to the one emitted by the page_data
event). If no data was recorded, it returns null
.
GET PAGE DATA
widget.getPageData();
Redirect
Redirects using the main window. Calling this method will send postMessage
to the LiveChat App, which will be handled there. After that, a redirect using a window object is performed.
REDIRECT
const target = 'https://example.com';
widget.redirect(target);
Advanced use
Developing your own widget
If you're building your own widget and you need to interact with the Agent App, be sure to use the Agent App SDK.
Accessing LiveChat data
You can leverage the OAuth 2.1 authorization flow to use all of LiveChat APIs. Head to Sign in with LiveChat docs for more information.
Layout and Styling
If you're using React, you can use the LiveChat Design System, which is a component library used directly in the LiveChat user interface.
Hosting the widget
You can host your widget locally or on a dedicated server. The hosted content has to be served over the HTTPS Protocol.
During development, you can use a self-signed certificate for localhost
or upload your widget to an SSL-enabled host. You can also leverage bundlers like Webpack to use an https-enabled development server.
If you need a quick way to deploy your widget, you can use Netlify Drop.
Creating a Customer Details widget
When developing an app in the Details section, you can add some content to the Customer Details view and display it as a widget. This way you turn it into a Customer Details widget.
Let's define the terms we use in this document:
- Section - an element of Customer Details. It contains a complete set of information grouped under a single widget.
- Component - a single line in a section. It can have one of the pre-defined formats and be filled with data from the app.
How to add a widget
To display a widget, first, you need to declare the initial state of a section. Go to Apps in Developer Console and create a new Details widget or update an exisiting one. The initial state of a section can be added using the Initial state
input.
Example of the initial state JSON:
{
"customerDetailsSections": [
{
"title": "Example section",
"components": [
{
"type": "button",
"data": {
"label": "Example button",
"id": "example-button"
}
}
]
}
]
}
You can define as many sections as you want. Once your widget is running within the Agent App, you can't add nor remove any sections. However, you can still modify the components within any section.
Also, the title
attribute in the section initial state acts as a section ID. You should not modify it.
How to update a section
You can control your widget and change its components using the Agent App SDK. Please refer to the Modify the Customer Details widget.
Component types
Here's the list of all the components you can use to build the Customer Details app.
Section
Section is a container for components.
Example of a section component
{
"title": "card with image",
"components": [],
"imgUrl": "https://www.gstatic.com/webp/gallery/4.jpg",
"openApp": true
}
Property | Required | Type |
---|---|---|
title | Yes | string |
components | Yes | array of components |
imgUrl | No | string |
openApp | No | boolean |
Title
Title could be used in several cases. Component look depends on the given data.
Example of a title component
{
"type": "title",
"data": {
"title": "title",
"value": "value",
"description": "description",
"imgUrl": "https://www.gstatic.com/webp/gallery/4.jpg"
}
}
Property | Required | Type | Note |
---|---|---|---|
title | Yes | string | |
value | No | string | |
description | No | string | |
imgUrl | No | string | |
imgSize | No | Value: "small" or "big" (default) | |
link | No | string | URL added when the title is a link |
id | No | string | ID passed to the widget on click |
clickable | No | boolean | Adds a border and makes it clickable |
openApp | No | boolean | Opens widget on click |
Button
Simple button component
Example of a button component
{
"type": "button",
"data": {
"id": "second-button",
"label": "second button",
"openApp": true,
"primary": true
}
}
Property | Required | Type | Description |
---|---|---|---|
id | Yes | string | |
label | Yes | string | |
openApp | No | boolean | Default value: false |
primary | No | boolean | Default value: false |
secondary | No | boolean | Default value: false |
Click events
You can listen for button clicks using the SDK. Note that buttonId
will be the same as the id
from the schema. If you want to capture a specific click, you need to make sure that the id
is unique across all definitions.
Label with value
Example of label with value component
{
"type": "label_value",
"data": {
"label": "Name",
"value": "Stefan",
"iconUrl": "https://www.gstatic.com/webp/gallery/4.jpg"
}
}
Property | Required | Type | Description |
---|---|---|---|
label | No | string | |
value | No | string | |
iconUrl | No | string | |
url | No | string |
Link
Example of a link component
{
"type": "link",
"data": {
"value": "click me",
"url": "http://google.com",
"inline": false
}
}
Property | Required | Type | Description |
---|---|---|---|
url | Yes | string | |
value | No | string | |
inline | No | boolean | default: true |
Line
Line could be used to separate section content. It has no components inside.
Example of a line component
{
"type": "line"
}
Customer
Renders a line with a customer's avatar, name, and email.
{
"type": "customer"
}
Tags
Renders a list of tags with an optional label.
{
"type": "tags",
"data": {
"tags": ["new", "important", "private"],
"label": "Tags:"
}
}
Property | Required | Type |
---|---|---|
tags | Yes | array of strings |
label | No | string |
Troubleshooting
There are errors in the console
Check out your browser's console to see if there are any of the errors listed below.
Error | Explanation |
---|---|
Mixed Content: The page at 'https://my.livechatinc.com/' was loaded over HTTPS, but requested an insecure resource '...'. This request has been blocked; the content must be served over HTTPS. | For security reasons the Agent App is served over HTTPS and so must be the extension. Learn more on why we need SSL-enabled address in MDN article about mixed content. |
Refused to display '...' in a frame because an ancestor violates the following Content Security Policy directive: "...". | The host that serves the plugin has specific Content Security Policy set up. |
Refused to display '...' in a frame because it set 'X-Frame-Options' to 'SAMEORIGIN'. | The host serving the content of the plugin has specific X-Frame-Options header set up. |
Contact us
If you have any feature requests related to the App Widgets, let us know! We're open to your insights and suggestions. Feel free to drop us an email at developers@text.com or join our community on Discord and ask us your questions there.