ECE ChatStatus API - V1 (PHP Version) - Legacy Version
Features
- Business Hours
- Open / Closed / Busy
- Busy based on:
- Min Agent Availability
- Max Queue Depth
- Max Wait Time
- Simple Proactive Chat - enable / disable & configurable timer
APIs used to achieve this functionality
ECE - liveSessionStatus - Display chat option based on queue depth and wait time
http://ucce-ece-db-12.lab2.purplepi.ie/system/egain/chat/entrypoint/liveSessionStatus/1001
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <sessionStatus xmlns:ns5="http://jabber.org/protocol/httpbind" xmlns:ns2="http://bindings.egain.com/chat" xmlns:ns4="jabber:client" xmlns:ns3="urn:ietf:params:xml:ns:xmpp-stanzas"> <ns2:waitTime>60.0</ns2:waitTime> <ns2:queueDepth>0</ns2:queueDepth> <ns2:altEngmtTime>0</ns2:altEngmtTime> </sessionStatus>
ECE - Agent Capacity
http://ucce-ece-db-12.lab2.purplepi.ie/system/egain/chat/entrypoint/capacity/1001
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <availableSlots xmlns:ns5="http://jabber.org/protocol/httpbind" xmlns:ns2="http://bindings.egain.com/chat" xmlns:ns4="jabber:client" xmlns:ns3="urn:ietf:params:xml:ns:xmpp-stanzas"> <ns2:count>3</ns2:count> </availableSlots>
CCE - Business Hours
https://ucce-hds-a.lab2.purplepi.ie/unifiedconfig/config/businesshour/5001
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <businessHour> <department> <refURL>/unifiedconfig/config/department/5000</refURL> <name>Department1</name> </department> <refURL>/unifiedconfig/config/businesshour/5001</refURL> <changeStamp>86</changeStamp> <configuredStatus> <status>2</status> <statusReason> <refURL>/unifiedconfig/config/businesshourstatusreason/5006</refURL> <reasonText>Open Override</reasonText> </statusReason> </configuredStatus> <description> </description> <name>Sales.Chat_0_1_6_120</name> <runTimeStatus>3</runTimeStatus> <runTimeStatusReason>Open Override</runTimeStatusReason> <specialDaySchedules> <specialDaySchedule> <refURL>/unifiedconfig/config/businesshour/5001/specialdayschedule/5000</refURL> <changeStamp>0</changeStamp> <date>18-03-2019</date> <description>St Pat Bank Holiday</description> <status>0</status> <statusReason> <refURL>/unifiedconfig/config/businesshourstatusreason/5001</refURL> <reasonText>Week Day closed reason</reasonText> </statusReason> </specialDaySchedule> </specialDaySchedules> <timezone> <refURL>/unifiedconfig/config/timezone/v2/5038</refURL> <displayName>(UTC+00:00) Dublin, Edinburgh, Lisbon, London</displayName> </timezone> <type>1</type> <weekDaySchedules> <weekDaySchedule> <refURL>/unifiedconfig/config/businesshour/5001/weekdayschedule/5011</refURL> <changeStamp>0</changeStamp> <endTime>17:00</endTime> <startTime>09:00</startTime> <dayOfWeek>1</dayOfWeek> </weekDaySchedule> <weekDaySchedule> <refURL>/unifiedconfig/config/businesshour/5001/weekdayschedule/5012</refURL> <changeStamp>0</changeStamp> <endTime>17:00</endTime> <startTime>09:00</startTime> <dayOfWeek>2</dayOfWeek> </weekDaySchedule> <weekDaySchedule> <refURL>/unifiedconfig/config/businesshour/5001/weekdayschedule/5013</refURL> <changeStamp>0</changeStamp> <endTime>17:00</endTime> <startTime>09:00</startTime> <dayOfWeek>3</dayOfWeek> </weekDaySchedule> <weekDaySchedule> <refURL>/unifiedconfig/config/businesshour/5001/weekdayschedule/5014</refURL> <changeStamp>0</changeStamp> <endTime>17:00</endTime> <startTime>09:00</startTime> <dayOfWeek>4</dayOfWeek> </weekDaySchedule> <weekDaySchedule> <refURL>/unifiedconfig/config/businesshour/5001/weekdayschedule/5015</refURL> <changeStamp>0</changeStamp> <endTime>17:00</endTime> <startTime>09:00</startTime> <dayOfWeek>5</dayOfWeek> </weekDaySchedule> </weekDaySchedules> </businessHour>
Disabling Chat Banner
Reference UCCE Chat User Admin - Page 111
Locate egainDockChat.UseCustomButton and egainDockChatIsChatLaunched and set the values to true and if you wish to allow the docked chat entry point to be initiated through a custom button or offer banner other than “Docked Chat”.
Chat Button Links
Example docked Chat JavaScript Function
<button onclick='egainDockChat.openHelp()'>Chat Now!</button>
Example Undocked Chat JavaScript Function
<button onclick="egainChat.openHelp()">Click to Chat!</button>
JavaScript - PHP File
Call the below PHP Code to set 3 JavaScript Variables, chatStatus, chatBusyReason and chatTimer by passing in the relevant ECE Chat Entry ID and Business Hours ID. and embed in your webpage that requires chat
Example HTML:
<!-- Custom PHP Javascript using Cisco ECE & CCE APIs to check opening hours - which returns variable 'chatStatus' Make sure to pass in a valid BusinessHour and Chat EntryPoint ID Example Response: var chatStatus = 'busy'; var chatBusyReason = 'MinAgentCount'; var chatTimer = '10000'; --> <script type="text/javascript" src="http://nas2.home.purplepi.ie/chat/demo-chat-api-lookups.php?chatEntryId=1001&businessHoursId=5001"></script> <!-- Custom Javascript in case PHP JavaScript does not return successfully--> <script> if (chatStatus == null) { var chatStatus = 'closed'; var chatTimer = '0'; var chatBusyReason = 'out of service'; } </script>
- demo-chat-api-lookups.php
<?php header('Content-Type: application/javascript'); // todo - check values of GET variables before setting them - and give them a default if not valid // Author: Gerry O'Rourke // Date: Feb 2019 // This is code created for a demo website and is not production ready. Update, secure and improve error handling if used on a a production website // Use at your own risk - provided for education purposes only $myChatEntryId = htmlspecialchars($_GET["chatEntryId"]); $myBusinessHoursId = htmlspecialchars($_GET["businessHoursId"]); $ccehostname = 'ucce-hds-a.lab2.purplepi.ie'; $ecehostname = 'ucce-ece-web.lab2.purplepi.ie'; $cceuser = '[email protected]'; $ccepass = 'mypassword'; $url = 'https://'.$ccehostname.'/unifiedconfig/config/businesshour/' . $myBusinessHoursId; $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_USERPWD,"$cceuser:$ccepass"); curl_setopt($ch, CURLOPT_HTTPGET, 1); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2); //connection timeout curl_setopt($ch, CURLOPT_TIMEOUT, 3); //timeout in seconds for transaction $output = curl_exec($ch); //echo $output."\n"; //$info = curl_getinfo($ch); //print_r($info); curl_close($ch); $xml=simplexml_load_string($output); //echo $xml; //print_r($xml); $bh_status=(int) $xml->runTimeStatus; $bh_name=$xml->name; //echo "name: $bh_name\n"; //echo "runTimeStatus: $bh_status\n"; //Parse BusinessHours Name for underscores $myvar = (explode("_",$bh_name)); $myProactiveChatTimer = $myvar[1]; $myMinAgentCount = $myvar[2]; $myMaxQueueDepth = $myvar[3]; $myMaxWaitTime = $myvar[4]; if ((empty($myProactiveChatTimer))||(!is_numeric($myProactiveChatTimer))) {$myProactiveChatTimer = '0';} if ((empty($myMinAgentCount))|| (!is_numeric($myMinAgentCount))) {$myMinAgentCount = '0';} if ((empty($myMaxQueueDepth))||(!is_numeric($myMaxQueueDepth))) {$myMaxQueueDepth = '5';} if ((empty($myMaxWaitTime))|| (!is_numeric($myMaxWaitTime))) {$myMaxWaitTime = '60';} $myProactiveChatTimer = $myProactiveChatTimer * 1000; //convert to ms //echo "\nmyProactiveChatTimer: ".$myProactiveChatTimer; //echo "\nmyMinAgentCount: ".$myMinAgentCount; //echo "\nmyMaxQueueDepth: ".$myMaxQueueDepth; //echo "\nmyMaxWaitTime: ".$myMaxWaitTime; //echo "\n\n"; //set open or closed based on runTimeStatus $chatStatus = 'closed'; if ($bh_status==1 or $bh_status==3){ $chatStatus = 'open'; // Capacity API - Checking Agents are available curl_reset($ch); $url = 'http://'.$ecehostname.'/system/egain/chat/entrypoint/capacity/' . $myChatEntryId; //echo $url."\n"; $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPGET, 1); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2); //connection timeout curl_setopt($ch, CURLOPT_TIMEOUT, 3); //timeout in seconds for transaction $capacity = curl_exec($ch); //$info = curl_getinfo($ch); //print_r($info); curl_close($ch); $xml_data = str_replace("ns2:","",$capacity); $xml_capacity=simplexml_load_string($xml_data); $agentcount=(int) $xml_capacity->count; if ($agentcount < $myMinAgentCount){ $chatStatus = 'busy'; $chatBusyReason = 'MinAgentCount'; } else { curl_reset($ch); $url = 'http://'.$ecehostname.'/system/egain/chat/entrypoint/liveSessionStatus/' . $myChatEntryId; $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPGET, 1); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2); //connection timeout curl_setopt($ch, CURLOPT_TIMEOUT, 3); //timeout in seconds for transaction $liveSessionStatus = curl_exec($ch); //$info = curl_getinfo($ch); //print_r($info); //curl_close($ch); $xml_data = str_replace("ns2:","",$liveSessionStatus); $xml_liveSessionStatus=simplexml_load_string($xml_data); $queueDepth=(int) $xml_liveSessionStatus->queueDepth; $waitTime=(int) $xml_liveSessionStatus->waitTime; if ($queueDepth>$myMaxQueueDepth){ $chatStatus = 'busy'; $chatBusyReason = 'MaxQueueDepth'; } if ($waitTime>$myMaxWaitTime){ $chatStatus = 'busy'; $chatBusyReason = 'MaxWaitTime'; } } } echo "var chatStatus = '$chatStatus';\n"; echo "var chatBusyReason = '$chatBusyReason';\n"; echo "var chatTimer = '$myProactiveChatTimer';\n"; echo "\nconsole.log('------- Demo API Lookups Start------');"; echo "\nconsole.log('Filename: " . basename(__FILE__) . "');"; echo "\nconsole.log('ChatEntryId: $myChatEntryId');"; echo "\nconsole.log('BusinessHoursId: $myBusinessHoursId');"; echo "\nconsole.log('chatStatus: $chatStatus');"; echo "\nconsole.log('chatTimer: $myProactiveChatTimer');"; echo "\nconsole.log('chatBusyReason: $chatBusyReason');"; echo "\nconsole.log('------- min / max queue values------');"; echo "\nconsole.log('minAgentCount: $myMinAgentCount');"; echo "\nconsole.log('maxQueueDepth: $myMaxQueueDepth');"; echo "\nconsole.log('maxWaitTime: $myMaxWaitTime');"; echo "\nconsole.log('------- current queuevalues------');"; echo "\nconsole.log('agentcount: $agentcount');"; echo "\nconsole.log('queueDepth: $queueDepth');"; echo "\nconsole.log('waitTime: $waitTime');"; echo "\nconsole.log('------- Demo API Lookups End------');"; ?> </php>
Example Dynamic JavaScript Code returned from above JavaScript API
var chatStatus = 'open'; var chatBusyReason = ''; var chatTimer = '10000';
Example JavaScript to hide / show the open / closed / busy html and show Proactive Chat
if (chatStatus == 'open'){ $('#mychatOn').show(); $('#mychatOff').hide(); $('#mychatBusy').hide(); //Proactive Chat setTimeout(function() { if (chatTimer != 0){ $('#chatModal').modal(); } }, chatTimer); } function disableProactiveChat() { window.chatTimer = 0; console.log('chatTimer: 0'); }
Sample HTML for Chat Button
This HTML as well as calling the ECE JavaScript function (egainChat.openHelp()) to open the ECE Chat , it also calls the custom function (disableProactiveChat()) to disable the Proactive Chat (so you don't get proactive chat popup after already starting a chat)
<div id="mychatOn" style="display: none"> <a onclick="disableProactiveChat();egainChat.openHelp();" href='javascript:void(0)'> <div class="vertical_list_pull-top verticalbuttonClass"> <div class="vertical_image_pull-top"> <img id="webchat-image" class="webchat-image" src="images/ready.png" title="Live Web Chat" alt="Live Web Chat"/> </div> <div class="vertical_title_pull-top">Live Web Chat</div> </div> </a> </div>
HTML for Proactive Chat
Note - uses Bootstrap CSS Modal for Popup - Reference
<!-- Modal --> <div class="modal fade" id="chatModal" tabindex="-1" role="dialog" aria-labelledby="chatModalLabel" aria-hidden="true"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="chatModalLabel">Proactive Chat Demo</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <p>Hello, one of our assistents is available to assist you now. <p>Do you want to chat? </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> <button type="button" class="btn btn-primary" onclick="$('#chatModal').modal('hide');egainChat.openHelp();">Chat Now!</button> </div> </div> </div> </div>
Open the above Modal for testing purposes
The above modal should popup using the JavaScript Timer code - but you can test it by using the below code to open it.
<button id="myBtn" onclick="$('#chatModal').modal();">Open Modal inline</button>
Simple End to End Example
- undocked.html
<!doctype html> <html lang="en"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- Optional JavaScript from Bootstrap--> <!-- jQuery first, then Popper.js, then Bootstrap JS --> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> <!-- Popper Not needed for this example --> <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script> --> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <title>Simple Chat Page with Proactive Chat</title> <!-- Custom PHP Javascript using Cisco ECE & CCE APIs to check opening hours - which returns variable 'chatStatus' Make sure to pass in a valid BusinessHour and Chat EntryPoint ID Example Response: var chatStatus = 'busy'; var chatBusyReason = 'MinAgentCount'; var chatTimer = '10000'; --> <script type="text/javascript" src="http://nas2.home.purplepi.ie/chat/chatStatus.php?chatEntryId=1001&businessHoursId=5001"></script> <!-- Custom Javascript in case PHP JavaScript does not return successfully--> <script> if (chatStatus == null) { var chatStatus = 'closed'; var chatTimer = '0'; var chatBusyReason = 'out of service'; } </script> <!-- Cisco Provided ECE JavaScript --> <script language=javascript> var egainChat = egainChat || {}; /*eGain Chat server */ egainChat.serverURL = "http://ucce-ece-db-12.lab2.purplepi.ie/system"; /*eGain Chat Entry Point*/ egainChat.EntryPointId = "1001"; /*eGain Chat Locale*/ egainChat.Locale = "en-US"; /*eGain template name*/ //egainChat.Template = "purplepi-anon"; egainChat.Template = "purplepi-nameonly"; /*Set to true to enable posting attributes to templates*/ egainChat.PostChatAttributes = false; egainChat.CustomerContextParameters = {}; egainChat.openHelp = function() { var domainRegex = /^((?:http?:\/\/)?(?:www\.)?([^\/]+))/i; try { if (egainChat.eglvchathandle != null && egainChat.eglvchathandle.closed == false) { egainChat.eglvchathandle.focus(); return; } } catch (err) {} var refererName = ""; refererName = encodeURIComponent(refererName); var refererurl = encodeURIComponent(document.location.href); var hashIndex = refererurl.lastIndexOf('#'); if (hashIndex != -1) { refererurl = refererurl.substring(0, hashIndex); } var eglvcaseid = (/eglvcaseid=[0-9]*/gi).exec(window.location.search); var vhtIds = ''; if (typeof EGAINCLOUD != 'undefined' && EGAINCLOUD.Account.getAllIds) { var ids = EGAINCLOUD.Account.getAllIds(); vhtIds = '&aId=' + ids.a + '&sId=' + ids.s + '&uId=' + ids.u; } var EG_CALL_Q = window.EG_CALL_Q || []; EG_CALL_Q.push(['enableTracker', true]); var eGainChatUrl = egainChat.serverURL + '/templates/chat/' + egainChat.Template + '/index.html?subActivity=Chat&entryPointId=' + egainChat.EntryPointId; eGainChatUrl += '' + '&templateName=' + egainChat.Template + '&locale=' + egainChat.Locale + '&ver=v11'; eGainChatUrl += '&postChatAttributes=' + egainChat.PostChatAttributes + '&eglvrefname=' + refererName + '&' + eglvcaseid + vhtIds; var domain = domainRegex.exec(eGainChatUrl)[0]; if ((eGainChatUrl + refererurl).length <= 2000) eGainChatUrl += '&referer=' + refererurl; var params = 'height=650,width=450,resizable=yes,scrollbars=yes,toolbar=no'; window.addEventListener('message', function(event) { try { var message = JSON.parse(event.data); if (event.origin === domain && message.Caller.indexOf('EGLV_DOCK') !== -1) { if (message.Key === 'X-egain-session') { var response = { value: window.sessionStorage.getItem('X-egain-session'), caller: message.Caller }; event.source.postMessage(JSON.stringify(response), event.origin); } } } catch (e) {} }); if (egainChat.PostChatAttributes) { if (window.navigator.userAgent.indexOf("Trident") != -1 || window.navigator.userAgent.indexOf("Edge") != -1) { var win = document.getElementById('egainChatDomainFrame'); win.contentWindow.postMessage(JSON.stringify(egainChat.CustomerContextParameters), domain); } else { window.addEventListener('message', function(event) { try { var message = JSON.parse(event.data); if (event.origin === domain && message.Caller.indexOf('EGLV_DOCK') !== -1) { if (message.Key === 'EgainChatParameter') { var response = { value: egainChat.CustomerContextParameters, caller: message.Caller }; event.source.postMessage(JSON.stringify(response), event.origin); } } } catch (e) {} }); } } egainChat.eglvchathandle = window.open(eGainChatUrl, '', params); }; /*To be called by client website. All the parameters specified in application-chat-defaults must be set here.*/ egainChat.SetCustomerParameters = function(egainAttributeName, attributeValue) { egainChat.CustomerContextParameters[egainAttributeName] = attributeValue; }; egainChat.writeIframeIfRequired = function() { if (egainChat.PostChatAttributes && (window.navigator.userAgent.indexOf("Trident") != -1 || window.navigator.userAgent.indexOf("Edge") != -1)) { var iframe = document.createElement('iframe'); iframe.src = egainChat.serverURL + '/web/view/live/customer/storeparams.html?wsname=' + window.location.protocol + '//' + window.location.host; iframe.style.display = 'none'; iframe.name = 'egainChatDomainFrame'; iframe.id = 'egainChatDomainFrame'; if (typeof document.body !== 'undefined' && document.body !== null) { document.body.appendChild(iframe); } else { setTimeout(egainChat.writeIframeIfRequired, 100); } } } egainChat.writeIframeIfRequired(); </script> </head> <body> <!-- Proactive Chat (hidden) which using Bootstrap's Modal feature --> <div class="modal fade" id="chatModal" tabindex="-1" role="dialog" aria-labelledby="chatModalLabel" aria-hidden="true"> <div class="modal-dialog" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="chatModalLabel">Proactive Chat Demo</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <p>Hello, one of our assistants is available to assist you now. <p>Do you want to chat? </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> <button type="button" class="btn btn-primary" onclick="$('#chatModal').modal('hide');egainChat.openHelp();">Chat Now!</button> </div> </div> </div> </div> <div class="d-flex justify-content-center"> <h1>Very Simple Undocked Chat Example<h1> </div> <div class="d-flex justify-content-center"> <h2>Includes Proactive Chat!<h2> </div> <!--Chat Options to display to end user - open / closed / busy --> <!--Chat Open--> <div id="mychatOn" align="center" style="display: none"> <button type="button" class="btn btn-primary" onclick="egainChat.openHelp();">Chat Now!</button> </div> <!--Chat Closed / Off --> <div id="mychatOff" align="center" style="display: none"> <h2>We are closed.</h2> </div> <!--Chat Busy--> <div id="mychatBusy" align="center" style="display: none"> <h2>Sorry, we are busy.</h2> <h3>Busy Reason: <script type="text/javascript">document.write(chatBusyReason)</script></h3> </div> <!-- Custom Cisco ECE JavaScript for Show or Hide the open / closed / busy Chat option based on var 'chatStatus' value and JS to display Proactive Chat Popup when the configured timer value expires--> <script type="text/javascript"> if (chatStatus == 'closed') { $('#mychatOff').show(); $('#mychatOn').hide(); $('#mychatBusy').hide(); } if (chatStatus == 'open') { $('#mychatOn').show(); $('#mychatOff').hide(); $('#mychatBusy').hide(); //Proactive Chat setTimeout(function() { if (chatTimer != 0) { $('#chatModal').modal(); } }, chatTimer); } if (chatStatus == 'busy') { $('#mychatBusy').show(); $('#mychatOff').hide(); $('#mychatOn').hide(); } function disableProactiveChat() { window.chatTimer = 0; console.log('chatTimer: 0'); } console.log('Source: displaychat.js chatStatus: ' + chatStatus); console.log('Source: displaychat.js chatTimer: ' + chatTimer); </script> </body> </html>
