github.com/grokify/go-ringcentral-client@v0.3.31/engagevoice/v1/js/cf-agent-library_v2.1.16-2019-07-09.js (about) 1 /*! cf-agent-library - v2.1.16 - 2019-07-09 */ 2 /** 3 * @fileOverview Exposed functionality for Contact Center AgentUI. 4 * @version 2.1.8 5 * @namespace AgentLibrary 6 */ 7 ;(function (global) { 8 var AddSessionNotification = function() { 9 }; 10 /* 11 * This class is responsible for handling "ADD-SESSION" packets from IntelliQueue. This is used by 12 * the CallControlForm. Then it will increment the total_calls count. 13 * 14 * { 15 * "ui_notification": { 16 * "@message_id": "IQ982008082918151403727", 17 * "@response_to": "", 18 * "@type": "ADD-SESSION", 19 * "session_id": { "#text": "2" }, 20 * "uii": { "#text": "200808291814560000000900016558" }, 21 * "phone": { "#text": "200808291814370000000900016555" }, 22 * "session_type": { "#text": "AGENT" }, 23 * "session_label": { "#text": "Primary Agents Call Session" }, 24 * "allow_control": { "#text": "TRUE" }, 25 * "monitoring": { "#text": "FALSE" }, 26 * "agent_id": { "#text": "1856" } 27 * } 28 * } 29 */ 30 AddSessionNotification.prototype.processResponse = function(notification) { 31 var formattedResponse = utils.buildDefaultResponse(notification); 32 var model = UIModel.getInstance(); 33 var notif = notification.ui_notification; 34 var sessionAgentId = utils.getText(notif, "agent_id"); 35 if(utils.getText(notif, "session_type") === "AGENT"){ 36 model.incrementTotalCalls(); 37 } 38 if(sessionAgentId === model.agentSettings.agentId){ 39 // add the session_id of this leg to the current call packet - 40 // this way we can use it for hangups later. 41 model.currentCall.sessionId = utils.getText(notif, "session_id"); 42 }else if(sessionAgentId != ""){ 43 // this is a monitoring session, lets save the monitored agent id for barge-ins 44 model.currentCall.monitorAgentId = sessionAgentId; 45 } 46 // Check to see if we have a transfer leg here, if so, register it 47 var sessionType = utils.getText(notif, "session_type"), 48 allowControl = utils.getText(notif, "allow_control"), 49 sessionId = utils.getText(notif, "session_id"), 50 uii = utils.getText(notif, "uii"), 51 isMonitoring = model.currentCall.isMonitoring, 52 monitoringType = model.currentCall.monitoringType; 53 var isBargeInMonitor = isMonitoring && monitoringType === 'FULL', 54 notCurrentAgent = sessionAgentId !== model.agentSettings.agentId, 55 notSessionOne = sessionId !== '1', 56 shouldTrackSession = false; 57 if(notSessionOne && notCurrentAgent) { 58 if(isBargeInMonitor) { 59 shouldTrackSession = true; 60 } else if(allowControl) { 61 if(sessionType === 'OUTBOUND' || sessionType === 'AGENT') { 62 shouldTrackSession = true; 63 } 64 } 65 } 66 if(shouldTrackSession) { 67 var destination = utils.getText(notif, "phone"); 68 if(sessionType === 'AGENT' || sessionAgentId !== '') { 69 destination = utils.getText(notif, "agent_name"); 70 } 71 model.transferSessions[sessionId] = { 72 sessionId: sessionId, 73 destination: destination, 74 uii: uii 75 }; 76 } 77 // if agent session, set on call status 78 if(notif.session_id === '2'){ 79 model.agentSettings.onCall = true; 80 } 81 formattedResponse.status = "OK"; 82 formattedResponse.message = "Received ADD-SESSION notification"; 83 formattedResponse.sessionId = utils.getText(notif, "session_id"); 84 formattedResponse.uii = utils.getText(notif, "uii"); 85 formattedResponse.phone = utils.getText(notif, "phone"); 86 formattedResponse.sessionType = utils.getText(notif, "session_type"); 87 formattedResponse.sessionLabel = utils.getText(notif, "session_label"); 88 formattedResponse.allowControl = utils.getText(notif, "allow_control"); 89 formattedResponse.monitoring = utils.getText(notif, "monitoring"); 90 formattedResponse.agentId = utils.getText(notif, "agent_id"); 91 formattedResponse.transferSessions = model.transferSessions; 92 return formattedResponse; 93 }; 94 var AdminDebugEmailNotification = function() { 95 }; 96 /* 97 * This class is responsible for handling "AGENT-DEBUG-EMAIL" packets from IntelliQueue 98 * 99 * { 100 * "ui_notification":{ 101 * "@message_id":"IQD01DEV2018071616521500004", 102 * "@response_to":"", 103 * "@type":"AGENT-DEBUG-EMAIL", 104 * "email_to": { 105 * "#text":"rmyers@connectfirst.com" 106 * } 107 * "requested_by": { 108 * "#text":"Ross Myers" 109 * } 110 * } 111 * } 112 */ 113 AdminDebugEmailNotification.prototype.processResponse = function(notification) { 114 var formattedResponse = utils.buildDefaultResponse(notification); 115 var notif = notification.ui_notification; 116 formattedResponse.status = "OK"; 117 formattedResponse.message = "Received AGENT-DEBUG-EMAIL notification"; 118 formattedResponse.emailTo = utils.getText(notif, "email_to"); 119 formattedResponse.requestedBy = utils.getText(notif, "requested_by"); 120 return formattedResponse; 121 }; 122 var DialGroupChangeNotification = function() { 123 }; 124 /* 125 * This class is responsible for handling a DIAL_GROUP_CHANGE notification. 126 * This event is sent from IQ when an agent's dial group is changed in through the AdminUI. 127 * 128 * { 129 * "ui_notification": { 130 * "@message_id": "IQ10012016080413085500263", 131 * "@type": "DIAL_GROUP_CHANGE", 132 * "agent_id": { "#text": "1180958" }, 133 * "dial_group_id": { "#text": "50354" }, 134 * "dialGroupName": { "#text": "Preview Dial Mode" }, 135 * "dial_group_desc": {} 136 * } 137 * } 138 */ 139 DialGroupChangeNotification.prototype.processResponse = function(notification) { 140 //Modify configRequest with new DialGroupId 141 var model = UIModel.getInstance(); 142 var notif = notification.ui_notification; 143 var origLoginType = model.configRequest.loginType; 144 var newDgId = utils.getText(notif, "dial_group_id"); 145 model.dialGroupChangeNotification = notification; 146 // Calculate type of login - called from AdminUI when assigning agent to new dial group. 147 // Only options should be BLENDED or OUTBOUND here. 148 if(newDgId && newDgId !== "" && (origLoginType === "INBOUND" || origLoginType === "BLENDED") ){ 149 model.configRequest.loginType = "BLENDED"; 150 }else if (newDgId && newDgId !== ""){ 151 model.configRequest.loginType = "OUTBOUND"; 152 }else if (origLoginType === "INBOUND"){ 153 model.configRequest.loginType = "INBOUND"; 154 }else{ 155 model.configRequest.loginType = "NO-SELECTION"; 156 } 157 UIModel.getInstance().configRequest.dialGroupId = newDgId; 158 var formattedResponse = { 159 message: "Dial Group Updated Successfully.", 160 detail: "Dial Group changed to [" + newDgId + "].", 161 dialGroupId: utils.getText(notif, "dial_group_id"), 162 dialGroupName: utils.getText(notif, "dialGroupName"), // camel case from server for some reason :/ 163 dialGroupDesc: utils.getText(notif, "dial_group_desc"), 164 agentId: utils.getText(notif, "agent_id") 165 }; 166 return formattedResponse; 167 }; 168 var DialGroupChangePendingNotification = function() { 169 }; 170 /* 171 * This class is responsible for handling a DIAL_GROUP_CHANGE_PENDING notification. 172 * This event is sent from IQ when an agent's dial group is changed and the agent is on a call. 173 * 174 * { 175 * "ui_notification": { 176 * "@message_id": "IQ10012016080515294800318", 177 * "@type": "DIAL_GROUP_CHANGE_PENDING", 178 * "agent_id": { "#text": "1180958" }, 179 * "dial_group_id": { "#text": "50354" }, 180 * "update_from_adminui": { "#text": "TRUE" } 181 * } 182 * } 183 */ 184 DialGroupChangePendingNotification.prototype.processResponse = function(notification) { 185 var model = UIModel.getInstance(); 186 var notif = notification.ui_notification; 187 model.agentSettings.pendingDialGroupChange = parseInt(utils.getText(notif, "dial_group_id"), 10); 188 // check if request originated with AdminUI 189 if(notif.update_from_adminui){ 190 model.agentSettings.updateDGFromAdminUI = utils.getText(notif, "update_from_adminui") === true; 191 }else{ 192 model.agentSettings.updateDGFromAdminUI = false; 193 } 194 var formattedResponse = { 195 message: "Dial Group Change Pending notification received.", 196 detail: "DialGroup switch for existing session pending until active call ends.", 197 agentId: utils.getText(notif, "agent_id"), 198 dialGroupId: utils.getText(notif, "dial_group_id"), 199 updateFromAdminUI: utils.getText(notif, "update_from_adminui") 200 }; 201 return formattedResponse; 202 }; 203 var DirectAgentTransferNotification = function() { 204 }; 205 /* 206 * This class is responsible for handling a DIRECT-AGENT-ROUTE notification. 207 * This event is sent from IQ when an agent is presented a direct transfer, in the case they are not in an 208 * available state to automatically be presented the call. 209 * 210 * { 211 * "ui_notification": { 212 * "@message_id": "IQ10012016080515294800318", 213 * "@type": "DIRECT-AGENT-ROUTE", 214 * "response_to": { "#text": "" }, 215 * "agent_id": { "#text": "" }, 216 * "uii": { "#text": "" }, 217 * "status": { "#text": "" }, 218 * "ani": { "#text": "" }, 219 * "dnis": { "#text": "" } 220 * "source_type": { "#text": "" }, 221 * "source_id": { "#text": "" }, 222 * "source_name": { "#text": "" } 223 * "voicemail_url": { "#text": "" } 224 * } 225 * } 226 */ 227 DirectAgentTransferNotification.prototype.processResponse = function(notification) { 228 var formattedResponse = utils.buildDefaultResponse(notification); 229 var notif = notification.ui_notification; 230 formattedResponse.message = "Received DIRECT-AGENT-ROUTE notification"; 231 formattedResponse.status = utils.getText(notif, "status"); 232 formattedResponse.agentId = utils.getText(notif, "agent_id"); 233 formattedResponse.uii = utils.getText(notif, "uii"); 234 formattedResponse.ani = utils.getText(notif, "ani"); 235 formattedResponse.dnis = utils.getText(notif, "dnis"); 236 formattedResponse.sourceType = utils.getText(notif, "source_type"); 237 formattedResponse.sourceId = utils.getText(notif, "source_id"); 238 formattedResponse.sourceName = utils.getText(notif, "source_name"); 239 formattedResponse.voicemailUrl = utils.getText(notif, "voicemail_url"); 240 return formattedResponse; 241 }; 242 var DropSessionNotification = function() { 243 }; 244 /* 245 * This class handles the DROP-SESSION packet from IQ. It doesn't really do anything 246 * besides format a response for the callback notification since there isn't any action needed. 247 * 248 * { 249 * "ui_notification": { 250 * "@message_id":"IQ10012016081613222800341", 251 * "@response_to":"", 252 * "@type":"DROP-SESSION", 253 * "session_id":{"#text":"3"}, 254 * "uii":{"#text":"201608161322180139000000000124"} 255 * } 256 * } 257 */ 258 DropSessionNotification.prototype.processResponse = function(notification) { 259 var formattedResponse = utils.buildDefaultResponse(notification); 260 var notif = notification.ui_notification; 261 var sessionId = utils.getText(notif, "session_id"); 262 var transfer = UIModel.getInstance().transferSessions[sessionId]; 263 // Check to see if we just disconnected a transfer session 264 // If so, we need to remove the session from our map 265 if(transfer){ 266 utils.logMessage(LOG_LEVELS.DEBUG, "Transfer to " + transfer.destination + " has terminated", ""); 267 delete UIModel.getInstance().transferSessions[sessionId]; 268 formattedResponse.transferEnd = transfer; 269 } 270 formattedResponse.message = "Received DROP-SESSION Notification"; 271 formattedResponse.status = "OK"; 272 formattedResponse.sessionId = utils.getText(notif, "session_id"); 273 formattedResponse.uii = utils.getText(notif, "uii"); 274 return formattedResponse; 275 }; 276 var EarlyUiiNotification = function() { 277 }; 278 /* 279 * This class is responsible for handling "EARLY_UII" packets from IntelliQueue. 280 * For manual outdials, this gives the uii to cancel a ringing line. 281 * 282 * { 283 * "ui_notification":{ 284 * "@message_id":"IQ10012016081611595000289", 285 * "@type":"EARLY_UII", 286 * "agent_id":{"#text":"1180958"}, 287 * "uii":{"#text":"201608161200240139000000000120"} 288 * } 289 * } 290 */ 291 EarlyUiiNotification.prototype.processResponse = function(notification) { 292 var formattedResponse = utils.buildDefaultResponse(notification); 293 var notif = notification.ui_notification; 294 formattedResponse.message = "Received EARLY_UII notification"; 295 formattedResponse.status = "OK"; 296 formattedResponse.agentId = utils.getText(notif, "agent_id"); 297 formattedResponse.uii = utils.getText(notif, "uii"); 298 return formattedResponse; 299 }; 300 var EndCallNotification = function(libInstance) { 301 this.libInstance = libInstance; 302 }; 303 /* 304 * This class is responsible for handling an END-CALL notification. 305 * Save the packet in the UIModel by appending it to the currentCall packet. 306 * Update the CallState field in the UIModel to "CALL-ENDED" 307 * 308 * { 309 * "ui_notification":{ 310 * "@message_id":"IQ982008082910362203349", 311 * "@response_to":"", 312 * "@type":"END-CALL", 313 * "agent_id":{"#text":"1856"}, 314 * "uii":{"#text":"200808291035510000000900029412"}, 315 * "session_id":{"#text":"2"}, 316 * "call_dts":{"#text":"2008-08-29 10:36:04"}, 317 * "call_duration":{"#text":"16"}, 318 * "term_party":{"#text":"CALLER"}, 319 * "term_reason":{}, 320 * "recording_url":{}, 321 * "disposition_timeout:{"#text":"60"} 322 * } 323 * } 324 */ 325 EndCallNotification.prototype.processResponse = function(notification) { 326 var model = UIModel.getInstance(); 327 var notif = notification.ui_notification; 328 model.endCallNotification = notification; 329 // add callDuration, termParty, and termReason to the current call packet 330 model.currentCall.duration = utils.getText(notif, "call_duration"); 331 model.currentCall.termParty = utils.getText(notif, "term_party"); 332 model.currentCall.termReason = utils.getText(notif, "term_reason"); 333 // set call state to "CALL-ENDED" 334 model.agentSettings.callState = "CALL-ENDED"; 335 model.agentSettings.onCall = false; 336 model.agentSettings.onManualOutdial = false; 337 // Clear out any transfer sessions from the previous call 338 model.transferSessions = {}; 339 // Check if there is a pending dial group change 340 if(model.agentSettings.pendingDialGroupChange > 0 || model.agentSettings.pendingDialGroupChange == -1) { 341 // update dial group id 342 model.configRequest.dialGroupId = model.agentSettings.pendingDialGroupChange; 343 // send login update request 344 this.libInstance.configureAgent(model.configRequest.queueIds, model.configRequest.chatIds, model.configRequest.skillProfileId, model.configRequest.dialGroupId, model.configRequest.dialDest, model.agentSettings.updateDGFromAdminUI); 345 // reset pending dial group variables 346 model.agentSettings.pendingDialGroupChange = 0; 347 model.agentSettings.updateDGFromAdminUI = false; 348 } 349 // start ping call interval timer, sends message every 30 seconds 350 // if this is not a manual outdial and we are not suppressing disposition pop 351 if(model.currentCall.outdialDispositions && model.currentCall.outdialDispositions.dispositions && model.currentCall.outdialDispositions.dispositions.length > 0 && model.currentCall.surveyPopType !== "SUPPRESS"){ 352 model.pingIntervalId = setInterval(utils.sendPingCallMessage, 30000); 353 } 354 var formattedResponse = { 355 message: "End Call Notification Received.", 356 detail: "", 357 uii: utils.getText(notif, "uii"), 358 sessionId: utils.getText(notif, "session_id"), 359 agentId: utils.getText(notif, "agent_id"), 360 callDts: utils.getText(notif, "call_dts"), 361 duration: model.currentCall.duration, 362 termParty: model.currentCall.termParty, 363 termReason: model.currentCall.termReason, 364 recordingUrl: utils.getText(notif, "recording_url"), 365 dispositionTimeout: utils.getText(notif, "disposition_timeout") 366 }; 367 return formattedResponse; 368 }; 369 var GatesChangeNotification = function() { 370 }; 371 /* 372 * This class is responsible for handling a gates change notification 373 * 374 * { 375 * "ui_notification":{ 376 * "@message_id":"IQ10012016080817344100936", 377 * "@type":"GATES_CHANGE", 378 * "agent_id":{"#text":"1180958"}, 379 * "gate_ids":{"#text":"11117,3"} 380 * } 381 * } 382 */ 383 GatesChangeNotification.prototype.processResponse = function(notification) { 384 var model = UIModel.getInstance(); 385 var notif = notification.ui_notification; 386 var newAssignedGates = []; 387 var availableQueues = model.inboundSettings.availableQueues; 388 var assignedGateIds = utils.getText(notif, "gate_ids"); 389 if(assignedGateIds !== ""){ 390 assignedGateIds = assignedGateIds.split(','); 391 } 392 for(var a = 0; a < assignedGateIds.length; a++){ 393 // find gate in avail list 394 var id = assignedGateIds[a]; 395 var foundGate = utils.findObjById(availableQueues, id, "gateId"); 396 if(foundGate){ 397 newAssignedGates.push(foundGate); 398 }else{ 399 // gate not in assigned list, add stub 400 var gate = { 401 gateId: id, 402 gateName:"", 403 gateDesc:"", 404 defaultDestOverride:"", 405 isAgentSelectable:false 406 }; 407 newAssignedGates.push(gate); 408 } 409 } 410 model.inboundSettings.queues = JSON.parse(JSON.stringify(newAssignedGates)); 411 var formattedResponse = { 412 agentId: utils.getText(notif, "agent_id"), 413 message: "Gates Change notification received.", 414 queues: newAssignedGates 415 }; 416 return formattedResponse; 417 }; 418 var GenericNotification = function() { 419 }; 420 /* 421 * This class is responsible for handling a generic notification 422 * 423 * { 424 * "ui_notification":{ 425 * "@message_id":"IQ10012016080317400400011", 426 * "@response_to":"1c2fe39f-a31e-aff8-8d23-92a61c88270f", 427 * "@type":"GENERIC", 428 * "message_code":{"#text":"0"}, 429 * "message":{"#text":"OK"}, 430 * "detail":{"#text":"Pending Callback Successfully Cancelled."} 431 * } 432 * } 433 */ 434 GenericNotification.prototype.processResponse = function(notification) { 435 var formattedResponse = utils.buildDefaultResponse(notification); 436 // add message and detail if present 437 formattedResponse.messageCode = utils.getText(notification.ui_notification,"message_code"); 438 return formattedResponse; 439 }; 440 var NewCallNotification = function() { 441 }; 442 /* 443 * This class processes a "NEW-CALL" packet received from Intelliqueue. It will determine 444 * if the call is a regular or monitoring call: 445 * @Monitoring==true: set state to ACTIVE-MONITORING, send NewMonitoringCall event 446 * @Monitoring==false: set state to ACTIVE, send newcall packet and increment total calls 447 * 448 * {"ui_notification":{ 449 * "@message_id":"IQ982010020911335300027", 450 * "@response_to":"", 451 * "@type":"NEW-CALL", 452 * "uii":{"#text":"201002091133350139990000000010"}, 453 * "ani":{"#text":"9548298548"}, 454 * "dnis":{}, 455 * "dial_dest":{"#text":"sip:+16789050673@sip.connectfirst.com"}, 456 * "call_type":{"#text":"OUTBOUND"}, 457 * "queue_dts":{"#text":"2010-02-09 11:33:53"}, 458 * "queue_time":{"#text":"-1"}, 459 * "agent_id":{"#text":"657"}, 460 * "app_url":{}, 461 * "is_monitoring":{"#text":"FALSE"}, 462 * "script_id":{}, 463 * "script_version":{}, 464 * "survey_id":{}, 465 * "survey_pop_type":{"#text":"SUPPRESS"}, 466 * "message":{}, 467 * "agent_recording":{"@default":"ON","@pause":"10","#text":"TRUE"}, 468 * "hangup_on_disposition":{"#text":"FALSE"}, 469 * "gate":{ 470 * "@number":"17038", 471 * "name":{"#text":"AM Campaign"}, 472 * "description":{} 473 * }, 474 * "outdial_dispositions":{ 475 * "@type":"CAMPAIGN|GATE", 476 * "disposition":[ 477 * { "@contact_forwarding":"FALSE", "@disposition_id":"20556", "@is_complete":"1", "@is_default"="0", "@require_note"="0", "@save_survey"="1", "@xfer"="0", "#text":"Not Available"}, 478 * { "@contact_forwarding":"FALSE", "@disposition_id":"20559", "@is_complete":"1", "@is_default"="1", "@require_note"="1", "@save_survey"="1", "@xfer"="0", #text":"Transfer Not Available"} 479 * ] 480 * }, 481 * "requeue_shortcuts":{ 482 * "requeue_shortcut":[ 483 * { "@gate_id":"2", "@name":"test queue" "@skill_id":""} 484 * ] 485 * }, 486 * "baggage":{ 487 * "@allow_updates":"TRUE", 488 * "@show_lead_passes":"TRUE", 489 * "@show_list_name":"TRUE", 490 * "aux_phone":{}, 491 * "aux_greeting":{}, 492 * "aux_external_url":{}, 493 * "aux_data1":{"#text":"BMAK"}, 494 * "aux_data2":{"#text":"BMAK-041653-934"}, 495 * "aux_data3":{"#text":"Call Ctr 1"}, 496 * "aux_data4":{}, 497 * "aux_data5":{}, 498 * "extern_id":{"#text":"9548298548"}, 499 * "lead_id":{"#text":"64306"}, 500 * "lead_passes":{"#text":"1"}, 501 * "first_name":{"#text":"Ryant"}, 502 * "last_name":{"#text":"Taylor"}, 503 * "mid_name":{}, 504 * "address1":{"#text":"8010 Maryland Ave"}, 505 * "address2":{}, 506 * "city":{"#text":"Cleveland"}, 507 * "state":{"#text":"OH"}, 508 * "zip":{"#text":"44105"}, 509 * "custom_labels":{ 510 * "aux_1_label":{}, 511 * "aux_2_label":{}, 512 * "aux_3_label":{}, 513 * "aux_4_label":{}, 514 * "aux_5_label":{} 515 * } 516 * }, 517 * "survey_response":{ 518 * "@response_id":"24", 519 * "@survey_id":"1775", 520 * "details":{ 521 * "detail":[ 522 * {"@element_id":"9001","@option_id":"0","#text":"Box 1"}, 523 * {"@element_id":"9002","@option_id":"0","#text":"Area 1"}, 524 * {"@element_id":"9003","@option_id":"6439"}, 525 * {"@element_id":"9004","@option_id":"6443"}, 526 * {"@element_id":"9004","@option_id":"6444"}, 527 * {"@element_id":"9005","@option_id":"6447"}, 528 * {"@element_id":"9006","@option_id":"0","#text":"11/20/2013"}, 529 * {"@element_id":"9015","@option_id":"0","#text":"Box 2"}, 530 * {"@element_id":"9016","@option_id":"0","#text":"Area 2"}, 531 * {"@element_id":"9017","@option_id":"6466"}, 532 * {"@element_id":"9018","@option_id":"6471"}, 533 * {"@element_id":"9018","@option_id":"6472"}, 534 * {"@element_id":"9019","@option_id":"6477"}, 535 * {"@element_id":"9020","@option_id":"0","#text":"11/21/2013"} 536 * ] 537 * } 538 * } 539 * } 540 * } 541 */ 542 NewCallNotification.prototype.processResponse = function(notification) { 543 var model = UIModel.getInstance(); 544 var notif = notification.ui_notification; 545 // set up new call obj 546 var newCall = { 547 uii: utils.getText(notif,'uii'), 548 agentId: utils.getText(notif,'agent_id'), 549 dialDest: utils.getText(notif,'dial_dest'), 550 queueDts: utils.getText(notif,'queue_dts'), 551 queueTime: utils.getText(notif,'queue_time'), 552 ani: utils.getText(notif,'ani'), 553 dnis: utils.getText(notif,'dnis'), 554 callType: utils.getText(notif,'call_type'), 555 appUrl: utils.getText(notif,'app_url'), 556 isMonitoring: utils.getText(notif,'is_monitoring'), 557 allowHold: utils.getText(notif,'allow_hold'), 558 allowTransfer: utils.getText(notif,'allow_transfer'), 559 allowManualInternationalTransfer: utils.getText(notif,'allow_manual_international_transfer'), 560 allowDirectAgentTransfer: utils.getText(notif,'allow_direct_agent_transfer'), 561 allowHangup: utils.getText(notif,'allow_hangup'), 562 allowRequeue: utils.getText(notif,'allow_requeue'), 563 allowEndCallForEveryone: utils.getText(notif,'allow_endcallforeveryone'), 564 scriptId: utils.getText(notif,'script_id'), 565 scriptVersion: utils.getText(notif,'script_version'), 566 surveyId: utils.getText(notif,'survey_id'), 567 surveyPopType: utils.getText(notif,'survey_pop_type'), 568 requeueType: utils.getText(notif,'requeue_type'), 569 hangupOnDisposition: utils.getText(notif,'hangup_on_disposition') 570 }; 571 if(newCall.isMonitoring) { 572 newCall.monitoringType = utils.getText(notif,'monitoring_type'); // FULL, COACHING, MONITOR 573 } 574 // set collection values 575 newCall.queue = utils.processResponseCollection(notification, 'ui_notification', 'gate')[0]; 576 newCall.agentRecording = utils.processResponseCollection(notification, 'ui_notification', 'agent_recording', 'agentRecording')[0]; 577 newCall.outdialDispositions = utils.processResponseCollection(notification, 'ui_notification', 'outdial_dispositions', 'disposition')[0]; 578 newCall.requeueShortcuts = utils.processResponseCollection(notification, 'ui_notification', 'requeue_shortcuts', 'requeueShortcut')[0] || []; 579 newCall.baggage = utils.processResponseCollection(notification, 'ui_notification', 'baggage')[0]; 580 newCall.surveyResponse = utils.processResponseCollection(notification, 'ui_notification', 'survey_response', 'detail')[0]; 581 newCall.scriptResponse = {}; 582 newCall.transferPhoneBook = utils.processResponseCollection(notification, 'ui_notification', 'transfer_phone_book')[0]; 583 newCall.lead = utils.processResponseCollection(notification, 'ui_notification', 'lead')[0]; 584 // parse extra data correctly 585 try { 586 if(notif.lead && notif.lead.extra_data) { 587 delete newCall.lead.extraDatas; 588 newCall.lead.extraData = {}; 589 for(var key in notif.lead.extra_data) { 590 newCall.lead.extraData[key] = notif.lead.extra_data[key]['#text']; 591 } 592 } 593 } catch(e) { 594 console.warn('error parsing new call lead extra data: ' + e); 595 } 596 if(newCall.baggage) { 597 // process custom labels correctly 598 newCall.baggage.customLabels = {}; 599 var notifLabels = notif.baggage['custom_labels']; 600 for(var key in notifLabels) { 601 var result = ''; 602 if(notifLabels && notifLabels[key] && notifLabels[key]['#text']) { 603 result = notifLabels[key]['#text']; 604 } 605 newCall.baggage.customLabels[key] = result; 606 } 607 } 608 // set saved script response if present 609 try{ 610 var savedModel = JSON.parse(notif.script_result["#text"]).model; 611 var results = {}; 612 var keys = Object.keys(savedModel); 613 for(var idx = 0; idx < keys.length; idx++){ 614 var key = keys[idx]; 615 var value = savedModel[key].value; 616 results[key] = value; 617 } 618 newCall.scriptResponse = results; 619 }catch(err){} 620 // fix phonebook format 621 if(newCall.transferPhoneBook && newCall.transferPhoneBook.entrys){ 622 newCall.transferPhoneBook = newCall.transferPhoneBook.entrys; 623 } 624 // fix requeue shortcuts 625 if(newCall.requeueShortcuts && newCall.requeueShortcuts.requeueShortcuts){ 626 newCall.requeueShortcuts = newCall.requeueShortcuts.requeueShortcuts; 627 } 628 // if only one disposition, convert to array 629 if(newCall.outdialDispositions && newCall.outdialDispositions.disposition){ 630 newCall.outdialDispositions.dispositions = [newCall.outdialDispositions] 631 } 632 // convert numbers to boolean where applicable 633 newCall.queue.isCampaign = newCall.queue.isCampaign === "1"; 634 if(newCall.outdialDispositions && newCall.outdialDispositions.dispositions){ 635 for(var d = 0; d < newCall.outdialDispositions.dispositions.length; d++) { 636 var disp = newCall.outdialDispositions.dispositions[d]; 637 disp.isComplete = disp.isComplete === "1"; 638 disp.requireNote = disp.requireNote === "1"; 639 disp.saveSurvey = disp.saveSurvey === "1"; 640 disp.xfer = disp.xfer === "1"; 641 disp.isDefault = disp.isDefault === "1"; 642 } 643 } 644 // Build token map 645 model.callTokens = buildCallTokenMap(notif, newCall); 646 newCall.baggage = model.callTokens; // add all tokens to baggage 647 // Is Monitoring Call? 648 if(newCall.isMonitoring){ 649 model.agentSettings.callState = "ACTIVE-MONITORING"; 650 }else{ 651 model.agentSettings.callState = "ACTIVE"; 652 // check for preloaded transfer number 653 if(newCall.baggage && newCall.baggage.auxPhone != ""){ 654 model.transferNumber = newCall.baggage.auxPhone; 655 } 656 } 657 // Reset the current call counter for Agent Daily Stats 658 model.agentDailyStats.currCallTime = 0; 659 // todo handle scripting?? 660 model.currentCall = newCall; 661 return newCall; 662 }; 663 function buildCallTokenMap(notif, newCall){ 664 var model = UIModel.getInstance(); 665 var tokens = newCall.baggage || {}; // seed with baggage values 666 if(notif.baggage && notif.baggage.generic_key_value_pairs){ 667 var keyValuePairs = []; 668 var keyValuePairsStr = utils.getText(notif.baggage, 'generic_key_value_pairs'); 669 if (keyValuePairsStr.length > 0){ 670 keyValuePairs = utils.parseKeyValuePairsFromString(keyValuePairsStr, "|", "::"); 671 } 672 for(var keyValue in keyValuePairs){ 673 tokens[keyValue] = keyValuePairs[keyValue]; 674 } 675 } 676 tokens["ani"] = newCall.ani; 677 tokens["dnis"] = newCall.dnis; 678 tokens["uii"] = newCall.uii; 679 try{ 680 if(newCall.queue.number){ 681 tokens["sourceId"] = newCall.queue.number || ""; 682 tokens["sourceName"] = newCall.queue.name || ""; 683 tokens["sourceDesc"] = newCall.queue.description || ""; 684 if(newCall.queue.isCampaign === "1" || newCall.queue.isCampaign === true){ 685 tokens["sourceType"] = "OUTBOUND"; 686 }else{ 687 tokens["sourceType"] = "INBOUND"; 688 } 689 }else{ 690 tokens["sourceId"] = "0"; 691 tokens["sourceType"] = "MANUAL"; 692 tokens["sourceName"] = ""; 693 tokens["sourceDesc"] = ""; 694 } 695 }catch(any){ 696 console.error("There was an error processing source tokenization", + any); 697 } 698 try{ 699 tokens["agentFirstName"] = model.agentSettings.firstName; 700 tokens["agentLastName"] = model.agentSettings.lastName; 701 tokens["agentExternalId"] = model.agentSettings.externalAgentId; 702 tokens["agentType"] = model.agentSettings.agentType; 703 tokens["agentEmail"] = model.agentSettings.email; 704 tokens["agentUserName"] = model.agentSettings.username; 705 }catch(any){ 706 console.error("There was an error parsing tokens for agent info. ", any); 707 } 708 return tokens; 709 } 710 function isCampaign(gate){ 711 if (gate && gate.isCampaign){ 712 return gate.isCampaign === "1" || gate.isCampaign === true; 713 } 714 return false; 715 } 716 var PendingChatDispNotification = function() { 717 }; 718 /* 719 * This class is responsible for handling a generic notification 720 * 721 * { 722 * "ui_notification":{ 723 * "@message_id":"IQD01DEV2018062912352800014", 724 * "@type":"PENDING_CHAT_DISP", 725 * "agent_id":{ "#text":"1182160" }, 726 * "uii":{ "#text":"201806291234550147950000000000" }, 727 * "status":{ "#text":"false" } 728 * } 729 * } 730 */ 731 PendingChatDispNotification.prototype.processResponse = function(notification) { 732 var formattedResponse = {}; 733 formattedResponse.agentId = utils.getText(notification.ui_notification,"agent_id"); 734 formattedResponse.uii = utils.getText(notification.ui_notification,"uii"); 735 formattedResponse.status = utils.getText(notification.ui_notification,"status") === 'true'; 736 return formattedResponse; 737 }; 738 var PendingDispNotification = function() { 739 }; 740 /* 741 * This class is responsible for handling a generic notification 742 * 743 * { 744 * "ui_notification":{ 745 * "@message_id":"IQ10012016080317400400011", 746 * "@type":"PENDING_DISP", 747 * "agent_id":{"#text":"3"}, 748 * "status":{"#text":"false"} 749 * } 750 * } 751 */ 752 PendingDispNotification.prototype.processResponse = function(notification) { 753 var formattedResponse = {}; 754 formattedResponse.agentId = utils.getText(notification.ui_notification,"agent_id"); 755 formattedResponse.status = utils.getText(notification.ui_notification,"status"); 756 return formattedResponse; 757 }; 758 var PreviewLeadStateNotification = function() { 759 }; 760 /* 761 * This class is responsible for processing the lead state packet 762 * received from intelliqueue. It will decide what type of leads are 763 * being processed, and depending on if the callback is true or false, it will 764 * call the appropriate form to update the lead state. 765 * 766 * { 767 * "ui_notification":{ 768 * "@type":"PREVIEW-LEAD-STATE", 769 * "@call_type":"MANUAL|PREVIEW", 770 * "@message_id":"IQ10012016092715393600184", 771 * "request_id":{"#text":"IQ10012016092715390900179"}, 772 * "lead_state":{"#text":"ANSWER"}, 773 * "callback":{"#text":"FALSE"} 774 * } 775 * } 776 * } 777 */ 778 PreviewLeadStateNotification.prototype.processResponse = function(notification) { 779 var notif = notification.ui_notification; 780 UIModel.getInstance().agentSettings.onManualOutdial = true; 781 var response = { 782 callType: notif['@call_type'], 783 messageId: notif['@message_id'], 784 requestId: utils.getText(notif, "request_id"), 785 leadState: utils.getText(notif,"lead_state"), 786 callback: utils.getText(notif,"callback") 787 }; 788 return response; 789 }; 790 var ReverseMatchNotification = function() { 791 }; 792 /* 793 * This class is responsible for processing a REVERSE_MATCH packet from IQ. It 794 * will log the packet was rec'd, save the packet to the UIModel for use by 795 * components like the WhosCallingForm 796 * { 797 * "ui_notification":{ 798 * "@message_id":"IQ10012016080317400400011", 799 * "@response_to":"1c2fe39f-a31e-aff8-8d23-92a61c88270f", 800 * "@type":"REVERSE_MATCH", 801 * "first_name":{"#text":""}, 802 * "mid_name":{"#text":""}, 803 * "last_name":{"#text":""}, 804 * "address1":{"#text":""}, 805 * "address2":{"#text":""}, 806 * "city":{"#text":""}, 807 * "state":{"#text":""}, 808 * "zip":{"#text":""}, 809 * "business_name":{"#text":""} 810 * } 811 * } 812 */ 813 ReverseMatchNotification.prototype.processResponse = function(notification) { 814 var notif = notification.ui_notification; 815 var model = UIModel.getInstance(); 816 model.tokens["first_name"] = utils.getText(notif,'first_name'); 817 model.tokens["mid_name"] = utils.getText(notif,'mid_name'); 818 model.tokens["last_name"] = utils.getText(notif,'last_name'); 819 model.tokens["address1"] = utils.getText(notif,'address1'); 820 model.tokens["address2"] = utils.getText(notif,'address2'); 821 model.tokens["suffix"] = utils.getText(notif,'suffix'); 822 model.tokens["title"] = utils.getText(notif,'title'); 823 model.tokens["city"] = utils.getText(notif,'city'); 824 model.tokens["state"] = utils.getText(notif,'state'); 825 model.tokens["zip"] = utils.getText(notif,'zip'); 826 model.tokens["business_name"] = utils.getText(notif,'business_name'); 827 return model.tokens; 828 }; 829 var TcpaSafeLeadStateNotification = function() { 830 }; 831 /* 832 * This class is responsible for processing the lead state packet 833 * received from intelliqueue. It will decide what type of leads are 834 * being processed, and depending on if the callback is true or false, it will 835 * call the appropriate form to update the lead state. 836 * 837 * { 838 * "ui_notification":{ 839 * "@message_id":"IQ10012016080317400400011", 840 * "@type":"TCPA-SAFE-LEAD-STATE", 841 * "@call_type":"MANUAL|TCPA-SAFE", 842 * "request_id":{"#text":""}, 843 * "lead_state":{"#text":"CALLING"}, 844 * "callback":{"#text":"false"} 845 * } 846 * } 847 */ 848 TcpaSafeLeadStateNotification.prototype.processResponse = function(notification) { 849 var notif = notification.ui_notification; 850 var response = { 851 callType: notif['@call_type'], 852 messageId: notif['@message_id'], 853 requestId: utils.getText(notif, "request_id"), 854 leadState: utils.getText(notif,"lead_state"), 855 callback: utils.getText(notif,"callback") 856 }; 857 return response; 858 }; 859 var AckRequest = function(audioType, agentId, uii, monitorAgentId) { 860 this.audioType = audioType || "FULL"; 861 this.agentId = agentId; 862 this.uii = uii; 863 this.monitorAgentId = monitorAgentId; 864 }; 865 /* 866 * This class processes ACK packets rec'd from IQ. 867 * This is a callback triggered by certain actions like 868 * sending dispositions or script results. 869 * NOTE: uii is added in utils message processing. 870 * 871 * {"ui_response":{ 872 * "@message_id":"IQ982008090317393001252", 873 * "@response_to":"1112222", 874 * "@type":"ACK", 875 * "type":{"#text":"CHAT-DISPOSITION|INBOUND-DISPOSITION|OUTDIAL-DISPOSITION|SCRIPT-RESULT"}, 876 * "status":{"#text":"OK|FAILURE"}, 877 * "message":{"#text":""}, 878 * "detail":{} 879 * } 880 * } 881 */ 882 AckRequest.prototype.processResponse = function(response) { 883 var resp = response.ui_response; 884 var formattedResponse = utils.buildDefaultResponse(response); 885 formattedResponse.type = utils.getText(resp, 'type'); 886 if(formattedResponse.status === "OK"){ 887 utils.logMessage(LOG_LEVELS.DEBUG, formattedResponse.message, response); 888 }else{ 889 utils.logMessage(LOG_LEVELS.WARN, formattedResponse.message + ': ' + formattedResponse.detail, response); 890 } 891 return formattedResponse; 892 }; 893 var AgentStateRequest = function(agentState, agentAuxState) { 894 if(agentState.toUpperCase() == "ON-BREAK" && UIModel.getInstance().onCall == true){ 895 this.agentState = "BREAK-AFTER-CALL"; 896 this.agentAuxState = ""; 897 }else{ 898 this.agentState = agentState.toUpperCase() || ""; 899 this.agentAuxState = agentAuxState || ""; 900 } 901 }; 902 AgentStateRequest.prototype.formatJSON = function() { 903 var msg = { 904 "ui_request": { 905 "@destination":"IQ", 906 "@type":MESSAGE_TYPES.AGENT_STATE, 907 "@message_id":utils.getMessageId(), 908 "response_to":"", 909 "agent_id":{ 910 "#text":UIModel.getInstance().agentSettings.agentId 911 }, 912 "state":{ 913 "#text":this.agentState 914 }, 915 "agent_aux_state":{ 916 "#text":this.agentAuxState 917 } 918 } 919 }; 920 return JSON.stringify(msg); 921 }; 922 /* 923 * This class processes AGENT-STATE packets rec'd from IQ. It will check the state of the 924 * packet and then set the state on the model. It will also check for deferred surveys, 925 * if one is found it will load it at this point. 926 * 927 * {"ui_response":{ 928 * "@message_id":"IQ982008082817165103294", 929 * "@type":"AGENT-STATE", 930 * "status":{"#text":"OK"}, 931 * "message":{}, 932 * "detail":{}, 933 * "agent_id":{"#text":"1856"}, 934 * "prev_state":{"#text":"ENGAGED"}, 935 * "current_state":{"#text":"WORKING"}, 936 * "agent_aux_state":{"#text":"Offhook Work"}, 937 * "prev_aux_state":{} 938 * } 939 * } 940 */ 941 AgentStateRequest.prototype.processResponse = function(response) { 942 var resp = response.ui_response; 943 var status = utils.getText(resp, "status"); 944 var prevState = utils.getText(resp, "prev_state"); 945 var currState = utils.getText(resp, "current_state"); 946 var prevAuxState = utils.getText(resp, "prev_aux_state"); 947 var currAuxState = utils.getText(resp, "agent_aux_state"); 948 var model = UIModel.getInstance(); 949 // add message and detail if present 950 var formattedResponse = utils.buildDefaultResponse(response); 951 formattedResponse.agentId = response.ui_response.agent_id['#text'] || ""; 952 formattedResponse.previousState = prevState; 953 formattedResponse.currentState = currState; 954 formattedResponse.previousAuxState = prevAuxState; 955 formattedResponse.currentAuxState = currAuxState; 956 if(status=="OK"){ 957 var prevStateStr = prevState; 958 var currStateStr = currState; 959 if(prevAuxState.length > 0){ 960 prevStateStr = prevAuxState; 961 } 962 if(currAuxState.length > 0){ 963 currStateStr = currAuxState; 964 } 965 // Update the state in the UIModel 966 model.agentSettings.currentState = currState; 967 model.agentSettings.currentStateLabel = currAuxState; 968 model.agentStatePacket = response; 969 }else{ 970 if(formattedResponse.message === ""){ 971 formattedResponse.message = "Unable to change agent state"; 972 } 973 // log message response 974 var message = "Unable to change agent state. " + formattedResponse.detail; 975 utils.logMessage(LOG_LEVELS.WARN, message, response); 976 } 977 return formattedResponse; 978 }; 979 var BargeInRequest = function(audioType, agentId, uii, monitorAgentId) { 980 this.audioType = audioType || "FULL"; 981 this.agentId = agentId; 982 this.uii = uii; 983 this.monitorAgentId = monitorAgentId; 984 }; 985 /* 986 * 987 * {"ui_request":{ 988 * "@destination":"IQ", 989 * "@message_id":"UIV22008931055822", 990 * "@response_to":"", 991 * "@type":"BARGE-IN", 992 * "agent_id":{"#text":"94"}, 993 * "uii":{"#text":"200809031054510000000900020961"}, 994 * "audio_state":{"#text":"FULL"}, 995 * "monitor_agent_id":{"#text":"1856"} 996 * } 997 * } 998 */ 999 BargeInRequest.prototype.formatJSON = function() { 1000 var model = UIModel.getInstance(); 1001 var msg = { 1002 "ui_request": { 1003 "@destination":"IQ", 1004 "@type":MESSAGE_TYPES.BARGE_IN, 1005 "@message_id":utils.getMessageId(), 1006 "@response_to":"", 1007 "agent_id":{ 1008 "#text":utils.toString(this.agentId) 1009 }, 1010 "uii":{ 1011 "#text":utils.toString(this.uii) 1012 }, 1013 "audio_state":{ 1014 "#text":utils.toString(this.audioType) 1015 }, 1016 "monitor_agent_id":{ 1017 "#text":utils.toString(this.monitorAgentId) 1018 } 1019 } 1020 }; 1021 return JSON.stringify(msg); 1022 }; 1023 /* 1024 * This class processes BARGE-IN packets rec'd from IQ. 1025 * 1026 * {"ui_response":{ 1027 * "@message_id":"IQ982008090317393001252", 1028 * "@response_to":"", 1029 * "@type":"BARGE-IN", 1030 * "agent_id":{"#text":"94"}, 1031 * "uii":{}, 1032 * "status":{"#text":"OK"}, 1033 * "message":{"#text":"Barge-In processed successfully!"}, 1034 * "detail":{} 1035 * } 1036 * } 1037 */ 1038 BargeInRequest.prototype.processResponse = function(response) { 1039 var resp = response.ui_response; 1040 var formattedResponse = utils.buildDefaultResponse(response); 1041 formattedResponse.agentId = utils.getText(resp, 'agent_id'); 1042 formattedResponse.uii = utils.getText(resp, 'uii'); 1043 if(formattedResponse.status === "OK"){ 1044 utils.logMessage(LOG_LEVELS.DEBUG, formattedResponse.message, response); 1045 }else{ 1046 utils.logMessage(LOG_LEVELS.WARN, "There was an error processing the Barge-In request. " + formattedResponse.detail, response); 1047 } 1048 return formattedResponse; 1049 }; 1050 var CallNotesRequest = function(notes) { 1051 this.notes = notes; 1052 }; 1053 /* 1054 * This event is responsible for allowing an agent to tag a call with notes 1055 */ 1056 CallNotesRequest.prototype.formatJSON = function() { 1057 var model = UIModel.getInstance(); 1058 var msg = { 1059 "ui_request": { 1060 "@destination":"IQ", 1061 "@message_id":utils.getMessageId(), 1062 "response_to":"", 1063 "@type":MESSAGE_TYPES.CALL_NOTES, 1064 "agent_id": { 1065 "#text" : utils.toString(model.agentSettings.agentId) 1066 }, 1067 "uii": { 1068 "#text" : utils.toString(model.currentCall.uii) 1069 }, 1070 "notes": { 1071 "#text" : utils.toString(this.notes) 1072 } 1073 } 1074 }; 1075 return JSON.stringify(msg); 1076 }; 1077 /* 1078 * This class process CALL-NOTES packets rec'd from IntelliQueue. 1079 * 1080 * {"ui_response":{ 1081 * "@message_id":"IQ982008082817165103294", 1082 * "@type":"CALL-NOTES", 1083 * "status":{"#text":"OK"}, 1084 * "message":{}, 1085 * "detail":{} 1086 * } 1087 * } 1088 */ 1089 CallNotesRequest.prototype.processResponse = function(response) { 1090 var formattedResponse = utils.buildDefaultResponse(response); 1091 if(formattedResponse.status === "OK"){ 1092 formattedResponse.message = "Call notes have been updated."; 1093 formattedResponse.type = "INFO_EVENT"; 1094 }else{ 1095 formattedResponse.type = "ERROR_EVENT"; 1096 formattedResponse.message = "Unable to update notes."; 1097 } 1098 return formattedResponse; 1099 }; 1100 var CallbackCancelRequest = function(leadId, agentId) { 1101 this.agentId = agentId || UIModel.getInstance().agentSettings.agentId; 1102 this.leadId = leadId; 1103 }; 1104 CallbackCancelRequest.prototype.formatJSON = function() { 1105 var msg = { 1106 "ui_request": { 1107 "@destination":"IQ", 1108 "@type":MESSAGE_TYPES.CALLBACK_CANCEL, 1109 "@message_id":utils.getMessageId(), 1110 "response_to":"", 1111 "agent_id":{ 1112 "#text":this.agentId 1113 }, 1114 "lead_id":{ 1115 "#text":this.leadId 1116 } 1117 } 1118 }; 1119 return JSON.stringify(msg); 1120 }; 1121 // NOTE: cancel callback response sent as a generic notification message 1122 var CallbacksPendingRequest = function(agentId) { 1123 this.agentId = agentId || UIModel.getInstance().agentSettings.agentId; 1124 }; 1125 CallbacksPendingRequest.prototype.formatJSON = function() { 1126 var msg = { 1127 "ui_request": { 1128 "@destination":"IQ", 1129 "@type":MESSAGE_TYPES.CALLBACK_PENDING, 1130 "@message_id":utils.getMessageId(), 1131 "response_to":"", 1132 "agent_id":{ 1133 "#text":this.agentId 1134 } 1135 } 1136 }; 1137 return JSON.stringify(msg); 1138 }; 1139 /* 1140 * This class is responsible for handling an PENDING-CALLBACKS response packet from IntelliQueue. 1141 * 1142 * {"ui_response":{ 1143 * "@message_id":"IQ982008091512353000875", 1144 * "@response_to":"UIV220089151235539", 1145 * "@type":"PENDING-CALLBACKS", 1146 * "lead":{ 1147 * "@aux_data1":"", 1148 * "@aux_data2":"", 1149 * "@aux_data3":"", 1150 * "@aux_data4":"", 1151 * "@aux_data5":"", 1152 * "@destination":"5555555555", 1153 * "@dial_group_id":"", 1154 * "@dial_group_name":"", 1155 * "@dial_time":"2016-08-03 10:00", 1156 * "@extern_id":"", 1157 * "@lead_id":"", 1158 * "lead_id":{}, 1159 * "extern_id":{}, 1160 * "extern_id":{}, 1161 * "first_name":{}, 1162 * "mid_name":{}, 1163 * "last_name":{}, 1164 * "suffix":{}, 1165 * "title":{}, 1166 * "address1":{}, 1167 * "address2":{}, 1168 * "city":{}, 1169 * "state":{}, 1170 * "zip":{}, 1171 * "gate_keeper":{} 1172 * } 1173 * } 1174 * } 1175 */ 1176 CallbacksPendingRequest.prototype.processResponse = function(response) { 1177 var leadsRaw = response.ui_response.lead; 1178 var leads = []; 1179 if(!Array.isArray(leadsRaw)) { 1180 leadsRaw = [leadsRaw]; 1181 } 1182 for(var l = 0; l < leadsRaw.length; l++){ 1183 var leadRaw = leadsRaw[l]; 1184 if (leadRaw == null) { 1185 continue; 1186 } 1187 leads.push(parseLead(leadRaw)); 1188 } 1189 UIModel.getInstance().agentSettings.pendingCallbacks = JSON.parse(JSON.stringify(leads)); 1190 return UIModel.getInstance().agentSettings.pendingCallbacks; 1191 }; 1192 function parseLead(leadRaw){ 1193 var lead = { 1194 auxData1 : leadRaw['@aux_data1'], 1195 auxData2 : leadRaw['@aux_data2'], 1196 auxData3 : leadRaw['@aux_data3'], 1197 auxData4 : leadRaw['@aux_data4'], 1198 auxData5 : leadRaw['@aux_data5'], 1199 destination : leadRaw['@destination'], 1200 dialGroupId : leadRaw['@dial_group_id'], 1201 dialGroupName : leadRaw['@dial_group_name'], 1202 dialTime : leadRaw['@dial_time'], 1203 externId : leadRaw['@extern_id'], 1204 leadId : leadRaw['@lead_id'], 1205 firstName : utils.getText(leadRaw, "first_name"), 1206 midName : utils.getText(leadRaw, "mid_name"), 1207 lastName : utils.getText(leadRaw, "last_name"), 1208 sufix : utils.getText(leadRaw, "suffix"), 1209 title : utils.getText(leadRaw, "title"), 1210 address1 : utils.getText(leadRaw, "address1"), 1211 address2 : utils.getText(leadRaw, "address2"), 1212 city : utils.getText(leadRaw, "city"), 1213 state : utils.getText(leadRaw, "state"), 1214 zip : utils.getText(leadRaw, "zip"), 1215 gateKeeper : utils.getText(leadRaw, "gate_keeper") 1216 }; 1217 return lead; 1218 } 1219 /* 1220 * This request is used to get the list of dispositions for a given campaign 1221 * E.g. in the lead search form for manual passes 1222 * 1223 */ 1224 var CampaignDispositionsRequest = function(campaignId) { 1225 this.agentId = UIModel.getInstance().agentSettings.agentId; 1226 this.campaignId = campaignId; 1227 }; 1228 CampaignDispositionsRequest.prototype.formatJSON = function() { 1229 var msg = { 1230 "ui_request": { 1231 "@destination":"IQ", 1232 "@type":MESSAGE_TYPES.CAMPAIGN_DISPOSITIONS, 1233 "@message_id":utils.getMessageId(), 1234 "response_to":"", 1235 "agent_id":{ 1236 "#text":utils.toString(this.agentId) 1237 }, 1238 "campaign_id": { 1239 "#text":utils.toString(this.campaignId) 1240 } 1241 } 1242 }; 1243 return JSON.stringify(msg); 1244 }; 1245 /* 1246 * This class is responsible for handling CAMPAIGN-DISPOSITIONS packets received 1247 * from IntelliQueue. It will save a copy of it in the UIModel. 1248 * 1249 * {"ui_response":{ 1250 * "@campaign_id":"60403", 1251 * "@message_id":"IQ10012016081813480400006", 1252 * "@response_to":"0b61c3ca-c4fc-9942-c139-da4978053c9d", 1253 * "@type":"CAMPAIGN-DISPOSITIONS", 1254 * "outdial_dispositions":{ 1255 * "disposition":[ 1256 * {"@disposition_id":"1","#text":"requeue"}, 1257 * {"@disposition_id":"2","#text":"complete"} 1258 * ] 1259 * } 1260 * } 1261 * } 1262 */ 1263 CampaignDispositionsRequest.prototype.processResponse = function(response) { 1264 var resp = response.ui_response; 1265 var model = UIModel.getInstance(); 1266 var dispositions = utils.processResponseCollection(resp, 'outdial_dispositions', 'disposition', 'disposition'); 1267 model.outboundSettings.campaignDispositions = dispositions; 1268 return dispositions; 1269 }; 1270 var ChatStateRequest = function(chatState) { 1271 this.chatState = (chatState && chatState.toUpperCase()) || ""; 1272 }; 1273 ChatStateRequest.prototype.formatJSON = function() { 1274 var msg = { 1275 "ui_request": { 1276 "@destination":"IQ", 1277 "@type":MESSAGE_TYPES.CHAT_STATE, 1278 "@message_id":utils.getMessageId(), 1279 "response_to":"", 1280 "agent_id":{ 1281 "#text":UIModel.getInstance().agentSettings.agentId 1282 }, 1283 "state":{ 1284 "#text":this.chatState 1285 } 1286 } 1287 }; 1288 return JSON.stringify(msg); 1289 }; 1290 /* 1291 * This class processes CHAT-STATE packets rec'd from IQ. It will check the state of the 1292 * packet and then set the state on the model. 1293 * 1294 * {"ui_response":{ 1295 * "@message_id":"IQ982008082817165103294", 1296 * "@type":"AGENT-STATE", 1297 * "status":{"#text":"OK"}, 1298 * "message":{}, 1299 * "detail":{}, 1300 * "agent_id":{"#text":"1856"}, 1301 * "prev_state":{"#text":"CHAT-PRESENTED"}, 1302 * "current_state":{"#text":"CHAT-ENGAGED"} 1303 * } 1304 * } 1305 */ 1306 ChatStateRequest.prototype.processResponse = function(response) { 1307 var resp = response.ui_response; 1308 var status = utils.getText(resp, "status"); 1309 var prevState = utils.getText(resp, "prev_state"); 1310 var currState = utils.getText(resp, "current_state"); 1311 var model = UIModel.getInstance(); 1312 // add message and detail if present 1313 var formattedResponse = utils.buildDefaultResponse(response); 1314 formattedResponse.agentId = response.ui_response.agent_id['#text'] || ""; 1315 formattedResponse.previousState = prevState; 1316 formattedResponse.currentState = currState; 1317 if(status=="OK"){ 1318 // Update the state in the UIModel 1319 model.agentSettings.currentChatState = currState; 1320 model.chatStatePacket = response; 1321 }else{ 1322 if(formattedResponse.message === ""){ 1323 formattedResponse.message = "Unable to change chat state"; 1324 } 1325 // log message response 1326 var message = "Unable to change chat state. " + formattedResponse.detail; 1327 utils.logMessage(LOG_LEVELS.WARN, message, response); 1328 } 1329 return formattedResponse; 1330 }; 1331 var XferColdRequest = function(dialDest, callerId, sipHeaders, countryId) { 1332 this.dialDest = dialDest; 1333 this.callerId = callerId || ""; 1334 this.sipHeaders = sipHeaders || []; 1335 this.countryId = countryId || ""; 1336 }; 1337 XferColdRequest.prototype.formatJSON = function() { 1338 var fields = []; 1339 for(var i =0; i < this.sipHeaders.length; i++){ 1340 var fieldObj = this.sipHeaders[i]; 1341 fields.push({ '@name' : utils.toString(fieldObj.name), '@value' : utils.toString(fieldObj.value)}); 1342 } 1343 var msg = { 1344 "ui_request": { 1345 "@destination":"IQ", 1346 "@type":MESSAGE_TYPES.XFER_COLD, 1347 "@message_id":utils.getMessageId(), 1348 "@response_to":"", 1349 "agent_id":{ 1350 "#text":UIModel.getInstance().agentSettings.agentId 1351 }, 1352 "uii":{ 1353 "#text":UIModel.getInstance().currentCall.uii 1354 }, 1355 "dial_dest":{ 1356 "#text":utils.toString(this.dialDest) 1357 }, 1358 "caller_id":{ 1359 "#text":utils.toString(this.callerId) 1360 }, 1361 "country_id": { 1362 "#text":utils.toString(this.countryId) 1363 }, 1364 "xfer_header": fields 1365 } 1366 }; 1367 return JSON.stringify(msg); 1368 }; 1369 /* 1370 * This class processes COLD-XFER packets rec'd from IQ. 1371 * 1372 * {"ui_response":{ 1373 * "@message_id":"IQ10012016082314475000219", 1374 * "@response_to":"", 1375 * "@type":"COLD-XFER", 1376 * "agent_id":{"#text":"1"}, 1377 * "uii":{"#text":"201608231447590139000000000200"}, 1378 * "session_id":{"#text":"3"}, 1379 * "status":{"#text":"OK"}, 1380 * "dial_dest":{"#text":"3038593775"}, 1381 * "message":{"#text":"OK"}, 1382 * "detail":{} 1383 * } 1384 * } 1385 */ 1386 XferColdRequest.prototype.processResponse = function(response) { 1387 var resp = response.ui_response; 1388 var formattedResponse = utils.buildDefaultResponse(response); 1389 formattedResponse.agentId = utils.getText(resp, 'agent_id'); 1390 formattedResponse.uii = utils.getText(resp, 'uii'); 1391 formattedResponse.sessionId = utils.getText(resp, 'session_id'); 1392 formattedResponse.dialDest = utils.getText(resp, 'dial_dest'); 1393 if(formattedResponse.status === "OK"){ 1394 }else{ 1395 // log message response 1396 var message = "There was an error processing the Cold Xfer request. " + formattedResponse.message + " : " + formattedResponse.detail; 1397 utils.logMessage(LOG_LEVELS.WARN, message, response); 1398 } 1399 return formattedResponse; 1400 }; 1401 var ConfigRequest = function(dialDest, queueIds, chatIds, skillProfileId, dialGroupId, updateFromAdminUI, isForce) { 1402 this.queueIds = queueIds || []; 1403 this.chatIds = chatIds || []; 1404 this.skillProfileId = skillProfileId || ""; 1405 this.dialGroupId = dialGroupId || ""; 1406 this.dialDest = dialDest || ""; 1407 this.updateFromAdminUI = updateFromAdminUI || false; 1408 this.loginType = "NO-SELECTION"; 1409 this.updateLogin = false; 1410 this.isForce = isForce; 1411 // Remove any ids agent doesn't have access to 1412 var model = UIModel.getInstance(); 1413 this.queueIds = utils.checkExistingIds(model.inboundSettings.availableQueues, this.queueIds, "gateId"); 1414 this.chatIds = utils.checkExistingIds(model.chatSettings.availableChatQueues, this.chatIds, "chatQueueId"); 1415 this.skillProfileId = utils.checkExistingIds(model.inboundSettings.availableSkillProfiles, [this.skillProfileId], "profileId")[0] || ""; 1416 this.dialGroupId = utils.checkExistingIds(model.outboundSettings.availableOutdialGroups, [this.dialGroupId], "dialGroupId")[0] || ""; 1417 // Set loginType value 1418 if(this.queueIds.length > 0 && this.dialGroupId !== ""){ 1419 this.loginType = "BLENDED"; 1420 } else if(this.queueIds.length > 0){ 1421 this.loginType = "INBOUND"; 1422 } else if(this.dialGroupId !== ""){ 1423 this.loginType = "OUTBOUND"; 1424 } else if(this.chatIds.length > 0){ 1425 this.loginType = "CHAT"; 1426 } else { 1427 this.loginType = "NO-SELECTION"; 1428 } 1429 // set updateLogin value 1430 if(model.agentSettings.isLoggedIn){ 1431 this.updateLogin = true; 1432 } 1433 // validate dialDest is sip or 10-digit num 1434 if(!utils.validateDest(this.dialDest)){ 1435 utils.logMessage(LOG_LEVELS.WARN, "dialDest [" + this.dialDest + "] must be a valid sip or 10-digit DID", ""); 1436 } 1437 }; 1438 ConfigRequest.prototype.formatJSON = function() { 1439 var msg = { 1440 "ui_request":{ 1441 "@destination":"IQ", 1442 "@type":MESSAGE_TYPES.LOGIN, 1443 "@message_id":utils.getMessageId(), 1444 "response_to":"", 1445 "agent_id":{ 1446 "#text":utils.toString(UIModel.getInstance().agentSettings.agentId) 1447 }, 1448 "agent_pwd":{ 1449 "#text": UIModel.getInstance().loginRequest.password 1450 }, 1451 "dial_dest":{ 1452 "#text":utils.toString(this.dialDest) 1453 }, 1454 "login_type":{ 1455 "#text":this.loginType 1456 }, 1457 "update_login":{ 1458 "#text":utils.toString(this.updateLogin) 1459 }, 1460 "outdial_group_id":{ 1461 "#text":utils.toString(this.dialGroupId) 1462 }, 1463 "skill_profile_id":{ 1464 "#text":utils.toString(this.skillProfileId) 1465 }, 1466 "update_from_adminui":{ 1467 "#text":utils.toString(this.updateFromAdminUI) 1468 }, 1469 "agent_platform_id" : { 1470 "#text" : utils.toString(2) //Hard-coded platformId 1471 }, 1472 "is_force" : { 1473 "#text" : utils.toString(this.isForce) 1474 } 1475 } 1476 }; 1477 // add arrays 1478 var queueIds = []; 1479 for(var i = 0; i < this.queueIds.length; i++){ 1480 if(this.queueIds[i] !== ""){ 1481 queueIds.push( { "#text": utils.toString(this.queueIds[i]) } ); 1482 } 1483 } 1484 if(queueIds.length > 0){ 1485 msg.ui_request.gates = { "gate_id" : queueIds }; 1486 }else{ 1487 msg.ui_request.gates = {}; 1488 } 1489 var chatIds = []; 1490 for(var i = 0; i < this.chatIds.length; i++){ 1491 if(this.chatIds[i] !== "") { 1492 chatIds.push( {"#text": utils.toString(this.chatIds[i]) } ); 1493 } 1494 } 1495 if(chatIds.length > 0) { 1496 msg.ui_request.chat_queues = {"chat_queue_id": chatIds}; 1497 }else{ 1498 msg.ui_request.chat_queues = {}; 1499 } 1500 return JSON.stringify(msg); 1501 }; 1502 /* 1503 * This function is responsible for handling the response to Login from IntelliQueue. 1504 * 1505 * {"ui_response":{ 1506 * "@message_id":"IQ10012016082513212000447", 1507 * "@response_to":"IQ201608251121200", 1508 * "@type":"LOGIN", 1509 * "agent_id":{"#text":"1"}, 1510 * "status":{"#text":"SUCCESS"}, 1511 * "message":{"#text":"Hello Geoffrey Mina!"}, 1512 * "detail":{"#text":"Logon request processed successfully!"}, 1513 * "hash_code":{"#text":"404946966"}, 1514 * "login_type":{"#text":"BLENDED"}, 1515 * "outdial_group_id":{"#text":"50692"}, 1516 * "skill_profile_id":{"#text":"1513"}, 1517 * "gates":{ 1518 * "gate_id":[ 1519 * {"#text":"11116"}, 1520 * {"#text":"11117"} 1521 * ] 1522 * }, 1523 * "chat_queues":{ 1524 * "chat_queue_id":{"#text":"30"} 1525 * } 1526 * } 1527 * } 1528 */ 1529 ConfigRequest.prototype.processResponse = function(response) { 1530 var resp = response.ui_response; 1531 var status = utils.getText(resp, "status"); 1532 var detail = utils.getText(resp, "detail"); 1533 var model = UIModel.getInstance(); 1534 var message = ""; 1535 var formattedResponse = utils.buildDefaultResponse(response); 1536 var Lib = UIModel.getInstance().libraryInstance; 1537 if(detail === "Logon Session Configuration Updated!"){ 1538 // this is an update login packet 1539 model.agentSettings.updateLoginMode = true; 1540 message = "Logon Session Configuration Updated!"; 1541 utils.logMessage(LOG_LEVELS.INFO, message, response); 1542 } 1543 if(status === "SUCCESS"){ 1544 if(!model.agentSettings.isLoggedIn){ 1545 // fresh login, set UI Model properties 1546 model.configPacket = response; 1547 model.connectionSettings.hashCode = utils.getText(resp, "hash_code"); 1548 model.agentSettings.isLoggedIn = true; 1549 model.agentSettings.loginDTS = new Date(); 1550 model.connectionSettings.reconnect = true; 1551 model.agentPermissions.allowLeadSearch = false; 1552 model.agentSettings.dialDest = model.configRequest.dialDest; // not sent in response 1553 model.agentSettings.loginType = utils.getText(resp, "login_type"); 1554 model.agentSettings.guid = utils.getText(resp,"guid"); 1555 model.agentSettings.accountId = utils.getText(resp,"account_id"); 1556 // Set collection values 1557 setDialGroupSettings(response); 1558 setGateSettings(response); 1559 setChatQueueSettings(response); 1560 setSkillProfileSettings(response); 1561 }else{ 1562 if(model.agentSettings.updateLoginMode){ 1563 model.agentSettings.dialDest = model.configRequest.dialDest; 1564 model.agentSettings.loginType = utils.getText(resp, "login_type"); 1565 model.agentSettings.guid = utils.getText(resp,"guid"); 1566 model.agentSettings.accountId = utils.getText(resp,"account_id"); 1567 // This was an update login request 1568 model.agentSettings.updateLoginMode = false; 1569 // reset to false before updating dial group settings 1570 model.agentPermissions.allowLeadSearch = false; 1571 model.agentPermissions.requireFetchedLeadsCalled = false; 1572 model.agentPermissions.allowPreviewLeadFilters = false; 1573 // Set collection values 1574 setDialGroupSettings(response); 1575 setGateSettings(response); 1576 setChatQueueSettings(response); 1577 setSkillProfileSettings(response); 1578 }else{ 1579 // this was a reconnect 1580 message = "Processed a Layer 2 Reconnect Successfully"; 1581 model.connectionSettings.isOnCall = utils.getText(resp, "is_on_call"); 1582 model.connectionSettings.activeCallUii = utils.getText(resp, "active_call_uii"); 1583 model.connectionSettings.isPendingDisp = utils.getText(resp, "is_pending_disp"); 1584 if(model.connectionSettings.isOnCall === false){ 1585 if(model.currentCall.uii) { 1586 var mockEndCallPacket = { 1587 "ui_notification": { 1588 "@message_id": "", 1589 "@type": "END-CALL", 1590 "uii": {"#text": model.currentCall.uii}, 1591 "term_reason": {"#text": "SOCKET-DISCONNECT"} 1592 } 1593 }; 1594 utils.processNotification(Lib, mockEndCallPacket); 1595 } 1596 if(model.agentSettings.isOffhook){ 1597 var offHookTermPacket = { 1598 "ui_notification" : { 1599 "agent_id" : {"#text": UIModel.getInstance().agentSettings.agentId}, 1600 "@type" : "OFF-HOOK-TERM", 1601 "@message_id": "" 1602 } 1603 }; 1604 var agentProcessOffhookCallback = utils.processNotification(Lib, offHookTermPacket); 1605 Lib.offhookTerm(agentProcessOffhookCallback); 1606 } 1607 }else if(model.connectionSettings.isOnCall && (model.currentCall.uii !== model.connectionSettings.activeCallUii || Lib.waitingForAddSession === true)){ 1608 //if the agent does not know it is on a call, but IQ thinks it is on a call 1609 //normally in the case of disconnect during transition 1610 model.currentCall.uii = model.connectionSettings.activeCallUii; 1611 model.currentCall.pendingDisp = false; 1612 Lib.hangup(1, true); 1613 1614 }else{ 1615 //agent still is on call and there are transferSessions, verify no transferSession were drop 1616 var activeAgentUiSessions = Lib.getTransferSessions(); 1617 var activeAgentSessions = response.ui_response.active_call_sessions.call_session_id.map(function(sessionObj){ 1618 return sessionObj['#text']; 1619 }); 1620 for(var transferSession in activeAgentUiSessions){ 1621 if(activeAgentSessions.indexOf(transferSession) === -1){ 1622 //if the active ui session is no longer active, we need to tell the ui 1623 delete UIModel.getInstance().transferSessions[transferSession]; 1624 } 1625 } 1626 } 1627 utils.logMessage(LOG_LEVELS.INFO, message, response); 1628 } 1629 } 1630 formattedResponse.agentSettings = model.agentSettings; 1631 formattedResponse.agentPermissions = model.agentPermissions; 1632 formattedResponse.applicationSettings = model.applicationSettings; 1633 formattedResponse.chatSettings = model.chatSettings; 1634 formattedResponse.connectionSettings = model.connectionSettings; 1635 formattedResponse.inboundSettings = model.inboundSettings; 1636 formattedResponse.outboundSettings = model.outboundSettings; 1637 formattedResponse.scriptSettings = model.scriptSettings; 1638 }else{ 1639 // Login failed 1640 if(formattedResponse.message === ""){ 1641 formattedResponse.message = "Agent configuration attempt failed (2nd layer login)" 1642 } 1643 utils.logMessage(LOG_LEVELS.WARN, formattedResponse.message, response); 1644 } 1645 return formattedResponse; 1646 }; 1647 function setDialGroupSettings(response){ 1648 var model = UIModel.getInstance(); 1649 var outdialGroups = model.outboundSettings.availableOutdialGroups; 1650 model.outboundSettings.outdialGroup = {}; // reset 1651 for(var g = 0; g < outdialGroups.length; g++){ 1652 var group = outdialGroups[g]; 1653 if(group.dialGroupId === response.ui_response.outdial_group_id['#text']){ 1654 model.agentPermissions.allowLeadSearch = group.allowLeadSearch; 1655 model.agentPermissions.allowPreviewLeadFilters = group.allowPreviewLeadFilters; 1656 model.agentPermissions.progressiveEnabled = group.progressiveEnabled; 1657 model.outboundSettings.outdialGroup = JSON.parse(JSON.stringify(group)); // copy object 1658 // Only used for Preview or TCPA Safe accounts. 1659 // If set to true, only allow fetching new leads when current leads are called or expired 1660 model.agentPermissions.requireFetchedLeadsCalled = group.requireFetchedLeadsCalled; 1661 } 1662 } 1663 } 1664 function setSkillProfileSettings(response){ 1665 var model = UIModel.getInstance(); 1666 model.inboundSettings.skillProfile = {}; 1667 var skillProfiles = model.inboundSettings.availableSkillProfiles; 1668 for(var s = 0; s < skillProfiles.length; s++){ 1669 var profile = skillProfiles[s]; 1670 var responseId = utils.getText(response.ui_response, "skill_profile_id"); 1671 if(profile.profileId === responseId){ 1672 model.inboundSettings.skillProfile = JSON.parse(JSON.stringify(profile)); // copy object 1673 } 1674 } 1675 } 1676 function setGateSettings(response){ 1677 var model = UIModel.getInstance(); 1678 var gates = model.inboundSettings.availableQueues; 1679 var selectedGateIds = []; 1680 var selectedGates = []; 1681 var gateIds = response.ui_response.gates.gate_id || []; 1682 if (!Array.isArray(gateIds)) { 1683 gateIds = [gateIds]; 1684 } 1685 for(var s = 0; s < gateIds.length; s++){ 1686 var obj = gateIds[s]; 1687 selectedGateIds.push(obj["#text"]); 1688 } 1689 for(var gIdx = 0; gIdx < gates.length; gIdx++){ 1690 var gate = gates[gIdx]; 1691 if(selectedGateIds.indexOf(gate.gateId) > -1){ 1692 selectedGates.push(gate); 1693 } 1694 } 1695 model.inboundSettings.queues = JSON.parse(JSON.stringify(selectedGates)); // copy array 1696 } 1697 function setChatQueueSettings(response){ 1698 var model = UIModel.getInstance(); 1699 var chatQueues = model.chatSettings.availableChatQueues; 1700 var selectedChatQueueIds = []; 1701 var selectedChatQueues = []; 1702 var cQueues = response.ui_response.chat_queues || {}; 1703 var chatQueueIds = cQueues.chat_queue_id || []; 1704 if (!Array.isArray(chatQueueIds)) { 1705 chatQueueIds = [chatQueueIds]; 1706 } 1707 for(var c = 0; c < chatQueueIds.length; c++){ 1708 var obj = chatQueueIds[c]; 1709 selectedChatQueueIds.push(obj["#text"]); 1710 } 1711 for(var cIdx = 0; cIdx < chatQueues.length; cIdx++){ 1712 var chatQueue = chatQueues[cIdx]; 1713 if(selectedChatQueueIds.indexOf(chatQueue.chatQueueId) > -1){ 1714 selectedChatQueues.push(chatQueue); 1715 } 1716 } 1717 model.chatSettings.chatQueues = JSON.parse(JSON.stringify(selectedChatQueues)); // copy array 1718 } 1719 var DirectAgentTransfer = function(targetAgentId, transferType, uii) { 1720 this.targetAgentId = targetAgentId; 1721 this.transferType = transferType; 1722 this.uii = uii || UIModel.getInstance().currentCall.uii; 1723 }; 1724 DirectAgentTransfer.prototype.formatJSON = function() { 1725 var model = UIModel.getInstance(); 1726 var msg = { 1727 "ui_request": { 1728 "@destination": "IQ", 1729 "@type": MESSAGE_TYPES.DIRECT_AGENT_TRANSFER, 1730 "@message_id": utils.getMessageId(), 1731 "@response_to": "", 1732 "agent_id":{ 1733 "#text": utils.toString(model.agentSettings.agentId) 1734 }, 1735 "uii": { 1736 "#text": utils.toString(this.uii) 1737 }, 1738 "target_agent_id": { 1739 "#text": utils.toString(this.targetAgentId) 1740 }, 1741 "transfer_type": { 1742 "#text": utils.toString(this.transferType) 1743 } 1744 } 1745 }; 1746 return JSON.stringify(msg); 1747 }; 1748 /* 1749 * This class processes DIRECT-AGENT-TRANSFER packets rec'd from IQ. 1750 * 1751 * {"ui_response":{ 1752 * "@message_id":"IQ10012016082314475000219", 1753 * "@response_to":"", 1754 * "@type":"DIRECT-AGENT-TRANSFER", 1755 * "status":{"#text":"OK"}, 1756 * "message":{"#text":"OK"}, 1757 * "type":{"#text":"WARM|COLD|CANCEL"} 1758 * } 1759 * } 1760 */ 1761 DirectAgentTransfer.prototype.processResponse = function(response) { 1762 var resp = response.ui_response; 1763 var formattedResponse = utils.buildDefaultResponse(response); 1764 formattedResponse.type = utils.getText(resp, 'type'); 1765 if(formattedResponse.status !== "OK"){ 1766 // log message response 1767 var message = "There was an error processing the Direct Agent Transfer request. " + formattedResponse.message + " : " + formattedResponse.detail; 1768 utils.logMessage(LOG_LEVELS.WARN, message, response); 1769 } 1770 return formattedResponse; 1771 }; 1772 var DirectAgentTransferList = function() { }; 1773 DirectAgentTransferList.prototype.formatJSON = function() { 1774 var msg = { 1775 "ui_request": { 1776 "@destination": "IQ", 1777 "@type": MESSAGE_TYPES.DIRECT_AGENT_TRANSFER_LIST, 1778 "@message_id": utils.getMessageId(), 1779 "@response_to": "", 1780 "agent_id":{ 1781 "#text": UIModel.getInstance().agentSettings.agentId 1782 } 1783 } 1784 }; 1785 return JSON.stringify(msg); 1786 }; 1787 /* 1788 * This class processes DIRECT-AGENT-TRANSFER-LIST packets rec'd from IQ. 1789 * 1790 * { 1791 * "ui_response":{ 1792 * "@message_id":"IQD01DEV2018052917202600038", 1793 * "@response_to":"f0b2e8a3-87fe-13ee-4d00-9d145bfe2be8", 1794 * "@type":"DIRECT-AGENT-TRANSFER-LIST", 1795 * "status":{ 1796 * "#text":"true" 1797 * }, 1798 * "message":{ 1799 * "#text":"OK" 1800 * }, 1801 * "agents": [ 1802 * { 1803 * "@agent_aux_state":"AVAILABLE", 1804 * "@agent_id":"1184160", 1805 * "@agent_state":"AVAILABLE", 1806 * "@available":"true", 1807 * "@first_name":"ross", 1808 * "@last_name":"m", 1809 * "@pending_disp":"false", 1810 * "@state_duration":"379", 1811 * "@username":"rm1" 1812 * }, 1813 * { 1814 * "@agent_aux_state":"AVAILABLE", 1815 * "@agent_id":"1184161", 1816 * "@agent_state":"AVAILABLE", 1817 * "@available":"true", 1818 * "@first_name":"ross", 1819 * "@last_name":"m", 1820 * "@pending_disp":"false", 1821 * "@state_duration":"84", 1822 * "@username":"rm2" 1823 * } 1824 * ] 1825 * } 1826 * } 1827 */ 1828 DirectAgentTransferList.prototype.processResponse = function(response) { 1829 var formattedResponse = utils.buildDefaultResponse(response); 1830 formattedResponse.agents = utils.processResponseCollection(response, 'ui_response', 'agents'); 1831 if(formattedResponse.status !== "OK"){ 1832 // log message response 1833 var message = "There was an error processing the Direct Agent Transfer List request. " + formattedResponse.message + " : " + formattedResponse.detail; 1834 utils.logMessage(LOG_LEVELS.WARN, message, response); 1835 } 1836 return formattedResponse; 1837 }; 1838 var DispositionRequest = function(uii, dispId, notes, callback, callbackDTS, contactForwardNumber, survey, externId, leadId, requestId) { 1839 this.uii = uii; 1840 this.dispId = dispId; 1841 this.notes = notes; 1842 this.callback = callback; 1843 this.callbackDTS = callbackDTS || ""; 1844 this.contactForwardNumber = contactForwardNumber || null; 1845 this.externId = externId || null; // outbound-disposition only 1846 this.leadId = leadId || null; // outbound-disposition only 1847 this.requestId = requestId || null; // outbound-disposition only (pipe leads) 1848 /* 1849 * survey = { 1850 * first_name: { 1851 * leadField: "first_name" 1852 * value: "Geoff" 1853 * }, 1854 * last_name: { 1855 * leadField: "last_name" 1856 * value: "Mina" 1857 * } 1858 * ... 1859 * } 1860 */ 1861 this.survey = survey || null; 1862 }; 1863 /* 1864 * This class is responsible for creating an inbound or outbound disposition packet to 1865 * send to intelliqueue. It will grab uii and agent_id directly from packets saved 1866 * in the UIModel. Then, using the information passed in, it will 1867 * create the remainder of the packet. This class is called from the ExtendedCallForm 1868 * 1869 * {"ui_request":{ 1870 * "@message_id":"IQ20160817145840132", 1871 * "@response_to":"", 1872 * "@type":"OUTDIAL-DISPOSITION|INBOUND-DISPOSITION", 1873 * "session_id":{"#text":"2"}, <-- ONLY WHEN AVAILABLE otherwise the node is left blank. this is the AGENT session_id 1874 * "uii":{"#text":"201608171658440139000000000165"}, 1875 * "agent_id":{"#text":"1180958"}, 1876 * "lead_id":{"#text":"1800"}, <-- OUTDIAL-DISPOSITION ONLY 1877 * "outbound_externid":{"#text":"3038593775"}, <-- OUTDIAL-DISPOSITION ONLY 1878 * "pending_request_id":{"#text":""}, <-- OUTDIAL-DISPOSITION ONLY 1879 * "disposition_id":{"#text":"5950"}, 1880 * "notes":{"#text":"note here"}, 1881 * "call_back":{"#text":"FALSE"}, 1882 * "call_back_DTS":{}, 1883 * "contact_forwarding":{}, 1884 * "survey":{ 1885 * "response":[ 1886 * {"@extern_id":"text_box","@lead_update_column":"","#text":"hello"}, 1887 * {"@extern_id":"check_box","@lead_update_column":"","#text":"20"}, 1888 * {"@extern_id":"radio_save","@lead_update_column":"","#text":"23"} 1889 * ] 1890 * } 1891 * } 1892 * } 1893 */ 1894 DispositionRequest.prototype.formatJSON = function() { 1895 var model = UIModel.getInstance(); 1896 var msg = { 1897 "ui_request": { 1898 "@destination":"IQ", 1899 "@message_id":utils.getMessageId(), 1900 "@response_to":"", 1901 "@type":MESSAGE_TYPES.OUTDIAL_DISPOSITION, 1902 "agent_id": { 1903 "#text" : utils.toString(model.agentSettings.agentId) 1904 }, 1905 "session_id":{ 1906 "#text": "" 1907 }, 1908 "uii": { 1909 "#text" : utils.toString(this.uii) 1910 }, 1911 "disposition_id": { 1912 "#text" : utils.toString(this.dispId) 1913 }, 1914 "notes": { 1915 "#text" : utils.toString(this.notes) 1916 }, 1917 "call_back": { 1918 "#text" : this.callback === true? "TRUE" : "FALSE" 1919 }, 1920 "call_back_DTS": { 1921 "#text" : utils.toString(this.callbackDTS) 1922 }, 1923 "contact_forwarding": { 1924 "#text" : utils.toString(this.contactForwardNumber) 1925 }, 1926 "outbound_externid": { 1927 "#text" : utils.toString(this.externId) 1928 }, 1929 "lead_id": { 1930 "#text" : utils.toString(this.leadId) 1931 }, 1932 "pending_request_id": { 1933 "#text" : utils.toString(this.requestId) 1934 } 1935 } 1936 }; 1937 if(model.currentCall.outdialDispositions && model.currentCall.outdialDispositions.type === "GATE") { 1938 msg.ui_request['@type'] = MESSAGE_TYPES.INBOUND_DISPOSITION; 1939 } 1940 if(model.currentCall.sessionId){ 1941 msg.ui_request.session_id = {"#text":model.currentCall.sessionId}; 1942 } 1943 /* 1944 * converts survey to this response 1945 * survey : { 1946 * response: [ 1947 * { "@extern_id":"", "@lead_update_column":"", "#text":"" } 1948 * ] 1949 * } 1950 */ 1951 if(this.survey !== null){ 1952 var response = []; 1953 var keys = Object.keys(this.survey); 1954 for(var i = 0; i < keys.length; i++){ 1955 var key = keys[i]; 1956 var obj = { 1957 "@extern_id": key, 1958 "@lead_update_column": utils.toString(this.survey[key].leadField), 1959 "#text": utils.toString(this.survey[key].value) 1960 }; 1961 response.push(obj); 1962 } 1963 msg.ui_request.survey = {"response":response}; 1964 } 1965 return JSON.stringify(msg); 1966 }; 1967 var DispositionManualPassRequest = function(dispId, notes, callback, callbackDTS, leadId, requestId, externId) { 1968 this.dispId = dispId; 1969 this.notes = notes; 1970 this.callback = callback; 1971 this.callbackDTS = callbackDTS || ""; 1972 this.leadId = leadId || null; 1973 this.requestId = requestId || null; 1974 this.externId = externId || null; 1975 }; 1976 /* 1977 * Sends an OUTDIAL-DISPOSITION request, just a separate class 1978 * specifically for dispositions on manual pass. 1979 * 1980 * {"ui_request":{ 1981 * "@message_id":"UIV220089241119416", 1982 * "@response_to":"", 1983 * "@type":"OUTDIAL-DISPOSITION", 1984 * "manual_disp":{"#text":"TRUE"}, 1985 * "request_key":{"#text":"IQ10012016081719070100875"}, 1986 * "session_id":{}, 1987 * "uii":{}, 1988 * "agent_id":{"#text":"1810"}, 1989 * "lead_id":{"#text":"213215"}, 1990 * "outbound_externid":{"#text":"909809"}, 1991 * "disposition_id":{"#text":"126"}, 1992 * "notes":{"#text":"here are my notes :)"}, 1993 * "call_back":{"#text":"TRUE | FALSE"}, 1994 * "call_back_DTS":{"#text":"2008-09-30 22:30:00 | null"}, 1995 * "contact_forwarding":{"#text":"null"} 1996 * } 1997 * } 1998 */ 1999 DispositionManualPassRequest.prototype.formatJSON = function() { 2000 var model = UIModel.getInstance(); 2001 var msg = { 2002 "ui_request": { 2003 "@destination":"IQ", 2004 "@message_id":utils.getMessageId(), 2005 "@response_to":"", 2006 "@type":MESSAGE_TYPES.OUTDIAL_DISPOSITION, 2007 "manual_disp": { 2008 "#text" : "TRUE" 2009 }, 2010 "agent_id": { 2011 "#text" : utils.toString(model.agentSettings.agentId) 2012 }, 2013 "request_key": { 2014 "#text": utils.toString(this.requestId) 2015 }, 2016 "disposition_id": { 2017 "#text" : utils.toString(this.dispId) 2018 }, 2019 "notes": { 2020 "#text" : utils.toString(this.notes) 2021 }, 2022 "call_back": { 2023 "#text" : this.callback === true? "TRUE" : "FALSE" 2024 }, 2025 "call_back_DTS": { 2026 "#text" : utils.toString(this.callbackDTS) 2027 }, 2028 "lead_id": { 2029 "#text" : utils.toString(this.leadId) 2030 }, 2031 "extern_id": { 2032 "#text" : utils.toString(this.externId) 2033 }, 2034 "contact_forwarding": { 2035 "#text": "null" 2036 }, 2037 "session_id":{}, 2038 "uii": {} 2039 } 2040 }; 2041 return JSON.stringify(msg); 2042 }; 2043 var HangupRequest = function(sessionId, resetPendingDisp) { 2044 this.sessionId = sessionId || null; 2045 this.resetPendingDisp = resetPendingDisp || false; 2046 }; 2047 HangupRequest.prototype.formatJSON = function() { 2048 var msg = { 2049 "ui_request": { 2050 "@destination":"IQ", 2051 "@type":MESSAGE_TYPES.HANGUP, 2052 "@message_id":utils.getMessageId(), 2053 "response_to":"", 2054 "agent_id":{ 2055 "#text":utils.toString(UIModel.getInstance().agentSettings.agentId) 2056 }, 2057 "uii":{ 2058 "#text":utils.toString(UIModel.getInstance().currentCall.uii) 2059 }, 2060 "session_id":{ 2061 "#text":utils.toString(this.sessionId === null ? UIModel.getInstance().currentCall.sessionId : this.sessionId) 2062 }, 2063 "cancel_pending_disp" : { 2064 "#text" : this.resetPendingDisp === true ? "TRUE" : "FALSE" 2065 } 2066 } 2067 }; 2068 return JSON.stringify(msg); 2069 }; 2070 var HoldRequest = function(holdState, sessionId) { 2071 this.holdState = holdState; 2072 this.sessionId = sessionId || '1'; 2073 }; 2074 /* 2075 * {"ui_request":{ 2076 * "@destination":"IQ", 2077 * "@message_id":"UI200809291036128", 2078 * "@response_to":"", 2079 * "@type":"HOLD", 2080 * "agent_id":{"#text":"1856"}, 2081 * "uii":{"#text":"200808291035510000000900029412"}, 2082 * "session_id":{"#text":"1"}, 2083 * "hold_state":{"#text":"ON"} 2084 * } 2085 * } 2086 */ 2087 HoldRequest.prototype.formatJSON = function() { 2088 var model = UIModel.getInstance(); 2089 var msg = { 2090 "ui_request": { 2091 "@destination":"IQ", 2092 "@type":MESSAGE_TYPES.HOLD, 2093 "@message_id":utils.getMessageId(), 2094 "@response_to":"", 2095 "agent_id":{ 2096 "#text":utils.toString(model.currentCall.agentId) 2097 }, 2098 "uii":{ 2099 "#text":utils.toString(model.currentCall.uii) 2100 }, 2101 "session_id":{ 2102 "#text": utils.toString(this.sessionId) 2103 }, 2104 "hold_state":{ 2105 "#text":this.holdState === true || this.holdState === "true" ? "ON" : "OFF" 2106 } 2107 } 2108 }; 2109 return JSON.stringify(msg); 2110 }; 2111 /* 2112 * This class processes HOLD packets rec'd from IQ. 2113 * 2114 * {"ui_response":{ 2115 * "@message_id":"IQ982008082910361503344", 2116 * "@response_to":"", 2117 * "@type":"HOLD", 2118 * "uii":{"#text":"200808291035510000000900029412"}, 2119 * "session_id":{"#text":"1"}, 2120 * "status":{"#text":"OK"}, 2121 * "message":{}, 2122 * "detail":{}, 2123 * "hold_state":{"#text":"ON"} 2124 * } 2125 * } 2126 */ 2127 HoldRequest.prototype.processResponse = function(response) { 2128 var resp = response.ui_response; 2129 var formattedResponse = utils.buildDefaultResponse(response); 2130 var currUII = ""; 2131 if(UIModel.getInstance().currentCall.uii){ 2132 currUII = UIModel.getInstance().currentCall.uii; 2133 } 2134 formattedResponse.holdState = utils.getText(resp, 'hold_state') === "ON"; 2135 formattedResponse.sessionId = utils.getText(resp, 'session_id'); 2136 formattedResponse.uii = utils.getText(resp, 'uii'); 2137 if(formattedResponse.status === "OK"){ 2138 // make sure we are talking about the same call 2139 if(formattedResponse.uii === currUII){ 2140 if(formattedResponse.message === ""){ 2141 formattedResponse.message = "Broadcasting new hold state of " + formattedResponse.holdState; 2142 } 2143 utils.logMessage(LOG_LEVELS.DEBUG, "Broadcasting new hold state of " + formattedResponse.holdState, response); 2144 } 2145 else{ 2146 utils.logMessage(LOG_LEVELS.DEBUG, "Hold Response is for a different call...discarding", response); 2147 } 2148 }else{ 2149 if(formattedResponse.message === ""){ 2150 formattedResponse.message = "Error processing HOLD request. " + + formattedResponse.message + "\n" + formattedResponse.detail; 2151 } 2152 utils.logMessage(LOG_LEVELS.WARN, "Error processing HOLD request. " + formattedResponse.detail, response); 2153 } 2154 var model = UIModel.getInstance(); 2155 if(formattedResponse.sessionId !== '1' && model.transferSessions[formattedResponse.sessionId]) { 2156 // we have a hold for a transfer session 2157 model.transferSessions[formattedResponse.sessionId].onHold = formattedResponse.holdState; 2158 } 2159 return formattedResponse; 2160 }; 2161 var LeadHistoryRequest = function(leadId) { 2162 this.leadId = leadId; 2163 }; 2164 /* 2165 * {"ui_request":{ 2166 * "@destination":"IQ", 2167 * "@message_id":"UI200809291036128", 2168 * "@response_to":"", 2169 * "@type":"LEAD-HISTORY", 2170 * "agent_id":{"#text":"1"}, 2171 * "lead_id":{"#text":"12"}, 2172 * } 2173 * } 2174 */ 2175 LeadHistoryRequest.prototype.formatJSON = function() { 2176 var model = UIModel.getInstance(); 2177 var msg = { 2178 "ui_request": { 2179 "@destination":"IQ", 2180 "@type":MESSAGE_TYPES.LEAD_HISTORY, 2181 "@message_id":utils.getMessageId(), 2182 "@response_to":"", 2183 "agent_id":{ 2184 "#text":utils.toString(model.agentSettings.agentId) 2185 }, 2186 "lead_id":{ 2187 "#text":utils.toString(this.leadId) 2188 } 2189 } 2190 }; 2191 return JSON.stringify(msg); 2192 }; 2193 /* 2194 * This class processes LEAD-HISTORY packets rec'd from IQ. 2195 * 2196 * {"ui_response":{ 2197 * "@lead_id":"2653", 2198 * "@message_id":"IQ982008091512353000875", 2199 * "@response_to":"UIV220089151235539", 2200 * "@type":"LEAD-HISTORY", 2201 * "previous_dial":{ 2202 * "@agent_name":"mandy pants (mandy)", 2203 * "@duration":"", 2204 * "@pass_disposition":"", 2205 * "@pass_dts":"2008-09-15 12:35:27", 2206 * "@pass_number":"", 2207 * "@pass_uii":"200809151234140000000900021288", 2208 * "agent_notes":{"#text":"This person was incredibly nice and agreed to buy donuts. "}, 2209 * "agent_disposition":{"#text":"Incomplete"} 2210 * } 2211 * } 2212 * } 2213 * 2214 * OR 2215 * 2216 * {"ui_response":{ 2217 * "@lead_id":"2653", 2218 * "@message_id":"IQ982008091512353000875", 2219 * "@response_to":"UIV220089151235539", 2220 * "@type":"LEAD-HISTORY", 2221 * "previous_dial":[ 2222 * { 2223 * "@agent_name":"mandy pants (mandy)", 2224 * "@duration":"", 2225 * "@pass_disposition":"", 2226 * "@pass_dts":"2008-09-15 12:35:27", 2227 * "@pass_number":"", 2228 * "@pass_uii":"200809151234140000000900021288", 2229 * "agent_notes":{"#text":"This person was incredibly nice and agreed to buy donuts. "}, 2230 * "agent_disposition":{"#text":"Incomplete"} 2231 * }, 2232 * { 2233 * "@agent_name":"mandy pants (mandy)", 2234 * "@duration":"", 2235 * "@pass_disposition":"", 2236 * "@pass_dts":"2008-09-15 12:35:27", 2237 * "@pass_number":"", 2238 * "@pass_uii":"200809151234140000000900021288", 2239 * "agent_notes":{"#text":"This person was incredibly nice and agreed to buy donuts. "}, 2240 * "agent_disposition":{"#text":"Incomplete"} 2241 * } 2242 * ] 2243 * } 2244 * } 2245 */ 2246 LeadHistoryRequest.prototype.processResponse = function(response) { 2247 var resp = response.ui_response; 2248 var histResponse = { 2249 leadId: resp['@lead_id'] 2250 }; 2251 var history = utils.processResponseCollection(response, 'ui_response', 'previous_dial'); 2252 // always return array, even if only one item 2253 if(!Array.isArray(history)){ 2254 history = [history]; 2255 } 2256 histResponse.leadHistory = history; 2257 return histResponse; 2258 }; 2259 var LeadInsertRequest = function(dataObj) { 2260 // handle boolean value conversion 2261 if(dataObj.agent_reserved && dataObj.agent_reserved === true){ 2262 dataObj.agent_reserved = "1"; 2263 }else{ 2264 dataObj.agent_reserved = "0"; 2265 } 2266 if(dataObj.dialable && dataObj.dialable === true){ 2267 dataObj.dialable = "1"; 2268 }else{ 2269 dataObj.dialable = "0"; 2270 } 2271 this.dataObj = dataObj; 2272 }; 2273 /* 2274 * {"ui_request":{ 2275 * "@destination":"IQ", 2276 * "@message_id":"UI200809291036128", 2277 * "@response_to":"", 2278 * "@type":"LEAD-INSERT", 2279 * "agent_id":{"#text":"1"}, 2280 * "campaign_id":{"#text":""}, 2281 * "lead_phone":{"#text":""}, 2282 * "dialable":{"#text":""}, 2283 * "agent_reserved":{"#text":""}, 2284 * "callback_dts":{"#text":""}, 2285 * "first_name":{"#text":""}, 2286 * "mid_name":{"#text":""}, 2287 * "last_name":{"#text":""}, 2288 * "suffix":{"#text":""}, 2289 * "title":{"#text":""}, 2290 * "address1":{"#text":""}, 2291 * "address2":{"#text":""}, 2292 * "city":{"#text":""}, 2293 * "state":{"#text":""}, 2294 * "zip":{"#text":""}, 2295 * "email":{"#text":""}, 2296 * "gateKeeper":{"#text":""}, 2297 * "aux_data1":{"#text":""}, 2298 * "aux_data2":{"#text":""}, 2299 * "aux_data3":{"#text":""}, 2300 * "aux_data4":{"#text":""}, 2301 * "aux_data5":{"#text":""}, 2302 * } 2303 * } 2304 */ 2305 LeadInsertRequest.prototype.formatJSON = function() { 2306 var model = UIModel.getInstance(); 2307 var msg = { 2308 "ui_request": { 2309 "@destination":"IQ", 2310 "@type":MESSAGE_TYPES.LEAD_INSERT, 2311 "@message_id":utils.getMessageId(), 2312 "@response_to":"", 2313 "agent_id":{ 2314 "#text":utils.toString(this.dataObj.agent_id) 2315 }, 2316 "campaign_id":{ 2317 "#text":utils.toString(this.dataObj.campaign_id) 2318 }, 2319 "lead_phone":{ 2320 "#text":utils.toString(this.dataObj.lead_phone) 2321 }, 2322 "dialable":{ 2323 "#text":utils.toString(this.dataObj.dialable) 2324 }, 2325 "agent_reserved":{ 2326 "#text":utils.toString(this.dataObj.agent_reserved) 2327 }, 2328 "call_back_dts":{ 2329 "#text":utils.toString(this.dataObj.callback_dts) 2330 }, 2331 "first_name":{ 2332 "#text":utils.toString(this.dataObj.first_name) 2333 }, 2334 "mid_name":{ 2335 "#text":utils.toString(this.dataObj.mid_name) 2336 }, 2337 "last_name":{ 2338 "#text":utils.toString(this.dataObj.last_name) 2339 }, 2340 "suffix":{ 2341 "#text":utils.toString(this.dataObj.suffix) 2342 }, 2343 "title":{ 2344 "#text":utils.toString(this.dataObj.title) 2345 }, 2346 "address1":{ 2347 "#text":utils.toString(this.dataObj.address1) 2348 }, 2349 "address2":{ 2350 "#text":utils.toString(this.dataObj.address2) 2351 }, 2352 "city":{ 2353 "#text":utils.toString(this.dataObj.city) 2354 }, 2355 "state":{ 2356 "#text":utils.toString(this.dataObj.state) 2357 }, 2358 "zip":{ 2359 "#text":utils.toString(this.dataObj.zip) 2360 }, 2361 "email":{ 2362 "#text":utils.toString(this.dataObj.email) 2363 }, 2364 "gate_keeper":{ 2365 "#text":utils.toString(this.dataObj.gate_keeper) 2366 }, 2367 "aux_data1":{ 2368 "#text":utils.toString(this.dataObj.aux_data1) 2369 }, 2370 "aux_data2":{ 2371 "#text":utils.toString(this.dataObj.aux_data2) 2372 }, 2373 "aux_data3":{ 2374 "#text":utils.toString(this.dataObj.aux_data3) 2375 }, 2376 "aux_data4":{ 2377 "#text":utils.toString(this.dataObj.aux_data4) 2378 }, 2379 "aux_data5":{ 2380 "#text":utils.toString(this.dataObj.aux_data5) 2381 } 2382 } 2383 }; 2384 return JSON.stringify(msg); 2385 }; 2386 /* 2387 * This class processes LEAD-INSERT packets rec'd from IQ. 2388 * 2389 * {"ui_response":{ 2390 * "@message_id":"IQ982008091512353000875", 2391 * "@response_to":"UIV220089151235539", 2392 * "@type":"LEAD-INSERT", 2393 * "status":{"#text":"TRUE|FALSE"}, 2394 * "msg":{"#text":""}, 2395 * "detail":{"#text":""}, 2396 * } 2397 * } 2398 */ 2399 LeadInsertRequest.prototype.processResponse = function(response) { 2400 var resp = response.ui_response; 2401 var formattedResponse = utils.buildDefaultResponse(response); 2402 formattedResponse.message = resp.msg["#text"]; 2403 return formattedResponse; 2404 }; 2405 var LeadUpdateRequest = function(leadId, leadPhone, baggage) { 2406 this.leadId = leadId; 2407 this.leadPhone = leadPhone; 2408 this.baggage = baggage; 2409 this.agentId = utils.toString(UIModel.getInstance().agentSettings.agentId); 2410 }; 2411 /* 2412 * {"ui_request":{ 2413 * "@destination":"IQ", 2414 * "@message_id":"UI200809291036128", 2415 * "@response_to":"", 2416 * "@type":"LEAD-UPDATE", 2417 * "agent_id":{"#text":"1"}, 2418 * "lead_id":{"#text":"12"}, 2419 * "lead_phone":{"#text":"12"}, 2420 * "baggage":{ 2421 * "lead_id":{"#text":"64306"}, 2422 * "extern_id":{"#text":"9548298548"}, 2423 * "first_name":{"#text":"Ryant"}, 2424 * "mid_name":{}, 2425 * "last_name":{"#text":"Taylor"}, 2426 * "state":{"#text":"OH"}, 2427 * "aux_data1":{"#text":"BMAK"}, 2428 * "aux_data2":{"#text":"BMAK-041653-934"}, 2429 * "aux_data3":{"#text":"Call Ctr 1"}, 2430 * "aux_data4":{}, 2431 * "aux_data5":{}, 2432 * "address1":{"#text":"8010 Maryland Ave"}, 2433 * "address2":{}, 2434 * "city":{"#text":"Cleveland"}, 2435 * "zip":{"#text":"44105"}, 2436 * "aux_external_url":{}, 2437 * "aux_greeting":{}, 2438 * "aux_phone":{} 2439 * }, 2440 * } 2441 * } 2442 */ 2443 LeadUpdateRequest.prototype.formatJSON = function() { 2444 // make sure required baggage fields are present 2445 this.baggage = _formatBaggage(this.baggage); 2446 var msg = { 2447 "ui_request": { 2448 "@destination":"IQ", 2449 "@type":MESSAGE_TYPES.LEAD_UPDATE, 2450 "@message_id":utils.getMessageId(), 2451 "@response_to":"", 2452 "agent_id":{ 2453 "#text":this.agentId 2454 }, 2455 "lead_id":{ 2456 "#text":utils.toString(this.leadId) 2457 }, 2458 "lead_phone":{ 2459 "#text":utils.toString(this.leadPhone) 2460 }, 2461 "baggage": this.baggage 2462 } 2463 }; 2464 return JSON.stringify(msg); 2465 }; 2466 /* 2467 * This class processes LEAD-UPDATE packets rec'd from IQ. 2468 * 2469 * {"ui_response":{ 2470 * "@message_id":"IQ982008091512353000875", 2471 * "@response_to":"UIV220089151235539", 2472 * "@type":"LEAD-UPDATE", 2473 * "status":{"#text":"TRUE|FALSE"}, 2474 * "msg":{"#text":"64306"}, 2475 * "detail":{"#text":"64306"}, 2476 * } 2477 * } 2478 */ 2479 LeadUpdateRequest.prototype.processResponse = function(response) { 2480 var resp = response.ui_response; 2481 var formattedResponse = utils.buildDefaultResponse(response); 2482 formattedResponse.message = resp.msg["#text"]; 2483 return formattedResponse; 2484 }; 2485 _formatBaggage = function(baggage){ 2486 var bag = {}; 2487 bag.first_name = {"#text": baggage.first_name || ""}; 2488 bag.mid_name = {"#text":baggage.mid_name || ""}; 2489 bag.last_name = {"#text":baggage.last_name || ""}; 2490 bag.suffix = {"#text":baggage.suffix || ""}; 2491 bag.title = {"#text":baggage.title || ""}; 2492 bag.address1 = {"#text":baggage.address1 || ""}; 2493 bag.address2 = {"#text":baggage.address2 || ""}; 2494 bag.city = {"#text":baggage.city || ""}; 2495 bag.state = {"#text":baggage.state || ""}; 2496 bag.zip = {"#text":baggage.zip || ""}; 2497 bag.email = {"#text":baggage.email || ""}; 2498 bag.gate_keeper = {"#text":baggage.gate_keeper || ""}; 2499 bag.extern_id = {"#text":baggage.extern_id || ""}; 2500 bag.aux_data1 = {"#text":baggage.aux_data1 || ""}; 2501 bag.aux_data2 = {"#text":baggage.aux_data2 || ""}; 2502 bag.aux_data3 = {"#text":baggage.aux_data3 || ""}; 2503 bag.aux_data4 = {"#text":baggage.aux_data4 || ""}; 2504 bag.aux_data5 = {"#text":baggage.aux_data5 || ""}; 2505 return bag; 2506 }; 2507 var LoginRequest = function(username, password, isCaseSensitive) { 2508 this.username = username; 2509 this.password = password; 2510 this.isCaseSensitive = isCaseSensitive || false; 2511 }; 2512 LoginRequest.prototype.formatJSON = function() { 2513 var msg = { 2514 "ui_request": { 2515 "@destination":"IS", 2516 "@type":MESSAGE_TYPES.LOGIN, 2517 "@message_id":utils.getMessageId(), 2518 "response_to":"", 2519 "username":{ 2520 "#text":this.username 2521 }, 2522 "password":{ 2523 "#text":this.password 2524 }, 2525 "is_case_sensitive":{ 2526 "#text":utils.toString(this.isCaseSensitive === true ? "TRUE" : "FALSE") 2527 } 2528 } 2529 }; 2530 return JSON.stringify(msg); 2531 }; 2532 /* 2533 * This function is responsible for handling the login packet received from IntelliServices. It will save 2534 * a copy of it in the UIModel as loginPacket, as well as set the isLoggedInIS variable to 2535 * true (for reconnect purposes) and the loginDTS with the current date/time. 2536 * 2537 * {"ui_response":{ 2538 * "@type":"login", 2539 * "status":{"#text":"OK"}, 2540 * "agent_id":{"#text":"1810"}, 2541 * "agent_pwd":{"#text":"bound25"}, 2542 * "first_name":{"#text":"mandy"}, 2543 * "last_name":{"#text":"pants"}, 2544 * "email":{"#text":"mandypants@aol.coim"}, 2545 * "agent_type":{"#text":"AGENT"}, 2546 * "external_agent_id":{"#text":"blahblah"}, 2547 * "default_login_dest":{"#text":"9548298548|123"}, 2548 * "alt_default_login_dest":{"#text":"9548298548|123"}, 2549 * "iq_url":{"#text":"dev.connectfirst.com"}, 2550 * "iq_port":{"#text":"1313"}, 2551 * "iq_ssl_port":{"#text":"1213"}, 2552 * "iq_secret_key":{"#text":"F-OFF"}, 2553 * "allow_inbound":{"#text":"1"}, 2554 * "allow_outbound":{"#text":"1"}, 2555 * "allow_chat":{"#text":"1"}, 2556 * "allow_blended":{"#text":"0"}, 2557 * "allow_off_hook":{"#text":"1"}, 2558 * "allow_call_control":{"#text":"1"}, 2559 * "allow_login_control":{"#text":"1"}, 2560 * "allow_login_updates":{"#text":"1"}, 2561 * "allow_lead_inserts":{"#text":"1"}, 2562 * "show_lead_history":{"#text":"1"}, 2563 * "allow_cross_gate_requeue":{"#text":"1"}, 2564 * "phone_login_dial_group":{"#text":"44"}, 2565 * "phone_login_pin":{"#text":"1234"}, 2566 * "allow_manual_calls":{"#text":"1"}, 2567 * "allow_manual_intl_calls":{"#text":"0"}, 2568 * "init_login_state":{"#text":"ON-BREAK"}, 2569 * "init_login_state_label":{"#text":"Morning Break"}, 2570 * "outbound_prepay":{"#text":"0"}, 2571 * "max_break_time":{"#text":"-1"}, 2572 * "max_lunch_time":{"#text":"-1"}, 2573 * "allow_lead_search":{"#text":"YES_ALL"}, 2574 * "tcpa_safe_mode":{"#text":"1|0"}, 2575 * "pci_enabled":{"#text":"1|0"}, 2576 * "login_gates":{ 2577 * "gate":[ 2578 * {"@default_dest_override":"","@gate_desc":"","@gate_id":"37","@gate_name":"test"}, 2579 * {"@default_dest_override":"","@gate_desc":"","@gate_id":"42","@gate_name":"test gate two"}, 2580 * {"@default_dest_override":"","@gate_desc":"","@gate_id":"43","@gate_name":"test gate three"}, 2581 * {"@default_dest_override":"","@gate_desc":"Amandas Other Gate","@gate_id":"46","@gate_name":"You know it!"} 2582 * ] 2583 * }, 2584 * "login_chat_queues":{ 2585 * "chat_queue":[ 2586 * {"@chat_queue_description":"","@chat_queue_id":"","@chat_queue_name":""}, 2587 * {"@chat_queue_description":"","@chat_queue_id":"","@chat_queue_name":""} 2588 * ] 2589 * }, 2590 * "outdial_groups":{ 2591 * "group":[ 2592 * {"@billing_key":"","@dial_group_desc":"","@dial_group_id":"44","@dial_group_name":"Geoff Dial Test","@dial_mode":"PREDICTIVE"}, 2593 * {"@billing_key":"2","@dial_group_desc":"AutoDial Configured Dial Group","@dial_group_id":"46","@dial_group_name":"Phone Only test5","@dial_mode":"PREDICTIVE"}, 2594 * {"@billing_key":"","@dial_group_desc":"Test","@dial_group_id":"200000","@dial_group_name":"Test","@dial_mode":"PREDICTIVE"}, 2595 * {"@billing_key":"","@dial_group_desc":"Test","@dial_group_id":"200010","@dial_group_name":"Carissa's Test Group","@dial_mode":"PREDICTIVE"} 2596 * ] 2597 * },"skill_profiles":{ 2598 * "profile":[ 2599 * {"@profile_desc":"","@profile_id":"571","@profile_name":"skill1"}, 2600 * {"@profile_desc":"","@profile_id":"572","@profile_name":"skill2"} 2601 * ] 2602 * }, 2603 * "requeue_gates":{ 2604 * "gate_group":[ 2605 * { 2606 * "@gate_group_id":"18", 2607 * "@group_name":"new gate group", 2608 * "gates":{ 2609 * "gate":[ 2610 * {"@gate_desc":"","@gate_id":"37","@gate_name":"test"}, 2611 * {"@gate_desc":"","@gate_id":"43","@gate_name":"test gate three"}, 2612 * {"@gate_desc":"","@gate_id":"42","@gate_name":"test gate two"} 2613 * ] 2614 * }, 2615 * "skills":{ 2616 * "skill":[ 2617 * {"@skill_desc":"","@skill_id":"58","@skill_name":"one"}, 2618 * {"@skill_desc":"","@skill_id":"59","@skill_name":"two"}, 2619 * ] 2620 * } 2621 * } 2622 * ] 2623 * }, 2624 * "chat_rooms":{}, 2625 * "scripts": { 2626 * "script": { 2627 * "@script_id": "15", 2628 * "@script_name": "Don't Read This Script" 2629 * } 2630 * }, 2631 * "campaigns": { 2632 * "campaign": { 2633 * "@allow_lead_updates": "", 2634 * "@campaign_id": "", 2635 * "@campaign_name": "", 2636 * "@survey_id": "", 2637 * "@survey_name": "", 2638 * "custom_labels": { 2639 * "@aux_1_label": "", 2640 * "@aux_2_label": "", 2641 * "@aux_3_label": "", 2642 * "@aux_4_label": "", 2643 * "@aux_5_label": "" 2644 * }, 2645 * "generic_key_value_pairs": {} 2646 * } 2647 * }, 2648 * "account_countries":{ 2649 * "country":[ 2650 * {"@country_id":"BRA"},{"@country_id":"FRA"},{"@country_id":"GER"} 2651 * ] 2652 * } 2653 * } 2654 * } 2655 */ 2656 LoginRequest.prototype.processResponse = function(response) { 2657 var resp = response.ui_response; 2658 var status = resp.status['#text']; 2659 var model = UIModel.getInstance(); 2660 var formattedResponse = utils.buildDefaultResponse(response); 2661 if(status === 'OK'){ 2662 if(!model.isLoggedInIS){ 2663 // save login packet properties to UIModel 2664 model.loginPacket = response; 2665 model.applicationSettings.isLoggedInIS = true; 2666 model.applicationSettings.isTcpaSafeMode = utils.getText(resp, 'tcpa_safe_mode') === "1"; 2667 model.applicationSettings.pciEnabled = utils.getText(resp, 'pci_enabled') === "1"; 2668 model.chatSettings.alias = utils.getText(resp, 'first_name') + " " + utils.getText(resp, 'last_name'); 2669 model.agentSettings.loginDTS = new Date(); 2670 model.agentSettings.maxBreakTime = utils.getText(resp, 'max_break_time'); 2671 model.agentSettings.maxLunchTime = utils.getText(resp, 'max_lunch_time'); 2672 model.agentSettings.firstName = utils.getText(resp, 'first_name'); 2673 model.agentSettings.lastName = utils.getText(resp, 'last_name'); 2674 model.agentSettings.email = utils.getText(resp, 'email'); 2675 model.agentSettings.agentId = utils.getText(resp, 'agent_id'); 2676 model.agentSettings.externalAgentId = utils.getText(resp, 'external_agent_id'); 2677 model.agentSettings.agentType = utils.getText(resp, 'agent_type'); 2678 model.agentSettings.realAgentType = utils.getText(resp, 'real_agent_type'); 2679 model.agentSettings.defaultLoginDest = utils.getText(resp, 'default_login_dest'); 2680 model.agentSettings.altDefaultLoginDest = utils.getText(resp, 'alt_default_login_dest'); 2681 model.agentSettings.initLoginState = utils.getText(resp, 'init_login_state'); 2682 model.agentSettings.initLoginStateLabel = utils.getText(resp, 'init_login_state_label'); 2683 model.agentSettings.outboundManualDefaultRingtime = utils.getText(resp, 'outbound_manual_default_ringtime'); 2684 model.agentSettings.isOutboundPrepay = utils.getText(resp, 'outbound_prepay') === "1"; 2685 model.agentSettings.phoneLoginPin = utils.getText(resp, 'phone_login_pin'); 2686 model.agentSettings.username = model.loginRequest.username; 2687 model.agentPermissions.allowCallControl = utils.getText(resp, 'allow_call_control') === "1"; 2688 model.agentPermissions.allowChat = utils.getText(resp, 'allow_chat') === "1"; 2689 model.agentPermissions.showLeadHistory = utils.getText(resp, 'show_lead_history') === "1"; 2690 model.agentPermissions.allowManualOutboundGates = utils.getText(resp, 'allow_manual_outbound_gates') === "1"; 2691 model.agentPermissions.allowOffHook = utils.getText(resp, 'allow_off_hook') === "1"; 2692 model.agentPermissions.allowManualCalls = utils.getText(resp, 'allow_manual_calls') === "1"; 2693 model.agentPermissions.allowManualPass = utils.getText(resp, 'allow_manual_pass') === "1"; 2694 model.agentPermissions.allowManualIntlCalls = utils.getText(resp, 'allow_manual_intl_calls') === "1"; 2695 model.agentPermissions.allowLoginUpdates = utils.getText(resp, 'allow_login_updates') === "1"; 2696 model.agentPermissions.allowInbound = utils.getText(resp, 'allow_inbound') === "1"; 2697 model.agentPermissions.allowOutbound = utils.getText(resp, 'allow_outbound') === "1"; 2698 model.agentPermissions.allowBlended = utils.getText(resp, 'allow_blended') === "1"; 2699 model.agentPermissions.allowLoginControl = utils.getText(resp, 'allow_login_control') === "1"; 2700 model.agentPermissions.allowCrossQueueRequeue = utils.getText(resp, 'allow_cross_gate_requeue') === "1"; 2701 model.agentPermissions.disableSupervisorMonitoring = utils.getText(resp, 'disable_supervisor_monitoring') === "1"; 2702 model.agentPermissions.allowAutoAnswer = utils.getText(resp, 'allow_auto_answer') === "1"; 2703 model.agentPermissions.defaultAutoAnswerOn = utils.getText(resp, 'default_auto_answer_on') === "1"; 2704 model.agentPermissions.allowHistoricalDialing = utils.getText(resp, 'allow_historical_dialing') === "1"; 2705 model.agentPermissions.allowAgentStats = utils.getText(resp, 'allow_agent_stats') === "1"; 2706 model.agentPermissions.allowCampaignStats = utils.getText(resp, 'allow_camp_stats') === "1"; 2707 model.agentPermissions.allowGateStats = utils.getText(resp, 'allow_gate_stats') === "1"; 2708 model.agentPermissions.allowChatStats = utils.getText(resp, 'allow_chat_stats') === "1"; 2709 model.outboundSettings.defaultDialGroup = utils.getText(resp, 'phone_login_dial_group'); 2710 if(response.ui_response.allow_lead_inserts && typeof resp.insert_campaigns !== 'undefined' && response.ui_response.insert_campaigns.campaign){ 2711 model.agentPermissions.allowLeadInserts = utils.getText(resp, 'allow_lead_inserts') === "1"; 2712 } 2713 // Set collection values 2714 model.outboundSettings.availableCampaigns = _processCampaigns(response); 2715 model.chatSettings.availableChatQueues = utils.processResponseCollection(response.ui_response, "login_chat_queues", "chat_queue"); 2716 processChatQueueDnis(model.chatSettings, response); 2717 model.chatSettings.availableChatRequeueQueues = utils.processResponseCollection(response.ui_response, "chat_requeue_queues", "chat_group"); 2718 model.inboundSettings.availableQueues = utils.processResponseCollection(response.ui_response, "login_gates", "gate"); 2719 model.inboundSettings.availableSkillProfiles = utils.processResponseCollection(response.ui_response, "skill_profiles", "profile"); 2720 model.inboundSettings.availableRequeueQueues = utils.processResponseCollection(response.ui_response, "requeue_gates", "gate_group"); 2721 model.chatSettings.availableChatRooms = utils.processResponseCollection(response.ui_response, "chat_rooms", "room"); 2722 model.scriptSettings.availableScripts = utils.processResponseCollection(response.ui_response, "scripts", "script"); 2723 model.agentSettings.callerIds = utils.processResponseCollection(response.ui_response, "caller_ids", "caller_id"); 2724 model.agentSettings.availableAgentStates = utils.processResponseCollection(response.ui_response, "agent_states", "agent_state"); 2725 model.applicationSettings.availableCountries = utils.processResponseCollection(response.ui_response, "account_countries", "country"); 2726 model.outboundSettings.insertCampaigns = utils.processResponseCollection(response.ui_response, "insert_campaigns", "campaign"); 2727 var dialGroups = utils.processResponseCollection(response.ui_response, "outdial_groups", "group"); 2728 // set boolean values 2729 for(var dg = 0; dg < dialGroups.length; dg++){ 2730 var group = dialGroups[dg]; 2731 group.allowLeadSearch = group.allowLeadSearch === "YES"; 2732 group.allowPreviewLeadFilters = group.allowPreviewLeadFilters === "1"; 2733 group.progressiveEnabled = group.progressiveEnabled === "1"; 2734 group.requireFetchedLeadsCalled = group.requireFetchedLeadsCalled === "1"; 2735 group.hciType = parseInt(group.hciEnabled) || 0; 2736 group.hciEnabled = group.hciEnabled === "1" || group.hciEnabled === "2"; 2737 group.hciClicker = group.hciClicker === "1"; 2738 } 2739 model.outboundSettings.availableOutdialGroups = dialGroups; 2740 } 2741 formattedResponse.agentSettings = model.agentSettings; 2742 formattedResponse.agentPermissions = model.agentPermissions; 2743 formattedResponse.applicationSettings = model.applicationSettings; 2744 formattedResponse.chatSettings = model.chatSettings; 2745 formattedResponse.connectionSettings = model.connectionSettings; 2746 formattedResponse.inboundSettings = model.inboundSettings; 2747 formattedResponse.outboundSettings = model.outboundSettings; 2748 formattedResponse.scriptSettings = model.scriptSettings; 2749 }else if(status === 'RESTRICTED'){ 2750 formattedResponse.message = "Invalid IP Address"; 2751 utils.logMessage(LOG_LEVELS.WARN, formattedResponse.message, response); 2752 }else{ 2753 formattedResponse.message = "Invalid Username or password"; 2754 utils.logMessage(LOG_LEVELS.WARN, formattedResponse.message, response); 2755 } 2756 return formattedResponse; 2757 }; 2758 function _processCampaigns(response){ 2759 var campaigns = []; 2760 var campaignsRaw = null; 2761 if(typeof response.ui_response.campaigns.campaign !== 'undefined'){ 2762 campaignsRaw = response.ui_response.campaigns.campaign; 2763 } 2764 if(campaignsRaw){ 2765 if(!Array.isArray(campaignsRaw)) { 2766 campaignsRaw = [campaignsRaw]; 2767 } 2768 for(var c = 0; c < campaignsRaw.length; c++){ 2769 campaigns.push(_processCampaign(campaignsRaw[c])); 2770 } 2771 } 2772 return campaigns; 2773 } 2774 function _processCampaign(campaignRaw) { 2775 // single campaign object 2776 var campaignId = campaignRaw['@campaign_id']; 2777 var allowLeadUpdates = campaignRaw['@allow_lead_updates']; // 0 = no update, 1 = allow phone update, 2 = don't allow phone update 2778 UIModel.getInstance().agentPermissions.allowLeadUpdatesByCampaign[campaignId] = allowLeadUpdates; 2779 var customLabels = campaignRaw['custom_labels']; 2780 var labelArray = []; 2781 for (var p in customLabels) { 2782 var label = p.replace(/@/, ''); // remove leading '@' 2783 var obj = {}; 2784 obj[label] = customLabels[p]; 2785 labelArray.push(obj); 2786 } 2787 return { 2788 campaignId: campaignId, 2789 campaignName: campaignRaw['@campaign_name'], 2790 surveyId: campaignRaw['@survey_id'], 2791 surveyName: campaignRaw['@survey_name'], 2792 customLabels: labelArray, 2793 allowLeadUpdates: allowLeadUpdates 2794 }; 2795 } 2796 /** 2797 * example packet 2798 * { 2799 * "chat_queue":[ 2800 * { 2801 * "@chat_queue_desc":"", 2802 * "@chat_queue_id":"74", 2803 * "@chat_queue_name":"Please don't delete" 2804 * }, 2805 * { 2806 * "@chat_queue_desc":"blah", 2807 * "@chat_queue_id":"131", 2808 * "@chat_queue_name":"cris chat queue", 2809 * "dnis":[ 2810 * {"#text":"5555551215"}, 2811 * {"#text":"5555554444"}, 2812 * {"#text":"8885551212"}, 2813 * {"#text":"97687"} 2814 * ] 2815 * } 2816 * ] 2817 * } 2818 * 2819 * 2820 * This function will format the dnis list and put them back on chatSettings.availableChatQueues 2821 **/ 2822 function processChatQueueDnis(chatSettings, response) { 2823 var queues = chatSettings.availableChatQueues; 2824 var rawQueues = response.ui_response.login_chat_queues.chat_queue; 2825 if(!Array.isArray(rawQueues)) { 2826 rawQueues = [rawQueues]; 2827 } 2828 for(var i = 0; i < queues.length; i++) { 2829 var queue = queues[i]; 2830 var rawQueue = {}; 2831 for (var j = 0; j < rawQueues.length; j++) { 2832 var rq = rawQueues[j]; 2833 if(rq['@chat_queue_id'] === queue.chatQueueId) { 2834 rawQueue = rq; 2835 break; 2836 } 2837 } 2838 if(rawQueue.dnis) { 2839 if(!Array.isArray(rawQueue.dnis)) { 2840 rawQueue.dnis = [rawQueue.dnis]; 2841 } 2842 // update the dnis array to just be a list 2843 queue.dnis = rawQueue.dnis.map(function(d) { 2844 return d['#text']; 2845 }); 2846 } 2847 } 2848 } 2849 var LogoutRequest = function(agentId, message, isSupervisor) { 2850 this.agentId = agentId; 2851 this.message = message || ""; 2852 this.isSupervisor = isSupervisor; 2853 }; 2854 LogoutRequest.prototype.formatJSON = function() { 2855 var msg = { 2856 "ui_request": { 2857 "@destination":"IQ", 2858 "@type":MESSAGE_TYPES.LOGOUT, 2859 "@message_id":utils.getMessageId(), 2860 "response_to":"", 2861 "agent_id":{ 2862 "#text":this.agentId 2863 }, 2864 "message":{ 2865 "#text":this.message 2866 } 2867 } 2868 }; 2869 return JSON.stringify(msg); 2870 }; 2871 var OffhookInitRequest = function() { 2872 }; 2873 OffhookInitRequest.prototype.formatJSON = function() { 2874 var msg = { 2875 "ui_request": { 2876 "@destination":"IQ", 2877 "@type":MESSAGE_TYPES.OFFHOOK_INIT, 2878 "@message_id":utils.getMessageId(), 2879 "response_to":"", 2880 "agent_id":{ 2881 "#text":UIModel.getInstance().agentSettings.agentId 2882 }, 2883 "dial_dest":{ 2884 "#text":UIModel.getInstance().agentSettings.dialDest 2885 } 2886 } 2887 }; 2888 return JSON.stringify(msg); 2889 }; 2890 /* 2891 * This class is responsible for handling an off-hook-init response packet from IntelliQueue. 2892 * If the offhookinit is successful, it will go into the UIModel and set the isOffhook variable 2893 * to true. 2894 * 2895 * {"ui_response":{ 2896 * "@message_id":"UI2005", 2897 * "@response_to":"", 2898 * "@type":"OFF-HOOK-INIT", 2899 * "status":{"#text":"OK|FAILURE"}, 2900 * "monitoring":{"#text:"TRUE|FALSE"}, 2901 * "message":{}, 2902 * "detail":{} 2903 * } 2904 * } 2905 */ 2906 OffhookInitRequest.prototype.processResponse = function(response) { 2907 var status = response.ui_response.status['#text']; 2908 var formattedResponse = utils.buildDefaultResponse(response); 2909 if(status === 'OK') { 2910 var isMonitoring = utils.getText(response.ui_response, "monitoring"); 2911 UIModel.getInstance().offhookInitPacket = response; 2912 UIModel.getInstance().agentSettings.isOffhook = true; 2913 UIModel.getInstance().agentSettings.isMonitoring = isMonitoring; 2914 formattedResponse.monitoring = isMonitoring; 2915 } else { 2916 if(formattedResponse.message === "") { 2917 formattedResponse.message = "Unable to process offhook request"; 2918 } 2919 utils.logMessage(LOG_LEVELS.WARN, formattedResponse.message + ' ' + formattedResponse.detail, response); 2920 } 2921 return formattedResponse; 2922 }; 2923 var OffhookTermRequest = function() { 2924 }; 2925 OffhookTermRequest.prototype.formatJSON = function() { 2926 var msg = { 2927 "ui_request": { 2928 "@destination":"IQ", 2929 "@type":MESSAGE_TYPES.OFFHOOK_TERM, 2930 "@message_id":utils.getMessageId(), 2931 "response_to":"", 2932 "agent_id":{ 2933 "#text":UIModel.getInstance().agentSettings.agentId 2934 } 2935 } 2936 }; 2937 return JSON.stringify(msg); 2938 }; 2939 /* 2940 * Process an OFF-HOOK-TERM packet and update various variables in the UI 2941 * 2942 * {"ui_notification":{ 2943 * "@message_id":"IQ10012016080217135001344", 2944 * "@response_to":"", 2945 * "@type":"OFF-HOOK-TERM", 2946 * "agent_id":{"#text":"1"}, 2947 * "start_dts":{"#text":"2016-08-02 17:11:38"}, 2948 * "end_dts":{"#text":"2016-08-02 17:14:07"}, 2949 * "monitoring":{"#text":"0"} 2950 * } 2951 * } 2952 */ 2953 OffhookTermRequest.prototype.processResponse = function(data) { 2954 var notif = data.ui_notification; 2955 var monitoring = utils.getText(notif, "monitoring") === '1'; 2956 var model = UIModel.getInstance(); 2957 model.agentSettings.wasMonitoring = monitoring; 2958 model.offhookTermPacket = data; 2959 model.agentSettings.isOffhook = false; 2960 model.agentSettings.isMonitoring = false; 2961 var formattedResponse = { 2962 status: "OK", 2963 agentId: utils.getText(notif, "agent_id"), 2964 startDts: utils.getText(notif, "start_dts"), 2965 endDts: utils.getText(notif, "end_dts"), 2966 monitoring: monitoring 2967 }; 2968 return formattedResponse; 2969 }; 2970 var OneToOneOutdialRequest = function(destination, callerId, ringTime, countryId, gateId) { 2971 this.destination = destination; 2972 this.callerId = callerId; 2973 this.ringTime = ringTime || "60"; 2974 this.countryId = countryId || "USA"; 2975 this.gateId = gateId || ""; 2976 }; 2977 OneToOneOutdialRequest.prototype.formatJSON = function() { 2978 var msg = { 2979 "ui_request": { 2980 "@destination":"IQ", 2981 "@type":MESSAGE_TYPES.ONE_TO_ONE_OUTDIAL, 2982 "@message_id":utils.getMessageId(), 2983 "response_to":"", 2984 "agent_id":{ 2985 "#text":utils.toString(UIModel.getInstance().agentSettings.agentId) 2986 }, 2987 "destination":{ 2988 "#text":utils.toString(this.destination) 2989 }, 2990 "ring_time":{ 2991 "#text":utils.toString(this.ringTime) 2992 }, 2993 "caller_id":{ 2994 "#text":utils.toString(this.callerId) 2995 }, 2996 "country_id":{ 2997 "#text":utils.toString(this.countryId) 2998 }, 2999 "gate_id":{ 3000 "#text":utils.toString(this.gateId) 3001 } 3002 } 3003 }; 3004 return JSON.stringify(msg); 3005 }; 3006 var OneToOneOutdialCancelRequest = function(uii) { 3007 this.uii = uii 3008 }; 3009 /* 3010 * This class is responsible for creating a new packet to cancel 3011 * an in-progress outbound call. 3012 */ 3013 OneToOneOutdialCancelRequest.prototype.formatJSON = function() { 3014 var msg = { 3015 "ui_request": { 3016 "@destination":"IQ", 3017 "@type":MESSAGE_TYPES.ONE_TO_ONE_OUTDIAL_CANCEL, 3018 "@message_id":utils.getMessageId(), 3019 "response_to":"", 3020 "agent_id":{ 3021 "#text":utils.toString(UIModel.getInstance().agentSettings.agentId) 3022 }, 3023 "uii":{ 3024 "#text":utils.toString(this.uii) 3025 } 3026 } 3027 }; 3028 return JSON.stringify(msg); 3029 }; 3030 var PauseRecordRequest = function(record) { 3031 this.record = record; 3032 }; 3033 /* 3034 * {"ui_request":{ 3035 * "@destination":"IQ", 3036 * "@message_id":"UI200809291036128", 3037 * "@response_to":"", 3038 * "@type":"PAUSE-RECORD", 3039 * "agent_id":{"#text":"1856"}, 3040 * "uii":{"#text":"200808291035510000000900029412"}, 3041 * "record":{"#text":"TRUE | FALSE"}, 3042 * "pause":{"#text":"10"} 3043 * } 3044 * } 3045 */ 3046 PauseRecordRequest.prototype.formatJSON = function() { 3047 var model = UIModel.getInstance(); 3048 var pauseTime = "10"; 3049 if(model.currentCall.agentRecording && model.currentCall.agentRecording.pause){ 3050 pauseTime = model.currentCall.agentRecording.pause; 3051 } 3052 var msg = { 3053 "ui_request": { 3054 "@destination":"IQ", 3055 "@type":MESSAGE_TYPES.PAUSE_RECORD, 3056 "@message_id":utils.getMessageId(), 3057 "@response_to":"", 3058 "agent_id":{ 3059 "#text":utils.toString(model.currentCall.agentId) 3060 }, 3061 "uii":{ 3062 "#text":utils.toString(model.currentCall.uii) 3063 }, 3064 "record":{ 3065 "#text":utils.toString(this.record === true ? "TRUE" : "FALSE") 3066 }, 3067 "pause":{ 3068 "#text":utils.toString(pauseTime) 3069 } 3070 } 3071 }; 3072 return JSON.stringify(msg); 3073 }; 3074 /* 3075 * This class processes PAUSE-RECORD packets rec'd from IQ. 3076 * 3077 * {"ui_response":{ 3078 * "@message_id":"IQ982008082910361503344", 3079 * "@response_to":"", 3080 * "@type":"PAUSE-RECORD", 3081 * "uii":{"#text":"200808291035510000000900029412"}, 3082 * "status":{"#text":"OK | FAILURE"}, 3083 * "message":{}, 3084 * "detail":{}, 3085 * "state":{"#text":"RECORDING | PAUSED"}, 3086 * "pause":{"#text":"10"} 3087 * } 3088 * } 3089 */ 3090 PauseRecordRequest.prototype.processResponse = function(response) { 3091 var resp = response.ui_response; 3092 var formattedResponse = utils.buildDefaultResponse(response); 3093 var currUII = ""; 3094 if(UIModel.getInstance().currentCall.uii){ 3095 currUII = UIModel.getInstance().currentCall.uii; 3096 } 3097 formattedResponse.uii = utils.getText(resp, 'uii'); 3098 formattedResponse.state = utils.getText(resp, 'state'); 3099 formattedResponse.pause = utils.getText(resp, 'pause'); 3100 if(formattedResponse.status === "OK"){ 3101 // make sure we are talking about the same call 3102 if(formattedResponse.uii === currUII) { 3103 if(formattedResponse.message === ""){ 3104 formattedResponse.message = "Broadcasting new record state of " + formattedResponse.state; 3105 } 3106 utils.logMessage(LOG_LEVELS.DEBUG, "Broadcasting new record state of " + formattedResponse.state, response); 3107 }else{ 3108 utils.logMessage(LOG_LEVELS.DEBUG, "Pause Record Response is for a different call...discarding", response); 3109 } 3110 }else{ 3111 if(formattedResponse.message === ""){ 3112 formattedResponse.message = "Error processing PAUSE-RECORD request." + formattedResponse.message + "\n" + formattedResponse.detail; 3113 } 3114 utils.logMessage(LOG_LEVELS.WARN, formattedResponse.message, response); 3115 } 3116 return formattedResponse; 3117 }; 3118 var PingCallRequest = function() { 3119 3120 }; 3121 PingCallRequest.prototype.formatJSON = function() { 3122 var msg = { 3123 "ui_request": { 3124 "@destination":"IQ", 3125 "@type":MESSAGE_TYPES.PING_CALL, 3126 "@message_id":utils.getMessageId(), 3127 "@response_to":"", 3128 "agent_id":{ 3129 "#text":UIModel.getInstance().currentCall.agentId 3130 }, 3131 "uii":{ 3132 "#text":UIModel.getInstance().currentCall.uii 3133 } 3134 } 3135 }; 3136 return JSON.stringify(msg); 3137 }; 3138 var PreviewDialRequest = function(action, searchFields, requestId, leadPhone) { 3139 this.agentId = UIModel.getInstance().agentSettings.agentId; 3140 this.searchFields = searchFields || []; 3141 this.requestId = requestId || ""; 3142 this.action = action || ""; 3143 this.leadPhone = leadPhone || ""; // pipe leads only 3144 }; 3145 /* 3146 * searchFields = [ 3147 * {key: "name", value: "Danielle"}, 3148 * {key: "number", value: "5555555555" 3149 * ]; 3150 */ 3151 PreviewDialRequest.prototype.formatJSON = function() { 3152 var fields = {}; 3153 for(var i =0; i < this.searchFields.length; i++){ 3154 var fieldObj = this.searchFields[i]; 3155 fields[fieldObj.key] = { "#text" : utils.toString(fieldObj.value) }; 3156 } 3157 var msg = { 3158 "ui_request": { 3159 "@destination":"IQ", 3160 "@type":MESSAGE_TYPES.PREVIEW_DIAL, 3161 "@message_id":utils.getMessageId(), 3162 "@action":this.action, 3163 "@response_to":"", 3164 "agent_id":{ 3165 "#text":utils.toString(UIModel.getInstance().agentSettings.agentId) 3166 }, 3167 "pending_request_id":{ 3168 "#text":utils.toString(this.requestId) 3169 }, 3170 "lead_phone":{ 3171 "#text":utils.toString(this.leadPhone) 3172 }, 3173 "search_fields": fields 3174 // { "name": {"#text": "Danielle" } } 3175 } 3176 }; 3177 return JSON.stringify(msg); 3178 }; 3179 /* 3180 * This class is responsible for handling PREVIEW-DIAL packets received 3181 * from the dialer. It will save a copy of it in the UIModel. 3182 * 3183 * {"dialer_request":{ 3184 * "@action":"", // <-- empty for Preview fetch, otherwise "SEARCH" 3185 * "@callbacks":"TRUE|FALSE" 3186 * ,"@message_id":"ID2008091513163400220", 3187 * "@response_to":"", 3188 * "@type":"PREVIEW_DIAL", 3189 * "dial_group_id":{"#text":"200018"}, 3190 * "account_id":{"#text":"99999999"}, 3191 * "agent_id":{"#text":"1810"}, 3192 * "is_insert":{"#text":"TRUE|FALSE"}, <--- TRUE if search triggered by insert 3193 * "destinations":{ 3194 * "lead":[ 3195 * { 3196 * "@aux_data1":"","@aux_data2":"","@aux_data3":"","@aux_data4":"","@aux_data5":"", 3197 * "@aux_phone":"","@campaign_id":"51","@destination":"9548298548","@dnis":"1112223333", 3198 * "@extern_id":"amanda","@lead_id":"2646","@lead_state":"PENDING","@live_answer_msg":"", 3199 * "@mach_answer_msg":"","@machine_detect":"FALSE","@request_key":"IQ982008091516241101125", 3200 * "@valid_until":"2008-09-15 17:24:11","extern_id":{"#text":"9548298548"}, 3201 * "first_name":{"#text":"Amanda"},"mid_name":{"#text":"Amanda"},"last_name":{"#text":"Machutta2"}, 3202 * "address1":{},"address2":{},"city":{},"state":{},"zip":{},"aux_greeting":{}, 3203 * "aux_external_url":{}, "app_url":{} 3204 * }, 3205 * ] 3206 * } 3207 * } 3208 * } 3209 */ 3210 PreviewDialRequest.prototype.processResponse = function(notification) { 3211 var notif = notification.dialer_request; 3212 var model = UIModel.getInstance(); 3213 var leads = utils.processResponseCollection(notif, 'destinations', 'lead'); 3214 // send over requestId (as well as requestKey for backwards compatibility) 3215 // to match previewLeadState.notification property 3216 for(var l = 0; l < leads.length; l++) { 3217 var lead = leads[l]; 3218 lead.requestId = lead.requestKey; 3219 lead.ani = lead.destination; // add ani prop since used in new call packet & update lead 3220 // In case of a single lead returned, the XML converter to JSON will add lead as an object and not an array 3221 // 3222 if (!Array.isArray(notif.destinations.lead)) { 3223 notif.destinations.lead = [notif.destinations.lead]; 3224 } 3225 // parse extra data correctly 3226 try { 3227 var notifLead = notif.destinations.lead[l]; 3228 if(notifLead.extra_data) { 3229 // if this lead doesn't match the current lead, find it from the notification 3230 if(notifLead['@lead_id'] !== lead.leadId) { 3231 notifLead = (notif.destinations.lead).filter( 3232 function(destLead) { 3233 return destLead['@lead_id'] === lead.leadId; 3234 } 3235 ); 3236 } 3237 delete lead.extraDatas; 3238 lead.extraData = {}; 3239 for(var key in notifLead.extra_data) { 3240 lead.extraData[key] = notifLead.extra_data[key]['#text']; 3241 } 3242 } 3243 } catch(e) { 3244 console.warn('error parsing lead extra data: ' + e); 3245 } 3246 } 3247 var formattedResponse = { 3248 action: notif['@action'], 3249 callbacks: notif['@callbacks'] === "TRUE", 3250 dialGroupId: utils.getText(notif,"dial_group_id"), 3251 accountId: utils.getText(notif,"account_id"), 3252 agentId: utils.getText(notif,"agent_id"), 3253 isInsert: utils.getText(notif,"is_insert"), 3254 leads: leads 3255 }; 3256 if(notif['@callbacks'] === 'TRUE'){ 3257 utils.logMessage(LOG_LEVELS.INFO, "New CALLBACK packet request rec'd from dialer", notification); 3258 // clear callbacks?? 3259 //model.callbacks = []; 3260 for(var l = 0; l < leads.length; l++){ 3261 var lead = leads[l]; 3262 model.callbacks.push(lead); 3263 } 3264 }else{ 3265 model.outboundSettings.previewDialLeads = leads; 3266 } 3267 return formattedResponse; 3268 }; 3269 var RecordRequest = function(record) { 3270 this.record = record; 3271 }; 3272 /* 3273 * {"ui_request":{ 3274 * "@destination":"IQ", 3275 * "@message_id":"UI200809291036128", 3276 * "@response_to":"", 3277 * "@type":"RECORD", 3278 * "agent_id":{"#text":"1856"}, 3279 * "uii":{"#text":"200808291035510000000900029412"}, 3280 * "record":{"#text":"TRUE | FALSE"} 3281 * } 3282 * } 3283 */ 3284 RecordRequest.prototype.formatJSON = function() { 3285 var model = UIModel.getInstance(); 3286 var msg = { 3287 "ui_request": { 3288 "@destination":"IQ", 3289 "@type":MESSAGE_TYPES.RECORD, 3290 "@message_id":utils.getMessageId(), 3291 "@response_to":"", 3292 "agent_id":{ 3293 "#text":utils.toString(model.currentCall.agentId) 3294 }, 3295 "uii":{ 3296 "#text":utils.toString(model.currentCall.uii) 3297 }, 3298 "record":{ 3299 "#text": this.record === true ? "TRUE" : "FALSE" 3300 } 3301 } 3302 }; 3303 return JSON.stringify(msg); 3304 }; 3305 /* 3306 * This class processes RECORD packets rec'd from IQ. 3307 * 3308 * {"ui_response":{ 3309 * "@message_id":"IQ982008082910361503344", 3310 * "@response_to":"", 3311 * "@type":"RECORD", 3312 * "uii":{"#text":"200808291035510000000900029412"}, 3313 * "status":{"#text":"OK"}, 3314 * "message":{}, 3315 * "detail":{}, 3316 * "state":{"#text":"RECORDING | STOPPED"} 3317 * } 3318 * } 3319 */ 3320 RecordRequest.prototype.processResponse = function(response) { 3321 var resp = response.ui_response; 3322 var formattedResponse = utils.buildDefaultResponse(response); 3323 var currUII = ""; 3324 if(UIModel.getInstance().currentCall.uii){ 3325 currUII = UIModel.getInstance().currentCall.uii; 3326 } 3327 formattedResponse.uii = utils.getText(resp, 'uii'); 3328 formattedResponse.state = utils.getText(resp, 'state'); 3329 if(formattedResponse.status === "OK"){ 3330 // make sure we are talking about the same call 3331 if(formattedResponse.uii === currUII) { 3332 if(formattedResponse.message === ""){ 3333 formattedResponse.message = "Broadcasting new record state of " + formattedResponse.state; 3334 } 3335 utils.logMessage(LOG_LEVELS.DEBUG, formattedResponse.message, response); 3336 }else{ 3337 utils.logMessage(LOG_LEVELS.DEBUG, "Record Response is for a different call...discarding", response); 3338 } 3339 }else{ 3340 if(formattedResponse.message === ""){ 3341 formattedResponse.message = "Error processing RECORD request." + formattedResponse.message + "\n" + formattedResponse.detail; 3342 } 3343 utils.logMessage(LOG_LEVELS.WARN, formattedResponse.message, response); 3344 } 3345 return formattedResponse; 3346 }; 3347 var RequeueRequest = function(queueId, skillId, maintain) { 3348 this.queueId = queueId; 3349 this.skillId = skillId; 3350 this.maintain = maintain; 3351 }; 3352 RequeueRequest.prototype.formatJSON = function() { 3353 var msg = { 3354 "ui_request": { 3355 "@destination":"IQ", 3356 "@type":MESSAGE_TYPES.REQUEUE, 3357 "@message_id":utils.getMessageId(), 3358 "response_to":"", 3359 "agent_id":{ 3360 "#text":UIModel.getInstance().agentSettings.agentId 3361 }, 3362 "uii":{ 3363 "#text":UIModel.getInstance().currentCall.uii 3364 }, 3365 "gate_number":{ 3366 "#text":utils.toString(this.queueId) 3367 }, 3368 "skill_id":{ 3369 "#text":utils.toString(this.skillId) 3370 }, 3371 "maintain_agent":{ 3372 "#text":this.maintain === true ? "TRUE" : "FALSE" 3373 } 3374 } 3375 }; 3376 return JSON.stringify(msg); 3377 }; 3378 /* 3379 * This class processes RE-QUEUE packets rec'd from IQ. 3380 * 3381 * {"ui_response":{ 3382 * "@message_id":"IQ982008082817165103291", 3383 * "@response_to":"UIV220088281716486", 3384 * "@type":"RE-QUEUE", 3385 * "status":"OK", 3386 * "message":"Success.", 3387 * "detail":"The re-queue request was successfully processed.", 3388 * "agent_id":{"#text":"1856"}, 3389 * "uii":{"#text":"200808281716090000000900028070"}, 3390 * "gate_number":{"#text":"19"}, 3391 * "maintain_agent":{"#text":"FALSE"} 3392 * } 3393 * } 3394 */ 3395 RequeueRequest.prototype.processResponse = function(response) { 3396 var resp = response.ui_response; 3397 var formattedResponse = utils.buildDefaultResponse(response); 3398 formattedResponse.agentId = utils.getText(resp, 'agent_id'); 3399 formattedResponse.uii = utils.getText(resp, 'uii'); 3400 formattedResponse.queueId = utils.getText(resp, 'gate_number'); 3401 if(formattedResponse.status === "OK"){ 3402 }else{ 3403 var message = "There was an error processing the requeue request. " + formattedResponse.detail; 3404 utils.logMessage(LOG_LEVELS.WARN, message, response); 3405 } 3406 return formattedResponse; 3407 }; 3408 var ScriptConfigRequest = function(scriptId, version) { 3409 this.scriptId = scriptId; 3410 this.version = version || null; 3411 }; 3412 /* 3413 * This event is responsible for requesting a script object 3414 */ 3415 ScriptConfigRequest.prototype.formatJSON = function() { 3416 var msg = { 3417 "ui_request": { 3418 "@destination":"IQ", 3419 "@message_id":utils.getMessageId(), 3420 "response_to":"", 3421 "@type":MESSAGE_TYPES.SCRIPT_CONFIG, 3422 "agent_id":{ 3423 "#text":utils.toString(UIModel.getInstance().agentSettings.agentId) 3424 }, 3425 "script_id": { 3426 "#text" : utils.toString(this.scriptId) 3427 } 3428 } 3429 }; 3430 return JSON.stringify(msg); 3431 }; 3432 /* 3433 * This class process SCRIPT-CONFIG packets received from IntelliQueue. 3434 * 3435 * {"ui_response":{ 3436 * "@message_id":"IQ982008082817165103294", 3437 * "@response_to":"", 3438 * "@type":"SCRIPT-CONFIG", 3439 * "status":{"#text":"OK"}, 3440 * "message":{}, 3441 * "script_id":{"#text":"123"}, 3442 * "version":{"#text":"1"}, 3443 * "json":{}, 3444 * } 3445 * } 3446 */ 3447 ScriptConfigRequest.prototype.processResponse = function(response) { 3448 var resp = response.ui_response; 3449 var formattedResponse = utils.buildDefaultResponse(response); 3450 if(formattedResponse.status === "true"){ 3451 formattedResponse.status = true; 3452 formattedResponse.scriptId = utils.getText(resp, 'script_id'); 3453 formattedResponse.version = utils.getText(resp, 'version'); 3454 formattedResponse.json = utils.getText(resp, 'json'); 3455 // store script on model 3456 UIModel.getInstance().scriptSettings.loadedScripts[formattedResponse.scriptId] = formattedResponse; 3457 }else{ 3458 formattedResponse.status = false; 3459 } 3460 return formattedResponse; 3461 }; 3462 var ScriptResultRequest = function(uii, scriptId, jsonResult) { 3463 this.uii = uii; 3464 this.scriptId = scriptId; 3465 this.jsonResult = jsonResult; 3466 }; 3467 /* 3468 * This event is responsible for sending the script result object 3469 */ 3470 ScriptResultRequest.prototype.formatJSON = function() { 3471 var msg = { 3472 "ui_request": { 3473 "@destination":"IQ", 3474 "@message_id":utils.getMessageId(), 3475 "response_to":"", 3476 "@type":MESSAGE_TYPES.SCRIPT_RESULT, 3477 "agent_id": { 3478 "#text" : utils.toString(UIModel.getInstance().agentSettings.agentId) 3479 }, 3480 "uii":{ 3481 "#text":utils.toString(this.uii) 3482 }, 3483 "script_id": { 3484 "#text" : utils.toString(this.scriptId) 3485 }, 3486 "json_result": { 3487 "#text": JSON.stringify(this.jsonResult) 3488 } 3489 } 3490 }; 3491 return JSON.stringify(msg); 3492 }; 3493 var StatsRequest = function() { 3494 3495 }; 3496 /* 3497 * { "ui_request": { 3498 * "@response_to":"", 3499 * "@message_id":"IS20160901142437535", 3500 * "@type":"STATS" 3501 * } 3502 * } 3503 */ 3504 StatsRequest.prototype.formatJSON = function() { 3505 var msg = { 3506 "ui_request": { 3507 "@destination":"IS", 3508 "@type":MESSAGE_TYPES.STATS, 3509 "@message_id":utils.getMessageId(), 3510 "@response_to":"" 3511 } 3512 }; 3513 return JSON.stringify(msg); 3514 }; 3515 var TcpaSafeRequest = function(action, searchFields, requestId, leadPhone) { 3516 this.agentId = UIModel.getInstance().agentSettings.agentId; 3517 this.searchFields = searchFields || []; 3518 this.requestId = requestId || ""; 3519 this.action = action || ""; 3520 this.leadPhone = leadPhone || ""; // pipe leads only 3521 }; 3522 /* 3523 * searchFields = [ 3524 * {key: "name", value: "Danielle"}, 3525 * {key: "number", value: "5555555555" 3526 * ]; 3527 */ 3528 TcpaSafeRequest.prototype.formatJSON = function() { 3529 var fields = {}; 3530 for(var i =0; i < this.searchFields.length; i++){ 3531 var fieldObj = this.searchFields[i]; 3532 fields[fieldObj.key] = { "#text" : utils.toString(fieldObj.value) }; 3533 } 3534 var msg = { 3535 "ui_request": { 3536 "@destination":"IQ", 3537 "@type":MESSAGE_TYPES.TCPA_SAFE, 3538 "@message_id":utils.getMessageId(), 3539 "@action":this.action, 3540 "response_to":"", 3541 "agent_id":{ 3542 "#text":utils.toString(UIModel.getInstance().agentSettings.agentId) 3543 }, 3544 "pending_request_id":{ 3545 "#text":utils.toString(this.requestId) 3546 }, 3547 "lead_phone":{ 3548 "#text":utils.toString(this.leadPhone) 3549 }, 3550 "search_fields": fields 3551 // { "name": {"#text": "Danielle"} } 3552 } 3553 }; 3554 return JSON.stringify(msg); 3555 }; 3556 /* 3557 * This class is responsible for handling TCPA-SAFE packets received 3558 * from the dialer. It will save a copy of it in the UIModel. 3559 * 3560 * {"dialer_request":{ 3561 * "@action":"", 3562 * "@callbacks":"TRUE|FALSE" 3563 * ,"@message_id":"ID2008091513163400220", 3564 * "@response_to":"", 3565 * "@type":"TCPA_SAFE", 3566 * "dial_group_id":{"#text":"200018"}, 3567 * "account_id":{"#text":"99999999"}, 3568 * "agent_id":{"#text":"1810"}, 3569 * "is_insert":{"#text":"TRUE|FALSE"}, <--- TRUE if search triggered by insert 3570 * "destinations":{ 3571 * "lead":[ 3572 * { 3573 * "@aux_data1":"","@aux_data2":"","@aux_data3":"","@aux_data4":"","@aux_data5":"", 3574 * "@aux_phone":"","@campaign_id":"51","@destination":"9548298548","@dnis":"1112223333", 3575 * "@extern_id":"amanda","@lead_id":"2646","@lead_state":"PENDING","@live_answer_msg":"", 3576 * "@mach_answer_msg":"","@machine_detect":"FALSE","@request_key":"IQ982008091516241101125", 3577 * "@valid_until":"2008-09-15 17:24:11","extern_id":{"#text":"9548298548"}, 3578 * "first_name":{"#text":"Amanda"},"mid_name":{"#text":"Amanda"},"last_name":{"#text":"Machutta2"}, 3579 * "address1":{},"address2":{},"city":{},"state":{},"zip":{},"aux_greeting":{}, 3580 * "aux_external_url":{}, "app_url":{} 3581 * }, 3582 * ] 3583 * } 3584 * } 3585 * } 3586 * 3587 */ 3588 TcpaSafeRequest.prototype.processResponse = function(notification) { 3589 var notif = notification.dialer_request; 3590 var model = UIModel.getInstance(); 3591 var leads = utils.processResponseCollection(notif, 'destinations', 'lead'); 3592 // send over requestId (as well as requestKey for backwards compatibility) 3593 // to match tcpaSafeLeadState.notification property 3594 for(var l = 0; l < leads.length; l++){ 3595 var lead = leads[l]; 3596 lead.requestId = lead.requestKey; 3597 lead.ani = lead.destination; // add ani prop since used in new call packet & update lead 3598 // parse extra data correctly 3599 try { 3600 var notifLead = notif.destinations.lead[l]; 3601 if(notifLead.extra_data) { 3602 // if this lead doesn't match the current lead, find it from the notification 3603 if(notifLead['@lead_id'] !== lead.leadId) { 3604 notifLead = (notif.destinations.lead).filter( 3605 function(destLead) { 3606 return destLead['@lead_id'] === lead.leadId; 3607 } 3608 ); 3609 } 3610 delete lead.extraDatas; 3611 lead.extraData = {}; 3612 for(var key in notifLead.extra_data) { 3613 lead.extraData[key] = notifLead.extra_data[key]['#text']; 3614 } 3615 } 3616 } catch(e) { 3617 console.warn('error parsing lead extra data: ' + e); 3618 } 3619 } 3620 var formattedResponse = { 3621 action: notif['@action'], 3622 callbacks: notif['@callbacks'] === "TRUE", 3623 dialGroupId: utils.getText(notif,"dial_group_id"), 3624 accountId: utils.getText(notif,"account_id"), 3625 agentId: utils.getText(notif,"agent_id"), 3626 isInsert: utils.getText(notif,"is_insert"), 3627 leads: leads 3628 }; 3629 if(notif['@callbacks'] === 'TRUE'){ 3630 var message = "New CALLBACK packet request rec'd from dialer"; 3631 utils.logMessage(LOG_LEVELS.INFO, message, notification); 3632 // clear callbacks?? 3633 //model.callbacks = []; 3634 for(var l = 0; l < leads.length; l++){ 3635 var lead = leads[l]; 3636 model.callbacks.push(lead); 3637 } 3638 }else{ 3639 model.outboundSettings.tcpaSafeLeads = leads; 3640 } 3641 return formattedResponse; 3642 }; 3643 var UpdateDialDestinationRequest = function(dialDest, isSoftphoneError) { 3644 this.dialDest = dialDest; 3645 this.isSoftphoneError = isSoftphoneError || false; 3646 }; 3647 /* 3648 * {"ui_request":{ 3649 * "@destination":"IQ", 3650 * "@type":MESSAGE_TYPES.UPDATE_DIAL_DESTINATION, 3651 * "@message_id":"UI200809291036128", 3652 * "@response_to":"", 3653 * "agent_id":"1", 3654 * "dial_dest":{"#text":"blah@something.com"}, 3655 * "log_softphone_error": {"#text":"TRUE|FALSE"}, 3656 * } 3657 * } 3658 */ 3659 UpdateDialDestinationRequest.prototype.formatJSON = function() { 3660 var msg = { 3661 "ui_request": { 3662 "@destination":"IQ", 3663 "@type":MESSAGE_TYPES.UPDATE_DIAL_DESTINATION, 3664 "@message_id":utils.getMessageId(), 3665 "@response_to":"", 3666 "agent_id":{ 3667 "#text":utils.toString(UIModel.getInstance().agentSettings.agentId) 3668 }, 3669 "dial_dest":{ 3670 "#text":utils.toString(this.dialDest) 3671 }, 3672 "log_softphone_error":{ 3673 "#text":utils.toString(this.isSoftphoneError === true ? "TRUE" : "FALSE") 3674 } 3675 } 3676 }; 3677 return JSON.stringify(msg); 3678 }; 3679 var XferWarmRequest = function(dialDest, callerId, sipHeaders, countryId) { 3680 this.dialDest = dialDest; 3681 this.callerId = callerId || ""; 3682 this.sipHeaders = sipHeaders || []; 3683 this.countryId = countryId; 3684 }; 3685 XferWarmRequest.prototype.formatJSON = function() { 3686 var fields = []; 3687 for(var i =0; i < this.sipHeaders.length; i++){ 3688 var fieldObj = this.sipHeaders[i]; 3689 fields.push({ '@name' : utils.toString(fieldObj.name), '@value' : utils.toString(fieldObj.value)}); 3690 } 3691 var msg = { 3692 "ui_request": { 3693 "@destination":"IQ", 3694 "@type":MESSAGE_TYPES.XFER_WARM, 3695 "@message_id":utils.getMessageId(), 3696 "@response_to":"", 3697 "agent_id":{ 3698 "#text":UIModel.getInstance().agentSettings.agentId 3699 }, 3700 "uii":{ 3701 "#text":UIModel.getInstance().currentCall.uii 3702 }, 3703 "dial_dest":{ 3704 "#text":utils.toString(this.dialDest) 3705 }, 3706 "caller_id":{ 3707 "#text":utils.toString(this.callerId) 3708 }, 3709 "country_id": { 3710 "#text":utils.toString(this.countryId) 3711 }, 3712 "xfer_header": fields 3713 } 3714 }; 3715 return JSON.stringify(msg); 3716 }; 3717 /* 3718 * This class processes WARM-XFER packets rec'd from IQ. 3719 * 3720 * {"ui_response":{ 3721 * "@message_id":"IQ10012016082314475000219", 3722 * "@response_to":"", 3723 * "@type":"WARM-XFER", 3724 * "agent_id":{"#text":"1"}, 3725 * "uii":{"#text":"201608231447590139000000000200"}, 3726 * "session_id":{"#text":"3"}, 3727 * "status":{"#text":"OK"}, 3728 * "dial_dest":{"#text":"3038593775"}, 3729 * "message":{"#text":"OK"},"detail":{} 3730 * } 3731 * } 3732 * Response on CANCEL: 3733 * {"ui_response":{ 3734 * "@message_id":"IQ10012016082315005000264", 3735 * "@response_to":"", 3736 * "@type":"WARM-XFER", 3737 * "agent_id":{"#text":"1"}, 3738 * "uii":{"#text":"201608231501090139000000000204"}, 3739 * "session_id":{}, 3740 * "status":{"#text":"FAILURE"}, 3741 * "dial_dest":{"#text":"3038593775"}, 3742 * "message":{"#text":"Transfer CANCELED"}, 3743 * "detail":{"#text":"NOANSWER after 3 seconds."} 3744 * } 3745 * } 3746 */ 3747 XferWarmRequest.prototype.processResponse = function(response) { 3748 var resp = response.ui_response; 3749 var formattedResponse = utils.buildDefaultResponse(response); 3750 formattedResponse.agentId = utils.getText(resp, 'agent_id'); 3751 formattedResponse.uii = utils.getText(resp, 'uii'); 3752 formattedResponse.sessionId = utils.getText(resp, 'session_id'); 3753 formattedResponse.dialDest = utils.getText(resp, 'dial_dest'); 3754 if(formattedResponse.status === "OK"){ 3755 utils.logMessage(LOG_LEVELS.DEBUG, "Warm Xfer to " + formattedResponse.dialDest + " processed successfully.", response); 3756 }else{ 3757 utils.logMessage(LOG_LEVELS.WARN, "There was an error processing the Warm Xfer request. " + formattedResponse.message + "\n" + formattedResponse.detail, response); 3758 } 3759 return formattedResponse; 3760 }; 3761 var XferWarmCancelRequest = function(dialDest) { 3762 this.dialDest = dialDest; 3763 }; 3764 XferWarmCancelRequest.prototype.formatJSON = function() { 3765 var msg = { 3766 "ui_request": { 3767 "@destination":"IQ", 3768 "@type":MESSAGE_TYPES.XFER_WARM_CANCEL, 3769 "@message_id":utils.getMessageId(), 3770 "@response_to":"", 3771 "agent_id":{ 3772 "#text":UIModel.getInstance().agentSettings.agentId 3773 }, 3774 "uii":{ 3775 "#text":UIModel.getInstance().currentCall.uii 3776 }, 3777 "dial_dest":{ 3778 "#text":utils.toString(this.dialDest) 3779 } 3780 } 3781 }; 3782 return JSON.stringify(msg); 3783 }; 3784 var ChatAgentEndRequest = function(agentId, uii){ 3785 this.uii = uii; 3786 this.agentId = agentId; 3787 }; 3788 /* 3789 External Chat : 3790 when agent submits a chat end request, send "CHAT-AGENT-END" request to IntelliQueue 3791 { 3792 "ui_request" : { 3793 "@destination" : "IQ", 3794 "@type" : MESSAGE_TYPES.CHAT_AGENT_END, 3795 "uii":{ 3796 "#text":utils.toString(this.uii) 3797 }, 3798 "agent_id":{ 3799 "#text":utils.toString(this.agentId) 3800 } 3801 } 3802 } 3803 */ 3804 ChatAgentEndRequest.prototype.formatJSON = function(){ 3805 var msg = { 3806 "ui_request" : { 3807 "@destination" : "IQ", 3808 "@type" : MESSAGE_TYPES.CHAT_AGENT_END, 3809 "uii":{ 3810 "#text":utils.toString(this.uii) 3811 }, 3812 "agent_id":{ 3813 "#text":utils.toString(this.agentId) 3814 } 3815 } 3816 }; 3817 return JSON.stringify(msg); 3818 }; 3819 var ChatAliasRequest = function(alias) { 3820 this.alias = alias; 3821 }; 3822 /* 3823 * This class is responsible for creating the request to change chat alias 3824 * packet and sending it to intelliservices. 3825 * {"ui_request":{ 3826 * "@destination":"IQ", 3827 * "@message_id":"UI200809291036128", 3828 * "@response_to":"", 3829 * "@type":"CHAT-ALIAS", 3830 * "alias":{"#text":""} 3831 * } 3832 * } 3833 */ 3834 ChatAliasRequest.prototype.formatJSON = function() { 3835 var msg = { 3836 "ui_request": { 3837 "@destination":"IS", 3838 "@type":MESSAGE_TYPES.CHAT_ALIAS, 3839 "@message_id":utils.getMessageId(), 3840 "@response_to":"", 3841 "alias":{ 3842 "#text":utils.toString(this.alias) 3843 } 3844 } 3845 }; 3846 return JSON.stringify(msg); 3847 }; 3848 var ChatDispositionRequest = function(uii, agentId, dispositionId, notes, sendAcknowlegement, survey, sessionId) { 3849 this.uii = uii; 3850 this.agentId = agentId; 3851 this.dispositionId = dispositionId; 3852 this.notes = notes || ""; 3853 this.sendAcknowlegement = sendAcknowlegement || false; 3854 this.sessionId = sessionId; 3855 /* 3856 * survey = { 3857 * first_name: { 3858 * leadField: "first_name" 3859 * value: "Geoff" 3860 * }, 3861 * last_name: { 3862 * leadField: "last_name" 3863 * value: "Mina" 3864 * } 3865 * ... 3866 * } 3867 */ 3868 this.survey = survey || null; 3869 }; 3870 /* 3871 * External Chat: 3872 * When agent dispositions a chat, send "CHAT-DISPOSITION" request to IntelliQueue 3873 * {"ui_request":{ 3874 * "@destination":"IQ", 3875 * "@type":"CHAT-DISPOSITION", 3876 * "@message_id":"", 3877 * "@response_to":"", 3878 * "uii":{"#text":""}, 3879 * "agent_id":{"#text":""}, 3880 * "session_id" : {"#text" : ""}, 3881 * "disposition_id":{"#text":""}, 3882 * "notes":{"#text":"hello"}, 3883 * "do_ack":{"#text":"true"}, 3884 * "survey":{ 3885 * "response":[ 3886 * {"@extern_id":"text_box","#text":"hello"}, 3887 * {"@extern_id":"check_box","#text":"20"}, 3888 * {"@extern_id":"radio_save","#text":"23"} 3889 * ] 3890 * } 3891 * } 3892 * } 3893 */ 3894 ChatDispositionRequest.prototype.formatJSON = function() { 3895 var msg = { 3896 "ui_request": { 3897 "@destination":"IQ", 3898 "@type":MESSAGE_TYPES.CHAT_DISPOSITION, 3899 "@message_id":utils.getMessageId(), 3900 "@response_to":"", 3901 "uii":{ 3902 "#text":utils.toString(this.uii) 3903 }, 3904 "agent_id":{ 3905 "#text":utils.toString(this.agentId) 3906 }, 3907 "session_id" : { 3908 "#text" : utils.toString(this.sessionId) 3909 }, 3910 "disposition_id":{ 3911 "#text":utils.toString(this.dispositionId) 3912 }, 3913 "notes":{ 3914 "#text":utils.toString(this.notes) 3915 }, 3916 "do_ack":{ 3917 "#text":this.sendAcknowlegement === true ? "TRUE" : "FALSE" 3918 } 3919 } 3920 }; 3921 /* 3922 * converts survey to this response 3923 * survey : { 3924 * response: [ 3925 * { "@extern_id":"", "@lead_update_column":"", "#text":"" } 3926 * ] 3927 * } 3928 */ 3929 if(this.survey !== null){ 3930 var response = []; 3931 var keys = Object.keys(this.survey); 3932 for(var i = 0; i < keys.length; i++){ 3933 var key = keys[i]; 3934 var obj = { 3935 "@extern_id": key, 3936 "#text": utils.toString(this.survey[key].value) 3937 }; 3938 response.push(obj); 3939 } 3940 msg.ui_request.survey = {"response":response}; 3941 } 3942 return JSON.stringify(msg); 3943 }; 3944 var ChatListRequest = function(agentId, monitorAgentId) { 3945 this.agentId = agentId; 3946 this.monitorAgentId = monitorAgentId; 3947 }; 3948 /* 3949 * External Chat: 3950 * Requests a list of all chats by monitor agent id 3951 * 3952 * {"ui_request":{ 3953 * "@destination":"IQ", 3954 * "@type":"CHAT-LIST", 3955 * "@message_id":"", 3956 * "@response_to":"", 3957 * "agent_id":{"#text":""}, 3958 * "monitor_agent_id":{"#text":""} 3959 * } 3960 * } 3961 */ 3962 ChatListRequest.prototype.formatJSON = function() { 3963 var msg = { 3964 "ui_request": { 3965 "@destination":"IQ", 3966 "@type":MESSAGE_TYPES.CHAT_LIST, 3967 "@message_id":utils.getMessageId(), 3968 "@response_to":"", 3969 "agent_id":{ 3970 "#text":utils.toString(this.agentId) 3971 }, 3972 "monitor_agent_id":{ 3973 "#text":utils.toString(this.monitorAgentId) 3974 } 3975 } 3976 }; 3977 return JSON.stringify(msg); 3978 }; 3979 /* 3980 * External Chat: 3981 * This class is responsible for handling "CHAT-LIST" packets from IntelliQueue. 3982 * 3983 * { 3984 * "ui_response":{ 3985 * "@message_id":"IQ10012016081611595000289", 3986 * "@type":"CHAT-LIST", 3987 * "@response_to":"", 3988 * "agent_id":{"#text":"17"}, 3989 * "monitor_agent_id":{"#text":"18"}, 3990 * "chat_list": {} 3991 * } 3992 * } 3993 */ 3994 ChatListRequest.prototype.processResponse = function(response) { 3995 var notif = response.ui_response; 3996 var model = UIModel.getInstance(); 3997 model.chatListResponse = response; 3998 return { 3999 message: "Received CHAT-LIST notification", 4000 status: "OK", 4001 messageId: notif['@message_id'], 4002 agentId: utils.getText(notif, "agent_id"), 4003 monitorAgentId: utils.getText(notif, "monitor_agent_id"), 4004 chatList: utils.processResponseCollection( notif, "chat_list", "active_chat") 4005 }; 4006 }; 4007 var ChatMessageRequest = function(uii, agentId, message, whisper) { 4008 this.uii = uii; 4009 this.agentId = agentId; 4010 this.message = message; 4011 this.whisper = whisper; 4012 }; 4013 /* 4014 * External Chat: 4015 * When agent submits a chat message, send "CHAT-MESSAGE" request to IntelliQueue 4016 * 4017 * {"ui_request":{ 4018 * "@destination":"IQ", 4019 * "@type":"CHAT-MESSAGE", 4020 * "@message_id":"", 4021 * "@response_to":"", 4022 * "uii":{"#text":""}, 4023 * "agent_id":{"#text":""}, 4024 * "message":{"#text":"hello"}, 4025 * "whisper":{"#text":"true|false"} 4026 * } 4027 * } 4028 */ 4029 ChatMessageRequest.prototype.formatJSON = function() { 4030 var msg = { 4031 "ui_request": { 4032 "@destination":"IQ", 4033 "@type":MESSAGE_TYPES.CHAT_MESSAGE, 4034 "@message_id":utils.getMessageId(), 4035 "@response_to":"", 4036 "uii":{ 4037 "#text":utils.toString(this.uii) 4038 }, 4039 "agent_id":{ 4040 "#text":utils.toString(this.agentId) 4041 }, 4042 "message":{ 4043 "#text":utils.toString(this.message) 4044 }, 4045 "whisper":{ 4046 "#text":utils.toString(this.whisper) 4047 } 4048 } 4049 }; 4050 return JSON.stringify(msg); 4051 }; 4052 /* 4053 * This class is responsible for handling external CHAT-MESSAGE packets received from 4054 * IntelliQueue. 4055 * 4056 * {"ui_notification":{ 4057 * "@message_id":"", 4058 * "@response_to":"", 4059 * "@type":"CHAT-MESSAGE", 4060 * "uii":{"#text":""}, 4061 * "account_id":{"#text":""}, 4062 * "from":{"#text":""}, 4063 * "message":{"#text":"hello"}, 4064 * "dts":{"#text":"2017-05-10 12:40:28"}, 4065 * "dequeue_agent_id":{"#text":"123"}, 4066 * "whisper":{"#text":'TRUE'|'FALSE'"} 4067 * } 4068 * } 4069 */ 4070 ChatMessageRequest.prototype.processResponse = function(response) { 4071 var resp = response.ui_notification; 4072 var dts = utils.getText(resp, 'dts').trim(); 4073 var dtsDate = new Date(dts.replace(' ','T')); 4074 var formattedResponse = { 4075 uii: utils.getText(resp, 'uii'), 4076 accountId: utils.getText(resp, 'account_id'), 4077 from: utils.getText(resp, 'from'), 4078 type: utils.getText(resp, 'type'), 4079 message: utils.getText(resp, 'message'), 4080 whisper: utils.getText(resp, 'whisper'), 4081 dequeueAgentId: utils.getText(resp, 'dequeue_agent_id'), 4082 dts: dtsDate, 4083 mediaLinks : utils.processResponseCollection(resp, "media_links", "link") 4084 }; 4085 utils.logMessage(LOG_LEVELS.DEBUG, "New CHAT-MESSAGE packet received from IntelliQueue", response); 4086 return formattedResponse; 4087 }; 4088 var ChatPresentedResponseRequest = function(uii, messageId, response, responseReason) { 4089 this.uii = uii; 4090 this.messageId = messageId; 4091 this.response = response; 4092 this.responseReason = responseReason || ""; 4093 }; 4094 /* 4095 * External Chat: 4096 * When Agent receives a CHAT-PRESENTED notification, respond with 4097 * either ACCEPT or REJECT for presented chat. 4098 * {"ui_request":{ 4099 * "@destination":"IQ", 4100 * "@type":"CHAT-PRESENTED", 4101 * "@message_id":"", 4102 * "@response_to":"", 4103 * "uii":{"#text":""}, 4104 * "agent_id":{"#text":""}, 4105 * "response":{"#text":"ACCEPT|REJECT"}, 4106 * "response_reason":{"#text":""} 4107 * } 4108 * } 4109 */ 4110 ChatPresentedResponseRequest.prototype.formatJSON = function() { 4111 var msg = { 4112 "ui_request": { 4113 "@destination":"IQ", 4114 "@type":MESSAGE_TYPES.CHAT_PRESENTED_RESPONSE, 4115 "@message_id":utils.getMessageId(), 4116 "@response_to":this.messageId, 4117 "uii":{ 4118 "#text":utils.toString(this.uii) 4119 }, 4120 "agent_id":{ 4121 "#text":UIModel.getInstance().agentSettings.agentId 4122 }, 4123 "response":{ 4124 "#text":utils.toString(this.response) 4125 }, 4126 "response_reason":{ 4127 "#text":utils.toString(this.responseReason) 4128 } 4129 } 4130 }; 4131 return JSON.stringify(msg); 4132 }; 4133 var ChatRequeueRequest = function(uii, agentId, chatQueueId, skillId, maintainAgent) { 4134 this.uii = uii; 4135 this.agentId = agentId; 4136 this.chatQueueId = chatQueueId; 4137 this.skillId = skillId || ""; 4138 this.maintainAgent = maintainAgent || false; 4139 }; 4140 /* 4141 * External Chat: 4142 * When agent submits a chat message, send "CHAT-REQUEUE" request to IntelliQueue 4143 * {"ui_request":{ 4144 * "@destination":"IQ", 4145 * "@type":"CHAT-REQUEUE", 4146 * "@message_id":"", 4147 * "@response_to":"", 4148 * "uii":{"#text":""}, 4149 * "agent_id":{"#text":""}, 4150 * "chat_queue_id":{"#text":""}, 4151 * "skill_id":{"#text":""}, 4152 * "maintain_agent":{"#text":"true|false"} 4153 * } 4154 * } 4155 */ 4156 ChatRequeueRequest.prototype.formatJSON = function() { 4157 var msg = { 4158 "ui_request": { 4159 "@destination":"IQ", 4160 "@type":MESSAGE_TYPES.CHAT_REQUEUE, 4161 "@message_id":utils.getMessageId(), 4162 "@response_to":"", 4163 "uii":{ 4164 "#text":utils.toString(this.uii) 4165 }, 4166 "agent_id":{ 4167 "#text":utils.toString(this.agentId) 4168 }, 4169 "chat_queue_id":{ 4170 "#text":utils.toString(this.chatQueueId) 4171 }, 4172 "skill_id":{ 4173 "#text":utils.toString(this.skillId) 4174 }, 4175 "maintain_agent":{ 4176 "#text":utils.toString(this.maintainAgent) 4177 } 4178 } 4179 }; 4180 return JSON.stringify(msg); 4181 }; 4182 var ChatRoomRequest = function(action, roomType, roomId, agentOne, agentTwo) { 4183 this.action = action; 4184 this.roomType = roomType; 4185 this.roomId = roomId; 4186 this.agentOne = agentOne || ""; 4187 this.agentTwo = agentTwo || ""; 4188 }; 4189 /* 4190 * This class is responsible for sending the packet requesting to either enter 4191 * a chatroom, or to exit a chatroom to IS. It also handles private chats. There are 4192 * two possible ways these packets could look: 4193 * 4194 * //PUBLIC 4195 * {"ui_request":{ 4196 * "@destination":"IS", 4197 * "@message_id":"", 4198 * "@response_to":"", 4199 * "@type":"CHAT-ROOM", 4200 * "@room_type":"PUBLIC", 4201 * "room_id":{"#text":""}, 4202 * "action":{"#text":"EXIT|ENTER"} 4203 * } 4204 * } 4205 * -OR- 4206 * // PRIVATE 4207 * {"ui_request":{ 4208 * "@destination":"IS", 4209 * "@message_id":"", 4210 * "@response_to":"", 4211 * "@type":"CHAT-ROOM", 4212 * "@room_type":"PRIVATE", 4213 * "agent_one":{"#text":""}, 4214 * "agent_two":{"#text":""}, 4215 * "action":{"#text":"ENTER|EXIT"} 4216 * } 4217 * } 4218 * 4219 */ 4220 ChatRoomRequest.prototype.formatJSON = function() { 4221 var msg = { 4222 "ui_request": { 4223 "@destination":"IS", 4224 "@type":MESSAGE_TYPES.CHAT_ROOM, 4225 "@message_id":utils.getMessageId(), 4226 "@response_to":"", 4227 "action":{ 4228 "#text":utils.toString(this.action) 4229 } 4230 } 4231 }; 4232 if(this.action !== "EXIT"){ 4233 msg.ui_request["@room_type"] = this.roomType; 4234 } 4235 if(this.roomType === "PRIVATE" && this.action === "ENTER"){ 4236 msg.ui_request.agent_one = { "#text":utils.toString(this.agentOne) }; 4237 msg.ui_request.agent_two = { "#text":utils.toString(this.agentTwo) }; 4238 }else{ 4239 msg.ui_request.room_id = { "#text":utils.toString(this.roomId) }; 4240 } 4241 return JSON.stringify(msg); 4242 }; 4243 var ChatRoomStateRequest = function() { 4244 }; 4245 /* 4246 * This class is responsible for processing CHAT-ROOM-STATE packets received 4247 * from IntelliServices. 4248 * 4249 * {"ui_request":{ 4250 * "@message_id":"", 4251 * "@response_to":"", 4252 * "@type":"CHAT-ROOM-STATE", 4253 * "room_id":{"#text":""}, 4254 * "agent_id":{"#text":""}, 4255 * "chat_alias":{"#text":""}, 4256 * "state":{"#text":""} 4257 * } 4258 * } 4259 */ 4260 ChatRoomStateRequest.prototype.processResponse = function(response) { 4261 var resp = response.ui_request; 4262 var formattedResponse = { 4263 roomId: utils.getText(resp, 'room_id'), 4264 agentId: utils.getText(resp, 'agent_id'), 4265 chatAlias: utils.getText(resp, 'chat_alias'), 4266 state: utils.getText(resp, 'state') 4267 }; 4268 utils.logMessage(LOG_LEVELS.DEBUG, "Chat-Room-State update packet received for room #" + formattedResponse.roomId, response); 4269 return formattedResponse; 4270 }; 4271 var ChatSendRequest = function(roomId, message) { 4272 this.roomId = roomId; 4273 this.message = message; 4274 }; 4275 /* 4276 * This class is responsible for creating the CHAT message packet and sending 4277 * it to IntelliServices. 4278 * 4279 * {"ui_request":{ 4280 * "@destination":"IQ", 4281 * "@message_id":"UI200809291036128", 4282 * "@response_to":"", 4283 * "@type":"CHAT", 4284 * "room_id":{"#text":""} 4285 * "message":{"#text":""} 4286 * } 4287 * } 4288 */ 4289 ChatSendRequest.prototype.formatJSON = function() { 4290 var msg = { 4291 "ui_request": { 4292 "@destination":"IS", 4293 "@type":MESSAGE_TYPES.CHAT_SEND, 4294 "@message_id":utils.getMessageId(), 4295 "@response_to":"", 4296 "room_id":{ 4297 "#text":utils.toString(this.roomId) 4298 }, 4299 "message":{ 4300 "#text":utils.toString(this.message) 4301 } 4302 } 4303 }; 4304 return JSON.stringify(msg); 4305 }; 4306 /* 4307 * This class is responsible for handling CHAT packets received from 4308 * IntelliServices. 4309 * 4310 * //PUBLIC 4311 * {"ui_request":{ 4312 * "@message_id":"", 4313 * "@response_to":"", 4314 * "@type":"CHAT", 4315 * "room_type":"GROUP", 4316 * "room_id":{"#text":""}, 4317 * "message":{"#text":""}, 4318 * "sender":{"#text":""}, 4319 * "sender_id":{"#text":""}, 4320 * "room_name":{"#text":""} 4321 * } 4322 * } 4323 * -OR- 4324 * // PRIVATE 4325 * {"ui_request":{ 4326 * "@dynamic_create":"TRUE", 4327 * "@message_id":"", 4328 * "@response_to":"", 4329 * "@type":"CHAT", 4330 * "room_type":"PRIVATE", 4331 * "room_id":{"#text":""}, 4332 * "message":{"#text":""}, 4333 * "sender":{"#text":""}, 4334 * "room_name":{"#text":""} 4335 * } 4336 * } 4337 */ 4338 ChatSendRequest.prototype.processResponse = function(response) { 4339 var resp = response.ui_request; 4340 var formattedResponse = { 4341 roomType: utils.getText(resp, 'room_type'), 4342 roomId: utils.getText(resp, 'room_id'), 4343 message: utils.getText(resp, 'message'), 4344 sender: utils.getText(resp, 'sender'), 4345 senderId: utils.getText(resp, 'sender_id'), 4346 roomName: utils.getText(resp, 'room_name'), 4347 dynamicCreate: utils.getText(resp, 'dynamic_create') === "TRUE" 4348 }; 4349 utils.logMessage(LOG_LEVELS.DEBUG, "New CHAT packet received from IntelliServices", response); 4350 return formattedResponse; 4351 }; 4352 var ChatTypingRequest = function(uii,message) { 4353 this.uii = uii; 4354 this.message=message; 4355 }; 4356 /* 4357 * External Chat: 4358 * Agent sends typing message to notify client widgets, 4359 * but the agent's pending message is not sent going this direction. 4360 * {"ui_request":{ 4361 * "@destination":"IQ", 4362 * "@type":"CHAT-TYPING", 4363 * "@message_id":"", 4364 * "@response_to":"", 4365 * "uii":{"#text":""}, 4366 * "agent_id":{"#text":""}, 4367 * "message":{"#text":""} 4368 * } 4369 * } 4370 */ 4371 ChatTypingRequest.prototype.formatJSON = function() { 4372 var msg = { 4373 "ui_request": { 4374 "@destination":"IQ", 4375 "@type":MESSAGE_TYPES.CHAT_TYPING, 4376 "@message_id":utils.getMessageId(), 4377 "@response_to":"", 4378 "uii":{ 4379 "#text":utils.toString(this.uii) 4380 }, 4381 "agent_id":{ 4382 "#text":UIModel.getInstance().agentSettings.agentId 4383 }, 4384 "message":{ 4385 "#text":utils.toString(this.message) 4386 } 4387 } 4388 }; 4389 return JSON.stringify(msg); 4390 }; 4391 var LeaveChatRequest = function(uii, agentId, sessionId) { 4392 this.uii = uii; 4393 this.agentId = agentId; 4394 this.sessionId = sessionId; 4395 }; 4396 /* 4397 * External Chat: 4398 * Requests to terminate a chat session on an existing chat uii 4399 * 4400 * {"ui_request":{ 4401 * "@destination":"IQ", 4402 * "@type":"CHAT-DROP-SESSION", 4403 * "@message_id":"", 4404 * "@response_to":"", 4405 * "uii":{"#text":""}, 4406 * "agent_id":{"#text":""}, 4407 * "session_id":{"#text":""} 4408 * } 4409 * } 4410 */ 4411 LeaveChatRequest.prototype.formatJSON = function() { 4412 var msg = { 4413 "ui_request": { 4414 "@destination":"IQ", 4415 "@type":MESSAGE_TYPES.LEAVE_CHAT, 4416 "@message_id":utils.getMessageId(), 4417 "@response_to":"", 4418 "uii":{ 4419 "#text":utils.toString(this.uii) 4420 }, 4421 "agent_id":{ 4422 "#text":UIModel.getInstance().agentSettings.agentId 4423 }, 4424 "session_id":{ 4425 "#text":utils.toString(this.sessionId) 4426 } 4427 } 4428 }; 4429 return JSON.stringify(msg); 4430 }; 4431 var ChatManualSmsRequest = function(agentId, chatQueueId, ani, dnis, message) { 4432 this.agentId = agentId; 4433 this.chatQueueId = chatQueueId; 4434 this.ani = ani; 4435 this.dnis = dnis; 4436 this.message = message; 4437 }; 4438 /* 4439 * External Chat: 4440 * When agent submits a manual sms message, send "MANUAL-SMS" request to IntelliQueue 4441 * 4442 * {"ui_request":{ 4443 * "@destination":"IQ", 4444 * "@type":"MANUAL-SMS", 4445 * "@message_id":"", 4446 * "@response_to":"", 4447 * "agent_id":{"#text":"1995"}, 4448 * "chatQueueId":{"#text":"44"}, 4449 * "ani":{"#text":"1231231234"}, 4450 * "dnis":{"#text":"5435435432"}, 4451 * "message":{"#text":"hello"} 4452 * } 4453 * } 4454 */ 4455 ChatManualSmsRequest.prototype.formatJSON = function() { 4456 var msg = { 4457 "ui_request": { 4458 "@destination":"IQ", 4459 "@type":MESSAGE_TYPES.CHAT_MANUAL_SMS, 4460 "@message_id":utils.getMessageId(), 4461 "@response_to":"", 4462 "agent_id":{ 4463 "#text":utils.toString(this.agentId) 4464 }, 4465 "chat_queue_id":{ 4466 "#text":utils.toString(this.chatQueueId) 4467 }, 4468 "ani":{ 4469 "#text":utils.toString(this.ani) 4470 }, 4471 "dnis":{ 4472 "#text":utils.toString(this.dnis) 4473 }, 4474 "message":{ 4475 "#text":utils.toString(this.message) 4476 } 4477 } 4478 }; 4479 return JSON.stringify(msg); 4480 }; 4481 var MonitorChatRequest = function(monitorAgentId) { 4482 this.monitorAgentId = monitorAgentId; 4483 }; 4484 /* 4485 * External Chat: 4486 * Requests a new session on an existing chat uii 4487 * 4488 * {"ui_request":{ 4489 * "@destination":"IQ", 4490 * "@type":"CHAT-MONITOR", 4491 * "@message_id":"", 4492 * "@response_to":"", 4493 * "agent_id":{"#text":""}, 4494 * "monitor_agent_id":{"#text":""} 4495 * } 4496 * } 4497 */ 4498 MonitorChatRequest.prototype.formatJSON = function() { 4499 var msg = { 4500 "ui_request": { 4501 "@destination":"IQ", 4502 "@type":MESSAGE_TYPES.MONITOR_CHAT, 4503 "@message_id":utils.getMessageId(), 4504 "@response_to":"", 4505 "agent_id":{ 4506 "#text":UIModel.getInstance().agentSettings.agentId 4507 }, 4508 "monitor_agent_id":{ 4509 "#text":utils.toString(this.monitorAgentId) 4510 } 4511 } 4512 }; 4513 return JSON.stringify(msg); 4514 }; 4515 var StopMonitorChatRequest = function(monitorAgentId) { 4516 this.monitorAgentId = monitorAgentId || ""; 4517 }; 4518 /* 4519 * External Chat: 4520 * Requests a termination of a chat monitor session for an agent 4521 * 4522 * {"ui_request":{ 4523 * "@destination":"IQ", 4524 * "@type":"CHAT-DROP-MONITORING-SESSION", 4525 * "@message_id":"", 4526 * "@response_to":"", 4527 * "agent_id":{"#text":""}, 4528 * "monitor_agent_id":{"#text":""} 4529 * } 4530 * } 4531 */ 4532 StopMonitorChatRequest.prototype.formatJSON = function() { 4533 var msg = { 4534 "ui_request": { 4535 "@destination":"IQ", 4536 "@type":MESSAGE_TYPES.STOP_MONITOR_CHAT, 4537 "@message_id":utils.getMessageId(), 4538 "@response_to":"", 4539 "agent_id":{ 4540 "#text":UIModel.getInstance().agentSettings.agentId 4541 }, 4542 "monitor_agent_id":{ 4543 "#text":utils.toString(this.monitorAgentId) 4544 } 4545 } 4546 }; 4547 return JSON.stringify(msg); 4548 }; 4549 /* 4550 * Process a CHAT-DROP-MONITORING-SESSION notification. Used to notify supervisor monitors that agent has logged out. 4551 * 4552 * {"ui_notification":{ 4553 * "@message_id":"IQ10012016080217135001344", 4554 * "@response_to":"", 4555 * "@type":"CHAT-DROP-MONITORING-SESSION", 4556 * "monitored_agent_id":{"#text":"1"} 4557 * } 4558 * } 4559 */ 4560 StopMonitorChatRequest.prototype.processResponse = function(data) { 4561 var notif = data.ui_notification; 4562 return ({ monitoredAgentId : utils.getText(notif, "monitored_agent_id") }); 4563 }; 4564 var SupervisorListRequest = function() { 4565 }; 4566 /* 4567 * This class is responsible for creating a packet to request a list of 4568 * supervisors from IntelliServices. This is used by the chat function so an 4569 * agent can grab a list of supervisors and then select one for a private chat. 4570 * 4571 * {"ui_request":{ 4572 * "@destination":"IQ", 4573 * "@message_id":"UI200809291036128", 4574 * "@response_to":"", 4575 * "@type":"SUPERVISOR-LIST", 4576 * "agent_id":{"#text":""} 4577 * } 4578 * } 4579 */ 4580 SupervisorListRequest.prototype.formatJSON = function() { 4581 var msg = { 4582 "ui_request": { 4583 "@destination":"IS", 4584 "@type":MESSAGE_TYPES.SUPERVISOR_LIST, 4585 "@message_id":utils.getMessageId(), 4586 "@response_to":"", 4587 "agent_id":{ 4588 "#text":utils.toString(UIModel.getInstance().agentSettings.agentId) 4589 } 4590 } 4591 }; 4592 return JSON.stringify(msg); 4593 }; 4594 /* 4595 * This class is responsible for handling the SUPERVISOR-LIST packet 4596 * rec'd from intelliservices. It will save a copy of this list in the 4597 * UIModel under a variable called "supervisors". Whenever a new list 4598 * is rec'd it is overwritten. 4599 * 4600 * {"ui_response":{ 4601 * "@message_id":"IQ982008082910361503344", 4602 * "@response_to":"", 4603 * "supervisor":[ 4604 * {"id":{"#text":""}, "fname":{"#text":""}, "lname":{"#text":""}, "uname":{"#text":""} } 4605 * {"id":{"#text":""}, "fname":{"#text":""}, "lname":{"#text":""}, "uname":{"#text":""} } 4606 * ] 4607 * } 4608 * } 4609 */ 4610 SupervisorListRequest.prototype.processResponse = function(response) { 4611 var model = UIModel.getInstance(); 4612 var tempList = utils.processResponseCollection(response, "ui_response", "supervisor"); 4613 var supervisors = []; 4614 for(var i = 0; i < tempList.length; i++){ 4615 var sup = tempList[i]; 4616 supervisors.push({ 4617 agentId:sup.id, 4618 firstName:sup.fname, 4619 lastName:sup.lname, 4620 username:sup.uname 4621 }); 4622 } 4623 utils.logMessage(LOG_LEVELS.DEBUG, "New supervisor list received ", supervisors); 4624 model.supervisors = supervisors; 4625 return model.supervisors; 4626 }; 4627 var ChatClientReconnectNotification = function() { 4628 }; 4629 /* 4630 * External Chat: 4631 * This class is responsible for handling "CHAT-CLIENT-RECONNECT" packets from IntelliQueue. 4632 * This is sent when a chat connect message is sent to a non-archieved chat. 4633 * 4634 * { 4635 * "ui_notification":{ 4636 * "@message_id":"IQ10012016081611595000289", 4637 * "@type":"CHAT-CLIENT-RECONNECT", 4638 * "@destination":"IQ", 4639 * "@response_to":"", 4640 * "account_id":{"#text":"99999999"}, 4641 * "uii":{"#text":"201608161200240139000000000120"} 4642 * "agent_id":{"#text":"1"} 4643 * } 4644 * } 4645 */ 4646 ChatClientReconnectNotification.prototype.processResponse = function(notification){ 4647 var notif = notification.ui_notification; 4648 return { 4649 message : "Received CHAT-CLIENT-RECONNECT notification", 4650 status : "OK", 4651 accountId : utils.getText(notif, "account_id"), 4652 uii : utils.getText(notif, "uii"), 4653 agentId : utils.getText(notif, "agent_id") 4654 }; 4655 }; 4656 var AddChatSessionNotification = function() { 4657 }; 4658 /* 4659 * This class is responsible for handling "ADD-CHAT-SESSION" packets from IntelliQueue. 4660 * 4661 * { 4662 * "ui_notification": { 4663 * "@message_id": "IQ982008082918151403727", 4664 * "@response_to": "", 4665 * "@type": "ADD-CHAT-SESSION", 4666 * "session_id": { "#text": "2" }, 4667 * "uii": { "#text": "200808291814560000000900016558" }, 4668 * "session_type": { "#text": "AGENT|MONITORING" }, 4669 * "agent_id": { "#text": "1856" } // null unless monitor type, 4670 * "transcript": { } 4671 * } 4672 * } 4673 */ 4674 AddChatSessionNotification.prototype.processResponse = function(notification) { 4675 var notif = notification.ui_notification; 4676 var formattedResponse = utils.buildDefaultResponse(notification); 4677 formattedResponse.status = "OK"; 4678 formattedResponse.message = "Received ADD-CHAT-SESSION notification"; 4679 formattedResponse.sessionId = utils.getText(notif, "session_id"); 4680 formattedResponse.uii = utils.getText(notif, "uii"); 4681 formattedResponse.sessionType = utils.getText(notif, "session_type"); 4682 formattedResponse.agentId = utils.getText(notif, "agent_id"); 4683 formattedResponse.transcript = utils.processResponseCollection(notification, 'ui_notification', 'transcript')[0]; 4684 return formattedResponse; 4685 }; 4686 var ChatActiveNotification = function() { 4687 }; 4688 /* 4689 * External Chat: 4690 * This class is responsible for handling "CHAT-ACTIVE" packets from IntelliQueue. 4691 * This is sent in response to an agent's CHAT-PRESENTED-RESPONSE accept request. 4692 * 4693 * { 4694 * "ui_notification":{ 4695 * "@message_id":"IQ10012016081611595000289", 4696 * "@type":"CHAT-ACTIVE", 4697 * "@destination":"IQ", 4698 * "@response_to":"", 4699 * "account_id":{"#text":"99999999"}, 4700 * "uii":{"#text":"201608161200240139000000000120"}, 4701 * "is_monitoring":{"#text":"TRUE"|"FALSE"} 4702 * } 4703 * } 4704 */ 4705 ChatActiveNotification.prototype.processResponse = function(notification) { 4706 var notif = notification.ui_notification; 4707 return { 4708 message: "Received CHAT-ACTIVE notification", 4709 status: "OK", 4710 accountId: utils.getText(notif, "account_id"), 4711 uii: utils.getText(notif, "uii"), 4712 isMonitoring: utils.getText(notif, "is_monitoring") 4713 }; 4714 }; 4715 var ChatCancelledNotification = function() { 4716 }; 4717 /* 4718 * External Chat: 4719 * This class is responsible for processing "CHAT-CANCELLED" packets from IntelliQueue. 4720 * If an agent is presented a chat and doesn't respond before the timeout, the CHAT-CANCELLED 4721 * message is sent from IQ. 4722 * 4723 * { 4724 * "ui_notification":{ 4725 * "@message_id":"IQ10012016081611595000289", 4726 * "@type":"CHAT-CANCELLED", 4727 * "@destination":"IQ", 4728 * "@response_to":"", 4729 * "account_id":{"#text":"99999999"}, 4730 * "uii":{"#text":"201608161200240139000000000120"} 4731 * } 4732 * } 4733 */ 4734 ChatCancelledNotification.prototype.processResponse = function(notification) { 4735 var notif = notification.ui_notification; 4736 return { 4737 message: "Received CHAT-CANCELLED notification", 4738 status: "OK", 4739 messageId: notif['@message_id'], 4740 accountId: utils.getText(notif, "account_id"), 4741 uii: utils.getText(notif, "uii") 4742 }; 4743 }; 4744 var ChatInactiveNotification = function() { 4745 }; 4746 /* 4747 * External Chat: 4748 * This class is responsible for handling "CHAT-INACTIVE" packets from IntelliQueue. 4749 * This is sent to the agent when the last session is disconnected from a chat. 4750 * 4751 * { 4752 * "ui_notification":{ 4753 * "@message_id":"IQ10012016081611595000289", 4754 * "@type":"CHAT-INACTIVE", 4755 * "@destination":"IQ", 4756 * "@response_to":"", 4757 * "account_id":{"#text":"99999999"}, 4758 * "uii":{"#text":"201608161200240139000000000120"}, 4759 * "disposition_timeout":{"#text":"30"}, 4760 * "dequeue_agent_id":{"#text":"123"} 4761 * } 4762 * } 4763 */ 4764 ChatInactiveNotification.prototype.processResponse = function(notification) { 4765 var notif = notification.ui_notification; 4766 return { 4767 message: "Received CHAT-INACTIVE notification", 4768 status: "OK", 4769 accountId: utils.getText(notif, "account_id"), 4770 uii: utils.getText(notif, "uii"), 4771 dispositionTimeout: utils.getText(notif, "disposition_timeout"), 4772 dequeueAgentId: utils.getText(notif, "dequeue_agent_id") 4773 }; 4774 }; 4775 var ChatPresentedNotification = function() { 4776 }; 4777 /* 4778 * External Chat: 4779 * This class is responsible for handling "CHAT-PRESENTED" packets from IntelliQueue. 4780 * When this notification is received, the Agent can either Accept or Decline which will 4781 * be sent back to IntelliQueue as a CHAT-PRESENTED-RESPONSE. 4782 * 4783 * { 4784 * "ui_notification":{ 4785 * "@message_id":"IQ10012016081611595000289", 4786 * "@type":"CHAT-PRESENTED", 4787 * "@destination":"IQ", 4788 * "@response_to":"", 4789 * "chat_queue_id":{"#text":"3"}, 4790 * "chat_queue_name":{"#text":"Support Chat"}, 4791 * "account_id":{"#text":"99999999"}, 4792 * "uii":{"#text":"201608161200240139000000000120"}, 4793 * "channel_type":{"#text":""}, 4794 * "allow_accept":{"#text":"TRUE|FALSE"} 4795 * } 4796 * } 4797 */ 4798 ChatPresentedNotification.prototype.processResponse = function(notification) { 4799 var notif = notification.ui_notification; 4800 return { 4801 message: "Received CHAT-PRESENTED notification", 4802 status: "OK", 4803 messageId: notif['@message_id'], 4804 accountId: utils.getText(notif, "account_id"), 4805 uii: utils.getText(notif, "uii"), 4806 channelType: utils.getText(notif, "channel_type"), 4807 chatQueueId: utils.getText(notif, "chat_queue_id"), 4808 chatQueueName: utils.getText(notif, "chat_queue_name"), 4809 allowAccept: utils.getText(notif, "allow_accept") 4810 }; 4811 }; 4812 var ChatTypingNotification = function() { 4813 }; 4814 /* 4815 * External Chat: 4816 * This class is responsible for handling "CHAT-TYPING" packets from IntelliQueue. 4817 * When this notification is received, the AgentUI will show the pending message 4818 * so far from the client chat widget and typing notification. 4819 * 4820 * { 4821 * "ui_notification":{ 4822 * "@message_id":"IQ10012016081611595000289", 4823 * "@type":"CHAT-TYPING", 4824 * "@destination":"IQ", 4825 * "@response_to":"", 4826 * "uii":{"#text":"201608161200240139000000000120"}, 4827 * "account_id":{"#text":"99999999"}, 4828 * "from":{"#text":""}, 4829 * "message":{"#text":"this is the message before actual send"} 4830 * "dequeue_agent_id":{"#text":"123"} 4831 * } 4832 * } 4833 */ 4834 ChatTypingNotification.prototype.processResponse = function(notification) { 4835 var notif = notification.ui_notification; 4836 return { 4837 message: "Received CHAT-TYPING notification", 4838 status: "OK", 4839 accountId: utils.getText(notif, "account_id"), 4840 uii: utils.getText(notif, "uii"), 4841 from: utils.getText(notif, "from"), 4842 type: utils.getText(notif, "type"), 4843 pendingMessage: utils.getText(notif, "message"), 4844 dequeueAgentId: utils.getText(notif, "dequeue_agent_id") 4845 }; 4846 }; 4847 var NewChatNotification = function() { 4848 }; 4849 /* 4850 * External Chat: 4851 * This class is responsible for handling "NEW-CHAT" packets from IntelliQueue. 4852 * 4853 * { 4854 * "ui_notification":{ 4855 * "@message_id":"IQ10012016081611595000289", 4856 * "@type":"NEW-CHAT", 4857 * "@destination":"IQ", 4858 * "@response_to":"", 4859 * "uii":{"#text":"201608161200240139000000000120"}, 4860 * "account_id":{"#text":"99999999"}, 4861 * "session_id":{"#text":"2"}, 4862 * "agent_id":{"#text":"1180958"}, 4863 * "queue_dts":{"#text":""}, 4864 * "queue_time":{"#text":""}, 4865 * "chat_queue_id":{"#text":""}, 4866 * "chat_queue_name":{"#text":""}, 4867 * "chat_requeue_type" : {"#text":""} 4868 * "app_url":{"#text":""}, 4869 * "channel_type":{"#text":""}, 4870 * "ani":{"#text":""}, 4871 * "dnis":{"#text":""}, 4872 * "survey_pop_type":{"#text":""}, 4873 * "script_id":{"#text":""}, 4874 * "script_version":{"#text":""}, 4875 * "idle_timeout":{"#text":""}, 4876 * "is_monitoring":{#text":"TRUE"|"FALSE"}, 4877 * "monitored_agent_id":{"#text":"123"| ""} <-- only populated if is_monitoring == TRUE 4878 * "requeue_shortcuts":{ 4879 * "requeue_shortcut":{ 4880 * "@chat_queue_id":"2", 4881 * "@name":"test queue", 4882 * "@skill_id":"" 4883 * } 4884 * }, 4885 * "chat_dispositions":{ 4886 * "disposition":[ 4887 * { "@disposition_id":"2", "@is_success":"true", "@is_complete":"false", "@is_default"="0", "@email_template_id":"1", "#text":"Complete"}, 4888 * { "@disposition_id":"3", "@is_success":"true", "@is_complete":"false", "@is_default"="0", "#text":"Requeue"} 4889 * ] 4890 * }, 4891 * "chat_requeue_shortcuts" :{ 4892 * shortcut : [ 4893 * {@chat_requeue_shortcut_id:"3", @name:"test", @rank:"1",@requeue_chat_queue_id:"74",@skill_id:""} 4894 * ] 4895 * } 4896 * "transcript":{ 4897 * "message":[ 4898 * { "@from":"system", "@type":"SYSTEM", "@whisper":"FALSE", "@dts":"yyyy-MM-dd HH:mm:ss", "#text":"User1 connected"}, 4899 * { "@from":"dlbooks", "@type":"AGENT", "@whisper":"FALSE", "@dts":"yyyy-MM-dd HH:mm:ss", "#text":"Hello"}, 4900 * { "@from":"user1", "@type":"CLIENT", "@whisper":"FALSE", "@dts":"yyyy-MM-dd HH:mm:ss", "#text":"Hi"} 4901 * ] 4902 * }, 4903 * "json_baggage":{"#text":"json_string_form_data"}, <--- pre-form chat data 4904 * } 4905 * } 4906 */ 4907 NewChatNotification.prototype.processResponse = function(notification) { 4908 var notif = notification.ui_notification; 4909 var dts = utils.getText(notif,'queue_dts'); 4910 dts = new Date(dts.replace(' ','T')); 4911 // set up new call obj 4912 var newChat = { 4913 uii: utils.getText(notif,'uii'), 4914 accountId: utils.getText(notif,'account_id'), 4915 sessionId: utils.getText(notif,'session_id'), 4916 agentId: utils.getText(notif,'agent_id'), 4917 queueDts: dts, 4918 queueTime: utils.getText(notif,'queue_time'), 4919 chatQueueId: utils.getText(notif,'chat_queue_id'), 4920 chatQueueName: utils.getText(notif,'chat_queue_name'), 4921 chatRequeueType : utils.getText(notif, 'chat_requeue_type'), 4922 appUrl: utils.getText(notif,'app_url'), 4923 channelType: utils.getText(notif,'channel_type'), 4924 ani: utils.getText(notif,'ani'), 4925 dnis: utils.getText(notif,'dnis'), 4926 surveyPopType: utils.getText(notif,'survey_pop_type'), 4927 scriptId: utils.getText(notif,'script_id'), 4928 scriptVersion: utils.getText(notif,'script_version'), 4929 idleTimeout: utils.getText(notif,'idle_timeout'), 4930 isMonitoring: utils.getText(notif,'is_monitoring'), 4931 monitoredAgentId: utils.getText(notif,'monitored_agent_id'), 4932 preChatData: utils.getText(notif,'json_baggage') 4933 }; 4934 newChat.requeueShortcuts = utils.processResponseCollection(notification, 'ui_notification', 'chat_requeue_shortcuts', 'shortcut')[0]; 4935 newChat.chatDispositions = utils.processResponseCollection(notification, 'ui_notification', 'chat_dispositions', 'disposition')[0]; 4936 newChat.transcript = utils.processResponseCollection(notification, 'ui_notification', 'transcript', 'message')[0]; 4937 newChat.baggage = utils.processResponseCollection(notification, 'ui_notification', 'json_baggage')[0]; 4938 if(newChat.chatDispositions && newChat.chatDispositions.disposition){ 4939 newChat.chatDispositions.dispositions = [newChat.chatDispositions] 4940 }else{ 4941 newChat.chatDispositions = newChat.chatDispositions.dispositions; 4942 } 4943 if(newChat.transcript && newChat.transcript.message){ 4944 newChat.transcript = [newChat.transcript]; 4945 }else{ 4946 newChat.transcript = newChat.transcript.messages; 4947 } 4948 if(newChat.preChatData){ 4949 try { 4950 newChat.preChatData = JSON.parse(newChat.preChatData); 4951 }catch(err){ 4952 utils.logMessage(LOG_LEVELS.ERROR, "Error parsing the pre-form chat data.", notif); 4953 } 4954 } 4955 // convert numbers to boolean 4956 if(newChat.chatDispositions){ 4957 for(var d = 0; d < newChat.chatDispositions.length; d++){ 4958 var disp = newChat.chatDispositions[d]; 4959 disp.isComplete = disp.isComplete === "1"; 4960 disp.isSuccess = disp.isSuccess === "1"; 4961 disp.isDefault = disp.isDefault === "1"; 4962 } 4963 } 4964 // convert dates 4965 if(newChat.transcript){ 4966 for(var t = 0; t < newChat.transcript.length; t++){ 4967 var msg = newChat.transcript[t]; 4968 if(msg.dts){ 4969 msg.dts = new Date(msg.dts.replace(' ','T')); 4970 } 4971 } 4972 } 4973 // Build token map 4974 newChat.baggage = buildChatTokenMap(notif, newChat); 4975 return newChat; 4976 }; 4977 function buildChatTokenMap(notif, newChat){ 4978 var tokens = {}; 4979 var model = UIModel.getInstance(); 4980 if(newChat.preChatData){ 4981 for(var prop in newChat.preChatData){ 4982 if(newChat.preChatData.hasOwnProperty(prop)){ 4983 tokens[prop] = newChat.preChatData[prop]; 4984 } 4985 } 4986 } 4987 try{ 4988 tokens["chatQueueId"] = newChat.chatQueueId; 4989 tokens["chatQueueName"] = newChat.chatQueueName; 4990 tokens["ani"] = newChat.ani; 4991 tokens["dnis"] = newChat.dnis; 4992 tokens["uii"] = newChat.uii; 4993 }catch(any){ 4994 console.error("There was an error parsing chat tokens for basic chat info. ", any); 4995 } 4996 try{ 4997 tokens["agentFirstName"] = model.agentSettings.firstName; 4998 tokens["agentLastName"] = model.agentSettings.lastName; 4999 tokens["agentExternalId"] = model.agentSettings.externalAgentId; 5000 tokens["agentType"] = model.agentSettings.agentType; 5001 tokens["agentEmail"] = model.agentSettings.email; 5002 tokens["agentUserName"] = model.agentSettings.username; 5003 }catch(any){ 5004 console.error("There was an error parsing chat tokens for agent info. ", any); 5005 } 5006 return tokens; 5007 } 5008 var AgentStats = function() { 5009 }; 5010 /* 5011 * This class is responsible for handling an Agent Stats packet rec'd from IntelliServices. 5012 * It will save a copy of it in the UIModel. Could be a single agent or array of agents. 5013 * 5014 {"ui_stats":{ 5015 "@type":"AGENT", 5016 "agent":{ 5017 "@alt":"INBOUND", 5018 "@atype":"AGENT", 5019 "@avgtt":"00.0", 5020 "@calls":"0", 5021 "@da":"0", 5022 "@droute":"6789050673", 5023 "@f":"John", 5024 "@gdesc":"", 5025 "@gname":"", 5026 "@id":"1856", 5027 "@l":"Doe", 5028 "@ldur":"6", 5029 "@ltype":"INBOUND", 5030 "@oh":"0", 5031 "@pd":"0", 5032 "@pdt":"0", 5033 "@pres":"0", 5034 "@rna":"0", 5035 "@sdur":"6", 5036 "@sp":"", 5037 "@state":"AVAILABLE", 5038 "@ttt":"0", 5039 "@u":"jdoe", 5040 "@uii":"", 5041 "@util":"0.00", 5042 "@call_duration:0" 5043 } 5044 } 5045 } 5046 */ 5047 AgentStats.prototype.processResponse = function(stats) { 5048 var resp = stats.ui_stats.agent; 5049 var agentStats = []; 5050 if (!Array.isArray(resp)) { 5051 resp = [resp]; 5052 } 5053 try { 5054 for (var i = 0; i < resp.length; i++) { 5055 agentStats.push({ 5056 agentLoginType: resp[i]["@alt"], 5057 agentType: resp[i]["@atype"], 5058 avgTalkTime: resp[i]["@avgtt"], 5059 calls: resp[i]["@calls"], 5060 isDequeueAgent: resp[i]["@da"], 5061 defaultRoute: resp[i]["@droute"], 5062 firstName: resp[i]["@f"], 5063 queueDesc: resp[i]["@gdesc"], 5064 queueName: resp[i]["@gname"], 5065 agentId: resp[i]["@id"], 5066 lastName: resp[i]["@l"], 5067 loginDuration: resp[i]["@ldur"], 5068 loginType: resp[i]["@ltype"], 5069 offHook: resp[i]["@oh"], 5070 pendingDisp: resp[i]["@pd"], 5071 pendingDispTime: resp[i]["@pdt"], 5072 presented: resp[i]["@pres"], 5073 rna: resp[i]["@rna"], 5074 stateDuration: resp[i]["@sdur"], 5075 skillProfileName: resp[i]["@sp"], 5076 agentState: resp[i]["@state"], 5077 totalTalkTime: resp[i]["@ttt"], 5078 username: resp[i]["@u"], 5079 uii: resp[i]["@uii"], 5080 utilization: resp[i]["@util"], 5081 callDuration: resp[i]["@call_duration"] 5082 }); 5083 } 5084 } catch(e) { 5085 } 5086 UIModel.getInstance().agentStats = agentStats; 5087 return agentStats; 5088 }; 5089 var AgentDailyStats = function() { 5090 }; 5091 /* 5092 * This class is responsible for handling an Agent Daily Stats packet rec'd from IntelliServices. 5093 * It will save a copy of it in the UIModel. 5094 * 5095 * {"ui_stats":{ 5096 * "@type":"AGENTDAILY", 5097 * "agent_id":{"#text":"1180723"}, 5098 * "total_login_sessions":{"#text":"1"}, 5099 * "total_calls_handled":{"#text":"0"}, 5100 * "total_preview_dials":{"#text":"0"}, 5101 * "total_manual_dials":{"#text":"0"}, 5102 * "total_rna":{"#text":"0"}, 5103 * "total_talk_time":{"#text":"0"}, 5104 * "total_offhook_time":{"#text":"0"}, 5105 * "total_login_time":{"#text":"7808"}, 5106 * "total_success_dispositions":{"#text":"0"} 5107 * } 5108 * } 5109 */ 5110 AgentDailyStats.prototype.processResponse = function(stats) { 5111 var model = UIModel.getInstance().agentDailyStats; 5112 var resp = stats.ui_stats; 5113 model.agentId = utils.getText(resp, "agent_id"); 5114 model.totalLoginSessions = utils.getText(resp, "total_login_sessions"); 5115 model.totalChatsHandled = utils.getText(resp, "total_chats_handled"); 5116 model.totalCallsHandled = utils.getText(resp, "total_calls_handled"); 5117 model.totalPreviewDials = utils.getText(resp, "total_preview_dials"); 5118 model.totalManualDials = utils.getText(resp, "total_manual_dials"); 5119 model.totalRna = utils.getText(resp, "total_rna"); 5120 model.totalSuccessDispositions = utils.getText(resp, "total_success_dispositions"); 5121 if(!model.totalTalkTime) { 5122 // init daily stats to first stats packet if they don't exist 5123 model.totalLoginTime = utils.getText(resp, "total_login_time"); 5124 model.totalOffhookTime = utils.getText(resp, "total_offhook_time"); 5125 model.totalTalkTime = utils.getText(resp, "total_talk_time"); 5126 model.currCallTime = "0"; 5127 } 5128 return model; 5129 }; 5130 var CampaignStats = function() { 5131 }; 5132 /* 5133 * This class is responsible for handling a Campaign Stats packet rec'd from IntelliServices. 5134 * It will save a copy of it in the UIModel. 5135 * 5136 * {"ui_stats":{ 5137 * "@type":"CAMPAIGN", 5138 * "campaign":[ 5139 * { 5140 * "@a":"0","@aba":"0","@an":"0","@av":"0","@b":"0","@c":"1","@e":"0","@f":"0", 5141 * "@id":"60275","@int":"0","@m":"0","@na":"0","@name":"Test Campaign", 5142 * "@p":"0","@r":"1","@s":"0","@tc":"0","@ttt":"0" 5143 * }, 5144 * { 5145 * "@a":"0","@aba":"0","@an":"0","@av":"0","@b":"0","@c":"0","@e":"0","@f":"0", 5146 * "@id":"60293","@int":"0","@m":"0","@na":"0","@name":"Test Campaign w\\ Search", 5147 * "@p":"0","@r":"19","@s":"0","@tc":"0","@ttt":"0" 5148 * } 5149 * ], 5150 * "totals":{ 5151 * "noanswer":{"#text":"0"}, 5152 * "totalConnects":{"#text":"0"}, 5153 * "pending":{"#text":"0"}, 5154 * "active":{"#text":"0"}, 5155 * "error":{"#text":"0"}, 5156 * "totalTalkTime":{"#text":"0"}, 5157 * "answer":{"#text":"0"}, 5158 * "abandon":{"#text":"0"}, 5159 * "ready":{"#text":"20"}, 5160 * "machine":{"#text":"0"}, 5161 * "intercept":{"#text":"0"}, 5162 * "busy":{"#text":"0"}, 5163 * "complete":{"#text":"1"}, 5164 * "fax":{"#text":"0"} 5165 * } 5166 * } 5167 * } 5168 */ 5169 CampaignStats.prototype.processResponse = function(stats) { 5170 var resp = stats.ui_stats; 5171 var totals = utils.processResponseCollection(stats,"ui_stats","totals")[0]; 5172 var campaigns = []; 5173 var campRaw = null; 5174 if (!Array.isArray(resp.campaign)) { 5175 resp.campaign = [resp.campaign]; 5176 } 5177 for(var c = 0; c < resp.campaign.length; c++){ 5178 campRaw = resp.campaign[c]; 5179 if (campRaw == null) { 5180 continue; 5181 } 5182 campaigns.push({ 5183 active:campRaw["@a"], 5184 abandon:campRaw["@aba"], 5185 answer:campRaw["@an"], 5186 available:campRaw["@av"], 5187 busy:campRaw["@b"], 5188 complete:campRaw["@c"], 5189 error:campRaw["@e"], 5190 fax:campRaw["@f"], 5191 campaignId:campRaw["@id"], 5192 intercept:campRaw["@int"], 5193 machine:campRaw["@m"], 5194 noanswer:campRaw["@na"], 5195 campaignName:campRaw["@name"], 5196 pending:campRaw["@p"], 5197 ready:campRaw["@r"], 5198 staffed:campRaw["@s"], 5199 totalConnects:campRaw["@tc"], 5200 totalTalkTime:campRaw["@ttt"] 5201 }); 5202 } 5203 var campaignStats = { 5204 type: resp["@type"], 5205 campaigns: campaigns, 5206 totals:totals 5207 }; 5208 UIModel.getInstance().campaignStats = campaignStats; 5209 return campaignStats; 5210 }; 5211 var ChatQueueStats = function() { 5212 }; 5213 /* 5214 * This class is responsible for handling an Chat Stats packet rec'd from IntelliServices. 5215 * It will save a copy of it in the UIModel. 5216 * 5217 *{ 5218 * "ui_stats": { 5219 * "@type": "CHAT", 5220 * "chatQueue": [ 5221 * { 5222 * "@active": "1", 5223 * "@available": "0", 5224 * "@avgAbandon": "00.0", 5225 * "@avgChatTime": "00.0", 5226 * "@avgQueueTime": "00.0", 5227 * "@chatQueueId": "1", 5228 * "@chatQueueName": "testing chat quuee", 5229 * "@deflected": "0", 5230 * "@inQueue": "0", 5231 * "@longestInQueue": "0", 5232 * "@presented": "0", 5233 * "@routing": "0", 5234 * "@staffed": "0", 5235 * "@totalAbandonTime": "0", 5236 * "@totalAnswerTime": "0", 5237 * "@totalChatTime": "0", 5238 * "@totalQueueTime": "0", 5239 * "@utilization": "00.0" 5240 * }, 5241 * { 5242 * "@active": "0", 5243 * "@available": "0", 5244 * "@avgAbandon": "00.0", 5245 * "@avgChatTime": "00.0", 5246 * "@avgQueueTime": "00.0", 5247 * "@chatQueueId": "3", 5248 * "@chatQueueName": "testing test", 5249 * "@deflected": "0", 5250 * "@inQueue": "0", 5251 * "@longestInQueue": "0", 5252 * "@presented": "0", 5253 * "@routing": "0", 5254 * "@staffed": "0", 5255 * "@totalAbandonTime": "0", 5256 * "@totalAnswerTime": "0", 5257 * "@totalChatTime": "0", 5258 * "@totalQueueTime": "0", 5259 * "@utilization": "00.0" 5260 * } 5261 * ], 5262 * "totals": { 5263 * "routing": {"#text": "0"}, 5264 * "ttotalAnswerTime": {"#text": "0"}, 5265 * "inQueue": { "#text": "0"}, 5266 * "ttotalChatTime": {"#text": "0"}, 5267 * "ttotalAbandonTime": {"#text": "0"}, 5268 * "presented": {"#text": "0}, 5269 * "accepted": {"#text": "0"}, 5270 * "deflected": {"#text": "0"}, 5271 * "active": {"#text": "1"}, 5272 * "abandoned": {"#text": "0"}, 5273 * "ttotalQueueTime": {"#text": "0"} 5274 * } 5275 * } 5276 *} 5277 */ 5278 ChatQueueStats.prototype.processResponse = function(stats) { 5279 var resp = stats.ui_stats; 5280 var totals = utils.processResponseCollection(stats,"ui_stats","totals")[0]; 5281 var chatQueues = utils.processResponseCollection(stats,"ui_stats","chatQueue"); 5282 var chatQueueStats = { 5283 type:resp["@type"], 5284 chatQueues: chatQueues, 5285 totals:totals 5286 }; 5287 UIModel.getInstance().chatQueueStats = chatQueueStats; 5288 return chatQueueStats; 5289 }; 5290 var QueueStats = function() { 5291 }; 5292 /* 5293 * This class is responsible for handling an Queue Stats packet rec'd from IntelliServices. 5294 * It will save a copy of it in the UIModel. 5295 * 5296 * { 5297 * "ui_stats":{ 5298 * "@type":"GATE", 5299 * "gate":{ 5300 * "@aba":"0","@active":"0","@ans":"0","@asa":"00.0","@avail":"2", 5301 * "@avga":"00.0","@avgq":"00.0","@avgt":"00.0","@def":"0","@id":"12126", 5302 * "@inq":"0","@long_c":"0","@longq":"0","@name":"Cris inbound", 5303 * "@pres":"0","@route":"0","@short_aba":"0","@short_c":"0","@sla":"100.0", 5304 * "@sla_f":"0","@sla_p":"0","@staff":"2","@t_aba":"0","@t_q":"0","@t_soa":"0","@util":"00.0" 5305 * }, 5306 * "totals":{ 5307 * "inQueue":{"#text":"0"}, 5308 * "answered":{"#text":"0"}, 5309 * "totalABATime":{"#text":"0"}, 5310 * "active":{"#text":"0"}, 5311 * "longCall":{"#text":"0"}, 5312 * "shortCall":{"#text":"0"}, 5313 * "slaPass":{"#text":"0"}, 5314 * "totalQueueTime":{"#text":"0"}, 5315 * "routing":{"#text":"0"}, 5316 * "totalTalkTime":{"#text":"0"}, 5317 * "shortAbandon":{"#text":"0"}, 5318 * "presented":{"#text":"0"}, 5319 * "totalSOA":{"#text":"0"}, 5320 * "slaFail":{"#text":"0"}, 5321 * "deflected":{"#text":"0"}, 5322 * "abandoned":{"#text":"0"} 5323 * } 5324 * } 5325 * } 5326 */ 5327 QueueStats.prototype.processResponse = function(stats) { 5328 var resp = stats.ui_stats; 5329 var totals = utils.processResponseCollection(stats,"ui_stats","totals")[0]; 5330 var queues = []; 5331 var gateRaw = {}; 5332 if (!Array.isArray(resp.gate)) { 5333 resp.gate = [resp.gate]; 5334 } 5335 for(var c = 0; c < resp.gate.length; c++) { 5336 gateRaw = resp.gate[c]; 5337 if (gateRaw == null) { 5338 continue; 5339 } 5340 queues.push({ 5341 abandon: gateRaw["@aba"], 5342 active: gateRaw["@active"], 5343 answer: gateRaw["@ans"], 5344 asa: gateRaw["@asa"], 5345 available: gateRaw["@avail"], 5346 avgAbandon: gateRaw["@avga"], 5347 avgQueue: gateRaw["@avgq"], 5348 avgTalk: gateRaw["@avgt"], 5349 deflected: gateRaw["@def"], 5350 queueId: gateRaw["@id"], 5351 inQueue: gateRaw["@inq"], 5352 longCall: gateRaw["@long_c"], 5353 longestInQueue: gateRaw["@longq"], 5354 queueName: gateRaw["@name"], 5355 presented: gateRaw["@pres"], 5356 routing: gateRaw["@route"], 5357 shortAbandon: gateRaw["@short_aba"], 5358 shortCall: gateRaw["@short_c"], 5359 sla: gateRaw["@sla"], 5360 slaPass: gateRaw["@sla_p"], 5361 slaFail: gateRaw["@sla_f"], 5362 staffed: gateRaw["@staff"], 5363 tAbandonTime: gateRaw["@t_aba"], 5364 tQueueTime: gateRaw["@t_q"], 5365 tSpeedOfAnswer: gateRaw["@t_soa"], 5366 utilization: gateRaw["@util"] 5367 }); 5368 } 5369 var queueStats = { 5370 type:resp["@type"], 5371 queues: queues, 5372 totals:totals 5373 }; 5374 UIModel.getInstance().queueStats = queueStats; 5375 return queueStats; 5376 }; 5377 var UIModel = (function() { 5378 var instance; 5379 function init() { 5380 // Singleton 5381 // Private methods and variables here // 5382 //function privateMethod(){ 5383 // console.log( "I am private" ); 5384 //} 5385 // 5386 //var privateVariable = "I'm also private"; 5387 // Public methods and variables 5388 return { 5389 currentCall: {}, // save the NEW-CALL notification in parsed form 5390 pendingNewCallSessions: {}, // save any pending call sessions, in case the new call packet hasn't arrived 5391 callTokens:{}, // Stores a map of all tokens for a call 5392 callbacks:[], 5393 libraryInstance: null, // Initialized to the library instance on startup 5394 pingIntervalId: null, // The id of the timer used to send ping-call messages 5395 statsIntervalId: null, // The id of the timer used to send stats request messages 5396 agentDailyIntervalId: null, // The id of the timer used to update some agent daily stats values 5397 waitingForAddSession : null, 5398 // internal chat requests 5399 chatAliasRequest : null, 5400 chatRoomRequest : null, 5401 chatSendRequest : null, 5402 supervisorListRequest : null, 5403 chatRoomStateRequest : new ChatRoomStateRequest(), 5404 // external chat requests/notifications 5405 chatActiveNotification : new ChatActiveNotification(), 5406 chatInactiveNotification : new ChatInactiveNotification(), 5407 chatDispositionRequest : null, 5408 chatMessageRequest : new ChatMessageRequest(), 5409 chatPresentedNotification : new ChatPresentedNotification(), 5410 chatPresentedRequest : null, 5411 chatRequeueRequest : null, 5412 chatTypingNotification : new ChatTypingNotification(), 5413 chatTypingRequest : null, 5414 newChatNotification : new NewChatNotification(), 5415 chatClientReconnectNotification : new ChatClientReconnectNotification(), 5416 // request instances 5417 agentStateRequest : null, 5418 chatStateRequest : null, 5419 ackRequest : new AckRequest(), 5420 bargeInRequest : null, 5421 callNotesRequest : null, 5422 callbacksPendingRequest : null, 5423 campaignDispositionsRequest : null, 5424 configRequest : null, 5425 coldXferRequest : null, 5426 dispositionRequest : null, 5427 dispositionManualPassRequest : null, 5428 hangupRequest : null, 5429 holdRequest : null, 5430 leadHistoryRequest : null, 5431 leadInsertRequest : null, 5432 leadUpdateRequest : null, 5433 logoutRequest : null, 5434 loginRequest : null, // Original LoginRequest sent to IS - used for reconnects 5435 offhookInitRequest : null, 5436 offhookTermRequest : null, 5437 oneToOneOutdialRequest : null, 5438 oneToOneOutdialCancelRequest : null, 5439 pauseRecordRequest : null, 5440 pingCallRequest : null, 5441 previewDialRequest : null, 5442 reconnectRequest : null, 5443 recordRequest : null, 5444 requeueRequest : null, 5445 statsRequest : null, 5446 tcpaSafeRequest : null, 5447 warmXferRequest : null, 5448 warmXferCancelRequest : null, 5449 chatListRequest: null, 5450 directAgentTransferListRequest: null, 5451 directAgentTransferRequest: null, 5452 // response packets 5453 agentStatePacket : null, 5454 chatStatePacket : null, 5455 configPacket : null, 5456 currentCallPacket : null, 5457 loginPacket : null, 5458 offhookInitPacket : null, 5459 offhookTermPacket : null, 5460 transferSessions: {}, 5461 chatListResponse : null, 5462 // notification packets 5463 addSessionNotification: new AddSessionNotification(), 5464 dialGroupChangeNotification : new DialGroupChangeNotification(), 5465 dialGroupChangePendingNotification : new DialGroupChangePendingNotification(), 5466 dropSessionNotification: new DropSessionNotification(), 5467 earlyUiiNotification: new EarlyUiiNotification(), 5468 endCallNotification : new EndCallNotification(), 5469 gatesChangeNotification : new GatesChangeNotification(), 5470 genericNotification : new GenericNotification(), 5471 newCallNotification: new NewCallNotification(), 5472 // stats packets 5473 agentStatsPacket: new AgentStats(), 5474 agentDailyStatsPacket: new AgentDailyStats(), 5475 queueStatsPacket: new QueueStats(), 5476 campaignStatsPacket: new CampaignStats(), 5477 chatQueueStatsPacket: new ChatQueueStats(), 5478 // application state 5479 applicationSettings : { 5480 availableCountries : [], 5481 isLoggedInIS : false, // a check for whether or not user is logged in with IntelliServices 5482 socketConnected : false, 5483 socketDest : "", 5484 isTcpaSafeMode : false // Comes in at the account-level - will get set to true if this interface should be in tcpa-safe-mode only. 5485 }, 5486 // stat objects 5487 agentStats:[], 5488 agentDailyStats: {}, 5489 campaignStats:{}, 5490 queueStats:{}, 5491 chatQueueStats:{}, 5492 // current agent settings 5493 agentSettings : { 5494 accountId: null, // account agent belongs to 5495 agentId : 0, 5496 agentType : "AGENT", // AGENT | SUPERVISOR 5497 altDefaultLoginDest : "", 5498 availableAgentStates : [], 5499 callerIds : [], 5500 callState: null, // display the current state of the call 5501 currentState : "OFFLINE", // Agent system/base state 5502 currentStateLabel : "", // Agent aux state label 5503 defaultLoginDest : "", 5504 dialDest : "", // Destination agent is logged in with for offhook session, set on configure response, if multi values in format "xxxx|,,xxxx" 5505 email : "", 5506 externalAgentId : "", 5507 firstName : "", 5508 guid: "", // unique key generated on login, used for accessing spring endpoints 5509 isLoggedIn : false, // agent is logged in to the platform 5510 isOffhook : false, // track whether or not the agent has an active offhook session 5511 isMonitoring : false, // track whether or not the offhook session is for monitoring 5512 initLoginState : "AVAILABLE", // state agent is placed in on successful login 5513 initLoginStateLabel : "Available", // state label for agent on successful login 5514 isOutboundPrepay : false, // determines if agent is a prepay agent 5515 lastName : "", 5516 loginDTS : null, // date and time of the final login phase (IQ) 5517 loginType : "NO-SELECTION", // Could be INBOUND | OUTBOUND | BLENDED | NO-SELECTION, set on login response 5518 maxBreakTime : -1, 5519 maxLunchTime : -1, 5520 onCall : false, // true if agent is on an active call 5521 onManualOutdial : false, // true if agent is on a manual outdial call 5522 outboundManualDefaultRingtime : "30", 5523 pendingCallbacks : [], 5524 pendingDialGroupChange: 0, // Set to Dial Group Id if we are waiting to change dial groups until agent ends call 5525 phoneLoginPin: "", 5526 realAgentType : "AGENT", 5527 supervisors : [], // Used for agent chat 5528 totalCalls : 0, // Call counter that is incremented every time a new session is received 5529 transferNumber : "", // May be pre-populated by an external interface, if so, the transfer functionality uses it 5530 updateDGFromAdminUI : false, // if pending Dial Group change came from AdminUI, set to true (only used if request is pending) 5531 updateLoginMode : false, // gets set to true when doing an update login (for events control) 5532 username : "", // Agent's username 5533 wasMonitoring : false // used to track if the last call was a monitoring call 5534 }, 5535 // current agent permissions 5536 agentPermissions : { 5537 allowBlended : true, // Controls whether or not the agent can log into both inbound queues and an outbound dialgroup 5538 allowCallControl : true, // Set from the the login response packet 5539 allowChat : false, // Controls whether or not the agent has the option to open the Chat Queue Manager 5540 allowCrossQueueRequeue : false, // Controls whether or not the agent can requeue to a different queue group 5541 allowInbound : true, // Controls whether or not the agent can log into an inbound queue 5542 allowLeadInserts : false, // Controls whether or not the agents can insert leads 5543 allowLeadSearch : false, // Controlled by the dial-group allow_lead_search setting. Enables or disables the lead search 5544 allowLoginControl : true, // Controls whether or not the agent can log in 5545 allowLoginUpdates : true, // Controls whether or not the agent can update their login 5546 allowManualCalls : true, // Controls whether or not the agents have the option to make a manual outbound call 5547 allowManualPass : true, // Controls whether or not the agent has the option to make a manual pass on a lead 5548 allowManualIntlCalls : false, // Controls whether or not the agent has the option to make international manual outbound calls 5549 allowManualOutboundGates : false, // Controls whether or not the agent has the option to select queues to convert manual outbound calls to 5550 allowOffHook : true, // Controls whether or not the agents can go offhook 5551 allowOutbound : true, // Controls whether or not the agent can log into an outdial group 5552 allowPreviewLeadFilters : false, // Controlled by the dial-group allow_preview_lead_filters setting. Enables or disables the filters on the preview style forms 5553 allowLeadUpdatesByCampaign : {}, // For each campaign ID, store whether leads can be updated 5554 disableSupervisorMonitoring : true, // Controls whether or not a supervisor can view agent stats 5555 progressiveEnabled : false, // Preview dial feature that enables auto-calls from the preview window. 5556 requireFetchedLeadsCalled : false, // Controlled by the dial-group require_fetched_leads_called setting. Enables or disables the requirement to only fetch new leads when current leads are called or expired. ONly for Preview or TCPA-SAFE. 5557 showLeadHistory : true // Controls whether or not the agents can view lead history 5558 }, 5559 // chat 5560 chatSettings :{ 5561 availableChatQueues : [], // List of all chat queues agent has access to, set on login 5562 availableChatRooms : [], // List of all chat rooms agent has access to, set on login 5563 chatQueues : [], // Array of chat queues agent is signed into 5564 alias : "" // Chat alias, on-login this is the UID, but is changed if the user changes it 5565 }, 5566 // connection objects 5567 connectionSettings : { 5568 hashCode : null, // used specifically for reconnects 5569 reconnect : false // variable tracks the type of login, on init it's false...once connected it's set to true 5570 }, 5571 // inbound settings 5572 inboundSettings : { 5573 availableQueues : [], // array of queues agent has access to, set on login 5574 availableSkillProfiles : [], // array of skill profiles agent has access to, set on login 5575 queues : [], // array of queues agent is signed into, set on config response 5576 skillProfile : {} // The skill profile the agent is signed into, set on config response 5577 }, 5578 // outbound settings 5579 outboundSettings : { 5580 availableCampaigns : [], // array of campaigns agent has access to, set on login 5581 availableOutdialGroups : [], // array of dial groups agent has access to, set on login 5582 insertCampaigns : [], 5583 defaultDialGroup: 0, 5584 outdialGroup : {}, // dial group agent is signed into 5585 previewDialLeads : [], // list of leads returned from preview dial request 5586 tcpaSafeLeads : [], // list of leads returned from tcpa safe request 5587 campaignDispositions : [] // list of campaign dispositions for specific campaign 5588 }, 5589 scriptSettings : { 5590 availableScripts : [], // array of all scripts associated with any campaigns or queues agent is logged into 5591 loadedScripts: {} // stores script data by script id e.g. {1:{}, 32:{}} 5592 }, 5593 // Public methods 5594 incrementTotalCalls: function() { 5595 this.agentSettings.totalCalls = this.agentSettings.totalCalls + 1; 5596 } 5597 }; 5598 } 5599 return { 5600 // Get the Singleton instance if one exists 5601 // or create one if it doesn't 5602 getInstance: function () { 5603 if (!instance) { 5604 instance = init(); 5605 } 5606 return instance; 5607 }, 5608 resetInstance: function () { 5609 instance = null; 5610 } 5611 }; 5612 })(); 5613 function NewCallUtils(instance, data) { 5614 this.instance = instance; 5615 this.data = data; 5616 var that = this; 5617 this.setupAddSessionCallback = function() { 5618 var sessionUii = utils.getText(data.ui_notification, "uii"), 5619 sessionId = utils.getText(data.ui_notification, "session_id"), 5620 call = UIModel.getInstance().currentCall; 5621 if(call.uii === sessionUii) { 5622 // we already have a new call packet for this session 5623 _delayedAddSessionCallback(that.instance, that.data); 5624 } else { 5625 // uii mismatch, but call has been dispositioned 5626 UIModel.getInstance().pendingNewCallSessions[sessionUii] = UIModel.getInstance().pendingNewCallSessions[sessionUii] || {}; 5627 UIModel.getInstance().pendingNewCallSessions[sessionUii][sessionId] = that; 5628 } 5629 }; 5630 this.processSessionsForCall = function() { 5631 var uii = UIModel.getInstance().currentCall.uii, 5632 delayedSessions = UIModel.getInstance().pendingNewCallSessions[uii]; 5633 if(delayedSessions && Object.keys(delayedSessions).length > 0) { 5634 // we have delayed sessions to process 5635 for(var sessionId in delayedSessions) { 5636 if(delayedSessions.hasOwnProperty(sessionId)) { 5637 var session = delayedSessions[sessionId]; 5638 _delayedAddSessionCallback(session.instance, session.data); 5639 } else { 5640 console.error('error processing sessions for uii: ' + uii + ' session: ' + sessionId ); 5641 } 5642 } 5643 delete UIModel.getInstance().pendingNewCallSessions[uii]; 5644 } 5645 }; 5646 function _delayedAddSessionCallback(instance, data) { 5647 var addSessionNotif = new AddSessionNotification(); 5648 var addResponse = addSessionNotif.processResponse(data); 5649 utils.fireCallback(instance, CALLBACK_TYPES.ADD_SESSION, addResponse); 5650 } 5651 } 5652 var utils = { 5653 logMessage: function(logLevel, message, data){ 5654 var instance = UIModel.getInstance().libraryInstance; 5655 if(instance._db){ 5656 var transaction = instance._db.transaction(["logger"], "readwrite"); 5657 var store = transaction.objectStore("logger"); 5658 var record = { 5659 logLevel: logLevel, 5660 message: message, 5661 dts: new Date(), 5662 data: data 5663 }; 5664 var request = store.add(record); 5665 }else{ 5666 //console.log("AgentLibrary: indexedDb not available"); 5667 } 5668 }, 5669 sendMessage: function(instance, msg) { 5670 var msgObj = JSON.parse(msg); 5671 if (instance.socket && instance.socket.readyState === 1) { 5672 // add message id to request map, then send message 5673 var type = msgObj.ui_request['@type']; 5674 var destination = msgObj.ui_request['@destination']; 5675 var message = "Sending " + type + " request message to " + destination; 5676 instance._requests.push({ id: msgObj.ui_request['@message_id'], type: msgObj.ui_request['@type'], msg: msgObj.ui_request }); 5677 // keep rolling window of latest 1000 requests 5678 if(instance._requests.length > 1000){ 5679 instance._requests.shift(); 5680 } 5681 instance.socket.send(msg); 5682 if(type === 'STATS'){ 5683 utils.logMessage(LOG_LEVELS.STATS, message, msgObj); 5684 }else{ 5685 utils.logMessage(LOG_LEVELS.INFO, message, msgObj); 5686 } 5687 } else { 5688 // add message to queue if socket is not open. 5689 instance._queuedMsgs.push({dts: new Date(), msg: msg}); 5690 } 5691 }, 5692 processResponse: function(instance, response) 5693 { 5694 var type = response.ui_response['@type']; 5695 var messageId = response.ui_response['@message_id']; 5696 var dest = (messageId === "" || !messageId) ? "IS" : messageId.slice(0, 2); 5697 var message = "Received " + type.toUpperCase() + " response message from " + dest; 5698 // log message response 5699 utils.logMessage(LOG_LEVELS.INFO, message, response); 5700 // Send generic on message response 5701 utils.fireCallback(instance, CALLBACK_TYPES.ON_MESSAGE, response); 5702 // Fire callback function 5703 switch (type.toUpperCase()) { 5704 case MESSAGE_TYPES.AGENT_STATE: 5705 if (UIModel.getInstance().agentStateRequest === null) { 5706 UIModel.getInstance().agentStateRequest = new AgentStateRequest(response.ui_response.current_state["#text"], response.ui_response.agent_aux_state['#text']); 5707 } 5708 var stateChangeResponse = UIModel.getInstance().agentStateRequest.processResponse(response); 5709 utils.fireCallback(instance, CALLBACK_TYPES.AGENT_STATE, stateChangeResponse); 5710 break; 5711 case MESSAGE_TYPES.BARGE_IN: 5712 var resp = UIModel.getInstance().bargeInRequest.processResponse(response); 5713 var responseTo = response.ui_response['@response_to']; 5714 var request = utils.findRequestById(instance, responseTo); 5715 if (request) { 5716 // found corresponding request, fire registered callback for type 5717 var audioState = request.msg.audio_state['#text']; 5718 if (audioState === "MUTE") { 5719 utils.fireCallback(instance, CALLBACK_TYPES.SILENT_MONITOR, resp); 5720 } else if (audioState === "COACHING") { 5721 utils.fireCallback(instance, CALLBACK_TYPES.COACH_CALL, resp); 5722 } else { 5723 utils.fireCallback(instance, CALLBACK_TYPES.BARGE_IN, resp); 5724 } 5725 } else { 5726 // no corresponding request, just fire FULL audio type BARGE-IN callback 5727 utils.fireCallback(instance, CALLBACK_TYPES.BARGE_IN, resp); 5728 } 5729 break; 5730 case MESSAGE_TYPES.CAMPAIGN_DISPOSITIONS: 5731 var campaignDispsResposne = UIModel.getInstance().campaignDispositionsRequest.processResponse(response); 5732 utils.fireCallback(instance, CALLBACK_TYPES.CAMPAIGN_DISPOSITIONS, campaignDispsResposne); 5733 break; 5734 case MESSAGE_TYPES.CALL_NOTES: 5735 var callNotes = UIModel.getInstance().callNotesRequest.processResponse(response); 5736 utils.fireCallback(instance, CALLBACK_TYPES.CALL_NOTES, callNotes); 5737 break; 5738 case MESSAGE_TYPES.CALLBACK_PENDING: 5739 var pendingCallbacks = UIModel.getInstance().callbacksPendingRequest.processResponse(response); 5740 utils.fireCallback(instance, CALLBACK_TYPES.CALLBACK_PENDING, pendingCallbacks); 5741 break; 5742 case MESSAGE_TYPES.HOLD: 5743 var holdRequest; 5744 if(UIModel.getInstance().holdRequest === null){ 5745 holdRequest = new HoldRequest(); 5746 }else{ 5747 holdRequest = UIModel.getInstance().holdRequest; 5748 } 5749 var hold = holdRequest.processResponse(response); 5750 utils.fireCallback(instance, CALLBACK_TYPES.HOLD, hold); 5751 break; 5752 case MESSAGE_TYPES.LEAD_HISTORY: 5753 var history = UIModel.getInstance().leadHistoryRequest.processResponse(response); 5754 utils.fireCallback(instance, CALLBACK_TYPES.LEAD_HISTORY, history); 5755 break; 5756 case MESSAGE_TYPES.LEAD_INSERT: 5757 var insert = UIModel.getInstance().leadInsertRequest.processResponse(response); 5758 utils.fireCallback(instance, CALLBACK_TYPES.LEAD_INSERT, insert); 5759 break; 5760 case MESSAGE_TYPES.LEAD_UPDATE: 5761 var update = UIModel.getInstance().leadUpdateRequest.processResponse(response); 5762 utils.fireCallback(instance, CALLBACK_TYPES.LEAD_UPDATE, update); 5763 break; 5764 case MESSAGE_TYPES.LOGIN: 5765 if (dest === "IS") { 5766 var loginResponse = UIModel.getInstance().loginRequest.processResponse(response); 5767 utils.fireCallback(instance, CALLBACK_TYPES.LOGIN, loginResponse); 5768 } else if (dest === 'IQ') { 5769 var configResponse = UIModel.getInstance().configRequest.processResponse(response); 5770 utils.fireCallback(instance, CALLBACK_TYPES.CONFIG, configResponse); 5771 } 5772 break; 5773 case MESSAGE_TYPES.LOGOUT: 5774 // TODO add processResponse? 5775 utils.fireCallback(instance, CALLBACK_TYPES.LOGOUT, response); 5776 break; 5777 case MESSAGE_TYPES.OFFHOOK_INIT: 5778 var offhook = new OffhookInitRequest(); 5779 var initResponse = offhook.processResponse(response); 5780 utils.fireCallback(instance, CALLBACK_TYPES.OFFHOOK_INIT, initResponse); 5781 break; 5782 case MESSAGE_TYPES.PAUSE_RECORD: 5783 var pauseRequest; 5784 if(UIModel.getInstance().pauseRecordRequest === null){ 5785 pauseRequest = new PauseRecordRequest(); 5786 }else{ 5787 pauseRequest = UIModel.getInstance().pauseRecordRequest; 5788 } 5789 var pauseRec = pauseRequest.processResponse(response); 5790 utils.fireCallback(instance, CALLBACK_TYPES.PAUSE_RECORD, pauseRec); 5791 break; 5792 case MESSAGE_TYPES.RECORD: 5793 var record = UIModel.getInstance().recordRequest.processResponse(response); 5794 utils.fireCallback(instance, CALLBACK_TYPES.RECORD, record); 5795 break; 5796 case MESSAGE_TYPES.REQUEUE: 5797 var requeue = UIModel.getInstance().requeueRequest.processResponse(response); 5798 utils.fireCallback(instance, CALLBACK_TYPES.REQUEUE, requeue); 5799 break; 5800 case MESSAGE_TYPES.SUPERVISOR_LIST: 5801 var supervisorList = UIModel.getInstance().supervisorListRequest.processResponse(response); 5802 utils.fireCallback(instance, CALLBACK_TYPES.SUPERVISOR_LIST, supervisorList); 5803 break; 5804 case MESSAGE_TYPES.SCRIPT_CONFIG: 5805 var script = UIModel.getInstance().scriptConfigRequest.processResponse(response); 5806 utils.fireCallback(instance, CALLBACK_TYPES.SCRIPT_CONFIG, script); 5807 break; 5808 case MESSAGE_TYPES.XFER_COLD: 5809 var coldXfer = UIModel.getInstance().coldXferRequest.processResponse(response); 5810 utils.fireCallback(instance, CALLBACK_TYPES.XFER_COLD, coldXfer); 5811 break; 5812 case MESSAGE_TYPES.XFER_WARM: 5813 var warmXfer = UIModel.getInstance().warmXferRequest.processResponse(response); 5814 utils.fireCallback(instance, CALLBACK_TYPES.XFER_WARM, warmXfer); 5815 break; 5816 case MESSAGE_TYPES.XFER_WARM_CANCEL: 5817 var warmXferCancel = UIModel.getInstance().warmXferCancelRequest.processResponse(response); 5818 utils.fireCallback(instance, CALLBACK_TYPES.XFER_WARM_CANCEL, warmXferCancel); 5819 break; 5820 case MESSAGE_TYPES.ACK: 5821 var ack = UIModel.getInstance().ackRequest.processResponse(response); 5822 var responseTo = response.ui_response['@response_to']; 5823 var request = utils.findRequestById(instance, responseTo); 5824 ack.uii = request.msg.uii && request.msg.uii["#text"]; 5825 utils.fireCallback(instance, CALLBACK_TYPES.ACK, ack); 5826 break; 5827 case MESSAGE_TYPES.CHAT_LIST: 5828 var chatList = new ChatListRequest(); 5829 var chatListResponse = chatList.processResponse(response); 5830 utils.fireCallback(instance, CALLBACK_TYPES.CHAT_LIST, chatListResponse); 5831 break; 5832 case MESSAGE_TYPES.CHAT_STATE: 5833 var chatState = new ChatStateRequest(); 5834 var chatStateResponse = chatState.processResponse(response); 5835 utils.fireCallback(instance, CALLBACK_TYPES.CHAT_STATE, chatStateResponse); 5836 break; 5837 case MESSAGE_TYPES.DIRECT_AGENT_TRANSFER_LIST: 5838 var agentList = new DirectAgentTransferList(); 5839 var agentListResponse = agentList.processResponse(response); 5840 utils.fireCallback(instance, CALLBACK_TYPES.DIRECT_AGENT_TRANSFER_LIST, agentListResponse); 5841 break; 5842 case MESSAGE_TYPES.DIRECT_AGENT_TRANSFER: 5843 var agentXfer = new DirectAgentTransfer(); 5844 var agentXferResponse = agentXfer.processResponse(response); 5845 utils.fireCallback(instance, CALLBACK_TYPES.DIRECT_AGENT_TRANSFER, agentXferResponse); 5846 break; 5847 } 5848 }, 5849 processNotification: function(instance, data) { 5850 var type = data.ui_notification['@type']; 5851 var messageId = data.ui_notification['@message_id']; 5852 var dest = messageId === "" ? "IS" : messageId.slice(0, 2); 5853 var message = "Received " + type.toUpperCase() + " notification message from " + dest; 5854 // log message response 5855 utils.logMessage(LOG_LEVELS.INFO, message, data); 5856 switch (type.toUpperCase()){ 5857 case MESSAGE_TYPES.ADD_SESSION: 5858 new NewCallUtils(instance, data).setupAddSessionCallback(); 5859 break; 5860 case MESSAGE_TYPES.DIAL_GROUP_CHANGE: 5861 var dgChangeNotif = new DialGroupChangeNotification(); 5862 var changeResponse = dgChangeNotif.processResponse(data); 5863 utils.fireCallback(instance, CALLBACK_TYPES.DIAL_GROUP_CHANGE, changeResponse); 5864 break; 5865 case MESSAGE_TYPES.DIAL_GROUP_CHANGE_PENDING: 5866 var dgChangePendNotif = new DialGroupChangePendingNotification(); 5867 var pendResponse = dgChangePendNotif.processResponse(data); 5868 utils.fireCallback(instance, CALLBACK_TYPES.DIAL_GROUP_CHANGE_PENDING, pendResponse); 5869 break; 5870 case MESSAGE_TYPES.DROP_SESSION: 5871 var dropSesNotif = new DropSessionNotification(instance); 5872 var dropSesResponse = dropSesNotif.processResponse(data); 5873 utils.fireCallback(instance, CALLBACK_TYPES.DROP_SESSION, dropSesResponse); 5874 break; 5875 case MESSAGE_TYPES.EARLY_UII: 5876 var earlyUiiNotif = new EarlyUiiNotification(instance); 5877 var earlyUiiResponse = earlyUiiNotif.processResponse(data); 5878 utils.fireCallback(instance, CALLBACK_TYPES.EARLY_UII, earlyUiiResponse); 5879 break; 5880 case MESSAGE_TYPES.END_CALL: 5881 var endCallNotif = new EndCallNotification(instance); 5882 var endCallResponse = endCallNotif.processResponse(data); 5883 utils.fireCallback(instance, CALLBACK_TYPES.END_CALL, endCallResponse); 5884 break; 5885 case MESSAGE_TYPES.GATES_CHANGE: 5886 var gateChangeNotif = new GatesChangeNotification(); 5887 var gateChangeResponse = gateChangeNotif.processResponse(data); 5888 utils.fireCallback(instance, CALLBACK_TYPES.GATES_CHANGE, gateChangeResponse); 5889 break; 5890 case MESSAGE_TYPES.GENERIC: 5891 var genericNotif = new GenericNotification(); 5892 var generic = genericNotif.processResponse(data); 5893 var responseTo = data.ui_notification['@response_to']; 5894 var request = utils.findRequestById(instance, responseTo); 5895 if(request){ 5896 // found corresponding request, fire registered callback for type 5897 var type = request.type; 5898 var callbackFnName = utils.findCallbackBasedOnMessageType(type); 5899 if(callbackFnName){ 5900 if(type === MESSAGE_TYPES.CALLBACK_CANCEL){ 5901 generic.leadId = request.msg.lead_id["#text"]; 5902 } 5903 utils.fireCallback(instance, callbackFnName, generic); 5904 }else{ 5905 // no registered callback, fallback to generic notification 5906 utils.fireCallback(instance, CALLBACK_TYPES.GENERIC_NOTIFICATION, generic); 5907 } 5908 }else{ 5909 if(generic.messageCode === "001") { 5910 // caller hangup, stop pinging call 5911 if(UIModel.getInstance().pingIntervalId){ 5912 clearInterval(UIModel.getInstance().pingIntervalId); 5913 } 5914 } 5915 // no corresponding request, just fire generic notification callback 5916 utils.fireCallback(instance, CALLBACK_TYPES.GENERIC_NOTIFICATION, generic); 5917 } 5918 break; 5919 case MESSAGE_TYPES.NEW_CALL: 5920 var newCallNotif = new NewCallNotification(); 5921 var newCallResponse = newCallNotif.processResponse(data); 5922 utils.fireCallback(instance, CALLBACK_TYPES.NEW_CALL, newCallResponse); 5923 new NewCallUtils(instance, data).processSessionsForCall(); 5924 break; 5925 case MESSAGE_TYPES.OFFHOOK_TERM: 5926 if(UIModel.getInstance().offhookTermRequest === null){ 5927 // offhook term initiated by IQ 5928 UIModel.getInstance().offhookTermRequest = new OffhookTermRequest(); 5929 } 5930 var termResponse = UIModel.getInstance().offhookTermRequest.processResponse(data); 5931 utils.fireCallback(instance, CALLBACK_TYPES.OFFHOOK_TERM, termResponse); 5932 break; 5933 case MESSAGE_TYPES.PREVIEW_LEAD_STATE: 5934 var leadStateNotif = new PreviewLeadStateNotification(); 5935 var leadStateResponse = leadStateNotif.processResponse(data); 5936 utils.fireCallback(instance, CALLBACK_TYPES.PREVIEW_LEAD_STATE, leadStateResponse); 5937 break; 5938 case MESSAGE_TYPES.PENDING_DISP: 5939 var pendingDispNotif = new PendingDispNotification(); 5940 var pendingDispResponse = pendingDispNotif.processResponse(data); 5941 utils.fireCallback(instance, CALLBACK_TYPES.PENDING_DISP, pendingDispResponse); 5942 break; 5943 case MESSAGE_TYPES.PENDING_CHAT_DISP: 5944 var pendingChatDispNotif = new PendingChatDispNotification(); 5945 var pendingChatDispResponse = pendingChatDispNotif.processResponse(data); 5946 utils.fireCallback(instance, CALLBACK_TYPES.PENDING_CHAT_DISP, pendingChatDispResponse); 5947 break; 5948 case MESSAGE_TYPES.REVERSE_MATCH: 5949 var reverseMatchNotif = new ReverseMatchNotification(); 5950 var reverseMatchResponse = reverseMatchNotif.processResponse(data); 5951 utils.fireCallback(instance, CALLBACK_TYPES.REVERSE_MATCH, reverseMatchResponse); 5952 break; 5953 case MESSAGE_TYPES.TCPA_SAFE_LEAD_STATE: 5954 var leadStateTcpaNotif = new TcpaSafeLeadStateNotification(); 5955 var leadStateTcpaResponse = leadStateTcpaNotif.processResponse(data); 5956 utils.fireCallback(instance, CALLBACK_TYPES.TCPA_SAFE_LEAD_STATE, leadStateTcpaResponse); 5957 break; 5958 case MESSAGE_TYPES.CHAT_ACTIVE: 5959 var activeNotif = new ChatActiveNotification(); 5960 var activeResponse = activeNotif.processResponse(data); 5961 utils.fireCallback(instance, CALLBACK_TYPES.CHAT_ACTIVE, activeResponse); 5962 break; 5963 case MESSAGE_TYPES.CHAT_INACTIVE: 5964 var inactiveNotif = new ChatInactiveNotification(); 5965 var inactiveResponse = inactiveNotif.processResponse(data); 5966 utils.fireCallback(instance, CALLBACK_TYPES.CHAT_INACTIVE, inactiveResponse); 5967 break; 5968 case MESSAGE_TYPES.CHAT_CLIENT_RECONNECT : 5969 var reconnectNotif = new ChatClientReconnectNotification(); 5970 var reconnectResponse = reconnectNotif.processResponse(data); 5971 utils.fireCallback(instance, CALLBACK_TYPES.CHAT_CLIENT_RECONNECT, reconnectResponse); 5972 break; 5973 case MESSAGE_TYPES.CHAT_PRESENTED: 5974 var presentedNotif = new ChatPresentedNotification(); 5975 var presentedResponse = presentedNotif.processResponse(data); 5976 utils.fireCallback(instance, CALLBACK_TYPES.CHAT_PRESENTED, presentedResponse); 5977 break; 5978 case MESSAGE_TYPES.CHAT_TYPING: 5979 var typingNotif = new ChatTypingNotification(); 5980 var typingResponse = typingNotif.processResponse(data); 5981 utils.fireCallback(instance, CALLBACK_TYPES.CHAT_TYPING, typingResponse); 5982 break; 5983 case MESSAGE_TYPES.CHAT_NEW: 5984 var newChatNotif = new NewChatNotification(); 5985 var newChatResponse = newChatNotif.processResponse(data); 5986 utils.fireCallback(instance, CALLBACK_TYPES.CHAT_NEW, newChatResponse); 5987 break; 5988 case MESSAGE_TYPES.CHAT_MESSAGE: 5989 var chatMessage = new ChatMessageRequest(); 5990 var chatMessageResponse = chatMessage.processResponse(data); 5991 utils.fireCallback(instance, CALLBACK_TYPES.CHAT_MESSAGE, chatMessageResponse); 5992 break; 5993 case MESSAGE_TYPES.CHAT_CANCELLED: 5994 var chatCancelled = new ChatCancelledNotification(); 5995 var chatCancelledResponse = chatCancelled.processResponse(data); 5996 utils.fireCallback(instance, CALLBACK_TYPES.CHAT_CANCELLED, chatCancelledResponse); 5997 break; 5998 case MESSAGE_TYPES.CHAT_ADD_SESSION: 5999 var addChatSession = new AddChatSessionNotification(); 6000 var addChatSessionResponse = addChatSession.processResponse(data); 6001 utils.fireCallback(instance, CALLBACK_TYPES.CHAT_ADD_SESSION, addChatSessionResponse); 6002 break; 6003 case MESSAGE_TYPES.STOP_MONITOR_CHAT: 6004 var stopChatMonitor = new StopMonitorChatRequest(); 6005 var stopChatMonitorResponse = stopChatMonitor.processResponse(data); 6006 utils.fireCallback(instance, CALLBACK_TYPES.CHAT_STOP_MONITOR, stopChatMonitorResponse); 6007 break; 6008 case MESSAGE_TYPES.DIRECT_AGENT_ROUTE: 6009 var directAgentTransfer = new DirectAgentTransferNotification(); 6010 var directAgentTransferResponse = directAgentTransfer.processResponse(data); 6011 utils.fireCallback(instance, CALLBACK_TYPES.DIRECT_AGENT_TRANSFER_NOTIF, directAgentTransferResponse); 6012 break; 6013 case MESSAGE_TYPES.AGENT_DEBUG_EMAIL: 6014 var emailNotif = new AdminDebugEmailNotification(); 6015 var emailNotifResp = emailNotif.processResponse(data); 6016 utils.fireCallback(instance, CALLBACK_TYPES.AGENT_DEBUG_EMAIL_NOTIF, emailNotifResp); 6017 break; 6018 case MESSAGE_TYPES.MONITOR_CHAT: 6019 //TODO: do this 6020 break; 6021 case MESSAGE_TYPES.LEAVE_CHAT: 6022 //TODO: do this 6023 break; 6024 } 6025 }, 6026 processDialerResponse: function(instance, response) { 6027 var type = response.dialer_request['@type']; 6028 var messageId = response.dialer_request['@message_id']; 6029 var dest = messageId === "" ? "IS" : messageId.slice(0, 2); 6030 var message = "Received " + type.toUpperCase() + " dialer response message from " + dest; 6031 // log message response 6032 utils.logMessage(LOG_LEVELS.INFO, message, response); 6033 // Send generic on message response 6034 utils.fireCallback(instance, CALLBACK_TYPES.ON_MESSAGE, response); 6035 // Fire callback function 6036 switch (type.toUpperCase()) { 6037 case MESSAGE_TYPES.PREVIEW_DIAL_ID: 6038 var pdRequest = new PreviewDialRequest(); 6039 var dialResponse = pdRequest.processResponse(response); 6040 if(dialResponse.action.toUpperCase() === "SEARCH"){ 6041 utils.fireCallback(instance, CALLBACK_TYPES.LEAD_SEARCH, dialResponse); 6042 }else{ 6043 utils.fireCallback(instance, CALLBACK_TYPES.PREVIEW_FETCH, dialResponse); 6044 } 6045 break; 6046 case MESSAGE_TYPES.TCPA_SAFE_ID: 6047 var tcpaRequest = new TcpaSafeRequest(); 6048 var tcpaResponse = tcpaRequest.processResponse(response); 6049 if(tcpaResponse.action.toUpperCase() === "SEARCH"){ 6050 utils.fireCallback(instance, CALLBACK_TYPES.SAFE_MODE_SEARCH, tcpaResponse); 6051 }else{ 6052 utils.fireCallback(instance, CALLBACK_TYPES.SAFE_MODE_FETCH, tcpaResponse); 6053 } 6054 break; 6055 } 6056 }, 6057 processRequest: function(instance, message) { 6058 var type = message.ui_request['@type']; 6059 // Fire callback function 6060 switch (type.toUpperCase()) { 6061 case MESSAGE_TYPES.CHAT_SEND: 6062 var chatSendRequest = new ChatSendRequest(); 6063 var chatSendResponse = chatSendRequest.processResponse(message); 6064 utils.fireCallback(instance, CALLBACK_TYPES.CHAT, chatSendResponse); 6065 break; 6066 case MESSAGE_TYPES.CHAT_ROOM_STATE: 6067 var chatRoomStateRequest = new ChatRoomStateRequest(); 6068 var chatRoomStateResponse = chatRoomStateRequest.processResponse(message); 6069 utils.fireCallback(instance, CALLBACK_TYPES.CHAT_ROOM_STATE, chatRoomStateResponse); 6070 break; 6071 } 6072 }, 6073 processStats: function(instance, data) { 6074 var type = data.ui_stats['@type']; 6075 var message = "Received " + type.toUpperCase() + " response message from IS"; 6076 // Fire callback function 6077 switch (type.toUpperCase()) { 6078 case MESSAGE_TYPES.STATS_AGENT: 6079 var agentStats = UIModel.getInstance().agentStatsPacket.processResponse(data); 6080 utils.fireCallback(instance, CALLBACK_TYPES.STATS_AGENT, agentStats); 6081 break; 6082 case MESSAGE_TYPES.STATS_AGENT_DAILY: 6083 var agentDailyStats = UIModel.getInstance().agentDailyStatsPacket.processResponse(data); 6084 utils.fireCallback(instance, CALLBACK_TYPES.STATS_AGENT_DAILY, agentDailyStats); 6085 // start daily stats interval timer, request update every second 6086 if(UIModel.getInstance().agentDailyIntervalId === null){ 6087 UIModel.getInstance().agentDailyIntervalId = setInterval(utils.onAgentDailyStats, 1000); 6088 } 6089 break; 6090 case MESSAGE_TYPES.STATS_CAMPAIGN: 6091 var campaignStats = UIModel.getInstance().campaignStatsPacket.processResponse(data); 6092 utils.fireCallback(instance, CALLBACK_TYPES.STATS_CAMPAIGN, campaignStats); 6093 break; 6094 case MESSAGE_TYPES.STATS_QUEUE: 6095 var queueStats = UIModel.getInstance().queueStatsPacket.processResponse(data); 6096 utils.fireCallback(instance, CALLBACK_TYPES.STATS_QUEUE, queueStats); 6097 break; 6098 case MESSAGE_TYPES.STATS_CHAT: 6099 var chatStats = UIModel.getInstance().chatQueueStatsPacket.processResponse(data); 6100 utils.fireCallback(instance, CALLBACK_TYPES.STATS_CHAT_QUEUE, chatStats); 6101 break; 6102 } 6103 }, 6104 /* 6105 * Take the xml marked JSON, group and item property names and reformat to 6106 * simple javascript object without the xml markers. 6107 * Will work recursively down the tree on nested objects and arrays. 6108 * 6109 * example of acceptable response tree (groupProp = requeue_gates, itemProp = gate_group): 6110 * "requeue_gates": { 6111 * "gate_group": [ 6112 * { 6113 * "@gate_group_id": "4", 6114 * "@group_name": "Test Gate Group", 6115 * "gates": { 6116 * "gate": [ 6117 * { 6118 * "@gate_desc": "", 6119 * "@gate_id": "10951", 6120 * "@gate_name": "CD ACD Queue" 6121 * }, 6122 * { 6123 * "@gate_desc": "", 6124 * "@gate_id": "11036", 6125 * "@gate_name": "Xerox Test Gate" 6126 * } 6127 * ] 6128 * }, 6129 * "skills": { 6130 * "skill": [ 6131 * { 6132 * "@skill_desc": "", 6133 * "@skill_id": "322", 6134 * "@skill_name": "English" 6135 * }, 6136 * { 6137 * "@skill_desc": "", 6138 * "@skill_id": "323", 6139 * "@skill_name": "Spanish" 6140 * } 6141 * ] 6142 * } 6143 * }, 6144 * { 6145 * "@gate_group_id": "14292", 6146 * "@group_name": "New Test Group", 6147 * "gates": { 6148 * "gate": { 6149 * "@gate_desc": "", 6150 * "@gate_id": "15535", 6151 * "@gate_name": "New Test Gate" 6152 * } 6153 * }, 6154 * "skills": { 6155 * "skill": { 6156 * "@skill_desc": "", 6157 * "@skill_id": "1658", 6158 * "@skill_name": "new skill" 6159 * } 6160 * } 6161 * } 6162 * ] 6163 * } 6164 * 6165 * OR 6166 * 6167 * "outdial_dispositions": { 6168 * "@type": "GATE", 6169 * "disposition": [ 6170 * { 6171 * "@contact_forwarding": "false", 6172 * "@disposition_id": "926", 6173 * "@is_complete": "1", 6174 * "@require_note": "0", 6175 * "@save_survey": "1", 6176 * "@xfer": "0", 6177 * "#text": "One B" 6178 * }, 6179 * { 6180 * "@contact_forwarding": "false", 6181 * "@disposition_id": "926", 6182 * "@is_complete": "1", 6183 * "@require_note": "0", 6184 * "@save_survey": "1", 6185 * "@xfer": "0", 6186 * "#text": "One B" 6187 * } 6188 * ] 6189 * } 6190 * 6191 * OR 6192 * 6193 * "outdial_dispositions": { 6194 * "@type": "GATE", 6195 * "disposition": { 6196 * { 6197 * "@contact_forwarding": "false", 6198 * "@disposition_id": "926", 6199 * "@is_complete": "1", 6200 * "@require_note": "0", 6201 * "@save_survey": "1", 6202 * "@xfer": "0", 6203 * "#text": "One B" 6204 * } 6205 * } 6206 * } 6207 */ 6208 processResponseCollection: function (response, groupProp, itemProp, textName) { 6209 textName = textName || "text"; 6210 if (response[groupProp] && typeof response[groupProp][itemProp] !== 'undefined') { 6211 var itemsRaw = response[groupProp][itemProp]; 6212 return this._processItems(itemsRaw, textName); 6213 } else { 6214 return []; 6215 } 6216 }, 6217 _processItems: function (itemsRaw, textName) { 6218 var result = []; 6219 if (typeof itemsRaw === "undefined" || itemsRaw === null) { 6220 return result; 6221 } 6222 if (!Array.isArray(itemsRaw)) { 6223 itemsRaw = [itemsRaw]; 6224 } 6225 for (var i = 0; i < itemsRaw.length; i++) { 6226 result.push(this._processItem(itemsRaw[i], textName)); 6227 } 6228 return result; 6229 }, 6230 _processItem: function (itemRaw, textName) { 6231 /* 6232 * Be sure that the item we are processing is not a #text node only, where the "texName" is also "text". If this 6233 * is the case, it means there's a default value that needs to get converted and isn't going to be mapped to a custom 6234 * field. Therefore, we treat it as just a single value, not an object. 6235 */ 6236 if (textName === "text" && Object.keys(itemRaw).length === 1 && itemRaw['#text'] != null) { 6237 return this._tryConvertValueToBoolean(itemRaw["#text"]); 6238 } 6239 // Convert the raw item to a new item, with keys and values processed below 6240 // 6241 var item = {}; 6242 for (var key in itemRaw) { 6243 var formattedKey = this._convertToFormattedKey(key, textName); 6244 var value = itemRaw[key]; 6245 // If we aren't an object, set the value and continue to next key 6246 if (typeof value !== "object") { 6247 item[formattedKey] = this._tryConvertValueToBoolean(value); 6248 continue; 6249 } 6250 if ((Array.isArray(value) && value.length === 0) || Object.keys(value).length === 0) { 6251 // Empty property 6252 item[formattedKey] = ""; 6253 } else if (Array.isArray(value) || Object.keys(value).length > 1) { 6254 // Array or object with more than one key 6255 formattedKey = this._convertKeyForCollection(formattedKey); 6256 item[formattedKey] = this._processItems(value, textName); 6257 } else if (Object.keys(value).length === 1 && value['#text'] != null) { 6258 // One property of type "#text" 6259 item[formattedKey] = value['#text']; 6260 } else { 6261 // One property not with key "#text" 6262 item[formattedKey] = this._processItems(value[Object.keys(value)[0]], "text"); 6263 } 6264 } 6265 return item; 6266 }, 6267 _convertToFormattedKey: function (key, textName) { 6268 var formattedKey; 6269 if (key.match(/^#/)) { 6270 // dealing with text property 6271 formattedKey = textName; 6272 } else { 6273 // dealing with attribute 6274 formattedKey = key.replace(/@/, ''); // remove leading '@' 6275 formattedKey = formattedKey.replace(/_([a-z])/g, function (g) { 6276 return g[1].toUpperCase(); 6277 }); // convert to camelCase 6278 } 6279 return formattedKey; 6280 }, 6281 _convertKeyForCollection: function (formattedKey) { 6282 if (formattedKey.substr(formattedKey.length - 1) !== 's') { 6283 return formattedKey + 's'; 6284 } 6285 return formattedKey; 6286 }, 6287 _tryConvertValueToBoolean: function (value) { 6288 if (value === null) { 6289 return null; 6290 } 6291 // can't convert 0 | 1 to boolean since some are counters 6292 if (value.toUpperCase() === "TRUE") { 6293 return true; 6294 } else if (value.toUpperCase() === "FALSE") { 6295 return false; 6296 } else { 6297 return value; 6298 } 6299 }, 6300 fireCallback: function(instance, type, response) { 6301 response = response || ""; 6302 if (typeof type !== 'undefined' && typeof instance.callbacks[type] === 'function') { 6303 instance.callbacks[type].call(instance, response); 6304 } 6305 }, 6306 setCallback: function(instance, type, callback) { 6307 if (typeof type !== 'undefined' && typeof callback !== 'undefined') { 6308 instance.callbacks[type] = callback; 6309 } 6310 }, 6311 getMessageId: function() { 6312 function s4() { 6313 return Math.floor((1 + Math.random()) * 0x10000) 6314 .toString(16) 6315 .substring(1); 6316 } 6317 return s4() + s4() + '-' + s4() + '-' + s4() + '-' + 6318 s4() + '-' + s4() + s4() + s4(); 6319 }, 6320 // check whether the given array of ids exist in the given array of objects 6321 // if not available, remove the id 6322 // returns the clean list of acceptable ids 6323 checkExistingIds: function(objArray, idArray, idProperty) { 6324 var availIds = []; 6325 var removeIds = []; 6326 // get list of available ids 6327 for(var o = 0; o < objArray.length; o++){ 6328 availIds.push(parseInt(objArray[o][idProperty], 10)); 6329 } 6330 // go through selected ids and mark unfound ones for removal 6331 for(var i = 0; i < idArray.length; i++){ 6332 if(availIds.indexOf(parseInt(idArray[i],10)) === -1){ 6333 // selected id not found in available list, mark for removal 6334 removeIds.push(parseInt(idArray[i],10)); 6335 } 6336 } 6337 // remove marked ids 6338 for(var r = idArray.length -1; r >= 0; r--){ 6339 if(removeIds.indexOf(parseInt(idArray[r],10)) > -1){ 6340 // remove 6341 idArray.splice(r,1); 6342 } 6343 } 6344 return idArray; 6345 }, 6346 // find an object by given id in an array of objects 6347 findObjById: function(objArray, id, propName) { 6348 for(var o = 0; o < objArray.length; o++){ 6349 var obj = objArray[o]; 6350 if(obj[propName] === id){ 6351 return obj; 6352 } 6353 } 6354 return null; 6355 }, 6356 // check whether agent dialDest is either a 10-digit number or valid sip 6357 validateDest: function(dialDest) { 6358 var isValid = false; 6359 var isNum = /^\d+$/.test(dialDest); 6360 if(isNum && dialDest.length === 10){ 6361 // is a 10-digit number 6362 isValid = true; 6363 }else if(dialDest.slice(0,4).toLowerCase() === "sip:" && dialDest.indexOf("@") !== -1){ 6364 // has sip prefix and '@' 6365 isValid = true; 6366 } 6367 return isValid; 6368 }, 6369 // pass in MESSAGE_TYPE string (e.g. "CANCEL-CALLBACK"), 6370 // return corresponding CALLBACK_TYPE function name string (e.g. "callbackCancelResponse") 6371 findCallbackBasedOnMessageType: function(messageType) { 6372 var callbackFnName = ""; 6373 for(var key in MESSAGE_TYPES){ 6374 if(MESSAGE_TYPES[key] === messageType){ 6375 callbackFnName = CALLBACK_TYPES[key]; 6376 } 6377 } 6378 return callbackFnName; 6379 }, 6380 // add message, detail, and status values to the formattedResponse 6381 // returned from each request processResponse method 6382 buildDefaultResponse: function(response) { 6383 var message = ""; 6384 var detail = ""; 6385 var status = ""; 6386 var msg = ""; 6387 var det = ""; 6388 var stat = ""; 6389 // add message and detail if present 6390 if(response.ui_response){ 6391 msg = response.ui_response.message; 6392 det = response.ui_response.detail; 6393 stat = response.ui_response.status; 6394 }else if(response.ui_notification){ 6395 msg = response.ui_notification.message; 6396 det = response.ui_notification.detail; 6397 stat = response.ui_notification.status; 6398 } 6399 if(msg){ 6400 message = msg['#text'] || ""; 6401 } 6402 if(det){ 6403 detail = det['#text'] || ""; 6404 } 6405 if(stat){ 6406 status = stat['#text'] || ""; 6407 } 6408 return ({ 6409 message: message, 6410 detail: detail, 6411 status: status 6412 }); 6413 }, 6414 toString: function(val) { 6415 if(val){ 6416 return val.toString(); 6417 }else{ 6418 return ""; 6419 } 6420 }, 6421 // safely check if property exists and return empty string 6422 // instead of undefined if it doesn't exist 6423 // convert "TRUE" | "FALSE" to boolean 6424 getText: function(obj,prop) { 6425 var o = obj[prop]; 6426 if(o && o['#text']){ 6427 if(o['#text'].toUpperCase() === "TRUE"){ 6428 return true; 6429 }else if(o['#text'].toUpperCase() === "FALSE"){ 6430 return false; 6431 }else{ 6432 return o['#text'] || ""; 6433 } 6434 }else{ 6435 return ""; 6436 } 6437 }, 6438 // safely check if property exists and return empty string 6439 // instead of undefined if it doesn't exist 6440 // convert "TRUE" | "FALSE" to boolean 6441 getAttribute: function(obj,prop) { 6442 var o = obj[prop]; 6443 if(o && o[prop]){ 6444 if(o[prop].toUpperCase() === "TRUE"){ 6445 return true; 6446 }else if(o[prop].toUpperCase() === "FALSE"){ 6447 return false; 6448 }else{ 6449 return o[prop] || ""; 6450 } 6451 }else{ 6452 return ""; 6453 } 6454 }, 6455 // Parses a string of key value pairs and returns an Array of KeyValue objects. 6456 // @param str The string of keyvalue pairs to parse 6457 // @param outerDelimiter The delimiter that separates each keyValue pair 6458 // @param innerDelimiter The delimiter that separates each key from its value 6459 parseKeyValuePairsFromString: function(str, outerDelimiter, innerDelimiter) { 6460 if (!str){ 6461 return []; 6462 } 6463 var arr = str.split(outerDelimiter).reduce(function(dict, pair){ 6464 var keyValue = pair.split(innerDelimiter); 6465 dict[keyValue[0]] = keyValue[1]; 6466 return dict; 6467 },{}); 6468 return arr; 6469 }, 6470 // Finds a request by responseTo id 6471 findRequestById: function(instance, id) { 6472 var request = null; 6473 for(var i = 0; i < instance._requests.length; i++){ 6474 if(instance._requests[i].id === id){ 6475 request = instance._requests[i]; 6476 break; 6477 } 6478 } 6479 return request; 6480 }, 6481 // called every 30 seconds letting intelliQueue know 6482 // not to archive the call so dispositions and other call 6483 // clean up actions can happen 6484 sendPingCallMessage: function() { 6485 UIModel.getInstance().pingCallRequest = new PingCallRequest(); 6486 var msg = UIModel.getInstance().pingCallRequest.formatJSON(); 6487 var msgObj = JSON.parse(msg); 6488 var agentId = utils.getText(msgObj.ui_request,'agent_id'); 6489 var uii = utils.getText(msgObj.ui_request,'uii'); 6490 if(agentId === "" || uii === ""){ 6491 utils.logMessage(LOG_LEVELS.WARN, "PING-CALL message failed, agentId or UII is empty", msgObj); 6492 }else{ 6493 utils.sendMessage(UIModel.getInstance().libraryInstance, msg); 6494 } 6495 }, 6496 // called every 5 seconds to request stats from IntelliServices 6497 sendStatsRequestMessage: function() { 6498 UIModel.getInstance().statsRequest = new StatsRequest(); 6499 var msg = UIModel.getInstance().statsRequest.formatJSON(); 6500 utils.sendMessage(UIModel.getInstance().libraryInstance, msg); 6501 }, 6502 // called every second 6503 // if we have received agent daily stats 6504 // start incrementing various data points since not all 6505 // data is incremented when we want on the IntelliServices side 6506 onAgentDailyStats: function() { 6507 if(Object.keys(UIModel.getInstance().agentDailyStats).length !== 0){ 6508 var agentSettings = UIModel.getInstance().agentSettings, 6509 stats = UIModel.getInstance().agentDailyStats; 6510 var curLoginTime = stats.totalLoginTime; 6511 stats.totalLoginTime = Number(curLoginTime) + 1; 6512 if(agentSettings.isOffhook){ 6513 var curOffhookTime = stats.totalOffhookTime; 6514 stats.totalOffhookTime = Number(curOffhookTime) + 1; 6515 } 6516 if(agentSettings.currentState == 'ENGAGED'){ 6517 var curTalkTime = stats.totalTalkTime; 6518 stats.totalTalkTime = Number(curTalkTime) + 1; 6519 var curCallTime = stats.currCallTime; 6520 stats.currCallTime = Number(curCallTime) + 1; 6521 } 6522 } 6523 } 6524 }; 6525 // CONSTANTS 6526 /*jshint esnext: true */ 6527 const LOG_LEVELS ={ 6528 "DEBUG":"debug", 6529 "STATS":"stats", 6530 "INFO":"info", 6531 "WARN":"warn", 6532 "ERROR":"error" 6533 }; 6534 // add all callback types to setCallback method description 6535 const CALLBACK_TYPES = { 6536 "ADD_SESSION":"addSessionNotification", 6537 "AGENT_STATE":"agentStateResponse", 6538 "ACK":"acknowledgeResponse", 6539 "BARGE_IN":"bargeInResponse", 6540 "CLOSE_SOCKET":"closeResponse", 6541 "COACH_CALL":"coachResponse", 6542 "CONFIG":"configureResponse", 6543 "CALL_NOTES":"callNotesResponse", 6544 "CALLBACK_PENDING":"callbacksPendingResponse", 6545 "CALLBACK_CANCEL":"callbackCancelResponse", 6546 "CAMPAIGN_DISPOSITIONS":"campaignDispositionsResponse", 6547 "CHAT":"chatResponse", // internal chat 6548 "CHAT_ACTIVE":"chatActiveNotification", // external chat 6549 "CHAT_CANCELLED":"chatCancelledNotification", // external chat 6550 "CHAT_INACTIVE":"chatInactiveNotification", // external chat 6551 "CHAT_PRESENTED":"chatPresentedNotification", // external chat 6552 "CHAT_TYPING":"chatTypingNotification", // external chat 6553 "CHAT_MESSAGE":"chatMessageNotification", // external chat 6554 "CHAT_NEW":"chatNewNotification", // external chat 6555 "CHAT_LIST":"chatListResponse", // external chat 6556 "CHAT_ADD_SESSION":"addChatSessionNotification",// external chat 6557 "CHAT_STOP_MONITOR":"stopAgentChatMonitorNotification",// external chat 6558 "CHAT_CLIENT_RECONNECT" : "chatClientReconnectNotification", 6559 "CHAT_STATE":"chatStateResponse", // external chat 6560 "CHAT_ROOM_STATE":"chatRoomStateResponse", 6561 "DIAL_GROUP_CHANGE":"dialGroupChangeNotification", 6562 "DIAL_GROUP_CHANGE_PENDING":"dialGroupChangePendingNotification", 6563 "DROP_SESSION":"dropSessionNotification", 6564 "EARLY_UII":"earlyUiiNotification", 6565 "END_CALL":"endCallNotification", 6566 "GATES_CHANGE":"gatesChangeNotification", 6567 "GENERIC_NOTIFICATION":"genericNotification", 6568 "GENERIC_RESPONSE":"genericResponse", 6569 "HOLD":"holdResponse", 6570 "LOG_RESULTS":"logResultsResponse", 6571 "LOG_CONSOLE_RESULTS":"logConsoleResultsResponse", 6572 "LOGIN":"loginResponse", 6573 "LOGOUT":"logoutResponse", 6574 "NEW_CALL":"newCallNotification", 6575 "LEAD_HISTORY":"leadHistoryResponse", 6576 "LEAD_INSERT":"leadInsertResponse", 6577 "LEAD_SEARCH":"leadSearchResponse", 6578 "LEAD_UPDATE":"leadUpdateResponse", 6579 "OFFHOOK_INIT":"offhookInitResponse", 6580 "OFFHOOK_TERM":"offhookTermNotification", 6581 "OPEN_SOCKET":"openResponse", 6582 "PAUSE_RECORD":"pauseRecordResponse", 6583 "PENDING_DISP":"pendingDispNotification", 6584 "PENDING_CHAT_DISP":"pendingChatDispNotification", 6585 "PREVIEW_FETCH":"previewFetchResponse", 6586 "PREVIEW_LEAD_STATE":"previewLeadStateNotification", 6587 "RECORD":"recordResponse", 6588 "REQUEUE":"requeueResponse", 6589 "REVERSE_MATCH":"reverseMatchNotification", 6590 "SAFE_MODE_FETCH":"safeModeFetchResponse", 6591 "SAFE_MODE_SEARCH":"safeModeSearchResponse", 6592 "SCRIPT_CONFIG":"scriptConfigResponse", 6593 "SILENT_MONITOR":"monitorResponse", 6594 "STATS_AGENT":"agentStats", 6595 "STATS_AGENT_DAILY":"agentDailyStats", 6596 "STATS_CAMPAIGN":"campaignStats", 6597 "STATS_QUEUE":"queueStats", 6598 "STATS_CHAT_QUEUE":"chatQueueStats", 6599 "SUPERVISOR_LIST":"supervisorListResponse", 6600 "TCPA_SAFE_LEAD_STATE":"tcpaSafeLeadStateNotification", 6601 "XFER_COLD":"coldXferResponse", 6602 "XFER_WARM":"warmXferResponse", 6603 "DIRECT_AGENT_TRANSFER_LIST": "directAgentTransferListResponse", 6604 "DIRECT_AGENT_TRANSFER": "directAgentTransferResponse", 6605 "DIRECT_AGENT_TRANSFER_NOTIF": "directAgentTransferNotification", 6606 "AGENT_DEBUG_EMAIL_NOTIF": "agentDebugEmailNotification" 6607 }; 6608 const MESSAGE_TYPES = { 6609 "ACK":"ACK", 6610 "ADD_SESSION":"ADD-SESSION", 6611 "AGENT_DEBUG_EMAIL": "AGENT-DEBUG-EMAIL", 6612 "BARGE_IN":"BARGE-IN", 6613 "AGENT_STATE":"AGENT-STATE", 6614 "CALL_NOTES":"CALL-NOTES", 6615 "CALLBACK_PENDING":"PENDING-CALLBACKS", 6616 "CALLBACK_CANCEL":"CANCEL-CALLBACK", 6617 "CAMPAIGN_DISPOSITIONS":"CAMPAIGN-DISPOSITIONS", 6618 "CHAT_SEND":"CHAT", // internal chat 6619 "CHAT_ALIAS":"CHAT-ALIAS", // internal chat 6620 "CHAT_ROOM":"CHAT-ROOM", // internal chat 6621 "CHAT_ROOM_STATE":"CHAT-ROOM-STATE", // internal chat 6622 "CHAT_ACTIVE":"CHAT-ACTIVE", // external chat 6623 "CHAT_CANCELLED":"CHAT-CANCELLED", // external chat 6624 "CHAT_INACTIVE":"CHAT-INACTIVE", // external chat 6625 "CHAT_DISPOSITION":"CHAT-DISPOSITION", // external chat 6626 "CHAT_MESSAGE":"CHAT-MESSAGE", // external chat 6627 "CHAT_NEW":"NEW-CHAT", // external chat 6628 "CHAT_PRESENTED":"CHAT-PRESENTED", // external chat 6629 "CHAT_PRESENTED_RESPONSE":"CHAT-PRESENTED-RESPONSE", // external chat 6630 "CHAT_REQUEUE":"CHAT-REQUEUE", // external chat 6631 "CHAT_STATE":"CHAT-STATE", // external chat 6632 "CHAT_TYPING":"CHAT-TYPING", // external chat 6633 "MONITOR_CHAT":"CHAT-MONITOR", // external chat 6634 "CHAT_ADD_SESSION":"ADD-CHAT-SESSION", // external chat 6635 "STOP_MONITOR_CHAT":"CHAT-DROP-MONITORING-SESSION", // external chat 6636 "LEAVE_CHAT":"CHAT-DROP-SESSION", // external chat 6637 "CHAT_LIST":"CHAT-LIST", // external chat 6638 "CHAT_AGENT_END" : "CHAT-END", // external chat 6639 "CHAT_CLIENT_RECONNECT" : "CHAT-CLIENT-RECONNECT", // external chat 6640 "CHAT_MANUAL_SMS": "MANUAL-SMS", // external chat 6641 "PENDING_CHAT_DISP": "PENDING-CHAT-DISP", // external chat 6642 "DIAL_GROUP_CHANGE":"DIAL_GROUP_CHANGE", 6643 "DIAL_GROUP_CHANGE_PENDING":"DIAL_GROUP_CHANGE_PENDING", 6644 "DROP_SESSION":"DROP-SESSION", 6645 "EARLY_UII":"EARLY_UII", 6646 "END_CALL":"END-CALL", 6647 "GATES_CHANGE":"GATES_CHANGE", 6648 "GENERIC":"GENERIC", 6649 "HANGUP":"HANGUP", 6650 "HOLD":"HOLD", 6651 "INBOUND_DISPOSITION":"INBOUND-DISPOSITION", 6652 "LEAD_HISTORY":"LEAD-HISTORY", 6653 "LEAD_INSERT":"LEAD-INSERT", 6654 "LEAD_UPDATE":"LEAD-UPDATE", 6655 "LOGIN":"LOGIN", 6656 "LOGOUT":"LOGOUT", 6657 "NEW_CALL":"NEW-CALL", 6658 "OFFHOOK_INIT":"OFF-HOOK-INIT", 6659 "OFFHOOK_TERM":"OFF-HOOK-TERM", 6660 "ON_MESSAGE":"ON-MESSAGE", 6661 "ONE_TO_ONE_OUTDIAL":"ONE-TO-ONE-OUTDIAL", 6662 "ONE_TO_ONE_OUTDIAL_CANCEL":"ONE-TO-ONE-OUTDIAL-CANCEL", 6663 "OUTDIAL_DISPOSITION":"OUTDIAL-DISPOSITION", 6664 "PAUSE_RECORD":"PAUSE-RECORD", 6665 "PING_CALL":"PING-CALL", 6666 "PREVIEW_DIAL":"PREVIEW-DIAL", 6667 "PENDING_DISP":"PENDING_DISP", 6668 "PREVIEW_DIAL_ID":"PREVIEW_DIAL", 6669 "PREVIEW_LEAD_STATE":"PREVIEW-LEAD-STATE", 6670 "RECORD":"RECORD", 6671 "REQUEUE":"RE-QUEUE", 6672 "REVERSE_MATCH":"REVERSE_MATCH", 6673 "SCRIPT_CONFIG":"SCRIPT-CONFIG", 6674 "SCRIPT_RESULT":"SCRIPT-RESULT", 6675 "STATS":"STATS", 6676 "STATS_AGENT":"AGENT", 6677 "STATS_AGENT_DAILY":"AGENTDAILY", 6678 "STATS_CAMPAIGN":"CAMPAIGN", 6679 "STATS_QUEUE":"GATE", 6680 "STATS_CHAT":"CHAT", 6681 "SUPERVISOR_LIST":"SUPERVISOR-LIST", // internal chat 6682 "TCPA_SAFE":"TCPA-SAFE", 6683 "TCPA_SAFE_ID":"TCPA_SAFE", 6684 "TCPA_SAFE_LEAD_STATE":"TCPA-SAFE-LEAD-STATE", 6685 "XFER_COLD":"COLD-XFER", 6686 "XFER_WARM":"WARM-XFER", 6687 "XFER_WARM_CANCEL":"WARM-XFER-CANCEL", 6688 "DIRECT_AGENT_TRANSFER_LIST": "DIRECT-AGENT-TRANSFER-LIST", 6689 "DIRECT_AGENT_TRANSFER": "DIRECT-AGENT-TRANSFER", 6690 "DIRECT_AGENT_ROUTE": "DIRECT-AGENT-ROUTE", 6691 "UPDATE_DIAL_DESTINATION": "UPDATE_DIAL_DESTINATION" 6692 }; 6693 /* 6694 * Init wrapper for the core module. 6695 * @param {Object} The Object that the library gets attached to in 6696 * library.init.js. If the library was not loaded with an AMD loader such as 6697 * require.js, this is the global Object. 6698 */ 6699 function initAgentLibraryCore (context) { 6700 'use strict'; 6701 /** 6702 * This is the constructor for the Library Object. Note that the constructor is also being 6703 * attached to the context that the library was loaded in. 6704 * @param {Object} [config={}] Set socket url and callback functions. 6705 * @constructor 6706 * @namespace Core 6707 * @memberof AgentLibrary 6708 * @property {object} callbacks Internal map of registered callback functions 6709 * @property {array} _requests Internal map of requests by message id, private property. 6710 * @property {array} _queuedMsgs Array of pending messages to be sent when socket reconnected 6711 * @property {boolean} _isReconnect Whether or not we are doing a reconnect for the socket 6712 * @example 6713 * var Lib = new AgentLibrary({ 6714 * socketDest:'ws://d01-test.cf.dev:8080', 6715 * callbacks: { 6716 * closeResponse: onCloseFunction, 6717 * openResponse: onOpenFunction 6718 * } 6719 * }); 6720 */ 6721 var AgentLibrary = context.AgentLibrary = function (config) { 6722 config = config || {}; 6723 // define properties 6724 this.callbacks = {}; 6725 this._requests = []; 6726 this._queuedMsgs = []; 6727 this._isReconnect = false; 6728 // start with new model instance 6729 UIModel.resetInstance(); 6730 // set instance on model object 6731 UIModel.getInstance().libraryInstance = this; 6732 // initialize indexedDB for logging 6733 this.openLogger(); 6734 this.openConsoleLogger(); 6735 // set default values 6736 if(typeof config.callbacks !== 'undefined'){ 6737 this.callbacks = config.callbacks; 6738 } 6739 if(typeof config.socketDest !== 'undefined'){ 6740 UIModel.getInstance().applicationSettings.socketDest = config.socketDest; 6741 this.openSocket(); 6742 }else{ 6743 // todo default socket address? 6744 } 6745 return this; 6746 }; 6747 /** 6748 * Set multiple callback functions based on type 6749 * @memberof AgentLibrary.Core 6750 * @param {Object} callbackMap Contains map of callback types to their respective functions:<br /> 6751 * <tt>callbackMap = {<br /> 6752 * closeResponse: onCloseFunction,<br /> 6753 * openResponse: onOpenFunction<br /> 6754 * } 6755 * </tt> 6756 *<br /> 6757 * Possible callback types: 6758 * <li>"addSessionNotification"</li> 6759 * <li>"agentStateResponse"</li> 6760 * <li>"acknowledgeResponse"</li> 6761 * <li>"bargeInResponse"</li> 6762 * <li>"closeResponse"</li> 6763 * <li>"coachResponse"</li> 6764 * <li>"configureResponse"</li> 6765 * <li>"callNotesResponse"</li> 6766 * <li>"callbacksPendingResponse"</li> 6767 * <li>"callbackCancelResponse"</li> 6768 * <li>"campaignDispositionsResponse"</li> 6769 * <li>"chatResponse"</li> 6770 * <li>"dialGroupChangeNotification"</li> 6771 * <li>"dialGroupChangePendingNotification"</li> 6772 * <li>"dropSessionNotification"</li> 6773 * <li>"earlyUiiNotification"</li> 6774 * <li>"endCallNotification"</li> 6775 * <li>"gatesChangeNotification"</li> 6776 * <li>"genericNotification"</li> 6777 * <li>"genericResponse"</li> 6778 * <li>"holdResponse"</li> 6779 * <li>"leadSearchResponse"</li> 6780 * <li>"loginResponse"</li> 6781 * <li>"logoutResponse"</li> 6782 * <li>"monitorResponse"</li> 6783 * <li>"newCallNotification"</li> 6784 * <li>"offhookInitResponse"</li> 6785 * <li>"offhookTermNotification"</li> 6786 * <li>"openResponse"</li> 6787 * <li>"pauseRecordResponse"</li> 6788 * <li>"pendingDispNotification"</li> 6789 * <li>"previewFetchResponse"</li> 6790 * <li>"previewLeadStateNotification"</li> 6791 * <li>"recordResponse"</li> 6792 * <li>"requeueResponse"</li> 6793 * <li>"reverseMatchNotification"</li> 6794 * <li>"safeModeFetchResponse"</li> 6795 * <li>"safeModeSearchResponse"</li> 6796 * <li>"scriptConfigResponse"</li> 6797 * <li>"supervisorListResponse"</li> 6798 * <li>"coldXferResponse"</li> 6799 * <li>"warmXferResponse"</li> 6800 * <li>"agentStats"</li> 6801 * <li>"agentDailyStats"</li> 6802 * <li>"campaignStats"</li> 6803 * <li>"queueStats"</li> 6804 * <li>"chatQueueStats"</li> 6805 * @type {object} 6806 */ 6807 AgentLibrary.prototype.setCallbacks = function(callbackMap) { 6808 for(var property in callbackMap) { 6809 this.callbacks[property] = callbackMap[property]; 6810 } 6811 }; 6812 /** 6813 * Set an individual callback function for the given type 6814 * @memberof AgentLibrary.Core 6815 * @param {string} type The name of the event that fires the callback function 6816 * @param {function} callback The function to call for the given type 6817 */ 6818 AgentLibrary.prototype.setCallback = function(type, callback) { 6819 this.callbacks[type] = callback; 6820 }; 6821 /** 6822 * Get the map of all registered callbacks 6823 * @memberof AgentLibrary.Core 6824 * @returns {array} 6825 */ 6826 AgentLibrary.prototype.getCallbacks = function(){ 6827 return this.callbacks; 6828 }; 6829 /** 6830 * Get a given registered callback by type 6831 * @memberof AgentLibrary.Core 6832 * @returns {object} 6833 */ 6834 AgentLibrary.prototype.getCallback = function(type){ 6835 return this.callbacks[type]; 6836 }; 6837 /** 6838 * Get the socket connection to IntelliSocket 6839 * @memberof AgentLibrary.Core 6840 * @returns {object} 6841 */ 6842 AgentLibrary.prototype.getSocket = function(type){ 6843 return this.socket; 6844 }; 6845 /** 6846 * @namespace Requests 6847 * @memberof AgentLibrary.Core 6848 */ 6849 //////////////////////////// 6850 // requests and responses // 6851 //////////////////////////// 6852 /** 6853 * Get outgoing Login Request object 6854 * @memberof AgentLibrary.Core.Requests 6855 * @returns {object} 6856 */ 6857 AgentLibrary.prototype.getLoginRequest = function() { 6858 return UIModel.getInstance().loginRequest; 6859 }; 6860 /** 6861 * Get outgoing Config Request object 6862 * @memberof AgentLibrary.Core.Requests 6863 * @returns {object} 6864 */ 6865 AgentLibrary.prototype.getConfigRequest = function() { 6866 return UIModel.getInstance().configRequest; 6867 }; 6868 /** 6869 * Get outgoing Logout Request object 6870 * @memberof AgentLibrary.Core.Requests 6871 * @returns {object} 6872 */ 6873 AgentLibrary.prototype.getLogoutRequest = function() { 6874 return UIModel.getInstance().logoutRequest; 6875 }; 6876 /** 6877 * Get latest Agent Daily Stats object 6878 * @memberof AgentLibrary.Core.Requests 6879 * @returns {object} 6880 */ 6881 AgentLibrary.prototype.getAgentDailyStats = function() { 6882 return UIModel.getInstance().agentDailyStats; 6883 }; 6884 /** 6885 * Get latest Call Tokens object 6886 * @memberof AgentLibrary.Core.Requests 6887 * @returns {object} 6888 */ 6889 AgentLibrary.prototype.getCallTokens = function() { 6890 return UIModel.getInstance().callTokens; 6891 }; 6892 /** 6893 * Get latest outgoing Agent State Request object 6894 * @memberof AgentLibrary.Core.Requests 6895 * @returns {object} 6896 */ 6897 AgentLibrary.prototype.getAgentStateRequest = function() { 6898 return UIModel.getInstance().agentStateRequest; 6899 }; 6900 /** 6901 * Get latest outgoing offhook init Request object 6902 * @memberof AgentLibrary.Core.Requests 6903 * @returns {object} 6904 */ 6905 AgentLibrary.prototype.getOffhookInitRequest = function() { 6906 return UIModel.getInstance().offhookInitRequest; 6907 }; 6908 /** 6909 * Get latest outgoing offhook termination Request object 6910 * @memberof AgentLibrary.Core.Requests 6911 * @returns {object} 6912 */ 6913 AgentLibrary.prototype.getOffhookTermRequest = function() { 6914 return UIModel.getInstance().offhookTermRequest; 6915 }; 6916 /** 6917 * Get latest outgoing Hangup Request object 6918 * @memberof AgentLibrary.Core.Requests 6919 * @returns {object} 6920 */ 6921 AgentLibrary.prototype.getHangupRequest = function() { 6922 return UIModel.getInstance().hangupRequest; 6923 }; 6924 /** 6925 * Get latest outgoing Preview Dial Request object 6926 * @memberof AgentLibrary.Core.Requests 6927 * @returns {object} 6928 */ 6929 AgentLibrary.prototype.getPreviewDialRequest = function() { 6930 return UIModel.getInstance().previewDialRequest; 6931 }; 6932 /** 6933 * Get latest TCPA Safe Request object 6934 * @memberof AgentLibrary.Core.Requests 6935 * @returns {object} 6936 */ 6937 AgentLibrary.prototype.getTcpaSafeRequest = function() { 6938 return UIModel.getInstance().tcpaSafeRequest; 6939 }; 6940 /** 6941 * Get latest Manual Outdial Request object 6942 * @memberof AgentLibrary.Core.Requests 6943 * @returns {object} 6944 */ 6945 AgentLibrary.prototype.getManualOutdialRequest = function() { 6946 return UIModel.getInstance().oneToOneOutdialRequest; 6947 }; 6948 /** 6949 * Get latest Manual Outdial Cancel Request object 6950 * @memberof AgentLibrary.Core.Requests 6951 * @returns {object} 6952 */ 6953 AgentLibrary.prototype.getManualOutdialCancelRequest = function() { 6954 return UIModel.getInstance().oneToOneOutdialCancelRequest; 6955 }; 6956 /** 6957 * Get latest Call Notes Request object 6958 * @memberof AgentLibrary.Core.Requests 6959 * @returns {object} 6960 */ 6961 AgentLibrary.prototype.getCallNotesRequest = function() { 6962 return UIModel.getInstance().callNotesRequest; 6963 }; 6964 /** 6965 * Get latest Campaign Dispositions Request object 6966 * @memberof AgentLibrary.Core.Requests 6967 * @returns {object} 6968 */ 6969 AgentLibrary.prototype.getCampaignDispositionsRequest = function() { 6970 return UIModel.getInstance().campaignDispositionsRequest; 6971 }; 6972 /** 6973 * Get latest Disposition Call Request object 6974 * @memberof AgentLibrary.Core.Requests 6975 * @returns {object} 6976 */ 6977 AgentLibrary.prototype.getDispositionRequest = function() { 6978 return UIModel.getInstance().dispositionRequest; 6979 }; 6980 /** 6981 * Get latest Disposition Manual Pass Request object 6982 * @memberof AgentLibrary.Core.Requests 6983 * @returns {object} 6984 */ 6985 AgentLibrary.prototype.getDispositionManualPassRequest = function() { 6986 return UIModel.getInstance().dispositionManualPassRequest; 6987 }; 6988 /** 6989 * Get latest Warm Transfer Request object 6990 * @memberof AgentLibrary.Core.Requests 6991 * @returns {object} 6992 */ 6993 AgentLibrary.prototype.getWarmTransferRequest = function() { 6994 return UIModel.getInstance().warmXferRequest; 6995 }; 6996 /** 6997 * Get latest Cold Transfer Request object 6998 * @memberof AgentLibrary.Core.Requests 6999 * @returns {object} 7000 */ 7001 AgentLibrary.prototype.getColdTransferRequest = function() { 7002 return UIModel.getInstance().coldXferRequest; 7003 }; 7004 /** 7005 * Get latest Warm Transfer Cancel Request object 7006 * @memberof AgentLibrary.Core.Requests 7007 * @returns {object} 7008 */ 7009 AgentLibrary.prototype.getWarmTransferCancelRequest = function() { 7010 return UIModel.getInstance().warmXferCancelRequest; 7011 }; 7012 /** 7013 * Get latest Requeue Request object 7014 * @memberof AgentLibrary.Core.Requests 7015 * @returns {object} 7016 */ 7017 AgentLibrary.prototype.getRequeueRequest = function() { 7018 return UIModel.getInstance().requeueRequest; 7019 }; 7020 /** 7021 * Get latest Barge-In Request object 7022 * @memberof AgentLibrary.Core.Requests 7023 * @returns {object} 7024 */ 7025 AgentLibrary.prototype.getBargeInRequest = function() { 7026 return UIModel.getInstance().bargeInRequest; 7027 }; 7028 /** 7029 * Get latest Hold Request object 7030 * @memberof AgentLibrary.Core.Requests 7031 * @returns {object} 7032 */ 7033 AgentLibrary.prototype.getHoldRequest = function() { 7034 return UIModel.getInstance().holdRequest; 7035 }; 7036 /** 7037 * Get latest Pause Record Request object 7038 * @memberof AgentLibrary.Core.Requests 7039 * @returns {object} 7040 */ 7041 AgentLibrary.prototype.getPauseRecordRequest = function() { 7042 return UIModel.getInstance().pauseRecordRequest; 7043 }; 7044 /** 7045 * Get latest Record Request object 7046 * @memberof AgentLibrary.Core.Requests 7047 * @returns {object} 7048 */ 7049 AgentLibrary.prototype.getRecordRequest = function() { 7050 return UIModel.getInstance().recordRequest; 7051 }; 7052 /** 7053 * Get latest Chat Presented Request object 7054 * @memberof AgentLibrary.Core.Requests 7055 * @returns {object} 7056 */ 7057 AgentLibrary.prototype.getChatPresentedRequest = function() { 7058 return UIModel.getInstance().chatPresentedRequest; 7059 }; 7060 /** 7061 * Get latest Chat Disposition Request object 7062 * @memberof AgentLibrary.Core.Requests 7063 * @returns {object} 7064 */ 7065 AgentLibrary.prototype.getChatDispositionRequest = function() { 7066 return UIModel.getInstance().chatDispositionRequest; 7067 }; 7068 /** 7069 * Get latest Chat Message Request object 7070 * @memberof AgentLibrary.Core.Requests 7071 * @returns {object} 7072 */ 7073 AgentLibrary.prototype.getChatMessageRequest = function() { 7074 return UIModel.getInstance().chatMessageRequest; 7075 }; 7076 /** 7077 * Get latest Chat Requeue Request object 7078 * @memberof AgentLibrary.Core.Requests 7079 * @returns {object} 7080 */ 7081 AgentLibrary.prototype.getChatRequeueRequest = function() { 7082 return UIModel.getInstance().chatRequeueRequest; 7083 }; 7084 /** 7085 * Get latest Chat Typing Request object 7086 * @memberof AgentLibrary.Core.Requests 7087 * @returns {object} 7088 */ 7089 AgentLibrary.prototype.getChatTypingRequest = function() { 7090 return UIModel.getInstance().chatTypingRequest; 7091 }; 7092 /** 7093 * Get latest Agent Stats object 7094 * @memberof AgentLibrary.Core.Requests 7095 * @returns {object} 7096 */ 7097 AgentLibrary.prototype.getAgentStatsPacket = function() { 7098 return UIModel.getInstance().agentStatsPacket; 7099 }; 7100 /** 7101 * Get latest Agent Daily Stats object 7102 * @memberof AgentLibrary.Core.Requests 7103 * @returns {object} 7104 */ 7105 AgentLibrary.prototype.getAgentDailyStatsPacket = function() { 7106 return UIModel.getInstance().agentDailyStatsPacket; 7107 }; 7108 /** 7109 * Get latest Queue Stats object 7110 * @memberof AgentLibrary.Core.Requests 7111 * @returns {object} 7112 */ 7113 AgentLibrary.prototype.getQueueStatsPacket = function() { 7114 return UIModel.getInstance().queueStatsPacket; 7115 }; 7116 /** 7117 * Get latest Chat Queue Stats object 7118 * @memberof AgentLibrary.Core.Requests 7119 * @returns {object} 7120 */ 7121 AgentLibrary.prototype.getChatQueueStatsPacket = function() { 7122 return UIModel.getInstance().chatQueueStatsPacket; 7123 }; 7124 /** 7125 * Get latest Campaign Stats object 7126 * @memberof AgentLibrary.Core.Requests 7127 * @returns {object} 7128 */ 7129 AgentLibrary.prototype.getCampaignStatsPacket = function() { 7130 return UIModel.getInstance().campaignStatsPacket; 7131 }; 7132 /** 7133 * Get packet received on successful Login 7134 * @memberof AgentLibrary.Core.Requests 7135 * @returns {object} 7136 */ 7137 AgentLibrary.prototype.getLoginPacket = function() { 7138 return UIModel.getInstance().loginPacket; 7139 }; 7140 /** 7141 * Get packet received on successful Configuration (2nd layer login) 7142 * @memberof AgentLibrary.Core.Requests 7143 * @returns {object} 7144 */ 7145 AgentLibrary.prototype.getConfigPacket = function() { 7146 return UIModel.getInstance().configPacket; 7147 }; 7148 /** 7149 * Get latest received packet for Agent State 7150 * @memberof AgentLibrary.Core.Requests 7151 * @returns {object} 7152 */ 7153 AgentLibrary.prototype.getAgentStatePacket = function() { 7154 return UIModel.getInstance().agentStatePacket; 7155 }; 7156 /** 7157 * Get latest received packet for the Current Call 7158 * @memberof AgentLibrary.Core.Requests 7159 * @returns {object} 7160 */ 7161 AgentLibrary.prototype.getCurrentCallPacket = function() { 7162 return UIModel.getInstance().currentCallPacket; 7163 }; 7164 /** 7165 * Get latest received packet for initiating an offhook session 7166 * @memberof AgentLibrary.Core.Requests 7167 * @returns {object} 7168 */ 7169 AgentLibrary.prototype.getOffhookInitPacket = function() { 7170 return UIModel.getInstance().offhookInitPacket; 7171 }; 7172 /** 7173 * Get latest received packet for terminating an offhook session 7174 * @memberof AgentLibrary.Core.Requests 7175 * @returns {object} 7176 */ 7177 AgentLibrary.prototype.getOffhookTermPacket = function() { 7178 return UIModel.getInstance().offhookTermPacket; 7179 }; 7180 /** 7181 * Get chat agent end request class 7182 * @memberof AgentLibrary.Core.Requests 7183 * @returns {object} 7184 */ 7185 AgentLibrary.prototype.getChatAgentEnd = function(){ 7186 return UIModel.getInstance().chatAgentEnd; 7187 }; 7188 AgentLibrary.prototype.getChatListRequest = function(){ 7189 return UIModel.getInstance().chatListRequest; 7190 }; 7191 /** 7192 * @namespace Notifications 7193 * @memberof AgentLibrary.Core 7194 */ 7195 /////////////////// 7196 // notifications // 7197 /////////////////// 7198 /** 7199 * Get Dial Group Change notification class 7200 * @memberof AgentLibrary.Core.Notifications 7201 * @returns {object} 7202 */ 7203 AgentLibrary.prototype.getDialGroupChangeNotification = function() { 7204 return UIModel.getInstance().dialGroupChangeNotification; 7205 }; 7206 /** 7207 * Get Dial Group Change Pending notification class 7208 * @memberof AgentLibrary.Core.Notifications 7209 * @returns {object} 7210 */ 7211 AgentLibrary.prototype.getDialGroupChangePendingNotification = function() { 7212 return UIModel.getInstance().dialGroupChangePendingNotification; 7213 }; 7214 /** 7215 * Get End Call notification class 7216 * @memberof AgentLibrary.Core.Notifications 7217 * @returns {object} 7218 */ 7219 AgentLibrary.prototype.getEndCallNotification = function() { 7220 return UIModel.getInstance().endCallNotification; 7221 }; 7222 /** 7223 * Get Gates Change notification class 7224 * @memberof AgentLibrary.Core.Notifications 7225 * @returns {object} 7226 */ 7227 AgentLibrary.prototype.getGatesChangeNotification = function() { 7228 return UIModel.getInstance().gatesChangeNotification; 7229 }; 7230 /** 7231 * Get Generic notification class 7232 * @memberof AgentLibrary.Core.Notifications 7233 * @returns {object} 7234 */ 7235 AgentLibrary.prototype.getGenericNotification = function() { 7236 return UIModel.getInstance().genericNotification; 7237 }; 7238 /** 7239 * Get New Call notification class 7240 * @memberof AgentLibrary.Core.Notifications 7241 * @returns {object} 7242 */ 7243 AgentLibrary.prototype.getNewCallNotification = function() { 7244 return UIModel.getInstance().newCallNotification; 7245 }; 7246 /** 7247 * Get current call object 7248 * @memberof AgentLibrary.Core.Notifications 7249 * @returns {object} 7250 */ 7251 AgentLibrary.prototype.getCurrentCall = function() { 7252 return UIModel.getInstance().currentCall; 7253 }; 7254 /** 7255 * Get Add Session notification class 7256 * @memberof AgentLibrary.Core.Notifications 7257 * @returns {object} 7258 */ 7259 AgentLibrary.prototype.getAddSessionNotification = function() { 7260 return UIModel.getInstance().addSessionNotification; 7261 }; 7262 /** 7263 * Get Drop Session notification class 7264 * @memberof AgentLibrary.Core.Notifications 7265 * @returns {object} 7266 */ 7267 AgentLibrary.prototype.getDropSessionNotification = function() { 7268 return UIModel.getInstance().dropSessionNotification; 7269 }; 7270 /** 7271 * Get Early UII notification class 7272 * @memberof AgentLibrary.Core.Notifications 7273 * @returns {object} 7274 */ 7275 AgentLibrary.prototype.getEarlyUiiNotification = function() { 7276 return UIModel.getInstance().earlyUiiNotification; 7277 }; 7278 /** 7279 * Get Chat Active notification class 7280 * @memberof AgentLibrary.Core.Notifications 7281 * @returns {object} 7282 */ 7283 AgentLibrary.prototype.getChatActiveNotification = function() { 7284 return UIModel.getInstance().chatActiveNotification; 7285 }; 7286 /** 7287 * Get Chat Inactive notification class 7288 * @memberof AgentLibrary.Core.Notifications 7289 * @returns {object} 7290 */ 7291 AgentLibrary.prototype.getChatInactiveNotification = function() { 7292 return UIModel.getInstance().chatInactiveNotification; 7293 }; 7294 /** 7295 * Get Chat Inactive notification class 7296 * @memberof AgentLibrary.Core.Notifications 7297 * @returns {object} 7298 */ 7299 AgentLibrary.prototype.getChatClientReconnectNotification = function(){ 7300 return UIModel.getInstance().chatClientReconnectNotification; 7301 }; 7302 /** 7303 * Get Chat Presented notification class 7304 * @memberof AgentLibrary.Core.Notifications 7305 * @returns {object} 7306 */ 7307 AgentLibrary.prototype.getChatPresentedNotification = function() { 7308 return UIModel.getInstance().chatPresentedNotification; 7309 }; 7310 /** 7311 * Get Chat Typing notification class 7312 * @memberof AgentLibrary.Core.Notifications 7313 * @returns {object} 7314 */ 7315 AgentLibrary.prototype.getChatTypingNotification = function() { 7316 return UIModel.getInstance().chatTypingNotification; 7317 }; 7318 /** 7319 * Get New Chat notification class 7320 * @memberof AgentLibrary.Core.Notifications 7321 * @returns {object} 7322 */ 7323 AgentLibrary.prototype.getNewChatNotification = function() { 7324 return UIModel.getInstance().newChatNotification; 7325 }; 7326 /** 7327 * @namespace Settings 7328 * @memberof AgentLibrary.Core 7329 */ 7330 ////////////////////// 7331 // settings objects // 7332 ////////////////////// 7333 /** 7334 * Get Application Settings object containing the current state of application related data 7335 * @memberof AgentLibrary.Core.Settings 7336 * @returns {object} 7337 */ 7338 AgentLibrary.prototype.getApplicationSettings = function() { 7339 return UIModel.getInstance().applicationSettings; 7340 }; 7341 /** 7342 * Get Chat Settings object containing the current state of chat related data 7343 * @memberof AgentLibrary.Core.Settings 7344 * @returns {object} 7345 */ 7346 AgentLibrary.prototype.getChatSettings = function() { 7347 return UIModel.getInstance().chatSettings; 7348 }; 7349 /** 7350 * Get Connection Settings object containing the current state of connection related data 7351 * @memberof AgentLibrary.Core.Settings 7352 * @returns {object} 7353 */ 7354 AgentLibrary.prototype.getConnectionSettings = function() { 7355 return UIModel.getInstance().connectionSettings; 7356 }; 7357 /** 7358 * Get Inbound Settings object containing the current state of inbound related data 7359 * @memberof AgentLibrary.Core.Settings 7360 * @returns {object} 7361 */ 7362 AgentLibrary.prototype.getInboundSettings = function() { 7363 return UIModel.getInstance().inboundSettings; 7364 }; 7365 /** 7366 * Get Outbound Settings object containing the current state of outbound related data 7367 * @memberof AgentLibrary.Core.Settings 7368 * @returns {object} 7369 */ 7370 AgentLibrary.prototype.getOutboundSettings = function() { 7371 return UIModel.getInstance().outboundSettings; 7372 }; 7373 /** 7374 * Get Agent Settings object containing the current state of agent related data 7375 * @memberof AgentLibrary.Core.Settings 7376 * @returns {object} 7377 */ 7378 AgentLibrary.prototype.getAgentSettings = function() { 7379 return UIModel.getInstance().agentSettings; 7380 }; 7381 /** 7382 * Get Transfer Sessions 7383 * @memberof AgentLibrary.Core.Settings 7384 * @returns {object} 7385 */ 7386 AgentLibrary.prototype.getTransferSessions = function() { 7387 return UIModel.getInstance().transferSessions; 7388 }; 7389 AgentLibrary.prototype.getPendingSessions = function() { 7390 return UIModel.getInstance().pendingNewCallSessions; 7391 }; 7392 /** 7393 * Get the Agent Permissions object containing the current state of agent permissions 7394 * @memberof AgentLibrary.Core.Settings 7395 * @returns {object} 7396 */ 7397 AgentLibrary.prototype.getAgentPermissions = function() { 7398 return UIModel.getInstance().agentPermissions; 7399 }; 7400 /** 7401 * @namespace Stats 7402 * @memberof AgentLibrary.Core 7403 */ 7404 /////////////////// 7405 // stats objects // 7406 /////////////////// 7407 /** 7408 * Get the Agent stats object containing the current state of agent stats 7409 * @memberof AgentLibrary.Core.Settings 7410 * @returns {object} 7411 */ 7412 AgentLibrary.prototype.getAgentStats = function() { 7413 return UIModel.getInstance().agentStats; 7414 }; 7415 /** 7416 * Get the Agent Daily stats object containing the current state of agent daily stats 7417 * @memberof AgentLibrary.Core.Stats 7418 * @returns {object} 7419 */ 7420 AgentLibrary.prototype.getAgentDailyStats = function() { 7421 return UIModel.getInstance().agentDailyStats; 7422 }; 7423 /** 7424 * Get the Queue stats object containing the current state of queue stats 7425 * @memberof AgentLibrary.Core.Stats 7426 * @returns {object} 7427 */ 7428 AgentLibrary.prototype.getQueueStats = function() { 7429 return UIModel.getInstance().queueStats; 7430 }; 7431 /** 7432 * Get the Chat Queue stats object containing the current state of chat queue stats 7433 * @memberof AgentLibrary.Core.Stats 7434 * @returns {object} 7435 */ 7436 AgentLibrary.prototype.getChatQueueStats = function() { 7437 return UIModel.getInstance().chatQueueStats; 7438 }; 7439 /** 7440 * Get the Campaign stats object containing the current state of campaign stats 7441 * @memberof AgentLibrary.Core.Stats 7442 * @returns {object} 7443 */ 7444 AgentLibrary.prototype.getCampaignStats = function() { 7445 return UIModel.getInstance().campaignStats; 7446 }; 7447 /********************** 7448 * PRIVATE FUNCTIONS * 7449 **********************/ 7450 AgentLibrary.prototype._utils = utils; 7451 AgentLibrary.prototype._NewCallUtils = NewCallUtils; 7452 AgentLibrary.prototype._getUIModel= function() { 7453 return UIModel; 7454 }; 7455 } 7456 function initAgentLibrarySocket (context) { 7457 'use strict'; 7458 var AgentLibrary = context.AgentLibrary; 7459 AgentLibrary.prototype.openSocket = function(callback){ 7460 var instance = this; 7461 utils.setCallback(instance, CALLBACK_TYPES.OPEN_SOCKET, callback); 7462 if("WebSocket" in context){ 7463 if(!instance.socket){ 7464 var socketDest = UIModel.getInstance().applicationSettings.socketDest; 7465 utils.logMessage(LOG_LEVELS.DEBUG, "Attempting to open socket connection to " + socketDest, ""); 7466 instance.socket = new WebSocket(socketDest); 7467 instance.socket.onopen = function() { 7468 UIModel.getInstance().applicationSettings.socketConnected = true; 7469 utils.fireCallback(instance, CALLBACK_TYPES.OPEN_SOCKET, {reconnect:instance._isReconnect}); 7470 instance.socketOpened(); 7471 }; 7472 7473 instance.socket.onmessage = function(evt){ 7474 var data = JSON.parse(evt.data); 7475 if(data.ui_response){ 7476 utils.processResponse(instance, data); 7477 }else if(data.ui_notification){ 7478 utils.processNotification(instance, data); 7479 }else if(data.dialer_request){ 7480 utils.processDialerResponse(instance, data); 7481 }else if(data.ui_stats){ 7482 utils.processStats(instance, data); 7483 }else if(data.ui_request){ 7484 utils.processRequest(instance, data); 7485 } 7486 }; 7487 instance.socket.onclose = function(){ 7488 utils.fireCallback(instance, CALLBACK_TYPES.CLOSE_SOCKET, ''); 7489 UIModel.getInstance().applicationSettings.socketConnected = false; 7490 instance.socket = null; 7491 // cancel daily stats timer 7492 clearInterval(UIModel.getInstance().agentDailyIntervalId); 7493 UIModel.getInstance().agentDailyIntervalId = null; 7494 // cancel stats timer 7495 clearInterval(UIModel.getInstance().statsIntervalId); 7496 UIModel.getInstance().statsIntervalId = null; 7497 // if we are still logged in, set reconnect flag and try to reconnect 7498 if(UIModel.getInstance().agentSettings.isLoggedIn){ 7499 instance._isReconnect = true; 7500 console.warn("AgentLibrary: WebSocket is not connected, attempting to reconnect."); 7501 setTimeout(function(){ 7502 instance.openSocket(); 7503 }, 5000); 7504 } 7505 }; 7506 } 7507 }else{ 7508 utils.logMessage(LOG_LEVELS.WARN, "WebSocket NOT supported by your Browser", ""); 7509 } 7510 }; 7511 AgentLibrary.prototype.closeSocket = function(){ 7512 this.socket.close(); 7513 }; 7514 // when socket is successfully opened, check to see if there are any queued messaged 7515 // and if so, send them. 7516 AgentLibrary.prototype.socketOpened = function(){ 7517 var instance = this; 7518 var currDts = new Date(); 7519 var threeMins = 3 * 60 * 1000; // milliseconds 7520 var queuedMsg; 7521 // if this is a reconnect, we need to re-authenticate with IntelliServices & IntelliQueue 7522 if(instance._isReconnect){ 7523 instance._isReconnect = false; 7524 // Add IntelliQueue reconnect 7525 var configRequest = JSON.parse(UIModel.getInstance().configRequest.formatJSON()); 7526 var hashCode = UIModel.getInstance().connectionSettings.hashCode; 7527 configRequest.ui_request.hash_code = { 7528 "#text":hashCode 7529 }; 7530 configRequest.ui_request.update_login = { 7531 "#text": "FALSE" 7532 }; 7533 configRequest.ui_request.reconnect = { 7534 "#text": "TRUE" 7535 }; 7536 instance._queuedMsgs.unshift({dts: new Date(), msg: JSON.stringify(configRequest)}); 7537 // Add IntelliServices reconnect 7538 var loginRequest = JSON.parse(UIModel.getInstance().loginRequest.formatJSON()); 7539 var agentId = UIModel.getInstance().agentSettings.agentId; 7540 loginRequest.ui_request.reconnect = { 7541 "#text":"TRUE" 7542 }; 7543 loginRequest.ui_request.agent_id = { 7544 "#text": utils.toString(agentId) 7545 }; 7546 instance._queuedMsgs.unshift({dts: new Date(), msg: JSON.stringify(loginRequest)}); 7547 } 7548 for(var idx=0; idx < instance._queuedMsgs.length; idx++){ 7549 queuedMsg = instance._queuedMsgs[idx]; 7550 if(currDts.getTime() - queuedMsg.dts.getTime() < threeMins){ 7551 // message queued less than 3 mins ago, send 7552 utils.logMessage(LOG_LEVELS.DEBUG, "Sending queued message to IntelliSocket.", queuedMsg.msg); 7553 utils.sendMessage(instance,queuedMsg.msg); 7554 }else{ 7555 // message expired, don't send 7556 utils.logMessage(LOG_LEVELS.DEBUG, "Queued message expired, discarding.", queuedMsg.msg); 7557 } 7558 } 7559 // reset queued messages 7560 instance._queuedMsgs = []; 7561 }; 7562 } 7563 function initAgentLibraryAgent (context) { 7564 /** 7565 * @namespace Agent 7566 * @memberof AgentLibrary 7567 */ 7568 'use strict'; 7569 var AgentLibrary = context.AgentLibrary; 7570 /** 7571 * Sends agent login message to IntelliServices 7572 * @memberof AgentLibrary.Agent 7573 * @param {string} username Agent's username 7574 * @param {string} password Agent's password 7575 * @param {function} [callback=null] Callback function when loginAgent response received 7576 */ 7577 AgentLibrary.prototype.loginAgent = function(username, password, callback){ 7578 UIModel.getInstance().loginRequest = new LoginRequest(username, password); 7579 var msg = UIModel.getInstance().loginRequest.formatJSON(); 7580 utils.setCallback(this, CALLBACK_TYPES.LOGIN, callback); 7581 utils.sendMessage(this, msg); 7582 }; 7583 /** 7584 * Sends agent login message to IntelliServices, with flag to tell IntelliServices 7585 * that agent password is to be treated as case sensitive 7586 * @memberof AgentLibrary.Agent 7587 * @param {string} username Agent's username 7588 * @param {string} password Agent's password 7589 * @param {function} [callback=null] Callback function when loginAgent response received 7590 */ 7591 AgentLibrary.prototype.loginAgentCaseSensitive = function(username, password, callback){ 7592 UIModel.getInstance().loginRequest = new LoginRequest(username, password, true); 7593 var msg = UIModel.getInstance().loginRequest.formatJSON(); 7594 utils.setCallback(this, CALLBACK_TYPES.LOGIN, callback); 7595 utils.sendMessage(this, msg); 7596 }; 7597 /** 7598 * Sends agent configure message (2nd layer login) to IntelliQueue 7599 * @memberof AgentLibrary.Agent 7600 * @param {string} dialDest The agent's number, sip | DID. 7601 * @param {string[]} [queueIds=null] The queue ids the agent will be logged into. 7602 * @param {string[]} [chatIds=null] The chat ids the agent will be logged into. 7603 * @param {string} [skillProfileId=null] The skill profile the agent will be logged into. 7604 * @param {string} [dialGroupId=null] The outbound dial group id the agent will be logged into. 7605 * @param {string} [updateFromAdminUI=false] Whether the request is generated from the AdminUI or not. 7606 * @param {boolean} isForce Whether the agent login is forcing an existing agentlogin out. 7607 * @param {function} [callback=null] Callback function when configureAgent response received. 7608 */ 7609 AgentLibrary.prototype.configureAgent = function(dialDest, queueIds, chatIds, skillProfileId, dialGroupId, updateFromAdminUI, isForce, callback){ 7610 UIModel.getInstance().configRequest = new ConfigRequest(dialDest, queueIds, chatIds, skillProfileId, dialGroupId, updateFromAdminUI, isForce); 7611 var msg = UIModel.getInstance().configRequest.formatJSON(); 7612 utils.setCallback(this, CALLBACK_TYPES.CONFIG, callback); 7613 utils.sendMessage(this, msg); 7614 }; 7615 /** 7616 * Sends agent logout message to IntelliQueue 7617 * @memberof AgentLibrary.Agent 7618 * @param {number} agentId Id of the agent that will be logged out. 7619 * @param {function} [callback=null] Callback function when logoutAgent response received. 7620 */ 7621 AgentLibrary.prototype.logoutAgent = function(agentId, callback){ 7622 UIModel.getInstance().logoutRequest = new LogoutRequest(agentId); 7623 utils.setCallback(this, CALLBACK_TYPES.LOGOUT, callback); 7624 UIModel.getInstance().agentSettings.isLoggedIn = false; 7625 // Agent requested logout, just close socket?? 7626 utils.fireCallback(this, CALLBACK_TYPES.LOGOUT, ""); 7627 this.closeSocket(); 7628 }; 7629 /** 7630 * Sends agent logout for the given agent to logout message to IntelliQueue 7631 * @memberof AgentLibrary.Agent 7632 * @param {number} agentToLogout Id of the agent that will be logged out. 7633 * @param {number} [requestMessage=""] Message to send for the logout request. 7634 * @param {function} [callback=null] Callback function when logoutAgent response received. 7635 */ 7636 AgentLibrary.prototype.requestLogoutAgent = function(agentToLogout, requestMessage, callback){ 7637 var isSupervisor = UIModel.getInstance().agentSettings.agentType === 'SUPERVISOR'; 7638 UIModel.getInstance().logoutRequest = new LogoutRequest(agentToLogout, requestMessage, isSupervisor); 7639 utils.setCallback(this, CALLBACK_TYPES.LOGOUT, callback); 7640 if(UIModel.getInstance().logoutRequest.isSupervisor){ 7641 //This is a supervisor request to log an agent out. Create the 7642 //logout packet and then send the packet to IntelliQueue. 7643 var msg = UIModel.getInstance().logoutRequest.formatJSON(); 7644 utils.sendMessage(this, msg); 7645 } 7646 }; 7647 /** 7648 * Sends agent state change message to IntelliQueue 7649 * @memberof AgentLibrary.Agent 7650 * @param {string} agentState The system/base state to transition to <br /> 7651 * AVAILABLE | TRANSITION | ENGAGED | ON-BREAK | WORKING | AWAY | LUNCH | AUX-UNAVAIL-NO-OFFHOOK | AUX-UNAVAIL-OFFHOOK 7652 * @param {string} [agentAuxState=""] The aux state display label 7653 * @param {function} [callback=null] Callback function when agentState response received 7654 */ 7655 AgentLibrary.prototype.setAgentState = function(agentState, agentAuxState, callback){ 7656 UIModel.getInstance().agentStateRequest = new AgentStateRequest(agentState, agentAuxState); 7657 var msg = UIModel.getInstance().agentStateRequest.formatJSON(); 7658 utils.setCallback(this, CALLBACK_TYPES.AGENT_STATE, callback); 7659 utils.sendMessage(this, msg); 7660 }; 7661 /** 7662 * Initiates an agent offhook session 7663 * @memberof AgentLibrary.Agent 7664 * @param {function} [callback=null] Callback function when offhookInit response received 7665 */ 7666 AgentLibrary.prototype.offhookInit = function(callback){ 7667 UIModel.getInstance().offhookInitRequest = new OffhookInitRequest(); 7668 var msg = UIModel.getInstance().offhookInitRequest.formatJSON(); 7669 utils.setCallback(this, CALLBACK_TYPES.OFFHOOK_INIT, callback); 7670 utils.sendMessage(this, msg); 7671 }; 7672 /** 7673 * Terminates agent's offhook session 7674 * @memberof AgentLibrary.Agent 7675 * @param {function} [callback=null] Callback function when pending callbacks response received 7676 */ 7677 AgentLibrary.prototype.offhookTerm = function(callback){ 7678 UIModel.getInstance().offhookTermRequest = new OffhookTermRequest(); 7679 var msg = UIModel.getInstance().offhookTermRequest.formatJSON(); 7680 utils.setCallback(this, CALLBACK_TYPES.OFFHOOK_TERM, callback); 7681 utils.sendMessage(this, msg); 7682 }; 7683 /** 7684 * Returns scheduled callbacks for the given agent 7685 * @memberof AgentLibrary.Agent 7686 * @param {number} [agentId=logged in agent id] Id of agent to get callbacks for 7687 * @param {function} [callback=null] Callback function when pending callbacks response received 7688 */ 7689 AgentLibrary.prototype.getPendingCallbacks = function(agentId, callback){ 7690 UIModel.getInstance().callbacksPendingRequest = new CallbacksPendingRequest(agentId); 7691 var msg = UIModel.getInstance().callbacksPendingRequest.formatJSON(); 7692 utils.setCallback(this, CALLBACK_TYPES.CALLBACK_PENDING, callback); 7693 utils.sendMessage(this, msg); 7694 }; 7695 /** 7696 * Cancel a scheduled callback for the given agent based on lead id 7697 * @memberof AgentLibrary.Agent 7698 * @param {number} leadId Id of lead callback to cancel 7699 * @param {number} [agentId=logged in agent id] Id of agent to cancel specified lead callback for 7700 * @param {function} [callback=null] Callback function when callback is canceled 7701 */ 7702 AgentLibrary.prototype.cancelCallback = function(leadId, agentId, callback){ 7703 UIModel.getInstance().callbackCancelRequest = new CallbackCancelRequest(leadId, agentId); 7704 var msg = UIModel.getInstance().callbackCancelRequest.formatJSON(); 7705 utils.setCallback(this, CALLBACK_TYPES.CALLBACK_CANCEL, callback); 7706 utils.sendMessage(this, msg); 7707 }; 7708 /** 7709 * Request stats messages to be sent every 5 seconds. The stats responses will be sent as 7710 * four possible callback types: agentStats, agentDailyStats, campaignStats, or queueStats 7711 * @memberof AgentLibrary.Agent 7712 */ 7713 AgentLibrary.prototype.requestStats = function(){ 7714 // start stats interval timer, request stats every 5 seconds 7715 if(UIModel.getInstance().statsIntervalId === null) { 7716 UIModel.getInstance().statsIntervalId = setInterval(utils.sendStatsRequestMessage, 5000); 7717 } 7718 }; 7719 /** 7720 * Terminate stats messages sent to the agent every 5 seconds. 7721 * @memberof AgentLibrary.Agent 7722 */ 7723 AgentLibrary.prototype.terminateStats = function(){ 7724 clearInterval(UIModel.getInstance().statsIntervalId); 7725 UIModel.getInstance().statsIntervalId = null; 7726 }; 7727 /** 7728 * Set the agent dial destination 7729 * @memberof AgentLibrary.Agent 7730 * @param {string} dialDest The dial destination used for softphone registration 7731 * @param {boolean} isSoftphoneError True - if we want to log this dial destination update as a softphone error 7732 */ 7733 AgentLibrary.prototype.updateDialDestination = function(dialDest, isSoftphoneError){ 7734 UIModel.getInstance().updateDialDestinationRequest = new UpdateDialDestinationRequest(dialDest, isSoftphoneError); 7735 var msg = UIModel.getInstance().updateDialDestinationRequest.formatJSON(); 7736 utils.sendMessage(this, msg); 7737 }; 7738 } 7739 function initAgentLibraryCall (context) { 7740 /** 7741 * @namespace Call 7742 * @memberof AgentLibrary 7743 */ 7744 'use strict'; 7745 var AgentLibrary = context.AgentLibrary; 7746 /** 7747 * Barge in on a call, can hear all parties and be heard by all 7748 * @memberof AgentLibrary.Call 7749 * @param {number} agentId Agent Id of the current logged in agent 7750 * @param {string} uii UII of the active call you wish to monitor 7751 * @param {number} monitorAgentId UII Agent Id of the agent you wish to monitor 7752 * @param {function} [callback=null] Callback function when barge in response received 7753 */ 7754 AgentLibrary.prototype.bargeIn = function(agentId, uii, monitorAgentId, callback){ 7755 UIModel.getInstance().bargeInRequest = new BargeInRequest("FULL", agentId, uii, monitorAgentId); 7756 var msg = UIModel.getInstance().bargeInRequest.formatJSON(); 7757 utils.setCallback(this, CALLBACK_TYPES.BARGE_IN, callback); 7758 utils.sendMessage(this, msg); 7759 }; 7760 /** 7761 * Add a coaching session to the call, can hear all parties but only able to speak on agent channel 7762 * @memberof AgentLibrary.Call 7763 * @param {number} agentId Agent Id of the current logged in agent 7764 * @param {string} uii UII of the active call you wish to monitor 7765 * @param {number} monitorAgentId UII Agent Id of the agent you wish to monitor 7766 * @param {function} [callback=null] Callback function when coaching session response received 7767 */ 7768 AgentLibrary.prototype.coach = function(agentId, uii, monitorAgentId, callback){ 7769 UIModel.getInstance().bargeInRequest = new BargeInRequest("COACHING", agentId, uii, monitorAgentId); 7770 var msg = UIModel.getInstance().bargeInRequest.formatJSON(); 7771 utils.setCallback(this, CALLBACK_TYPES.COACH_CALL, callback); 7772 utils.sendMessage(this, msg); 7773 }; 7774 /** 7775 * Transfer to another number and end the call for the original agent (cold transfer). 7776 * @memberof AgentLibrary.Call 7777 * @param {number} dialDest Number to transfer to 7778 * @param {number} [callerId=""] Caller Id for caller (DNIS) 7779 * @param {number} [sipHeaders=[]] Name/Value header pairs 7780 * @param {function} [callback=null] Callback function when cold transfer response received 7781 */ 7782 AgentLibrary.prototype.coldXfer = function(dialDest, callerId, sipHeaders, callback){ 7783 UIModel.getInstance().coldXferRequest = new XferColdRequest(dialDest, callerId, sipHeaders); 7784 var msg = UIModel.getInstance().coldXferRequest.formatJSON(); 7785 utils.setCallback(this, CALLBACK_TYPES.XFER_COLD, callback); 7786 utils.sendMessage(this, msg); 7787 }; 7788 /** 7789 * Transfer to another number and end the call for the original agent (cold transfer). 7790 * @memberof AgentLibrary.Call 7791 * @param {number} dialDest Number to transfer to 7792 * @param {number} [callerId=""] Caller Id for caller (DNIS) 7793 * @param {number} [sipHeaders=[]] Name/Value header pairs 7794 * @param {number} [countryId=""] Country Id for the dialDest 7795 * @param {function} [callback=null] Callback function when warm transfer response received 7796 */ 7797 AgentLibrary.prototype.internationalColdXfer = function(dialDest, callerId, sipHeaders, countryId, callback){ 7798 UIModel.getInstance().coldXferRequest = new XferColdRequest(dialDest, callerId, sipHeaders, countryId); 7799 var msg = UIModel.getInstance().coldXferRequest.formatJSON(); 7800 utils.setCallback(this, CALLBACK_TYPES.XFER_COLD, callback); 7801 utils.sendMessage(this, msg); 7802 }; 7803 /** 7804 * Send a disposition for an inbound or outbound call 7805 * @memberof AgentLibrary.Call 7806 * @param {string} uii UII (unique id) for call 7807 * @param {string} dispId The disposition id 7808 * @param {string} notes Agent notes for call 7809 * @param {boolean} callback Boolean for whether or not this call is a callback 7810 * @param {string} [callbackDTS=""] date time stamp if callback 7811 * @param {string} [contactForwardNumber=null] Number for contact forwarding 7812 * @param {string} [survey=null] The survey response values for the call. 7813 * Format: survey = [ { label: "", externId: "", leadUpdateColumn: ""} ] 7814 * @param {string} [externId=null] The external id associated with the lead for this call (only for Outbound Dispositions). 7815 * @param {string} [leadId=null] The lead id associated with this call (only for Outbound Dispositions). 7816 * @param {string} [requestId=null] The request id associated with a preview fetched lead (only for Outbound Dispositions). 7817 */ 7818 AgentLibrary.prototype.dispositionCall = function(uii, dispId, notes, callback, callbackDTS, contactForwardNumber, survey, externId, leadId, requestId){ 7819 var model = UIModel.getInstance(); 7820 model.dispositionRequest = new DispositionRequest(uii, dispId, notes, callback, callbackDTS, contactForwardNumber, survey, externId, leadId, requestId); 7821 var msg = model.dispositionRequest.formatJSON(); 7822 utils.sendMessage(this, msg); 7823 // cancel ping call timer 7824 if(model.pingIntervalId){ 7825 clearInterval(model.pingIntervalId); 7826 model.pingIntervalId = null; 7827 } 7828 }; 7829 /** 7830 * Send a disposition for a manual pass on a lead 7831 * @memberof AgentLibrary.Call 7832 * @param {string} dispId The disposition id 7833 * @param {string} notes Agent notes for call 7834 * @param {boolean} callback Boolean for whether or not this call is a callback 7835 * @param {string} [callbackDTS=""] date time stamp if callback 7836 * @param {string} [leadId=null] The lead id 7837 * @param {string} [requestId=null] The request key for the lead 7838 * @param {string} [externId=null] The external id of the lead 7839 */ 7840 AgentLibrary.prototype.dispositionManualPass = function(dispId, notes, callback, callbackDTS, leadId, requestId, externId){ 7841 UIModel.getInstance().dispositionManualPassRequest = new DispositionManualPassRequest(dispId, notes, callback, callbackDTS, leadId, requestId, externId); 7842 var msg = UIModel.getInstance().dispositionManualPassRequest.formatJSON(); 7843 utils.sendMessage(this, msg); 7844 }; 7845 /** 7846 * Get a list of all campaign dispositions for given campaign id 7847 * @memberof AgentLibrary.Call 7848 * @param {string} campaignId Id for campaign to get dispositions for 7849 * @param {function} [callback=null] Callback function when campaign dispositions response received 7850 */ 7851 AgentLibrary.prototype.getCampaignDispositions = function(campaignId, callback){ 7852 UIModel.getInstance().campaignDispositionsRequest = new CampaignDispositionsRequest(campaignId); 7853 var msg = UIModel.getInstance().campaignDispositionsRequest.formatJSON(); 7854 utils.setCallback(this, CALLBACK_TYPES.CAMPAIGN_DISPOSITIONS, callback); 7855 utils.sendMessage(this, msg); 7856 }; 7857 /** 7858 * Sends a hangup request message 7859 * @memberof AgentLibrary.Call 7860 * @param {string} [sessionId=""] Session to hangup, defaults to current call session id 7861 * @param {boolean} resetPendingDisp, reset pendingDisp to false, in case of bad reconnect 7862 */ 7863 AgentLibrary.prototype.hangup = function(sessionId, resetPendingDisp){ 7864 UIModel.getInstance().hangupRequest = new HangupRequest(sessionId, resetPendingDisp); 7865 var msg = UIModel.getInstance().hangupRequest.formatJSON(); 7866 utils.sendMessage(this, msg); 7867 }; 7868 /** 7869 * Place a call on hold 7870 * @memberof AgentLibrary.Call 7871 * @param {boolean} holdState Whether we are putting call on hold or taking off hold - values true | false 7872 * @param {function} [callback=null] Callback function when hold response received 7873 */ 7874 AgentLibrary.prototype.hold = function(holdState, callback){ 7875 UIModel.getInstance().holdRequest = new HoldRequest(holdState); 7876 var msg = UIModel.getInstance().holdRequest.formatJSON(); 7877 utils.setCallback(this, CALLBACK_TYPES.HOLD, callback); 7878 utils.sendMessage(this, msg); 7879 }; 7880 /** 7881 * Place a specified session of a call on hold 7882 * @memberof AgentLibrary.Call 7883 * @param {boolean} holdState Whether we are putting call on hold or taking off hold - values true | false 7884 * @param {integer|string} sessionId session id of the call to place on hold 7885 * @param {function} [callback=null] Callback function when hold response received 7886 */ 7887 AgentLibrary.prototype.holdSession = function(holdState, sessionId, callback){ 7888 UIModel.getInstance().holdRequest = new HoldRequest(holdState, sessionId); 7889 var msg = UIModel.getInstance().holdRequest.formatJSON(); 7890 utils.setCallback(this, CALLBACK_TYPES.HOLD, callback); 7891 utils.sendMessage(this, msg); 7892 }; 7893 /** 7894 * Sends a manual outdial request message 7895 * @memberof AgentLibrary.Call 7896 * @param {string} destination Number to call - ANI 7897 * @param {number} callerId Number displayed to callee, DNIS 7898 * @param {number} [ringTime=60] Time in seconds to ring call 7899 * @param {string} [countryId='USA'] Country for the destination number 7900 * @param {number} [queueId=''] Queue id to tie manual call to 7901 */ 7902 AgentLibrary.prototype.manualOutdial = function(destination, callerId, ringTime, countryId, queueId){ 7903 UIModel.getInstance().oneToOneOutdialRequest = new OneToOneOutdialRequest(destination, callerId, ringTime, countryId, queueId); 7904 var msg = UIModel.getInstance().oneToOneOutdialRequest.formatJSON(); 7905 utils.sendMessage(this, msg); 7906 }; 7907 /** 7908 * Cancels a manual outdial request by UII. 7909 * @memberof AgentLibrary.Call 7910 * @param {string} uii UII of manual call request, the UII is returned in the EARLY_UII notification. 7911 */ 7912 AgentLibrary.prototype.manualOutdialCancel = function(uii){ 7913 UIModel.getInstance().oneToOneOutdialCancelRequest = new OneToOneOutdialCancelRequest(uii); 7914 var msg = UIModel.getInstance().oneToOneOutdialCancelRequest.formatJSON(); 7915 utils.sendMessage(this, msg); 7916 }; 7917 /** 7918 * Pause call recording 7919 * @memberof AgentLibrary.Call 7920 * @param {boolean} record Whether we are recording or not 7921 * @param {function} [callback=null] Callback function when pause record response received 7922 */ 7923 AgentLibrary.prototype.pauseRecord = function(record, callback){ 7924 UIModel.getInstance().pauseRecordRequest = new PauseRecordRequest(record); 7925 var msg = UIModel.getInstance().pauseRecordRequest.formatJSON(); 7926 utils.setCallback(this, CALLBACK_TYPES.PAUSE_RECORD, callback); 7927 utils.sendMessage(this, msg); 7928 }; 7929 /** 7930 * Sends a preview dial request to call lead based on request id and (optional) lead phone. 7931 * Call previewFetch method first to get request id. 7932 * @memberof AgentLibrary.Call 7933 * @param {number} requestId Pending request id sent back with lead, required to dial lead. 7934 * @param {number} [leadPhone=""] Lead phone number. Only needed if there are multiple numbers loaded for given lead. 7935 */ 7936 AgentLibrary.prototype.previewDial = function(requestId, leadPhone){ 7937 UIModel.getInstance().previewDialRequest = new PreviewDialRequest("", [], requestId, leadPhone); 7938 var msg = UIModel.getInstance().previewDialRequest.formatJSON(); 7939 utils.sendMessage(this, msg); 7940 }; 7941 /** 7942 * Sends a message to fetch preview dialable leads 7943 * @memberof AgentLibrary.Call 7944 * @param {array} [searchFields=[]] Array of objects with key/value pairs for search parameters 7945 * e.g. [ {key: "name", value: "Geoff"} ] 7946 * @param {function} [callback=null] Callback function when preview fetch completed, returns matched leads 7947 */ 7948 AgentLibrary.prototype.previewFetch = function(searchFields, callback){ 7949 UIModel.getInstance().previewDialRequest = new PreviewDialRequest("", searchFields, ""); 7950 var msg = UIModel.getInstance().previewDialRequest.formatJSON(); 7951 utils.setCallback(this, CALLBACK_TYPES.PREVIEW_FETCH, callback); 7952 utils.sendMessage(this, msg); 7953 }; 7954 /** 7955 * Pull back leads that match search criteria 7956 * @memberof AgentLibrary.Call 7957 * @param {array} [searchFields=[]] Array of objects with key/value pairs for search parameters 7958 * e.g. [ {key: "name", value: "Geoff"} ] 7959 * @param {function} [callback=null] Callback function when lead search completed, returns matched leads 7960 */ 7961 AgentLibrary.prototype.searchLeads = function(searchFields, callback){ 7962 UIModel.getInstance().previewDialRequest = new PreviewDialRequest("search", searchFields, ""); 7963 var msg = UIModel.getInstance().previewDialRequest.formatJSON(); 7964 utils.setCallback(this, CALLBACK_TYPES.LEAD_SEARCH, callback); 7965 utils.sendMessage(this, msg); 7966 }; 7967 /** 7968 * Set agent notes for a call 7969 * @memberof AgentLibrary.Call 7970 * @param {string} notes Agent notes to add to call 7971 * @param {function} [callback=null] Callback function when call notes response received 7972 */ 7973 AgentLibrary.prototype.setCallNotes = function(notes, callback){ 7974 UIModel.getInstance().callNotesRequest = new CallNotesRequest(notes); 7975 var msg = UIModel.getInstance().callNotesRequest.formatJSON(); 7976 utils.setCallback(this, CALLBACK_TYPES.CALL_NOTES, callback); 7977 utils.sendMessage(this, msg); 7978 }; 7979 /** 7980 * Add a silent monitor session to a call, can hear all channels but can't be heard by any party 7981 * @memberof AgentLibrary.Call 7982 * @param {number} agentId Agent Id of the current logged in agent 7983 * @param {string} uii UII of the active call you wish to monitor 7984 * @param {number} monitorAgentId UII Agent Id of the agent you wish to monitor 7985 * @param {function} [callback=null] Callback function when silent monitor response received 7986 */ 7987 AgentLibrary.prototype.monitor = function(agentId, uii, monitorAgentId, callback){ 7988 UIModel.getInstance().bargeInRequest = new BargeInRequest("MUTE", agentId, uii, monitorAgentId); 7989 var msg = UIModel.getInstance().bargeInRequest.formatJSON(); 7990 utils.setCallback(this, CALLBACK_TYPES.SILENT_MONITOR, callback); 7991 utils.sendMessage(this, msg); 7992 }; 7993 /** 7994 * Toggle call recording based on passed in boolean true | false 7995 * @memberof AgentLibrary.Call 7996 * @param {boolean} record Whether we are recording or not 7997 * @param {function} [callback=null] Callback function when record response received 7998 */ 7999 AgentLibrary.prototype.record = function(record, callback){ 8000 UIModel.getInstance().recordRequest = new RecordRequest(record); 8001 var msg = UIModel.getInstance().recordRequest.formatJSON(); 8002 utils.setCallback(this, CALLBACK_TYPES.RECORD, callback); 8003 utils.sendMessage(this, msg); 8004 }; 8005 /** 8006 * Requeue a call 8007 * @memberof AgentLibrary.Call 8008 * @param {number} queueId Queue Id to send the call to 8009 * @param {number} skillId Skill Id for the requeued call 8010 * @param {boolean} maintain Whether or not to maintain the current agent 8011 * @param {function} [callback=null] Callback function when requeue response received 8012 */ 8013 AgentLibrary.prototype.requeueCall = function(queueId, skillId, maintain, callback){ 8014 UIModel.getInstance().requeueRequest = new RequeueRequest(queueId, skillId, maintain); 8015 var msg = UIModel.getInstance().requeueRequest.formatJSON(); 8016 utils.setCallback(this, CALLBACK_TYPES.REQUEUE, callback); 8017 utils.sendMessage(this, msg); 8018 }; 8019 /** 8020 * Sends a TCPA Safe call request to call lead based on request id and (optional) lead phone. 8021 * Call safeModeFetch method first to get request id. 8022 * @memberof AgentLibrary.Call 8023 * @param {number} requestId Pending request id sent back with lead, required to dial lead. 8024 * @param {number} [leadPhone=""] Lead phone number. Only needed if there are multiple numbers loaded for given lead. 8025 */ 8026 AgentLibrary.prototype.safeModeCall = function(requestId, leadPhone){ 8027 UIModel.getInstance().tcpaSafeRequest = new TcpaSafeRequest("", [], requestId, leadPhone); 8028 var msg = UIModel.getInstance().tcpaSafeRequest.formatJSON(); 8029 utils.sendMessage(this, msg); 8030 }; 8031 /** 8032 * Sends a message to fetch safe mode dialable leads 8033 * @memberof AgentLibrary.Call 8034 * @param {array} [searchFields=[]] Array of objects with key/value pairs for search parameters 8035 * e.g. [ {key: "name", value: "Geoff"} ] 8036 * @param {function} [callback=null] Callback function when safe mode fetch completed, returns matched leads 8037 */ 8038 AgentLibrary.prototype.safeModeFetch = function(searchFields, callback){ 8039 UIModel.getInstance().tcpaSafeRequest = new TcpaSafeRequest("", searchFields, ""); 8040 var msg = UIModel.getInstance().tcpaSafeRequest.formatJSON(); 8041 utils.setCallback(this, CALLBACK_TYPES.SAFE_MODE_FETCH, callback); 8042 utils.sendMessage(this, msg); 8043 }; 8044 /** 8045 * Pull back Safe Mode leads that match search criteria 8046 * @memberof AgentLibrary.Call 8047 * @param {array} [searchFields=[]] Array of objects with key/value pairs for search parameters 8048 * e.g. [ {key: "name", value: "Geoff"} ] 8049 * @param {function} [callback=null] Callback function when safe mode fetch completed, returns matched leads 8050 */ 8051 AgentLibrary.prototype.safeSearchLeads = function(searchFields, callback){ 8052 UIModel.getInstance().tcpaSafeRequest = new TcpaSafeRequest("search", searchFields, ""); 8053 var msg = UIModel.getInstance().tcpaSafeRequest.formatJSON(); 8054 utils.setCallback(this, CALLBACK_TYPES.SAFE_MODE_SEARCH, callback); 8055 utils.sendMessage(this, msg); 8056 }; 8057 /** 8058 * Transfer to another number while keeping the original agent on the line (warm transfer). 8059 * @memberof AgentLibrary.Call 8060 * @param {number} dialDest Number to transfer to 8061 * @param {number} [callerId=""] Caller Id for caller (DNIS) 8062 * @param {number} [sipHeaders=[]] Name/Value header pairs 8063 * @param {number} [countryId=""] Country Id for the dialDest 8064 * @param {function} [callback=null] Callback function when warm transfer response received 8065 */ 8066 AgentLibrary.prototype.internationalWarmXfer = function(dialDest, callerId, sipHeaders, countryId, callback){ 8067 UIModel.getInstance().warmXferRequest = new XferWarmRequest(dialDest, callerId, sipHeaders, countryId); 8068 var msg = UIModel.getInstance().warmXferRequest.formatJSON(); 8069 utils.setCallback(this, CALLBACK_TYPES.XFER_WARM, callback); 8070 utils.sendMessage(this, msg); 8071 }; 8072 /** 8073 * Transfer to another number while keeping the original agent on the line (warm transfer). 8074 * @memberof AgentLibrary.Call 8075 * @param {number} dialDest Number to transfer to 8076 * @param {number} [callerId=""] Caller Id for caller (DNIS) 8077 * @param {number} [sipHeaders=[]] Name/Value header pairs 8078 * @param {function} [callback=null] Callback function when warm transfer response received 8079 */ 8080 AgentLibrary.prototype.warmXfer = function(dialDest, callerId, sipHeaders, callback){ 8081 UIModel.getInstance().warmXferRequest = new XferWarmRequest(dialDest, callerId, sipHeaders); 8082 var msg = UIModel.getInstance().warmXferRequest.formatJSON(); 8083 utils.setCallback(this, CALLBACK_TYPES.XFER_WARM, callback); 8084 utils.sendMessage(this, msg); 8085 }; 8086 /** 8087 * Cancel a warm transfer 8088 * @memberof AgentLibrary.Call 8089 * @param {number} dialDest Number that was transfered to 8090 */ 8091 AgentLibrary.prototype.warmXferCancel = function(dialDest){ 8092 UIModel.getInstance().warmXferCancelRequest = new XferWarmCancelRequest(dialDest); 8093 var msg = UIModel.getInstance().warmXferCancelRequest.formatJSON(); 8094 utils.sendMessage(this, msg); 8095 }; 8096 /** 8097 * Requests a script object based on given id 8098 * @memberof AgentLibrary.Call 8099 * @param {number} scriptId Id of script 8100 * @param {number} version The version number of the script, if the current loaded script version matches, 8101 * just return current script. Otherwise, fetch new version of script. 8102 * @param {function} [callback=null] Callback function when warm transfer response received 8103 */ 8104 AgentLibrary.prototype.getScript = function(scriptId, version, callback){ 8105 var model = UIModel.getInstance(); 8106 var script = model.scriptSettings.loadedScripts[scriptId]; 8107 utils.setCallback(this, CALLBACK_TYPES.SCRIPT_CONFIG, callback); 8108 if(script && script.version === version){ 8109 // return from memory 8110 var savedScript = UIModel.getInstance().scriptSettings.loadedScripts[scriptId]; 8111 callback(savedScript); 8112 }else{ 8113 // load script 8114 model.scriptConfigRequest = new ScriptConfigRequest(scriptId); 8115 var msg = UIModel.getInstance().scriptConfigRequest.formatJSON(); 8116 utils.sendMessage(this, msg); 8117 } 8118 }; 8119 /** 8120 * Saves the results from a script 8121 * @memberof AgentLibrary.Call 8122 * @param {string} uii The UII of the call the script results belong to 8123 * @param {number} scriptId Id of script 8124 * @param {object} jsonResult JSON object of script results, name/value pairs 8125 */ 8126 AgentLibrary.prototype.saveScriptResult = function(uii, scriptId, jsonResult){ 8127 UIModel.getInstance().scriptResultRequest = new ScriptResultRequest(uii, scriptId, jsonResult); 8128 var msg = UIModel.getInstance().scriptResultRequest.formatJSON(); 8129 utils.sendMessage(this, msg); 8130 }; 8131 /** 8132 * Get available list of agents available for Direct Transfer 8133 * @memberof AgentLibrary.Call 8134 */ 8135 AgentLibrary.prototype.directAgentXferList = function(callback) { 8136 UIModel.getInstance().directAgentTransferListRequest = new DirectAgentTransferList(); 8137 var msg = UIModel.getInstance().directAgentTransferListRequest.formatJSON(); 8138 utils.setCallback(this, CALLBACK_TYPES.DIRECT_AGENT_TRANSFER_LIST, callback); 8139 utils.sendMessage(this, msg); 8140 }; 8141 /** 8142 * Transfer directly to an available agent from the directAgentXferList result and stay on the call 8143 * @memberof AgentLibrary.Call 8144 * @param {number} targetAgentId Agent id to transfer the call to 8145 */ 8146 AgentLibrary.prototype.warmDirectAgentXfer = function(targetAgentId) { 8147 UIModel.getInstance().directAgentTransferRequest = new DirectAgentTransfer(targetAgentId, 'WARM'); 8148 var msg = UIModel.getInstance().directAgentTransferRequest.formatJSON(); 8149 utils.sendMessage(this, msg); 8150 }; 8151 /** 8152 * Transfer directly to an available agent from the directAgentXferList result 8153 * and terminate the current agents call session 8154 * @memberof AgentLibrary.Call 8155 * @param {number} targetAgentId Agent id to transfer the call to 8156 */ 8157 AgentLibrary.prototype.coldDirectAgentXfer = function(targetAgentId) { 8158 UIModel.getInstance().directAgentTransferRequest = new DirectAgentTransfer(targetAgentId, 'COLD'); 8159 var msg = UIModel.getInstance().directAgentTransferRequest.formatJSON(); 8160 utils.sendMessage(this, msg); 8161 }; 8162 /** 8163 * Cancel the request to transfer directly to an agent 8164 * @memberof AgentLibrary.Call 8165 * @param {number} targetAgentId Agent id to transfer the call to 8166 */ 8167 AgentLibrary.prototype.cancelDirectAgentXfer = function(targetAgentId) { 8168 UIModel.getInstance().directAgentTransferRequest = new DirectAgentTransfer(targetAgentId, 'CANCEL'); 8169 var msg = UIModel.getInstance().directAgentTransferRequest.formatJSON(); 8170 utils.sendMessage(this, msg); 8171 }; 8172 /** 8173 * Send the direct agent transfer straight to voicemail, avoid any attempts to connect to the target agent 8174 * @memberof AgentLibrary.Call 8175 * @param {number} targetAgentId Agent id to receive the voicemail 8176 */ 8177 AgentLibrary.prototype.voicemailDirectAgentXfer = function(targetAgentId) { 8178 UIModel.getInstance().directAgentTransferRequest = new DirectAgentTransfer(targetAgentId, 'VOICEMAIL'); 8179 var msg = UIModel.getInstance().directAgentTransferRequest.formatJSON(); 8180 utils.sendMessage(this, msg); 8181 }; 8182 /** 8183 * Reject a presented direct agent transfer, if WARM requesting agent will be notified to try again, 8184 * if COLD a voicemail will be left for the target agent 8185 * @memberof AgentLibrary.Call 8186 * @param {number} targetAgentId Agent id to receive the voicemail 8187 */ 8188 AgentLibrary.prototype.rejectDirectAgentXfer = function(uii) { 8189 UIModel.getInstance().directAgentTransferRequest = new DirectAgentTransfer('0', 'REJECT', uii); 8190 var msg = UIModel.getInstance().directAgentTransferRequest.formatJSON(); 8191 utils.sendMessage(this, msg); 8192 }; 8193 } 8194 function initAgentLibraryLead (context) { 8195 /** 8196 * @namespace Lead 8197 * @memberof AgentLibrary 8198 */ 8199 8200 'use strict'; 8201 var AgentLibrary = context.AgentLibrary; 8202 /** 8203 * Get the history for a given lead 8204 * @memberof AgentLibrary.Lead 8205 * @param {number} leadId The lead id to retrieve history for 8206 * @param {function} [callback=null] Callback function when lead history response received 8207 */ 8208 AgentLibrary.prototype.leadHistory = function(leadId, callback){ 8209 UIModel.getInstance().leadHistoryRequest = new LeadHistoryRequest(leadId); 8210 var msg = UIModel.getInstance().leadHistoryRequest.formatJSON(); 8211 utils.setCallback(this, CALLBACK_TYPES.LEAD_HISTORY, callback); 8212 utils.sendMessage(this, msg); 8213 }; 8214 /** 8215 * Insert a lead to the given campaign 8216 * @memberof AgentLibrary.Lead 8217 * @param {object} dataObj agentId, campaignId, and lead info 8218 * @param {function} [callback=null] Callback function when lead history response received 8219 */ 8220 AgentLibrary.prototype.leadInsert = function(dataObj, callback){ 8221 UIModel.getInstance().leadInsertRequest = new LeadInsertRequest(dataObj); 8222 var msg = UIModel.getInstance().leadInsertRequest.formatJSON(); 8223 utils.setCallback(this, CALLBACK_TYPES.LEAD_INSERT, callback); 8224 utils.sendMessage(this, msg); 8225 }; 8226 /** 8227 * Update lead information 8228 * @memberof AgentLibrary.Lead 8229 * @param {string} leadId Id for lead to update 8230 * @param {string} leadPhone Lead phone number 8231 * @param {object} baggage Object containing lead information 8232 * @param {function} [callback=null] Callback function when lead history response received 8233 */ 8234 AgentLibrary.prototype.leadUpdate = function(leadId, leadPhone, baggage, callback){ 8235 UIModel.getInstance().leadUpdateRequest = new LeadUpdateRequest(leadId, leadPhone, baggage); 8236 var msg = UIModel.getInstance().leadUpdateRequest.formatJSON(); 8237 utils.setCallback(this, CALLBACK_TYPES.LEAD_UPDATE, callback); 8238 utils.sendMessage(this, msg); 8239 }; 8240 } 8241 function initAgentLibraryChat (context) { 8242 /** 8243 * @namespace Chat 8244 * @memberof AgentLibrary 8245 */ 8246 'use strict'; 8247 var AgentLibrary = context.AgentLibrary; 8248 /** 8249 * Set the agent chat alias 8250 * @memberof AgentLibrary.Chat 8251 * @param {string} alias The alias string to be used for agent chat messages 8252 */ 8253 AgentLibrary.prototype.setChatAlias = function(alias){ 8254 UIModel.getInstance().chatAliasRequest = new ChatAliasRequest(alias); 8255 var msg = UIModel.getInstance().chatAliasRequest.formatJSON(); 8256 utils.sendMessage(this, msg); 8257 }; 8258 /** 8259 * Request to enter/exit a public chat room 8260 * @memberof AgentLibrary.Chat 8261 * @param {string} action "ENTER" | "EXIT" 8262 * @param {integer} roomId Chat room id 8263 */ 8264 AgentLibrary.prototype.publicChatRoom = function(action, roomId){ 8265 UIModel.getInstance().chatRoomRequest = new ChatRoomRequest(action, "PUBLIC", roomId); 8266 var msg = UIModel.getInstance().chatRoomRequest.formatJSON(); 8267 utils.sendMessage(this, msg); 8268 }; 8269 /** 8270 * Request to enter/exit a private chat room 8271 * @memberof AgentLibrary.Chat 8272 * @param {string} action "ENTER" | "EXIT" 8273 * @param {integer} roomId Chat room id 8274 * @param {integer} agentOne Id for the logged in agent 8275 * @param {integer} agentTwo Id for the agent or supervisor the logged in agent is chatting with 8276 */ 8277 AgentLibrary.prototype.privateChatRoom = function(action, roomId, agentOne, agentTwo){ 8278 UIModel.getInstance().chatRoomRequest = new ChatRoomRequest(action, "PRIVATE", roomId, agentOne, agentTwo); 8279 var msg = UIModel.getInstance().chatRoomRequest.formatJSON(); 8280 utils.sendMessage(this, msg); 8281 }; 8282 /** 8283 * Send a chat message to the given room 8284 * @memberof AgentLibrary.Chat 8285 * @param {integer} roomId Id for chat room 8286 * @param {string} message The message to be sent 8287 * @param {function} [callback=null] Callback function when chat message received 8288 */ 8289 AgentLibrary.prototype.sendChat = function(roomId, message, callback){ 8290 UIModel.getInstance().chatSendRequest = new ChatSendRequest(roomId, message); 8291 var msg = UIModel.getInstance().chatSendRequest.formatJSON(); 8292 utils.setCallback(this, CALLBACK_TYPES.CHAT, callback); 8293 utils.sendMessage(this, msg); 8294 }; 8295 /** 8296 * Get list of supervisors for logged in agent 8297 * @memberof AgentLibrary.Chat 8298 * @param {function} [callback=null] Callback function when chat message received 8299 */ 8300 AgentLibrary.prototype.getSupervisors = function(callback){ 8301 UIModel.getInstance().supervisorListRequest = new SupervisorListRequest(); 8302 var msg = UIModel.getInstance().supervisorListRequest.formatJSON(); 8303 utils.setCallback(this, CALLBACK_TYPES.SUPERVISOR_LIST, callback); 8304 utils.sendMessage(this, msg); 8305 }; 8306 /** 8307 * Send accept/decline response when a chat is presented to an agent 8308 * @memberof AgentLibrary.Chat 8309 * @param {string} uii Unique identifier for the chat session 8310 * @param {string} response ACCEPT|REJECT response 8311 * @param {string} responseReason Agent reason for Reject 8312 */ 8313 AgentLibrary.prototype.chatPresentedResponse = function(uii, messageId, response, responseReason){ 8314 UIModel.getInstance().chatPresentedRequest = new ChatPresentedResponseRequest(uii, messageId, response, responseReason); 8315 var msg = UIModel.getInstance().chatPresentedRequest.formatJSON(); 8316 utils.sendMessage(this, msg); 8317 }; 8318 /** 8319 * Send an external chat message 8320 * @memberof AgentLibrary.Chat 8321 * @param {string} uii Unique identifier for the chat session 8322 * @param {string} agentId The agent associated with the chat 8323 * @param {string} message The message sent by the agent 8324 */ 8325 AgentLibrary.prototype.chatMessage = function(uii, agentId, message){ 8326 UIModel.getInstance().chatMessageRequest = new ChatMessageRequest(uii, agentId, message, false); 8327 var msg = UIModel.getInstance().chatMessageRequest.formatJSON(); 8328 utils.sendMessage(this, msg); 8329 }; 8330 /** 8331 * Send an whisper type chat message 8332 * @memberof AgentLibrary.Chat 8333 * @param {string} uii Unique identifier for the chat session 8334 * @param {string} agentId The agent associated with the chat 8335 * @param {string} message The message sent by the agent 8336 */ 8337 AgentLibrary.prototype.chatWhisper = function(uii, agentId, message){ 8338 UIModel.getInstance().chatMessageRequest = new ChatMessageRequest(uii, agentId, message, true); 8339 var msg = UIModel.getInstance().chatMessageRequest.formatJSON(); 8340 utils.sendMessage(this, msg); 8341 }; 8342 /** 8343 * Send a disposition to end a chat session 8344 * @memberof AgentLibrary.Chat 8345 * @param {string} uii Unique identifier for the chat session 8346 * @param {number} agentId The agent's id 8347 * @param {number} dispositionId Id of the selected disposition 8348 * @param {string} [notes=""] Agent notes 8349 * @param {boolean} sendAcknowlegement Whether or not to fire callback 8350 * @param {object} [script=null] Script data associated with the chat session 8351 */ 8352 AgentLibrary.prototype.chatDisposition = function(uii, agentId, dispositionId, notes, sendAcknowlegement, script, sessionId){ 8353 UIModel.getInstance().chatDispositionRequest = new ChatDispositionRequest(uii, agentId, dispositionId, notes, sendAcknowlegement, script, sessionId); 8354 var msg = UIModel.getInstance().chatDispositionRequest.formatJSON(); 8355 utils.sendMessage(this, msg); 8356 }; 8357 /** 8358 * Send the chat to a different Chat Queue 8359 * @memberof AgentLibrary.Chat 8360 * @param {string} uii Unique identifier for the chat session 8361 * @param {number} agentId The agent's id 8362 * @param {number} chatQueueId Id of the Chat Queue to requeue to 8363 * @param {number} skillId Skill id associated with the Chat Queue 8364 * @param {boolean} [maintainAgent=fakse] Whether or not to keep the current agent connected to the chat on requeue 8365 */ 8366 AgentLibrary.prototype.chatRequeue = function(uii, agentId, chatQueueId, skillId, maintainAgent){ 8367 UIModel.getInstance().chatRequeueRequest = new ChatRequeueRequest(uii, agentId, chatQueueId, skillId, maintainAgent); 8368 var msg = UIModel.getInstance().chatRequeueRequest.formatJSON(); 8369 utils.sendMessage(this, msg); 8370 }; 8371 /** 8372 * Sent when agent starts/stops typing 8373 * @memberof AgentLibrary.Chat 8374 * @param {string} uii Unique identifier for the chat session 8375 * @param {string} message Pending Agent message - sent to any monitoring Supervisors 8376 */ 8377 AgentLibrary.prototype.chatTyping = function(uii,message){ 8378 UIModel.getInstance().chatTypingRequest = new ChatTypingRequest(uii,message); 8379 var msg = UIModel.getInstance().chatTypingRequest.formatJSON(); 8380 utils.sendMessage(this, msg); 8381 }; 8382 /** 8383 * Request to add a session on an existing chat 8384 * @memberof AgentLibrary.Chat 8385 * @param {string} monitorAgentId Agent id handling this chat, the agent being monitored 8386 */ 8387 AgentLibrary.prototype.monitorAgentChats = function(monitorAgentId){ 8388 UIModel.getInstance().monitorChatRequest = new MonitorChatRequest(monitorAgentId); 8389 var msg = UIModel.getInstance().monitorChatRequest.formatJSON(); 8390 utils.sendMessage(this, msg); 8391 }; 8392 /** 8393 * Request to stop a chat monitoring session for a specific agent 8394 * @memberof AgentLibrary.Chat 8395 * @param {string} monitorAgentId Agent id of agent being monitored 8396 */ 8397 AgentLibrary.prototype.stopMonitoringChatsByAgent = function(monitorAgentId){ 8398 UIModel.getInstance().stopMonitorChatRequest = new StopMonitorChatRequest(monitorAgentId); 8399 var msg = UIModel.getInstance().stopMonitorChatRequest.formatJSON(); 8400 utils.sendMessage(this, msg); 8401 }; 8402 /** 8403 * Request to drop all chat monitoring sessions for the logged in agent 8404 * @memberof AgentLibrary.Chat 8405 */ 8406 AgentLibrary.prototype.stopMonitoringAllAgentChats = function(){ 8407 UIModel.getInstance().stopMonitorChatRequest = new StopMonitorChatRequest(); 8408 var msg = UIModel.getInstance().stopMonitorChatRequest.formatJSON(); 8409 utils.sendMessage(this, msg); 8410 }; 8411 /** 8412 * Request to terminate an active chat session 8413 * @memberof AgentLibrary.Chat 8414 * @param {string} uii Unique identifier for the chat session 8415 * @param {string} agentId Current logged in agent id 8416 * @param {string} sessionId Chat session id 8417 */ 8418 AgentLibrary.prototype.leaveChat = function(uii, agentId, sessionId){ 8419 UIModel.getInstance().leaveChatRequest = new LeaveChatRequest(uii, agentId, sessionId); 8420 var msg = UIModel.getInstance().leaveChatRequest.formatJSON(); 8421 utils.sendMessage(this, msg); 8422 }; 8423 /** 8424 * Request a list of active chats by agent id 8425 * @memberof AgentLibrary.Chat 8426 * @param {string} agentId Current logged in agent id 8427 * @param {string} monitorAgentId Agent id handling chats 8428 * @param {function} [callback=null] Callback function when chat-list request received 8429 */ 8430 AgentLibrary.prototype.chatList = function(agentId, monitorAgentId, callback){ 8431 UIModel.getInstance().chatListRequest = new ChatListRequest(agentId, monitorAgentId); 8432 var msg = UIModel.getInstance().chatListRequest.formatJSON(); 8433 utils.setCallback(this, CALLBACK_TYPES.CHAT_LIST, callback); 8434 utils.sendMessage(this, msg); 8435 }; 8436 /** 8437 * set chat in state of agent-chat-end 8438 * @memberof AgentLibrary.Chat 8439 * @param {string} uii Unique identifier for the chat session 8440 * @param {string} agentId Current logged in agent id 8441 */ 8442 AgentLibrary.prototype.chatAgentEnd = function(agentId, uii){ 8443 UIModel.getInstance().chatAgentEnd = new ChatAgentEndRequest(agentId, uii); 8444 var msg = UIModel.getInstance().chatAgentEnd.formatJSON(); 8445 utils.sendMessage(this, msg); 8446 }; 8447 /** 8448 * Sends chat state change message to IntelliQueue 8449 * @memberof AgentLibrary.Agent 8450 * @param {string} chatState The base chat state <br /> 8451 * CHAT-AVAILABLE | CHAT-PRESENTED | CHAT-ENGAGED | CHAT-RNA 8452 * @param {function} [callback=null] Callback function when chatState response received 8453 */ 8454 AgentLibrary.prototype.setChatState = function(chatState, callback){ 8455 UIModel.getInstance().chatStateRequest = new ChatStateRequest(chatState); 8456 var msg = UIModel.getInstance().chatStateRequest.formatJSON(); 8457 utils.setCallback(this, CALLBACK_TYPES.CHAT_STATE, callback); 8458 utils.sendMessage(this, msg); 8459 }; 8460 /** 8461 * initialize a chat session by sending a manual outbound sms 8462 * @memberof AgentLibrary.Chat 8463 * @param {string} agentId Current logged in agent id 8464 * @param {number} chatQueueId Id of the Chat Queue to send this sms through 8465 * @param {number} ani to receive the sms 8466 * @param {number} dnis to be used for the sms 8467 * @param {string} message content 8468 */ 8469 AgentLibrary.prototype.sendManualOutboundSms = function(agentId, chatQueueId, ani, dnis, message){ 8470 UIModel.getInstance().chatManualSms = new ChatManualSmsRequest(agentId, chatQueueId, ani, dnis, message); 8471 var msg = UIModel.getInstance().chatManualSms.formatJSON(); 8472 utils.sendMessage(this, msg); 8473 }; 8474 } 8475 function initAgentLibraryLogger(context) { 8476 'use strict'; 8477 var AgentLibrary = context.AgentLibrary; 8478 AgentLibrary.prototype.openLogger = function(){ 8479 var instance = this; 8480 if("indexedDB" in context){ 8481 // Open database 8482 var dbRequest = indexedDB.open("AgentLibraryLogging", 6); // version number 8483 dbRequest.onerror = function(event) { 8484 console.error("Error requesting DB access"); 8485 }; 8486 dbRequest.onsuccess = function(event) { 8487 instance._db = event.target.result; 8488 //prune items older than 2 days 8489 instance.purgeLog(instance._db, "logger"); 8490 instance._db.onerror = function(event) { 8491 // Generic error handler for all errors targeted at this database requests 8492 console.error("AgentLibrary: Database error - " + event.target.errorCode); 8493 }; 8494 instance._db.onsuccess = function(event) { 8495 console.log("AgentLibrary: Successful logging of record"); 8496 }; 8497 }; 8498 // This event is only implemented in recent browsers 8499 dbRequest.onupgradeneeded = function(event) { 8500 instance._db = event.target.result; 8501 // Create an objectStore to hold log information. Key path should be unique 8502 if(!instance._db.objectStoreNames.contains("logger")){ 8503 var objectStore = instance._db.createObjectStore("logger", { autoIncrement: true }); 8504 // simple indicies: index name, index column path 8505 objectStore.createIndex("logLevel", "logLevel", {unique: false}); 8506 objectStore.createIndex("dts", "dts", {unique: false}); 8507 // index for logLevel and date range 8508 var name = "levelAndDate"; 8509 var keyPath = ['logLevel','dts']; 8510 objectStore.createIndex(name, keyPath, {unique: false}); 8511 } 8512 }; 8513 }else{ 8514 console.warn("AgentLibrary: indexedDB NOT supported by your Browser."); 8515 } 8516 }; 8517 /** 8518 * Purge records older than 2 days from the AgentLibrary log 8519 * @memberof AgentLibrary 8520 */ 8521 AgentLibrary.prototype.purgeLog = function(db, store){ 8522 var instance = this; 8523 if(db){ 8524 try{ 8525 var transaction = db.transaction([store], "readwrite"); 8526 var objectStore = transaction.objectStore(store); 8527 var dateIndex = objectStore.index("dts"); 8528 var endDate = new Date(); 8529 endDate.setDate(endDate.getDate() - 2); // two days ago 8530 var range = IDBKeyRange.upperBound(endDate); 8531 dateIndex.openCursor(range).onsuccess = function(event){ 8532 var cursor = event.target.result; 8533 if(cursor){ 8534 objectStore.delete(cursor.primaryKey); 8535 cursor.continue(); 8536 } 8537 }; 8538 } catch(err){ 8539 // no op 8540 } 8541 } 8542 }; 8543 /** 8544 * Clear the AgentLibrary log by emptying the IndexedDB object store 8545 * @memberof AgentLibrary 8546 */ 8547 AgentLibrary.prototype.clearLog = function(db){ 8548 var transaction = db.transaction(["logger"], "readwrite"); 8549 var objectStore = transaction.objectStore("logger"); 8550 var objectStoreRequest = objectStore.clear(); 8551 objectStoreRequest.onsuccess = function(event){ 8552 console.log("AgentLibrary: logger database cleared"); 8553 }; 8554 }; 8555 AgentLibrary.prototype.deleteDB = function(dbName){ 8556 dbName = dbName || 'AgentLibraryLogging'; 8557 var DBDeleteRequest = indexedDB.deleteDatabase(dbName); 8558 DBDeleteRequest.onerror = function(event) { 8559 console.log("Error deleting database.", dbName); 8560 }; 8561 DBDeleteRequest.onsuccess = function(event) { 8562 console.log("Database", dbName, "deleted successfully"); 8563 }; 8564 }; 8565 AgentLibrary.prototype.getLogRecords = function(logLevel, startDate, endDate, maxRows, callback){ 8566 logLevel = logLevel || ""; 8567 var instance = this; 8568 var transaction = instance._db.transaction(["logger"], "readonly"); 8569 var objStore = transaction.objectStore("logger"); 8570 var index = null, 8571 cursor = null, 8572 range = null, 8573 limit = maxRows || 100; 8574 utils.setCallback(instance, CALLBACK_TYPES.LOG_RESULTS, callback); 8575 if(logLevel !== "" && logLevel.toUpperCase() !== "ALL" && logLevel.toUpperCase() !== "NO-STATS") { // looking for specific log level type 8576 if(startDate && endDate){ 8577 var lowerBound = [logLevel.toLowerCase(), startDate]; 8578 var upperBound = [logLevel.toLowerCase(), endDate]; 8579 range = IDBKeyRange.bound(lowerBound,upperBound); 8580 }else if(startDate){ 8581 range = IDBKeyRange.lowerBound([logLevel.toLowerCase(), startDate]); 8582 }else if(endDate){ 8583 range = IDBKeyRange.upperBound([logLevel.toLowerCase(), endDate]); 8584 } 8585 if(range !== null){ 8586 // with the provided date range 8587 var levelAndDateReturn = []; 8588 var idxLevelAndDate = 0; 8589 index = objStore.index("levelAndDate"); 8590 index.openCursor(range, "prev").onsuccess = function(event){ 8591 cursor = event.target.result; 8592 if(cursor && idxLevelAndDate < limit){ 8593 levelAndDateReturn.push(cursor.value); 8594 idxLevelAndDate = idxLevelAndDate + 1; 8595 cursor.continue(); 8596 }else{ 8597 utils.fireCallback(instance, CALLBACK_TYPES.LOG_RESULTS, levelAndDateReturn); 8598 } 8599 }; 8600 }else{ 8601 // no date range specified, return all within log level 8602 var logLevelReturn = []; 8603 var idxLogLevel = 0; 8604 index = objStore.index("logLevel"); 8605 index.openCursor(logLevel, "prev").onsuccess = function(event){ 8606 cursor = event.target.result; 8607 if(cursor && idxLogLevel < limit){ 8608 logLevelReturn.push(cursor.value); 8609 idxLogLevel = idxLogLevel + 1; 8610 cursor.continue(); 8611 }else{ 8612 utils.fireCallback(instance, CALLBACK_TYPES.LOG_RESULTS, logLevelReturn); 8613 } 8614 }; 8615 } 8616 } else if(logLevel.toUpperCase() === "NO-STATS"){ // give us all types except stats 8617 if(startDate && endDate){ 8618 range = IDBKeyRange.bound(startDate,endDate); 8619 }else if(startDate){ 8620 range = IDBKeyRange.lowerBound(startDate); 8621 }else if(endDate){ 8622 range = IDBKeyRange.upperBound(endDate); 8623 } 8624 if(range !== null){ 8625 // with the provided date range 8626 var dtsNoStatsReturn = []; 8627 var idxDTSNoStats = 0; 8628 index = objStore.index("dts"); 8629 index.openCursor(range, "prev").onsuccess = function(event){ 8630 cursor = event.target.result; 8631 if(cursor && idxDTSNoStats < limit){ 8632 if(cursor.value.logLevel !== "stats"){ 8633 dtsNoStatsReturn.push(cursor.value); 8634 idxDTSNoStats = idxDTSNoStats + 1; 8635 } 8636 cursor.continue(); 8637 }else{ 8638 utils.fireCallback(instance, CALLBACK_TYPES.LOG_RESULTS, dtsNoStatsReturn); 8639 } 8640 }; 8641 }else{ 8642 // no date range specified, return all records 8643 var noStatsReturn = []; 8644 var idxNoStats = 0; 8645 objStore.openCursor().onsuccess = function(event){ 8646 cursor = event.target.result; 8647 if(cursor && idxNoStats < limit){ 8648 if(cursor.value.logLevel !== "stats"){ 8649 noStatsReturn.push(cursor.value); 8650 idxNoStats = idxNoStats + 1; 8651 } 8652 cursor.continue(); 8653 }else{ 8654 utils.fireCallback(instance, CALLBACK_TYPES.LOG_RESULTS, noStatsReturn); 8655 } 8656 }; 8657 } 8658 } else { // give us all log level types 8659 if(startDate && endDate){ 8660 range = IDBKeyRange.bound(startDate,endDate); 8661 }else if(startDate){ 8662 range = IDBKeyRange.lowerBound(startDate); 8663 }else if(endDate){ 8664 range = IDBKeyRange.upperBound(endDate); 8665 } 8666 if(range !== null){ 8667 // with the provided date range 8668 var dtsReturn = []; 8669 var idxDTS = 0; 8670 index = objStore.index("dts"); 8671 index.openCursor(range, "prev").onsuccess = function(event){ 8672 cursor = event.target.result; 8673 if(cursor && idxDTS < limit){ 8674 dtsReturn.push(cursor.value); 8675 idxDTS = idxDTS + 1; 8676 cursor.continue(); 8677 }else{ 8678 utils.fireCallback(instance, CALLBACK_TYPES.LOG_RESULTS, dtsReturn); 8679 } 8680 }; 8681 }else{ 8682 // no date range specified, return all records 8683 var allValsReturn = []; 8684 var idxAll = 0; 8685 objStore.openCursor().onsuccess = function(event){ 8686 cursor = event.target.result; 8687 if(cursor && idxAll < limit){ 8688 allValsReturn.push(cursor.value); 8689 idxAll = idxAll + 1; 8690 cursor.continue(); 8691 }else{ 8692 utils.fireCallback(instance, CALLBACK_TYPES.LOG_RESULTS, allValsReturn); 8693 } 8694 }; 8695 } 8696 } 8697 return null; 8698 }; 8699 } 8700 function initAgentLibraryConsoleLogger(context) { 8701 'use strict'; 8702 var AgentLibrary = context.AgentLibrary; 8703 AgentLibrary.prototype.openConsoleLogger = function() { 8704 var instance = this; 8705 if("indexedDB" in context){ 8706 var dbRequest = indexedDB.open("AgentLibraryConsoleLogging", 1); 8707 dbRequest.onerror = function(event){ 8708 console.error("Error requesting DB access"); 8709 }; 8710 dbRequest.onsuccess = function(event){ 8711 instance._consoleDb = event.target.result; 8712 //prune items older than 2 days 8713 instance.purgeLog(instance._consoleDb, "consoleLogger"); 8714 instance._consoleDb.onerror = function(event) { 8715 // Generic error handler for all errors targeted at this database requests 8716 console.error("AgentLibrary: Database error - " + event.target.errorCode); 8717 }; 8718 instance._consoleDb.onsuccess = function(event) { 8719 console.log("AgentLibrary: Successful logging of record"); 8720 }; 8721 _overrideConsole(); 8722 }; 8723 // This event is only implemented in recent browsers 8724 dbRequest.onupgradeneeded = function(event) { 8725 instance._consoleDb = event.target.result; 8726 // Create an objectStore to hold log information. Key path should be unique 8727 if(!instance._consoleDb.objectStoreNames.contains("consoleLogger")){ 8728 var objectStore = instance._consoleDb.createObjectStore("consoleLogger", { autoIncrement: true }); 8729 // simple indicies: index name, index column path 8730 objectStore.createIndex("type", "type", {unique: false}); 8731 objectStore.createIndex("dts", "dts", {unique: false}); 8732 objectStore.createIndex("agentId", "agentId", {unique: false}); 8733 // index for type and agent id 8734 var name = "typeAndAgent"; 8735 var keyPath = ['type', 'agentId']; 8736 objectStore.createIndex(name, keyPath, {unique: false}); 8737 } 8738 _overrideConsole(); 8739 }; 8740 } else { 8741 console.warn("AgentLibrary: indexedDB NOT supported by your Browser."); 8742 } 8743 }; 8744 AgentLibrary.prototype.getConsoleLogRecords = function(type, callback) { 8745 var agentId = UIModel.getInstance().agentSettings.agentId; // only return records for this agent id 8746 var instance = this; 8747 var transaction = instance._consoleDb.transaction(["consoleLogger"], "readonly"); 8748 var objStore = transaction.objectStore("consoleLogger"); 8749 var index = null, 8750 cursor = null, 8751 range = null, 8752 limit = 5000; 8753 utils.setCallback(instance, CALLBACK_TYPES.LOG_CONSOLE_RESULTS, callback); 8754 var result = []; 8755 if(type) { 8756 // everything with this type 8757 index = objStore.index("typeAndAgent"); 8758 range = IDBKeyRange.only([type.toUpperCase(), agentId]); 8759 } else { 8760 index = objStore.index("agentId"); 8761 range = IDBKeyRange.only(agentId); 8762 } 8763 var count = 0; 8764 index.openCursor(range, "prev").onsuccess = function(event){ 8765 cursor = event.target.result; 8766 if(cursor && count < limit) { 8767 result.push(cursor.value); 8768 count++; 8769 cursor.continue(); 8770 } else { 8771 utils.fireCallback(instance, CALLBACK_TYPES.LOG_CONSOLE_RESULTS, result); 8772 } 8773 }; 8774 }; 8775 function _overrideConsole() { 8776 // override the window.console functions, process as normal then save to the local db 8777 var browserConsole = Object.assign({}, window.console); 8778 (function (defaultConsole) { 8779 var instance = UIModel.getInstance().libraryInstance; 8780 var agentSettings = UIModel.getInstance().agentSettings; 8781 function _getRecord(type, text) { 8782 if(typeof text === 'function') { 8783 text = text.toString(); 8784 } else if(typeof text === 'object') { 8785 try { 8786 text = JSON.stringify(text); 8787 } catch(e) {} 8788 } 8789 return { 8790 type: type, 8791 message: text, 8792 dts: new Date(), 8793 agentId: agentSettings.agentId, 8794 agentName: agentSettings.firstName + ' ' + agentSettings.lastName 8795 }; 8796 } 8797 function _saveRecord(type, text) { 8798 if (instance._consoleDb) { 8799 var transaction = instance._consoleDb.transaction(["consoleLogger"], "readwrite"); 8800 var store = transaction.objectStore("consoleLogger"); 8801 store.add(_getRecord(type, text)); 8802 } 8803 } 8804 window.console.log = function(text) { 8805 defaultConsole.log(text); 8806 _saveRecord('LOG', text); 8807 }; 8808 window.console.info = function(text) { 8809 defaultConsole.info(text); 8810 _saveRecord('INFO', text); 8811 }; 8812 window.console.warn = function(text) { 8813 defaultConsole.warn(text); 8814 _saveRecord('WARN', text); 8815 }; 8816 window.console.error = function(text) { 8817 defaultConsole.error(text); 8818 _saveRecord('ERROR', text); 8819 }; 8820 }(browserConsole)); 8821 } 8822 } 8823 var initAgentLibrary = function (context) { 8824 initAgentLibraryCore(context); 8825 initAgentLibrarySocket(context); 8826 initAgentLibraryAgent(context); 8827 initAgentLibraryCall(context); 8828 initAgentLibraryLead(context); 8829 initAgentLibraryChat(context); 8830 initAgentLibraryLogger(context); 8831 initAgentLibraryConsoleLogger(context); 8832 return context.AgentLibrary; 8833 }; 8834 if (typeof define === 'function' && define.amd) { 8835 // Expose Library as an AMD module if it's loaded with RequireJS or 8836 // similar. 8837 //console.log("AgentLibrary: using AMD"); 8838 define(function () { 8839 return initAgentLibrary({}); 8840 }); 8841 } else if (typeof module === 'object' && module.exports) { 8842 // Node. Does not work with strict CommonJS, but 8843 // only CommonJS-like environments that support module.exports, 8844 // like Node. 8845 //console.log("AgentLibrary: Using Node"); 8846 module.exports = initAgentLibrary(this); 8847 } else { 8848 // Load Library normally (creating a Library global) if not using an AMD 8849 // loader. 8850 //console.log("AgentLibrary: Not using AMD"); 8851 initAgentLibrary(this); 8852 } 8853 } (this));