/* * Allows an Helper to manage its Availability Status, receive Contact * Notification Requests from Helpees, Accept/Deny them and receive Session-Level * notifications (openchat, openclient, creaticket). */ var SparkomAvailabilityApi = function() { var SERVER_ROOT = "https://www.spark-angels.com/panserver3"; function ava_setServerRoot(serverRoot) { SERVER_ROOT = serverRoot; } var AVAILABILITY_URL = "/web_availability"; var WIDGETLIST_URL = "/preferences/get/"; var ACCEPTDENY_URL = "/notifications/reponse/"; var SDETAILS_URL = "/wcsessiondetails"; var REQUESTSTATUS_HELPERACCEPTED = 3; var REQUESTSTATUS_HELPERDENIED = 4; // u_ are variables set by the Local API user var u_login = null; var u_password = null; var u_obfuscated = null; var u_corpoId = null; var u_apiKey = null; // Availability Statuses var STATUS_OFFLINE = "unav"; var STATUS_AVAILABLE = "av"; var STATUS_OBSERVER = "obs"; // Availability Status set by the Local User: null, true, false var u_status = STATUS_OFFLINE; // Availability Status returned by the Server: null (unknown), true (Available), false (Unavailable) var obs_available = null; var refreshTimer = null; // Function to invoke when Request(s) is/are available // If null, internal dialog implementation. var u_notifRequestCallback = null; // Function to invoke when the Availability Status changes (MVC) var u_availabilityCallback = null; // Last Notified Availability Status: null, true, false var lastNotifiedAvailability = null; // For receiving Error Messages or Empty String var u_errorCallback = null; // Last Notified Error Message var lastNotifiedError = ""; // Function to invoque when querying the server var u_queryingCallback = null; // Screen Sharing Handling Modes definitions var SCREENSHARE_IGNORE = "no"; // Ignore these requests var SCREENSHARE_APINOTIFY = "api"; // Notify them to u_notifRequestCallback var SCREENSHARE_AUTOSTART = "startsa"; // Dont Notify, auto-start Spark-Angels // Screen Sharing Handling Mode var u_screenSharingMode = SCREENSHARE_IGNORE; // OpenChat Modes Definition var OPENCHAT_AUTO = "auto"; var OPENCHAT_CALLBACK = "callback"; var u_openchatMode = OPENCHAT_AUTO; // OpenChat Auto URL var u_openchatUrl = "../sparkom/wchat.html"; var u_openchatWinParams = "scrollbars=no,location=no,width=500,height=420,location=no,menubar=no,status=no,toolbar=no"; // OpenChat Callback Function var u_openchatCallback = null; // OpenClient Callback Function var u_openclientCallback = null; // Create Ticket Callback Function var u_createTicketCallback = null; function ava_corpoLogin(corpoId, apiKey, login) { u_corpoId = corpoId; u_apiKey = apiKey; u_login = login; } function ava_directLogin(login, password) { u_login = login; u_password = password; } function ava_obfuscLogin(obfuscated) { u_obfuscated = obfuscated; } function private_addAuth(params) { if((u_corpoId != null) && (u_apiKey != null) && (u_login != null)) { params["corpoid"] = u_corpoId; params["akey"] = u_apiKey; params["login"] = u_login; } else if((u_login != null) && (u_password != null)) { params["login"] = u_login; params["password"] = u_password; } else if(u_obfuscated != null) { params["ob"] = u_obfuscated; } } function ava_logout() { ava_stop(); u_login = null; u_password = null; u_obfuscated = null; u_corpoId = null; u_apiKey = null; } function ava_startAsAvailable(notifRequestCallback) { if(notifRequestCallback == undefined) { u_notifRequestCallback = null; } else { u_notifRequestCallback = notifRequestCallback; } if(refreshTimer != null) { clearTimeout(refreshTimer); } u_status = STATUS_AVAILABLE; refreshTimer = setTimeout(private_queryServer, 10); } function ava_startAsObserver(notifRequestCallback) { if(notifRequestCallback == undefined) { u_notifRequestCallback = null; } else { u_notifRequestCallback = notifRequestCallback; } if(refreshTimer != null) { clearTimeout(refreshTimer); } u_status = STATUS_OBSERVER; refreshTimer = setTimeout(private_queryServer, 10); } function ava_stop() { if(refreshTimer != null) { clearTimeout(refreshTimer); } refreshTimer = null; u_status = STATUS_OFFLINE; private_queryServer(); } function private_notifyStartQuerying() { if(u_queryingCallback != null) { u_queryingCallback(true); } } function private_notifyStopQuerying() { if(u_queryingCallback != null) { u_queryingCallback(false); } } function private_queryServer() { var params = { json: true, ustatus: u_status, uscmode: u_screenSharingMode }; private_addAuth(params); private_notifyStartQuerying(); private_ajaxPost(AVAILABILITY_URL, params, private_handleResponse, private_handleError); } function private_handleResponse(data) { private_notifyStopQuerying(); if(data.retCode != 0) { // Error. private_updateAvailability(false, data.message); } else { private_updateAvailability(data.obsAvailable, ""); var numPendingNotifs = data.nbNotifs; var pendingNotifs = new Array(); if((u_status != STATUS_OFFLINE)&&(u_notifRequestCallback != null)) { for(var i=0; i < numPendingNotifs; i++) { var notif = data["notif_" + i]; pendingNotifs[i] = new PendingNotif(notif); } u_notifRequestCallback(pendingNotifs); } if(u_createTicketCallback != null) { var cmd = data.cmd; if(cmd == "creaticket") { u_createTicketCallback(data.cmdparams); } } } if(u_status != STATUS_OFFLINE) { refreshTimer = setTimeout(private_queryServer, 6000); } } function PendingNotif(jsonNotif) { this.requestId = jsonNotif.requestId; this.requestDurationSecs = jsonNotif.requestDuration; this.widgetId = jsonNotif.widgetId; this.widgetDisplayName = jsonNotif.widgetDisplayName; this.helpeeDisplayName = jsonNotif.helpeeDisplayName; this.helpeeDemand = jsonNotif.helpeeAddedInfoMore; this.requestOrigin = jsonNotif.requestOrigin; } function private_handleError(request, textStatus, errorThrown) { private_notifyStopQuerying(); // textStatus is the true reason, such as "timeout" if((u_errorCallback != null) && (lastNotifiedError != textStatus)) { lastNotifiedError = textStatus; u_errorCallback(textStatus); } if(u_status != STATUS_OFFLINE) { refreshTimer = setTimeout(private_queryServer, 6000); } } function ava_isAvailable() { return obs_available; } // Will receive as argument the Availability Status: true,false,null function ava_setAvailabilityCallback(availabilityCallback) { u_availabilityCallback = availabilityCallback; } // Will receive as argument true when starting a Query, false when it returns function ava_setQueryingCallback(queryingCallback) { u_queryingCallback = queryingCallback; } // Always signal the Server-Backed status function private_updateAvailability(available, errMessage) { // Availability can change following user intervention or network notification if((available != obs_available)&&(u_availabilityCallback != null)) { obs_available = available; setTimeout(private_signalNotifyAvailability, 5); } if((u_errorCallback != null) && (lastNotifiedError != errMessage)) { lastNotifiedError = errMessage; u_errorCallback(errMessage); } } function private_signalNotifyAvailability() { if((obs_available != lastNotifiedAvailability)&&(u_availabilityCallback != null)) { lastNotifiedAvailability = obs_available; u_availabilityCallback(obs_available); //// USE APPLY } } function ava_setErrorCallback(errorCallback) { if(errorCallback == null || errorCallback == undefined || errorCallback == "") { u_errorCallback = null; } else { u_errorCallback = errorCallback; } } function ava_listWidgets(resultCallback, errorCallback) { if(errorCallback == undefined) { errorCallback = u_errorCallback; } var params = { noalp: true, json: true }; private_addAuth(params); private_ajaxPost(WIDGETLIST_URL, params, function(data) { if(data.retCode != 0) { if(errorCallback != null) { errorCallback(data.message); } } else { var nWidgets = data.numallWidgets; var allWidgets = new Array(nWidgets); for(var i=0; i < nWidgets; i++) { var w = new Widget(data["allwidget."+i]); allWidgets[i] = w; } resultCallback(allWidgets); } }, function(request, textStatus, errorThrown) { errorCallback(textStatus); }); } function Widget(jsonWidgetObject) { this.widgetId = jsonWidgetObject.widgetId; this.widgetType = jsonWidgetObject.widgetType; this.widgetFlags = jsonWidgetObject.widgetFlags; this.widgetDisplayName = jsonWidgetObject.widgetDName; this.widgetLaunchUrl = jsonWidgetObject.widgetLaunchUrl; } function ava_acceptRequest(requestId, resultCallback, errorCallback) { if(errorCallback == undefined) { errorCallback = u_errorCallback; } if(u_status != STATUS_AVAILABLE) { console.log("Api Use Error: AcceptRequest can only be called when Available."); return; } var params = { rp: "version=2&phmode=NONE" } var url = ACCEPTDENY_URL + REQUESTSTATUS_HELPERACCEPTED + "/" + requestId; private_addAuth(params); private_ajaxPost(url, params, function(data) { if(data.retCode != -7) { errorCallback(data.message); } else if(resultCallback != undefined) { resultCallback(); } if(u_openchatMode == OPENCHAT_AUTO) { var openchatUrl = null; if(u_openchatUrl!= null) { var urlParams = data.urlParams; openchatUrl = u_openchatUrl + "?" + urlParams; } else { openchatUrl = data.url; } var wname = "Chat ["+data.csid + "] "; setTimeout(function() { private_startHelperChat(openchatUrl,wname);}, 10); } else if(u_openchatCallback != null) { setTimeout(function() { u_openchatCallback(data); }, 10); } if((u_openclientCallback != null)&&(!data.trustcircle)) { setTimeout(function() { u_openclientCallback(data.helpeeDisplayName, data.csid)}, 10); } }, function(request, textStatus, errorThrown) { errorCallback(textStatus); }); } function ava_denyRequest(requestId, resultCallback, errorCallback) { if(errorCallback == undefined) { errorCallback = u_errorCallback; } if(u_status != STATUS_AVAILABLE) { console.log("Api Use Error: DenyRequest can only be called when Available."); return; } var params = { rp: "version=2&phmode=NONE" } var url = ACCEPTDENY_URL + REQUESTSTATUS_HELPERDENIED + "/" + requestId; private_addAuth(params); private_ajaxPost(url, params, function(data) { if(data.retCode != -7) { errorCallback(data.message); } else if(resultCallback != undefined) { resultCallback(data.url); } }, function(request, textStatus, errorThrown) { errorCallback(textStatus); }); } function ava_setOpenChatWinParams(winParams) { u_openchatWinParams = winParams; } function private_startHelperChat(openchatUrl, wname) { var winParams = u_openchatWinParams; var f = window.open(openchatUrl, wname, winParams); } /** * Sets the Callback function to invoke when a WebChat Request is accepted * and the Widget is not a a "Trust Circle" widget. *

* This function will be invoked with: * - clientid: Name given by the Helpee * - csid: Identifier for the Webchat Session */ function ava_setOpenClientCallback(openClientCallback) { u_openclientCallback = openClientCallback; } /** * Open HelperChat Specification * When the Server has received an Acceptation of a Pending Request : *

* In "auto" mode, the API opens a predefined Helper Webchat window
* -- The [Optional] param specifies the URL of the Custom Webchat to be opened, * by default: /panserver3/wchat/sparkom/wchat.html * In "callback" mode, the API invokes the specified callback function * -- The [Required] param is the callback function, it will receive as parameter * chaturlparams: the Query String to append to the desired Helper Webchat URL (does not include the ?). * csid: Identifier for the Webchat Session * @param mode: "auto" or "callback" * @param param: WebChat URL or Callback function */ function ava_setOpenHelperChat(mode, param) { if(mode == OPENCHAT_AUTO) { u_openchatMode = OPENCHAT_AUTO; if(param == undefined) { u_openchatUrl = null; } else { u_openchatUrl = param; } u_openchatCallback = null; } else if(mode == OPENCHAT_CALLBACK) { u_openchatMode = OPENCHAT_CALLBACK; u_openchatUrl = null; u_openchatCallback = param; } else { private_handleError("", "Invalid Mode for openHelperChat", ""); } } /** * Sets the Callback function to invoke when a Create Ticket signal has been * sent from the Helper Webchat, at end of session. *

* This function will be invoked with a JS object having the following fields: * - csid: Identifier of the Webchat Session. * - clientid: The Helpee Display Name * - session_details_url: URL that links to the Session Details page in the Sparkom application (/rss2) * - helper_notes: Notes taken by the Helper during the Session * - session_transcript: HTML Transcript of the Session lines. */ function ava_setCreateTicketCallback(createTicketCallback) { u_createTicketCallback = createTicketCallback; } /** * Retrieves from the Server the full Details of the Session * identified by its csid Identifier. It may be called anytime after the * Session end (otherwise, transient or uncomplete data can be returned) * * The specified sessionDetailsCallback callback function is invoked with * two parameters that are JS objects: * - wcSession: This Object contains information on the WebChat part of the session. * .csid: Identifier of the Session * .startTime: Date and Time (Locale:FRANCE) of the Session Initiation * .endTime: Date and Time (Locale:FRANCE) of the Session Termination * .duration: Session Duration in hh:mm:ss format * .status: Session Status. The Session Information is complete only when this * field has the value "TERMINATED". * .helpeeDisplayName: Identification of the Helpee, who requested the session. * .helperDisplayName: Helper, who answered the request. * .initRequest: Text of the Initial Request by the Helpee * .htmlTranscript: Transcript of the webchat exchange. * .waitTime: Time in hh:mm:ss between Helpee Request and session acceptation. * .widgetId: ID of the Widget Access Point used. * .helperLoginId: ID of the Helper who accepted the Session. * - sxrSession: null if no Screen Sharing occured. Otherwise: * .sxrid: Local Identifier of the Screen Sharing sub-session * .status: Status of the Screen Sharing sub-session: * NOT_FINISHED - In progress or being setup * DENIED - All Helpers rejected or became Unavailable * CANCELLED - Cancelled by the Helpee * ERROR - An Error occurred * FINISHED - Screen-Sharing is terminated. * .startTime: Date and Time of the Screen Sharing Start * .endTime: Date and Time of the Screen Sharing Start * .duration: Formatted duration (as a String) * .waitTime: Formatted wait time (only available on instrumented Widgets) * .accessWidget: Helper and Widget string * .widgetId: The Widget used. * .helpeeDisplayName: (when known) * .proClientId: when applicable (Session paid by Codes) * .crmClientName: Name of the Helpee as entered by the Helper in the application's mini-crm * .sessionNotation: Numeric value of the Notation given be the Helpee (-1 if not available) * .clientComments: Comments associated with this notation, when applicable. * .prestaName: DisplayName of the Helper Account * .distribHelperId: Distributor tag when applicable * .scrm: Comments entered by the Helper in the application's mini-crm * The errorCallback may not be supplied - in this case the global error callback would be * invoked in case of error. */ function ava_getSessionDetails(csid, sessionDetailsCallback, errorCallback) { if(errorCallback == undefined) { errorCallback = u_errorCallback; } var params = { json: true, csid: csid }; private_addAuth(params); private_ajaxPost(SDETAILS_URL, params, function(data) { if(data.retCode != 0) { if(errorCallback != null) { errorCallback(data.message); } } else if(sessionDetailsCallback != undefined) { var wcSession = data.wcSession; var sxrSession = data.sxrSession; if(sxrSession == "") { sessionDetailsCallback(wcSession, null); } else { sessionDetailsCallback(wcSession, sxrSession); } } }, errorCallback); } // JSON POST action with callbacks on success and error function private_ajaxPost(relativeUrl, params, successCallback, errorCallback){ var settings = { type: "POST", data: params, success: successCallback, dataType: "json", error: errorCallback } $.ajax(SERVER_ROOT + relativeUrl, settings); } return { setServerRoot: ava_setServerRoot, setAvailabilityCallback: ava_setAvailabilityCallback, setQueryingCallback: ava_setQueryingCallback, setErrorCallback: ava_setErrorCallback, corpoLogin: ava_corpoLogin, directLogin: ava_directLogin, obfuscLogin: ava_obfuscLogin, logout: ava_logout, // Helper Availability Control startAsAvailable: ava_startAsAvailable, startAsObserver: ava_startAsObserver, stop: ava_stop, isAvailable: ava_isAvailable, listWidgets: ava_listWidgets, // Helper Handling of Pending Requests acceptRequest: ava_acceptRequest, denyRequest: ava_denyRequest, // Session Events Callbacks setOpenClientCallback: ava_setOpenClientCallback, setOpenHelperChat: ava_setOpenHelperChat, setOpenChatWinParams: ava_setOpenChatWinParams, setCreateTicketCallback: ava_setCreateTicketCallback, // Session Details getSessionDetails: ava_getSessionDetails } }();