<%@language = JScript %> <% /* Author: Gerry O'Rourke - Purplepi.ie Date: 22 September 2019 Version 2.0 /* /* MIT License Copyright (c) 2019 Gerard O'Rourke - purplepi.ie Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* Example Location of File on ECE Web Server: D:\ECE\eService\templates\chat\businessHours\ Example JSON format URL: http://ucce-ece-db-12.lab2.purplepi.ie/system/templates/chat/businessHours/chatStatus.asp?businessHoursId=5001&chatEntryId=1001 Example JSONP format URL: http://ucce-ece-db-12.lab2.purplepi.ie/system/templates/chat/businessHours/chatStatus.asp?businessHoursId=5001&chatEntryId=1001&callback=parseResponse */ /* --- Overview --- The relevant businessHourId and chatEntryId (case sensative) must be passed into this script otherwise a chatStatus of 'closed' and chatStatusReason of 'out of service' will be returned. The response is in JSON format, unless a query variable 'callback' is set in the URL. If the variable callback is set, the response will use in JSONP with the function name set to value of the callback variable. This key variables chatStatus API that are returned via JSON format are:. chatStatus chatStatusReason myProactiveChatTimer --- chatStatus --- This Variable chatStatus should return one of 3 possible values 'open' 'closed' 'busy' --- chatStatusReason --- This Variable should return the reasonText from the BusinessHours API. In the Web Demo, the reasonText of "Emergency" and "Holiday" are used and were created in CCE admin Business Hours section. This enabled a differnet closed message if the day was a holiday or was forced closed and Reason set to 'Emergency' --- myProactiveChatTimer --- This is the timer for a Proactive Chat in Milliseconds. The time in SECONDS is set as part of the Business Hour Name e.g. a Business Hours Name of "Sales.Chat_A_B_C_D" where A = proactive timer set in seconds, e.g. for 10 seconds before a proactive chat is given set to '10' - Note setting to '0' disabled proactive chat) B = Minimum Number of Chat Agents required - before giving back chatStatus of 'busy' - e.g. set to '0' to allow queuing, set to '1' to require at least 1 agent available before giving busy. C = Max Queue Depth - e.g. set to 5 to give back a busy if there are 5 or more chats in the current chat queue D = Max Expected Wait Time in seconds, e.g. set to '120' to give back a busy if the expected wait time is more than 120 seconds. Example Business Hours Name: "Sales.Chat_10_0_5_120" Example JSON Output: { "debugLevel":"1", "errorcode":"0", "errorstring":"", "chatStatus":"busy", "chatStatusReason":"myMinAgentCount", "chatTimer":"0" } For more info check out: http://orourke.tv/web/doku.php?id=vendors:cisco:uc:ece:apiexample For chat Demo Check out: http://purplepi.ie/web/doku.php?id=chat For Sample HTML + JavaScript Code using this chatStatus API to create a dyanmically updating webpage: https://github.com/gerardorourke/startbootstrap-landing-page */ try { //start of Global Try // ******************************************************************************************** // // *************************** Review and change the BELOW variables ************************* // // ******************************************************************************************** // // Variables CCE & ECE Server Details var ccehostname = 'ucce-hds-a.lab2.purplepi.ie'; var ecehostname = 'ucce-ece-db-12.lab2.purplepi.ie'; var cceuser = 'chatapiuser@lab2.purplepi.ie'; //create a PCCE User Administrator dedicated for this role. var ccepass = 'myPa$$w0rd!'; // HTTPS Connection Timemout and TLS setttings var SXH_OPTION_2_VALUE = 13056; // SXH_OPTION_IGNORE_SERVER_SSL_CERT_ERROR_FLAGS -> 'SXH_OPTION_2_VALUE = 13056;' to ignore all SSL errors var resolveTimeout = 3000; // DNS Resolve Timeout (ms) var connectTimeout = 3000; // Value (ms) is applied to establishing a communication socket with the target server var sendTimeout = 3000; // The value applies to sending an individual packet of request data (if any) on the communication socket to the target server. (ms) var receiveTimeout = 3000; // The value applies to receiving a packet of response data from the target server (ms) // Default Values if unable to read valid values from BusinessHours Name var defaultProactiveChatTimer = '0'; // value here in seconds, e.g. '10' for a 10 second delay for Proactive Chat (note this value is converted to ms when presented to Client Browser) var defaultMinAgentCount = '0'; var defaultMaxQueueDepth = '0'; var defaultMaxWaitTime = '900'; var debuglevel = 1; // 0 = disabled, 1 = minimum (use on client to output JSON to Console, 2 = basic debugging, 3 = all. Set to 0 in production unless you have an issue to troubleshoot the script. var JSONP_allow = true; // ******************************************************************************************** // // **************************** Review and change the ABOVE variables ************************ // // ******************************************************************************************** // // Initial JS variable values var chatStatus = 'closed'; //Defaults value until overwritten var chatStatusReason = 'out of service'; //Defaults value until overwritten var errorcode = '0'; var errorstring = ''; // Query String - Retrieve dyanmic values for the Business Hours and ECE API IDs. var myQuerySring = Request.QueryString; var myChatEntryId = Request.QueryString("chatEntryId"); var myBusinessHoursId = Request.QueryString("businessHoursId"); var myCallback = Request.QueryString("callback"); var responseFormat = 'json'; var outputfilestarted = false; // CCE & ECE URLs var businessHoursUrl = 'https://' + ccehostname + '/unifiedconfig/config/businesshour/' + myBusinessHoursId; var liveSessionStatusUrl = 'http://' + ecehostname + '/system/egain/chat/entrypoint/liveSessionStatus/' + myChatEntryId; var capacityUrl = 'http://' + ecehostname + '/system/egain/chat/entrypoint/capacity/' + myChatEntryId; // Declare Global Variables used in both businessHours and ECE APIs var myProactiveChatTimer = '0'; //Defaults value until overwritten var myMaxQueueDepth var myMaxWaitTime var myMinAgentCount if (isNaN(myChatEntryId)) { errorcode = '501'; errorstring = 'ChatEntryId not a number,'; } if (isNaN(myBusinessHoursId)) { errorcode = '501'; errorstring = errorstring + 'businessHoursId not a number,'; } if ((Request.QueryString("callback").count > 0) && (JSONP_allow == true)) { if (/\s/.test(myCallback)) { errorcode = '501'; errorstring = 'callback variable contains spaces'; } else{ responseFormat = 'jsonp'; } } // ***** Start of Output File ***** if (responseFormat == 'jsonp') { Response.ContentType = "application/javascript"; // Set Content Type to JavaScript Response.Write(myCallback + '('); } else { Response.ContentType = "application/json"; // Set Content Type to JSON } Response.Write('{'); // Start of JSON Output File outputfilestarted = true; if (errorcode == '0') { chatStatus = businessHoursAPI() // BusinessHours API - returns 'open' or 'closed' } if ((chatStatus == 'open') && (errorcode == '0')) { chatStatus = liveSessionStatusAPI() // ECE liveSessionStatus API - returns 'open' or 'busy' or if unable to read - 'closed' with chatStatusReason 'out of service' } if ((chatStatus == 'open') && (myMinAgentCount > 0) && (errorcode == '0')) { chatStatus = capacityAPI() // ECE Capacity API - returns 'open' or 'busy' or if unable to read - 'closed' with chatStatusReason 'out of service' } if (debuglevel > 1) { Response.Write('\n"QueryString":"' + Request.QueryString + '",'); } Response.Write('\n"debugLevel":"' + debuglevel + '",'); Response.Write('\n"errorcode":"' + errorcode + '",'); Response.Write('\n"errorstring":"' + errorstring + '",'); Response.Write('\n"chatStatus":"' + chatStatus + '",'); Response.Write('\n"chatStatusReason":"' + chatStatusReason + '",'); Response.Write('\n"chatTimer":"' + myProactiveChatTimer + '"'); Response.Write('\n}'); if (responseFormat == 'jsonp') { Response.Write(');'); } // ******************************************************************************************** // // ******************************** Functions ************************************************* // // ******************************************************************************************** // function businessHoursAPI() { try { var srvXmlHttp srvXmlHttp = Server.CreateObject("Msxml2.ServerXMLHTTP.3.0"); srvXmlHttp.setOption(2, SXH_OPTION_2_VALUE); //Ignore SSL Certs srvXmlHttp.setTimeouts(resolveTimeout, connectTimeout, sendTimeout, receiveTimeout); srvXmlHttp.open("GET", businessHoursUrl, false, cceuser, ccepass); srvXmlHttp.send(); var httpstatus = srvXmlHttp.status; if (debuglevel > 1) { Response.Write('\n"businessHoursApiHttpStatus":"' + httpstatus + '",'); } if (httpstatus != 200) { chatStatus = 'closed'; chatStatusReason = 'out of service'; myProactiveChatTimer = '0'; errorcode = httpstatus; errorstring = 'businessHour API http error'; return chatStatus; } var businessHours = srvXmlHttp.responseXML; var businessHoursName = businessHours.selectSingleNode("//businessHour/name"); var runTimeStatus = businessHours.selectSingleNode("//businessHour/runTimeStatus"); var runTimeStatusReason = businessHours.selectSingleNode("//businessHour/runTimeStatusReason"); chatStatusReason = runTimeStatusReason.text; //Parse Business Hours Name to retrieve the Proactive Chat Timer, Min Agent Count, Max Queue Depth & Max Wait Timeouts var businessHoursNameArray = businessHoursName.text.split("_"); var myBusinessHoursName = businessHoursNameArray[0]; myProactiveChatTimer = businessHoursNameArray[1]; myMinAgentCount = businessHoursNameArray[2]; myMaxQueueDepth = businessHoursNameArray[3]; myMaxWaitTime = businessHoursNameArray[4]; myProactiveChatTimer = myProactiveChatTimer * 1000; //Converts ChatTimer from seconds to milliseconds // Check if Valid Values from BusinessHour - if not - overwrite with the default values. if (isNaN(myProactiveChatTimer)) { myProactiveChatTimer = defaultProactiveChatTimer * 1000; //note - converts to milliseconds } if (isNaN(myMinAgentCount)) { myMinAgentCount = defaultMinAgentCount; } if (isNaN(myMaxQueueDepth)) { myMaxQueueDepth = defaultMaxQueueDepth; } if (isNaN(myMaxWaitTime)) { myMaxWaitTime = defaultMaxWaitTime; } if (runTimeStatus.text == 1 || runTimeStatus.text == 3) { chatStatus = 'open'; } else { chatStatus = 'closed'; // Not actually needed as already set to 'closed' as the initial value but ... myProactiveChatTimer = '0'; } if (debuglevel > 2) { Response.Write('\n"fullBusinessHoursName":"' + businessHoursName.text + '",'); Response.Write('\n"runTimeStatusReason":"' + runTimeStatusReason.text + '",'); Response.Write('\n"myBusinessHoursName":"' + myBusinessHoursName + '",'); Response.Write('\n"myProactiveChatTimer":"' + myProactiveChatTimer + '",'); Response.Write('\n"myMinAgentCount":"' + myMinAgentCount + '",'); Response.Write('\n"myMaxQueueDepth":"' + myMaxQueueDepth + '",'); Response.Write('\n"myMaxWaitTime":"' + myMaxWaitTime + '",'); Response.Write('\n"runTimeStatus":"' + runTimeStatus.text + '",'); } return chatStatus; } //Try catch (err) { chatStatus = 'closed'; chatStatusReason = 'out of service'; myProactiveChatTimer = '0'; errorcode = '500'; errorstring = 'businessHours API Error'; return chatStatus; } //end of catch } //end of function function liveSessionStatusAPI() { try { var srvXmlHttp srvXmlHttp = Server.CreateObject("Msxml2.ServerXMLHTTP.3.0"); srvXmlHttp.setOption(2, SXH_OPTION_2_VALUE); //Ignore SSL Certs srvXmlHttp.open("GET", liveSessionStatusUrl, false); srvXmlHttp.send(); var httpstatus = srvXmlHttp.status; if (debuglevel > 1) { Response.Write('\n"liveSessionApiHttpStatus":"' + httpstatus + '",'); } if (httpstatus != 200) { chatStatus = 'closed'; chatStatusReason = 'out of service'; myProactiveChatTimer = '0'; errorcode = httpstatus; errorstring = 'liveSession API http error'; return chatStatus; } var liveSessionStatus = srvXmlHttp.responseXML; var waitTime = liveSessionStatus.selectSingleNode("//ns2:waitTime"); var queueDepth = liveSessionStatus.selectSingleNode("//ns2:queueDepth"); if (parseInt(queueDepth.text, 10) > myMaxQueueDepth) { chatStatus = 'busy'; chatStatusReason = 'MaxQueueDepth'; myProactiveChatTimer = '0'; } if (parseInt(waitTime.text, 10) > myMaxWaitTime) { chatStatus = 'busy'; chatStatusReason = 'MaxWaitTime'; myProactiveChatTimer = '0'; } if (debuglevel > 2) { Response.Write('\n"waitTime":"' + waitTime.text + '",'); Response.Write('\n"queueDepth":"' + queueDepth.text + '",'); } return chatStatus; } //end of try catch (err) { chatStatus = 'closed'; chatStatusReason = 'out of service'; myProactiveChatTimer = '0'; errorcode = '500'; errorstring = 'liveSession API Error'; return chatStatus; } //end of catch } //end of function function capacityAPI() { try { srvXmlHttp = Server.CreateObject("Msxml2.ServerXMLHTTP.3.0"); srvXmlHttp.setOption(2, SXH_OPTION_2_VALUE); //Ignore SSL Certs srvXmlHttp.open("GET", capacityUrl, false); srvXmlHttp.send(); var httpstatus = srvXmlHttp.status; if (debuglevel > 1) { Response.Write('\n"capacityApiHttpStatus":"' + httpstatus + '",'); } if (httpstatus != 200) { chatStatus = 'closed'; chatStatusReason = 'out of service'; myProactiveChatTimer = '0'; errorcode = httpstatus; errorstring = 'capacity API http error'; return chatStatus; } var capacity = srvXmlHttp.responseXML; var count = capacity.selectSingleNode("//ns2:count"); if (parseInt(count.text, 10) < myMinAgentCount) { chatStatus = 'busy'; chatStatusReason = 'myMinAgentCount'; myProactiveChatTimer = '0'; } if (debuglevel > 2) { Response.Write('\n"agentCount":"' + count.text + '",'); } return chatStatus; } // Try catch (err) { chatStatus = 'closed'; chatStatusReason = 'out of service'; chatTimer = '0'; errorcode = '500'; errorstring = 'capacity API Error'; return chatStatus; } //Catch } //Function } //End of Global Try catch (err) { chatStatus = 'closed'; chatStatusReason = 'out of service'; chatTimer = '0'; errorcode = '500'; errorstring = 'Script Error'; if ((outputfilestarted == false) || (typeof outputfilestarted == 'undefined')){ if (responseFormat == 'jsonp') { Response.ContentType = "application/javascript"; // Set Content Type to JavaScript Response.Write(myCallback + '('); } else { Response.ContentType = "application/json"; // Set Content Type to JSON } Response.Write('{'); // Start of JSON Output File } Response.Write('\n"chatStatus":"' + chatStatus + '",'); Response.Write('\n"chatStatusReason":"' + chatStatusReason + '",'); Response.Write('\n"chatTimer":"' + chatTimer + '",'); Response.Write('\n"errorcode":"' + errorcode + '",'); Response.Write('\n"errorstring":"' + errorstring + '"'); Response.Write('\n}'); } %>