var finesse = finesse || {}; finesse.gadget = finesse.gadget || {}; finesse.container = finesse.container || {}; clientLogs = finesse.cslogger.ClientLogger || {}; // for logging /** @namespace */ finesse.modules = finesse.modules || {}; finesse.modules.SampleGadget = (function ($) { var user, dialogs, currentDialog, defaultHtml = "This Gadget will populate once call arrives --\ Left side manual entry -- Right side click to update the Call Data", /** * Make a REST API request and send the response to the success or error * handler depending on the HTTP status code * * @param {String} url * The unencoded URL to which the request is sent (will be encoded) * @param {Object} options * An object containing additional options for the request. * * {String} options.method * The type of request (e.g. GET, PUT, POST, DELETE) * {String} options.authorization * [Optional] The authorization string for the request * {String} options.contentType * [Optional] The Content-Type of the request (e.g. application/json, * application/xml) * {String} options.content * A string to send in the content body of the request. * @param {Object} handlers * An object containing the success and error handlers. * * {Function} handlers.success(response) * A callback function to be invoked for a successful request. * {Function} handlers.error(response) * A callback function to be invoked for an unsuccessful request. */ makeRequest = function (url, options, handlers) { var params, uuid; clientLogs.log("makeRequest()"); // Protect against null dereferencing of options & handlers allowing its (nonexistant) keys to be read as undefined params = {}; options = options || {}; handlers.success = _util.validateHandler(handlers.success); handlers.error = _util.validateHandler(handlers.error); // Request Headers params[gadgets.io.RequestParameters.HEADERS] = {}; // HTTP method is a passthrough to gadgets.io.makeRequest params[gadgets.io.RequestParameters.METHOD] = options.method; if (options.method === "GET") { // Disable caching for GETs if (url.indexOf("?") > -1) { url += "&"; } else { url += "?"; } url += "nocache=" + _util.currentTimeMillis(); } else { // Generate a requestID and add it to the headers uuid = _util.generateUUID(); params[gadgets.io.RequestParameters.HEADERS].requestId = uuid; params[gadgets.io.RequestParameters.GET_FULL_HEADERS] = "true"; } // Add authorization to the request header if provided if(options.authorization) { params[gadgets.io.RequestParameters.HEADERS].Authorization = options.authorization; } // Add content type & body if content body is provided if (options.content) { // Content Type params[gadgets.io.RequestParameters.HEADERS]["Content-Type"] = options.contentType; // Content params[gadgets.io.RequestParameters.POST_DATA] = options.content; } // Call the gadgets.io.makereqest function with the encoded url clientLogs.log("makeRequest(): Making a REST API request to: " + url); gadgets.io.makeRequest(encodeURI(url), handleResponse(handlers), params); }, /** * Handler for the response of the REST API request. This function determines if * the success or error handler should be called based on HTTP status code. * * @param {Object} handlers * An object containing the success and error handlers. * * {Function} handlers.success(response) * A callback function to be invoked for a successful request. * {Function} handlers.error(response) * A callback function to be invoked for an unsuccessful request. */ handleResponse = function(handlers) { return function (response) { clientLogs.log("handleResponse(): The response status code is: " + response.rc); // Send the response to the success handler if the http status // code is 200 or 202. Send the response to the error handler // otherwise. if ((response.rc === 200 || response.rc === 202) && handlers.success) { clientLogs.log("handleResponse(): Got a successful response."); handlers.success(response); } else if (handlers.error) { clientLogs.log("handleResponse(): Got a failure response."); handlers.error(response); } else { clientLogs.log("handleResponse(): Missing the success and/or error handler."); } }; }, /** * Handler for when the REST API response has a HTTP status code >= 200 and < 300. * * @param {Object} response * An object containing the HTTP response. */ handleResponseSuccess = function(response) { clientLogs.log("handleResponseSuccess():"); }, /** * Handler for when the REST API response has a HTTP status code < 200 and >= 300. * * @param {Object} response * An object containing the HTTP response. */ handleResponseError = function(response) { clientLogs.log("handleResponseError():"); }, /** * Get the logged in user's participant object * from the dialog object. * * @param {Object} dialog * An object containing the dialog * @returns {Object} participant * The participant object representing the * logged in user for the given dialog */ getParticipant = function (dialog) { clientLogs.log("getParticipant(): Getting the participant."); var participants = dialog.getParticipants(); for (var num in participants) { var participant = participants[num]; // Found the user if (participant.mediaAddress === user.getExtension()) { return participant; } } return null; }, /** * Determine if UPDATE_CALL_DATA is an allowable action * for the currently logged in user. * * @param {Object} dialog * An object containing the dialog * @returns {boolean} * true if UPDATE_CALL_DATA is allowed * false otherwise */ isUCDAllowableAction = function (dialog) { clientLogs.log("isUCDAllowableAction(): Checking to see if UPDATE_CALL_DATA is an allowable action."); var participant = getParticipant(dialog); if (participant != null) { // Check the allowable actions var allowableActions = participant.actions.action; if (typeof allowableActions === 'string') { // Make it an array allowableActions = [allowableActions]; } if (allowableActions.indexOf(finesse.restservices.Dialog.Actions.UPDATE_CALL_DATA) !== -1) { clientLogs.log("isUCDAllowableAction(): UPDATE_CALL_DATA is an allowable action."); return true; } } clientLogs.log("isUCDAllowableAction(): UPDATE_CALL_DATA is not an allowable action."); return false; }, /** * Build the default HTML to display when there isn't a call * where call variables can be updated. */ displayDefaultHtml = function () { currentDialog = null; $('#callVariablesDiv').html(defaultHtml); gadgets.window.adjustHeight(); }, /** * Build the HTML to display the list of callvariables with * buttons on the gadget. * * @param {Object} dialog * An object containing the dialog */ displayCallVariables = function (dialog) { // Check to see if the user has UPDATE_CALL_DATA as an allowable action if(isUCDAllowableAction(dialog)) { // The user has UPDATE_CALL_DATA as an allowable action // Build the list of call variables that can be updated var callVariables = dialog.getMediaProperties(); html = ""; var i = 1; for (var callVariableName in callVariables) { clientLogs.log("displayCallVariables(): key is: " + callVariableName); var callVarMap = { 'userContact_Info' : 'Contact Info' , 'callVariable3' : 'Contact ID' , 'userContactName' : 'Contact Name' , 'userCID' : 'Customer ID' , 'callVariable2' : 'Customer Name' , 'userPartnerName' : 'Partner Name' , 'callVariable4' : 'Priority' , 'callVariable7' : 'Request Type' , 'callVariable8' : 'Severity' , 'callVariable9' : 'Summary of Issue' , 'callVariable10' : 'Ticket ID' , 'userVIPType' : 'VIP' } ; var callVarDisplayName = callVarMap[callVariableName]; if (callVariableName in callVarMap) { var inputId = "callVariable" + i; html += ""; html += ""; html += "
"; i++; } } $('#callVariablesDiv').html(html); gadgets.window.adjustHeight(); } else { displayDefaultHtml(); } }, /** * Handler for when the dialog object changes. * * @param {Object} dialog * The dialog object that has changed */ _processCall = function (dialog) { clientLogs.log("_processCall():"); // See if this dialog is the current active call var participant = getParticipant(dialog); if ((participant != null) && (participant.state == 'ACTIVE')) { currentDialog = dialog; } if (currentDialog.getId() === dialog.getId()) { displayCallVariables(currentDialog); } }, /** * Handler for additions to the Dialogs collection object. This will occur when a new * Dialog is created on the Finesse server for this user. */ handleNewDialog = function (dialog) { if(isUCDAllowableAction(dialog)) { currentDialog = dialog; displayCallVariables(currentDialog); } // add a dialog change handler in case the callvars didn't arrive yet dialog.addHandler('change', _processCall); }, /** * Handler for deletions to the Dialogs collection object. This will occur when a * Dialog is removed from the Finesse server for this user. */ handleEndDialog = function (dialog) { var numDialogs = dialogs.getDialogCount(true); if (numDialogs == 2) { dialogCollection = dialogs.getCollection(); for (var dialogId in dialogCollection) { if (dialogId !== dialog.getId()) { currentDialog = dialogCollection[dialogId]; displayCallVariables(currentDialog); } } } else { displayDefaultHtml(); } }, /** * Handler for the onLoad of a User object. This occurs when the User object is initially read * from the Finesse server. Any once only initialization should be done within this function. */ _handleUserLoad = function (userevent) { // Get an instance of the dialogs collection and register handlers for dialog additions and // removals dialogs = user.getDialogs( { onCollectionAdd : handleNewDialog, onCollectionDelete : handleEndDialog }); }, /** * Handler for all User updates */ _handleUserChange = function(userevent) { }, /** * Update the given call variable via the Update Call Data API. * * @param {String} name * The name of the call variable * {String} value * The value to set the call variable to */ updateCallVariable = function(name, value) { if (currentDialog) { clientLogs.log("updateCallVariable(): Updating " + name + " to " + value + " for dialog with id: " + currentDialog.getId()); // Call the Dialog — Update Call Variable Data REST API var config = finesse.gadget.Config; var url = config.scheme + "://" + config.host + ":" + config.hostPort + currentDialog.getRestUrl(); clientLogs.log("updateCallVariable(): URL is: " + url); // Build the content body var contentBody = { "Dialog" : { "requestedAction": finesse.restservices.Dialog.Actions.UPDATE_CALL_DATA, "mediaProperties": { "callvariables": { "CallVariable": { "name": name, "value": value } } } } }; makeRequest(url, { method: 'PUT', authorization: _util.getAuthHeaderString(finesse.gadget.Config), contentType: 'application/xml', content: _util.json2xml(contentBody), }, { success: handleResponseSuccess, error: handleResponseError }); } else { clientLogs.log("updateCallVariable(): There are currently no active dialogs"); } }; /** @scope finesse.modules.SampleGadget */ return { /** * Update the call variable. */ updateCallVariable : function (name, value) { updateCallVariable(name, value); }, /** * Performs all initialization for this gadget */ init : function () { var cfg = finesse.gadget.Config; _util = finesse.utilities.Utilities; clientLogs.init(gadgets.Hub, "UpdateCallVariableDataSampleGadget", finesse.gadget.Config); //this gadget id will be logged as a part of the message // Initiate the ClientServices and the logger and then load the user object. ClientServices are // initialized with a reference to the current configuration. finesse.clientservices.ClientServices.init(finesse.gadget.Config); user = new finesse.restservices.User({ id: cfg.id, onLoad : _handleUserLoad, onChange : _handleUserChange }); displayDefaultHtml(); containerServices = finesse.containerservices.ContainerServices.init(); clientLogs.log("Adding Tab Visible Handler..."); containerServices.addHandler(finesse.containerservices.ContainerServices.Topics.ACTIVE_TAB, function() { clientLogs.log("Gadget is now visible"); // log to Finesse logger // automatically adjust the height of the gadget to show the html gadgets.window.adjustHeight(); }); containerServices.makeActiveTabReq(); } }; }(jQuery));