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
© Copyright 2024