Learn more - Amazon Web Services

WebApp Integration SDK
Guide
Learn how to use our SDK
Overview
The SDK is a lightweight, client-side package for communicating with the Liveperson Agent
Workspace. Using the SDK, Agent Managers can add custom widgets to LiveEngage, which
makes it possible to integrate external web applications.
You can get/bind/unbind any data that can be found within the public model which is explained
below. You can also send commands to the Agent Workspace, such as a 'Write Chat Line'
command which sends text.
This article will help you develop an application which uses the SDK.
Main Features
• This SDK allows external applications to communicate with LivePerson.
• It allows you to populate chat lines in the chat window from information provided
•
•
•
•
elsewhere.
The Agent Workspace can receive updates on parameters as requested from the
application.
The chat transcript can be passed to the application during the chat or upon its
conclusion.
All attributes and parameters will be available through the SDK.
Integration.
Getting Started
To integrate the application you developed using the client-SDK follow these steps:
1. Reference the client-SDK.min.js file in your site's code.
o
o
o
o
For developers in a QA environment (updated manually) - reference the ClientSDK js file in QA
For developers in a CI environment (updated automatically) - reference the
Client-SDK js file in CI
For developers in the Alpha environment (updated manually) - reference the
Client-SDK js file in Alpha
For developers in GA environment (updated manually) - reference the ClientSDK js file in GA
2. In your LiveEngage account, define a new custom widget with the URL of your web
application (which uses the client-SDK). Learn more.
Limitations
1. The SDK will only communicate with LivePerson's Agent Workspace if the account has
configured an iFrame widget that refers to a web page which was developed using the
SDK.
2
2. The SDK only supports browsers which implement postMessage API and have native
JSON implementation (IE8+, Chrome, FF, Safari, Opera, IOS, Opera Mini, Android)
3. IE9-, FF & Opera Mini do not support MessageChannel and therefore the fallback is
using basic postMessage. This makes the communication open to any handler
registered for messages with the same origin.
4. When the browser does not support passing object using postMessage (IE8+, Opera
Mini), and no special serialize/deserialize methods are supplied, all data is serialized
using JSON.stringify/JSON.parse which means that Object data is limited to any JSON
which supports types like: strings, numbers, null, arrays, and objects (and does not
allow circular references). Trying to serialize other types, will result in conversion to null
(like Infinity or NaN) or to a string (Dates), that must be manually deserialized on the
other side
5. If the agent refreshes the iFrame widget - the page is reloaded from scratch. Any databindings that existed before refreshing are removed.
6. The application you are developing must be able to open within an iFrame: Some
applications prevent themselves from opening within an iFrame (these are known as
‘Frame Busters’).
7. The application must be hosted over SSL (the URL must begin with https)
8. Automatic focus management may be problematic: Applications with focus stealing can
cause issues in the user interface of the Agent Workspace.
How to Use the SDK
All public properties and methods can be found in the namespace lpTag.agentSDK.
Note: The project is called the client-SDK as it is the client-side of our SDK. However, since
you use it to communicate with the agent -the code you write acknowledges the fact that
you're communicating with the Agent Workspace.
Public Properties
•
•
•
•
•
v: The version of the service
name: The name of the service
appNames: Names of apps for communication with the agent
cmdNames: Names of commands for the agent
reqNames: Names of requests for the agents
Public Methods
• init: The method used to initialize the service and perform a handshake with the agent.
This can be provided with an optional callback for notifications.
3
• get: Gets data from the public model. The data that arrives in the callback is the data
•
•
•
•
from the mode. If no data can be found in the provided key - you will receive null.
bind: Binds to data in the public model. The data returns in the following structure {key:
'', newValue: {}} where the key is the location of the data within the public model,
and the newValue is the data update. When binding, you will first receive a callback with
existing data (if there is any), and then you will receive the updated current data. In
other words, if the data is an object or an array - you will receive the data that was
added. If the entire object/array is set - you will receive the entire object/array. For most
data - we set the entire object/array. For chat lines - we add the most recent lines only.
unbind: Unbinds from data in the public model. The provided key and callback must be
identical to those used to bind in order for the unbind operation to work.
command: Sends a command to the agent. Currently the only supported command is
'Write ChatLine', which writes text to the agent's chat input.
dispose: Disposes of the service. It is not mandatory to call this method.
Note: you should call init once at the beginning before calling any other method.
Public Model Structure
The structure of the Public Model is subject to change, and may vary in future versions. In
addition, data you are attempting to get/bind to may not be present, and so it is not guaranteed
that you will receive data.
{
chatInfo: {
rtSessionId: 1, // The real time session ID
accountId: '', // The account Id
chatRequestedTime: 1, // The time the chat was requested (the visitor clickedto-chat)
chatStartTime: 1, // The time the chat started
chatStartUrl: '', // The URL of the page where the visitor clicked-to-chat
spectatedEngagement: false, // True if the engagement is spectated (and the
agent logged in is not the chatting agent)
},
chattingAgentInfo: { // Information about the chatting agent (may not be the agent
which is currently logged in)
agentName: '', // The name of the agent
agentId: 1, // The ID of the agent
agentNickname: '' // The nickname of the agent
},
agentInfo: { // Information about the agent that is currently logged in (may not
be the chatting agent)
agentName: '', // The name of the agent
agentId: 1, // The ID of the agent
agentNickname: '', // The nickname of the agent
agentEmail: '', // The email of the agent
maxChats: 1, // The maximum number of chats the agent can be in
}
chatTranscript: {
lines: [] // Array of chat lines
4
},
surveyQuestions: {
preChat: {
email: {
value: '', // The email of the visitor, as entered in the pre-chat
survey
displayName: '' // The pre-chat survey question asking for the email
},
phone: {
value: '', // The phone number of the visitor, as entered in the prechat survey
displayName: '' // The pre-chat survey question asking for the phone
number
},
name: {
value: '', // The name of the visitor, as entered in the pre-chat
survey
displayName: '' // The pre-chat survey question asking for the name
},
customizedQuestions: [] // Array of pre-chat survey questions containing
'displayName' (the question) and 'value' (the answer)
},
postChat: [] // Array of post-chat survey questions containing 'displayName'
(the question) and 'value' (the answer)
agentSurvey: [] // Array of agent survey questions containing 'displayName'
(the question) and 'value' (the answer)
},
visitorInfo: {
visitorId: '', // The ID of the visitor
visitorName: '', // The visitor name
visitorSso: false, // Boolean indicating if the visitor used a single sign on.
Legacy accounts only.
device: '', // The device used by the visitor ('DESKTOP', 'TABLET' or
'MOBILE'). LE accounts only.
browser: '', // The browser used by the visitor
operatingSystem: '', //The operating system used by the visitor
country: '', // The country of the visitor
state: '', // The geographic state of the visitor
city: '', // The city of the visitor
isp: '', // The Internet Service Provider (ISP) of the visitor
organization: '', // The organization of the visitor
IpAddress: '', // The IP address of the visitor
visitStartTime: '', // The time the visitor entered the site
chattingVisitorState: '', // The chat-state of the visitor ('CHATTING',
'ENDED', etc.)
chatRequestedTime: '', // The time the visitor clicked-to-chat
chatStartUrl: '', // The URL of the page in which the visitor clicked to chat
visitorTimezone: '', // The timezone of the visitor
5
visitorTyping: false // Boolean indicating if the visitor is typing
},
campaignInfo: {
campaignName: '', // The campaign name
campaignId: '', // The campaign ID
campaignDescription: '', // The campaign description
targetAudience: '', // The target audience (visitor profile)
goalName: '', // The goal name
goalId: '', // The goal ID
goalDescription: '' // The goal description
},
engagementInfo: {
VisitorBehavior: '', // The visitor behavior
skill: '', // The chat skill
engagementType: '', // The engagement type
engagementId: '', // The engagement ID
agentNote: '' // The agent note
},
visitorJourney: {
pages: [], // Array of pages the visitor visited
searchEngine: {
searchProvider: '', // The search provider
searchKeywords: '' // The search keywords
}
},
SDE: {
customerDetails: {
customerStatus: '', // The customer's status
customerType: '', // The customer type
balance: 1, // The customer's balance
customerId: '', // The customer ID
lastPaymentDate: {
year: '', // The year of the last payment
month: '', // The month of the last payment
day: '' // The day of the last payment
},
registrationDate: {
year: '', // The registration year
month: '', // The registration month
day: '' // The registration day
}
},
personalInfo: {
name: '', // The first name of the customer
surname: '', // The surname of the customer
contacts: [], // Array of contact details, containing phone numbers and
emails
6
gender: '', // The gender of the customer
company: '', // The company where the customer works
customerAge: {
customerAgeInYears: '', // The customer's age
customerYearOfBirth: '', // The customer's year of birth
customerMonthOfBirth: '', // The customer's month of birth
customerDateOfBirth: '' // The customer's day of birth
}
},
marketingSource: [], // Array of marketing information
leadGeneration: [], // Array of lead generation information
transaction: [], // Array of transactions
viewedProducts: [], // Array of viewed products
shoppingCart: [], // Array of shopping cart updates
serviceActivity: [], // Array of service activity information
error: [] // Array of visitor errors
},
customVariables: [] // Array of custom variables
}
Some of the public model data specified above returns an object or an array of objects. We'll
now go over the structure of the objects/arrays that can be returned.
• chatTranscript.lines:
{
id: '', // The serial ID of the chat line
type: 'line', // Should always be 'line'
by: '', // The name of the visitor/agent who sent the line. Can also be 'info'
source: 'visitor', // Is the chat line from the 'visitor' or 'agent' or 'system'
subType: 'REGULAR', // May include other types of content in the future
systemMessageId: 1, // If it's a system message - this is the ID of the system
message; if not - this property doesn't exist
text: '', // Contains the text/HTML content of the chat line
textType: 'html', // Can be 'plain' for plain text or 'html' for html content; all
agent lines are HTML content
time: '' // String representation of the time the line was added
}
Note: unlike other arrays/objects - binding to the chat transcript lines will give you updates which
only include the recently added lines - not the entire array with all the lines from the beginning.
• surveyQuestions.preChat.customizedQuestions, surveyQuestions.postChat,
surveyQuestions.agentSurvey, customVariables:
7
{
@scope: 'session', // The scope of the survey question/custom variable; can have
values such as 'session' or 'visitor'
@source: 'rule engine', // The source of the survey question/custom variable; can
have values such as 'prechat', 'chat window', 'rule engine'
name: '', // The internal name of the survey question/custom variable - used by
the server as an ID
displayName: '', // The display name - usually identical to the name, but can be a
'prettier' version in some cases, for display purposes. For surveys - this is the
question text
time: '', // String representation of the time the survey question or custom
variable was added.
value: '' // The answer to the survey question or the value of the custom variable
}
• visitorJourney.pages:
{
id: '', // The ID of the page
pageBasic: {
referrer: '', // The URL of the referrer; can be null
sections: '', // The page sections; can be null
startTime: 1, // The start time in standard milliseconds
title: '', // The title of the page
url: '' // The URL of the page
},
pageLoaded: true, // True if the page has finished loading
pageTitle: '', // The title of the page
referrer: '', // The URL of the referrer; can be null
revActiveOSLs: { // Active on site locations
1234: { // The property name is the ID of the on site location
revision: 1 // The revision of the on site location
}
},
startTime: 1, // The start time in standard milliseconds
timeOnPage: 1, // The time (in seconds) the visitor has been on the page
url: '' // The URL of the page
}
Note: some of the parameters are duplicated within the 'pageBasic' object.
• SDE.personalInfo.contacts
8
{
email: '', // The email of the customer
phone: '' // The phone number of the customer
}
Note: the reason this is an array is that the customer can provide home contact info, work contact
info and other contact info.
• SDE.marketingSource
{
serverTimeStamp: 1, // The server time stamp in standard milliseconds
pageId: '', // Optional page ID
engagementId: '', // Optional engagement ID
originatingChannel: '', // The channel of the marketing data
affiliate: '', // The affiliate
campaignId: '' // The campaign ID
}
• SDE.leadGeneration
{
serverTimeStamp: 1, // The server time stamp in standard milliseconds
pageId: '', // Optional page ID
engagementId: '', // Optional engagement ID
leadId: '', // The ID of the lead; optional
topic: '', // The topic of the lead; optional
value: '' // The value of the lead; optional
}
• SDE.transaction
{
serverTimeStamp: 1, // The server time stamp in standard milliseconds
pageId: '', // Optional page ID
engagementId: '', // Optional engagement ID
total: '', // The total value of the transaction
orderId: 1 // The order ID
cart: {} // A shopping cart Object
}
• SDE.shoppingCart, SDE.transaction.[].cart:
9
{
serverTimeStamp: 1, // The server time stamp in standard milliseconds
pageId: '', // Optional page ID
engagementId: '', // Optional engagement ID
cartTotal: '', // The total value of the cart
numItems: 1, // The number of items in the cart
products: [] // Array of products, as in the viewedProducts SDE
}
• SDE.viewedProducts, SDE.transaction.[].products, SDE.shoppingCart.[].products
{
serverTimeStamp: 1, // The server time stamp in standard milliseconds
pageId: '', // Optional page ID
engagementId: '', // Optional engagement ID
products: [
// Array of products
{ // Each product has the following structure
name: '', // The product name
category: '', // The product category
sku: '', // The product SKU
price: '', // The price of the product
quantity: 1 // Where applicable - the number of identical items
}
]
}
• SDE.serviceActivity
{
serverTimeStamp: 1, // The server time stamp in standard milliseconds
pageId: '', // Optional page ID
engagementId: '', // Optional engagement ID
category: '', // The category of the service activity
id: '', // The ID of the service activity
status: '', // The status of the service activity
topic: '' // The topic of the service activity
}
• SDE.error
10
{
serverTimeStamp: 1, // The server time stamp in standard milliseconds
pageId: '', // Optional page ID
engagementId: '', // Optional engagement ID
contextId: '', // The context ID
message: '', // The error message
messageTooltip: '', // The error message tooltip (for display purposes)
code: '', // The error code
codeTooltip: '', // The error code tooltip (for display purposes)
level: '', // The error level
resolved: true // Is the error resolved
}
Usage Examples
init
var notificationHandler = function(data) {
// Do something with the notifications
};
lpTag.agentSDK.init({notificationCallback: notificationHandler});
Note: the notification callback is optional. Remember to call init once at the beginning, before
calling any other method.
get
var onSuccess = function(data) {
// Do something with the returning data
};
var onError = function(err) {
// Do something with the error
};
var pathToData = "visitorInfo.visitorName";
lpTag.agentSDK.get(pathToData, onSuccess, onError);
bind
11
var updateCallback = function(data) {
// Do something with the returning data
var path = data.key;
var value = data.newValue;
// called each time the value is updated; if there is an existing value when bind
is called - this callback will be called with the existing value
};
var notifyWhenDone = function(err) {
if (err) {
// Do something with the error
}
// called when the bind is completed successfully,
// or when the action terminated with an error
};
var pathToData = "visitorInfo.visitorName";
lpTag.agentSDK.bind(pathToData, updateCallback, notifyWhenDone);
Note: notifyWhenDone is an optional callback.
unbind
// Use the same callback for both bind and unbind
var updateCallback = function(data) {
// Do something with the returning data
var path = data.key;
var value = data.newValue;
// called each time the value is updated. If there's an existing value when bind
is called - this callback will be called with the existing value
};
var notifyWhenDone = function(err) {
if (err) {
// Do something with the error
}
// called when the unbind is completed successfully,
// or when the action terminated with an error
};
var pathToData = "visitorInfo.visitorName";
lpTag.agentSDK.unbind(pathToData, updateCallback, notifyWhenDone);
Note: The updateCallback must be the same callback provided for the bind. Note:
notifyWhenDone is an optional callback.
12
command
var notifyWhenDone = function(err) {
if (err) {
// Do something with the error
}
// called when the command is completed successfully,
// or when the action terminated with an error
};
var cmdName = lpTag.agentSDK.cmdNames.write; // = "Write ChatLine"
var data = {text: "Some text"};
lpTag.agentSDK.unbind(cmdName, data, notifyWhenDone);
Note: Currently the write (Write ChatLine) command is the only supported command. It writes the
text in the data to the chat input. Note: notifyWhenDone is an optional callback.
dispose
lpTag.agentSDK.dispose();
Note: you should only call dispose if & when you are completely done with the communication.
You're not required to call dispose.
Full flow
var name = '';
var location = '';
var triedCountry = false;
var notificationHandler = function(data) {
// Do something with the notifications
};
var notifyWhenDone = function(err) {
if (err) {
// Do something with the error
}
// called when the bind is completed successfully,
// or when the action terminated with an error
};
var updateCallback = function(data) {
// Do something with the returning data
var path = data.key;
var value = data.newValue;
13
// called each time the value is updated; if there is an existing value when bind
is called - this callback
// will be called with the existing value
if (path === 'visitorInfo.visitorName') {
lpTag.agentSDK.command(lpTag.agentSDK.cmdNames.write, {text: 'Hello ' + value
+ '!'}, notifyWhenDone);
if (location) {
lpTag.agentSDK.command(lpTag.agentSDK.cmdNames.write, {text: 'I see you
are from ' + location}, notifyWhenDone);
}
}
};
var onSuccess = function(data) {
// Do something with the returning data
location = data;
lpTag.agentSDK.bind('visitorInfo.visitorName', updateCallback, notifyWhenDone);
};
var onError = function(err) {
// Do something with the error
if (err) {
if (!triedCountry) {
triedCountry = true;
lpTag.agentSDK.get('country', onSuccess, onError);
} else {
lpTag.agentSDK.bind('visitorInfo.visitorName', updateCallback,
notifyWhenDone);
}
}
};
lpTag.agentSDK.init({notificationCallback: notificationHandler});
lpTag.agentSDK.get('city', onSuccess, onError);
14
This document, materials or presentation, whether offered online or presented in hard copy ("LivePerson Informational Tools") is for informational purposes only.
LIVEPERSON, INC. PROVIDES THESE LIVEPERSON INFORMATIONAL TOOLS "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT
NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
The LivePerson Informational Tools contain LivePerson proprietary and confidential materials. No part of the LivePerson Informational Tools may be modified,
altered, reproduced, stored in or introduced into a retrieval system, or transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or
otherwise), without the prior written permission of LivePerson, Inc., except as otherwise permitted by law. Prior to publication, reasonable effort was made to validate
this information. The LivePerson Information Tools may include technical inaccuracies or typographical errors. Actual savings or results achieved may be different
from those outlined in the LivePerson Informational Tools. The recipient shall not alter or remove any part of this statement.
Trademarks or service marks of LivePerson may not be used in any manner without LivePerson's express written consent. All other company and product names
mentioned are used only for identification purposes and may be trademarks or registered trademarks of their respective companies.
LivePerson shall not be liable for any direct, indirect, incidental, special, consequential or exemplary damages, including but not limited to, damages for loss of profits,
goodwill, use, data or other intangible losses resulting from the use or the inability to use the LivePerson Information Tools, including any information contained
herein.
© 2015 LivePerson, Inc. All rights reserved.
15