Built xcally-motion-dialpad from commit 141221b.|1.0.96
[dialpad.git] / js / controllers / classic.controller.js
1 'use strict';
2
3 angular
4     .module('motion')
5     .controller('classicController', classicController);
6
7 function classicController($scope, $window, $interval, $location, angularLoad, $http) {
8
9     var vm = this;
10
11     // Integration
12     var agentCallbacks = {};
13     var callsCallbacks = {};
14
15     // Socket object
16     var socket = null;
17
18     // Data
19     vm.timer = '';
20     vm.phone = '';
21     vm.inCall = false;
22
23     // task
24     var _task = {}; // global 
25     var _xml = {};
26
27     // Methods
28     vm.compose = compose;
29     vm.remove = remove;
30     vm.hangup = hangup;
31     vm.dial = dial;
32
33     var dialCount = 0;
34
35     //********************************************* */
36
37     var scriptTag = angular.element(document.createElement('base'));
38     scriptTag.href = window.location.pathname;
39
40     //*****************************************//
41     // LOADING
42     //********************************************* */
43
44     angularLoad
45         .loadScript(window.location.pathname.substring(0,window.location.pathname.lastIndexOf('/'))  + '/js/salesforce/interaction.js') //
46         //.loadScript(window.location.origin  + '/js/salesforce/interaction.js') //
47         .then(function () {
48
49             console.log('Salesforce Classic');
50             sforce.interaction.cti.getCallCenterSettings(getCallCenterSettingsCallback);
51             sforce.interaction.cti.enableClickToDial(enableClickToDialCallback);
52
53         }).catch(function (err) {
54             console.error(err);
55         });
56
57     function enableClickToDialCallback(response) {
58         if (response.result) { // boolean
59             sforce.interaction.cti.onClickToDial(onClickToDialListener);
60         } else {
61             console.error('Something went wrong! Errors:', response.errors);
62         }
63     }
64
65     //*****************************************//
66     // getCallCenterSettingsCallback
67     //*****************************************//
68     function getCallCenterSettingsCallback(response) {
69
70         var _parsedXml = {};
71
72         if (response.result) {
73
74             _parsedXml = JSON.parse(response.result);
75             vm.host = _parsedXml['/Motion/Host'];
76             //_xml.host = _parsedXml['/Motion/Host'];
77
78             _xml.createTask = _parsedXml['/ManageTask/createTask'];
79             _xml.createTask = _xml.createTask ? _xml.createTask : 'false';
80
81             _xml.createOnAnswer = _parsedXml['/ManageTask/createOnAnswer'];
82             _xml.createOnAnswer = _xml.createOnAnswer ? _xml.createOnAnswer : 'false';
83
84             _xml.updateOnHangup = _parsedXml['/ManageTask/updateOnHangup'];
85             _xml.updateOnHangup = _xml.updateOnHangup ? _xml.updateOnHangup : 'false';
86
87             _xml.refreshOnHangup = _parsedXml['/ManageTask/refreshOnHangup'];
88             _xml.refreshOnHangup = _xml.refreshOnHangup ? _xml.refreshOnHangup : 'false';
89
90             _xml.defaultCreateStatus = _parsedXml['/ManageTask/defaultCreateStatus'];
91             _xml.defaultCreateStatus = _xml.defaultCreateStatus ? _xml.defaultCreateStatus : 'In Progress';
92
93             _xml.defaultUpdateStatus = _parsedXml['/ManageTask/defaultUpdateStatus'];
94             _xml.defaultUpdateStatus = _xml.defaultUpdateStatus ? _xml.defaultUpdateStatus : 'Completed';
95
96             _xml.uniqueid = _parsedXml['/FieldMapping/uniqueid'];
97             _xml.uniqueid = _xml.uniqueid ? _xml.uniqueid : null;
98             _xml.agent = _parsedXml['/FieldMapping/agent'];
99             _xml.agent = _xml.agent ? _xml.agent : null;
100             _xml.callerid = _parsedXml['/FieldMapping/callerid'];
101             _xml.callerid = _xml.callerid ? _xml.callerid : null;
102             _xml.date = _parsedXml['/FieldMapping/date'];
103             _xml.date = _xml.date ? _xml.date : null;
104             _xml.time = _parsedXml['/FieldMapping/time'];
105             _xml.time = _xml.time ? _xml.time : null;
106             _xml.starttime = _parsedXml['/FieldMapping/starttime'];
107             _xml.starttime = _xml.starttime ? _xml.starttime : null;
108             _xml.endtime = _parsedXml['/FieldMapping/endtime'];
109             _xml.endtime = _xml.endtime ? _xml.endtime : null;
110             _xml.answertime = _parsedXml['/FieldMapping/answertime'];
111             _xml.answertime = _xml.answertime ? _xml.answertime : null;
112             _xml.holdtime = _parsedXml['/FieldMapping/holdtime'];
113             _xml.holdtime = _xml.holdtime ? _xml.holdtime : null;
114             _xml.duration = _parsedXml['/FieldMapping/duration'];
115             _xml.duration = _xml.duration ? _xml.duration : null;
116             _xml.billsec = _parsedXml['/FieldMapping/billsec'];
117             _xml.billsec = _xml.billsec ? _xml.billsec : null;
118
119         } else {
120             console.error('Something went wrong! Errors:', response.errors);
121         }
122     }
123
124     //*****************************************//
125     // onClickToDialListener
126     //*****************************************//
127     function onClickToDialListener(response) {
128
129         var result = JSON.parse(response.result);
130
131         if (dialCount < 1) {
132
133             if (vm.online && result.number) {
134
135                 vm.phone = result.number;
136
137                 _task.endUserPhone = angular.copy(result.number);
138                 _task.endUserObjectType = result.object;
139                 _task.endUserId = result.objectId;
140                 _task.endUserName = result.objectName;
141
142                 vm.dial();
143
144                 dialCount++;
145             }
146         }
147     }
148
149     //*****************************************//
150     // display
151     //*****************************************//
152
153     function display(task) {
154         console.log('Display', task);
155         sforce.interaction.screenPop(task.recordId, true, screenPopCallback);
156     }
157
158     //****************************************************** */
159     // compose
160     //****************************************************** */
161     function compose(value) {
162         vm.phone = vm.phone.concat(value);
163     }
164
165     //****************************************************** */
166     // remove
167     //****************************************************** */
168     function remove() {
169         vm.phone = vm.phone.substring(0, vm.phone.length - 1);
170     }
171
172      //****************************************************** */
173     //  KEEPALIVE
174     //****************************************************** */
175     function keepalive() {
176
177         var uniqueid = Date.now();
178
179         $http.get('http://localhost:9888/api/agent')
180             .then(agentCallbacks[uniqueid] = function (result) {
181                 if (result && result.status >= 200 && result.status < 300) {
182                     var message = result.data;
183                     vm.id = message.id;
184                     vm.name = message.name;
185                     vm.fullname = message.fullname;
186                     vm.internal = String(message.internal);
187                     vm.online = true;
188
189                     //****************************************************** */
190                     if (!socket) {
191                         if (vm.host && vm.id) {
192                             socket = io(vm.host, {
193                                 query: {
194                                     id: vm.id
195                                 },
196                                 autoConnect: false,
197                                 transports: ['websocket', 'polling']
198                             });
199
200                             // NOTE: RIVEDERE CON ANDREA
201                             socket.on('trigger:salesforce:display', display);
202
203                             //****************************************************** */
204                             // connessione socket OUTBOUND CHANNEL
205
206                             // socket.on to launch saveLog()
207
208                             socket.on('voice_outbound_channel:save', function (evt) {
209                                 // evento
210                                 if (evt.destexten && evt.destexten === String(_task.endUserPhone) &&
211                                     !evt.dialstatus) { // simple ring
212                                     if (_xml.createTask === 'true' && _xml.createOnAnswer === 'false') { // creazione task
213                                         saveLog(evt);
214                                     }
215                                 }
216
217                                 // evento
218                                 if (evt.destexten && evt.destexten === String(_task.endUserPhone) &&
219                                     evt.dialstatus && evt.dialstatus === 'ANSWER') { // on answer
220                                     if (_xml.createTask === 'true' && _xml.createOnAnswer === 'true') { // creazione task
221                                         saveLog(evt);
222                                     }
223                                 }
224                             });
225
226                             // socket.on to launch updateLog()
227
228                             socket.on('voice_outbound_channel:remove', function (evt) {
229
230                                 vm.phone = '';
231
232                                 if (evt.destexten && evt.destexten === String(_task.endUserPhone)) {
233                                     if (_xml.createTask === 'true' && _xml.updateOnHangup === 'true') { // 
234                                         updateLog(evt);
235                                     } else {
236                                         _task = {};
237                                     }
238                                 }
239                             });
240                         }
241                     }
242                     //****************************************************** */
243                     if (socket && socket.disconnected) {
244                         socket.connect();
245                     }
246                 } else {
247                     vm.online = false;
248                 }
249             })
250             .catch(function(err){
251                 console.error(err);
252             });
253     }
254
255 //****************************************************** */
256     //  getCalls (checking status)
257     //****************************************************** */
258
259     function getCalls() {
260         var uniqueid = Date.now();
261
262         $http.get('http://localhost:9888/api/calls')
263         .then(
264             callsCallbacks[uniqueid] = function (result) {
265                 if (result && result.status >= 200 && result.status < 300) {
266                     var message = result.data;
267                     if (_.isArray(message) && _.find(message, {
268                             stateId: 8
269                         })) {
270                         //******************************** */
271                         // activeDuration exists
272                         vm.timer = parseTime(message[0].callingNumber, message[0].activeDuration);
273                         //******************************** */
274                         vm.inCall = true;
275                     } else {
276                         // activeDuration undefined
277                         vm.inCall = false;
278                         vm.timer = '';
279                     }
280                 } else {
281                     vm.inCall = false;
282                     vm.timer = '';
283                 }
284             }
285
286         )
287         .catch(function(err){
288             console.error(err);
289         });
290
291         //postExtMessage('http://localhost:9888/api/calls', uniqueid);
292     }
293
294     function parseTime(cl_n, aD) {
295         var parsedTime = cl_n + ' ACTIVE  (';
296         parsedTime += aD.hours < 10 ? '0' : '';
297         parsedTime += aD.hours;
298         parsedTime += ':';
299         parsedTime += aD.minutes < 10 ? '0' : '';
300         parsedTime += aD.minutes;
301         parsedTime += ':';
302         parsedTime += aD.seconds < 10 ? '0' : '';
303         parsedTime += aD.seconds;
304         parsedTime += ')';
305
306         return parsedTime;
307     }
308
309     //******************************** */
310     //  DIAL
311     //******************************** */
312     function dial() {
313         $http.get('http://localhost:9888/api/originate/' + vm.phone);
314         $http.get('http://localhost:9888/api/answer');
315         getUser_Apex(); // logged user UserId
316     }
317
318     function getUser_Apex() {
319         sforce.interaction.runApex('UserInfo', 'getUserId', null, getUser_ApexCallback);
320     }
321
322     function getUser_ApexCallback(response) {
323         if (response.result) {
324             _task.userId = String(response.result);
325             //saveLog(); // ora gestito da evento socket.on in keepalive
326         } else {
327             console.error('Something went wrong! Errors:', response.errors);
328         }
329     }
330
331     //******************************** */
332     //  SAVELOG
333     //******************************** */
334
335     function saveLog(evt) {
336
337         _task.activityDate = moment().utc(); //
338
339         // 00Q means a lead.. adding this to support logging on leads as well as contacts.
340
341         var endUserIdSubstr = _task.endUserId.substr(0, 3);
342         var description = '';
343         description += '*** Call Info ***\n';
344         description += 'Called Number: ' + _task.endUserPhone + '\n';
345         description += 'Member Name: ' + evt.membername + '\n';
346         description += 'UniqueId: ' + evt.uniqueid + '\n';
347         description += 'Date: ' + evt.starttime + '\n'; // creato alla chiamata
348         // if(evt.evt.answertime) {
349         //   description += 'Date: ' + evt.answertime + '\n'; // creato alla risposta
350         // }
351         description += '*** Time Info ***\n';
352         if (evt.answertime) {
353             description += 'Answer Time: ' + evt.answertime + '\n'; // creato alla risposta
354         }
355
356         var saveParams = 'Subject=' + 'Outbound Call [xCALLY Ticket] '  + _task.endUserPhone;
357         saveParams += '&Activitydate=' + _task.activityDate;
358         saveParams += '&Phone=' + _task.endUserPhone;
359         saveParams += '&Description=' + description;
360         saveParams += '&OwnerId=' + _task.userId; // different from ProfileId [ERROR: invalid field input type]
361         if (endUserIdSubstr === '003' || endUserIdSubstr === '00Q') {
362             saveParams += '&whoId=' + _task.endUserId;
363         } else {
364             saveParams += '&whatId=' + _task.endUserId;
365         }
366         saveParams += '&Priority=Normal';
367         //saveParams += '&Status=In Progress'; // or '&Status=Not Started';
368         saveParams += '&Status=' + _xml.defaultCreateStatus; // or '&Status=Not Started';
369         saveParams += '&Type=Call';
370         //saveParams += '&CallType=' + SP.calltype;  //should change this to reflect actual inbound or outbound
371         //
372
373         if (_xml.uniqueid && evt.uniqueid) {
374             saveParams += '&' + _xml.uniqueid + '=' + String(evt.uniqueid);
375         }
376         //   if(_xml.agent && evt.membername) {
377         //     saveParams += '&' + _xml.agent + '=' + evt.membername;
378         //   }
379         if (_xml.agent && vm.fullname) {
380             saveParams += '&' + _xml.agent + '=' + vm.fullname;
381         }
382         if (_xml.callerid && evt.calleridnum) {
383             saveParams += '&' + _xml.callerid + '=' + evt.calleridnum;
384         }
385         if (_xml.date && evt.starttime) {
386             var _date = String(evt.starttime).split(' ')[0];
387             saveParams += '&' + _xml.date + '=' + _date;
388         }
389         if (_xml.time && evt.starttime) {
390             var _time = String(evt.starttime).split(' ')[1];
391             saveParams += '&' + _xml.time + '=' + _time;
392         }
393         if (_xml.starttime && evt.starttime) {
394             saveParams += '&' + _xml.starttime + '=' + evt.starttime;
395         }
396         if (_xml.answertime && evt.answertime) {
397             saveParams += '&' + _xml.answertime + '=' + evt.answertime;
398         }
399
400         sforce.interaction.saveLog('Task', encodeURI(saveParams), saveLogCallback);
401
402         description = '';
403     }
404
405     function saveLogCallback(response) {
406
407         if (response.result) { // boolean
408             _task.Id = response.result; // differente dalla documentazione
409             dialCount = 0; // reset click count to 0 (new dial possible)
410             
411             //sforce.interaction.cti.enableClickToDial(enableClickToDialCallback);
412             
413             saveScreenPop();
414         } else {
415             console.error('Something went wrong! Errors:', response.errors);
416         }
417     }
418
419     function saveScreenPop() {
420         sforce.interaction.screenPop('/' + _task.Id, true, screenPopCallback);
421     }
422
423     function screenPopCallback(response) {
424         if (response.result) { // boolean
425             console.log('API screenPop executed successfully!');
426         } else {
427             console.error('Something went wrong! Errors:', response.errors);
428         }
429     }
430
431     //***************************************** */
432     // HANGUP
433     //***************************************** */
434
435     function hangup() {
436
437         vm.phone = '';
438         $http.get('http://localhost:9888/api/hangup');
439
440         // hangup comunicato alla phonebar
441         // phonebar comunica a asterisk* che invia evt relativo all'hangup
442         // intercettiamo hangup via socket - verifichiamo il numero della chiamata
443     }
444
445     //***************************************** */
446     // UPDATELOG
447     //***************************************** */
448
449     // keepalive lancia la funzione updateLog
450
451     function updateLog(evt) {
452
453         _task.activityDate = moment().utc(); // 
454
455         var description = '';
456         description += '*** Call Info ***\n';
457         description += 'Called Number: ' + _task.endUserPhone + '\n';
458         description += 'Member Name: ' + evt.membername + '\n';
459         description += 'UniqueId: ' + evt.uniqueid + '\n';
460         description += 'Date: ' + evt.endtime + '\n'; // creato alla chiusura
461         description += '*** Time Info ***\n';
462         if (evt.answertime) {
463             description += 'Answer Time: ' + evt.answertime + '\n';
464         }
465         description += 'End Time: ' + evt.endtime + '\n';
466         if (evt.holdtime) {
467             description += 'Hold Time: ' + evt.holdtime + '\n';
468         }
469         description += 'Duration: ' + evt.duration + '\n';
470         if (evt.billableseconds) {
471             description += 'Billable Seconds: ' + evt.billableseconds + '\n';
472         }
473
474         var updateParams = 'Id=' + _task.Id; // on UPDATE
475         updateParams += '&Activitydate=' + _task.activityDate;
476         //updateParams += '&Status=Completed'; // '&Status=In Progress';
477         updateParams += '&Status=' + _xml.defaultUpdateStatus;
478         updateParams += '&Description=' + description;
479         //
480         // if(_xml.uniqueid && evt.uniqueid) {
481         //   updateParams += '&' + _xml.uniqueid + '=' + String(evt.uniqueid);
482         // }
483         // if(_xml.agent && evt.membername) {
484         //   updateParams += '&' + _xml.agent + '=' + evt.membername;
485         // }
486         // if(_xml.agent && vm.fullname) {
487         //   updateParams += '&' + _xml.agent + '=' + vm.fullname;
488         // }
489         // if(_xml.callerid && evt.calleridnum) {
490         //   updateParams += '&' + _xml.callerid + '=' + evt.calleridnum;
491         // }
492         if (_xml.date && evt.endtime) {
493             var _date = String(evt.endtime).split(' ')[0];
494             updateParams += '&' + _xml.date + '=' + _date;
495         }
496         if (_xml.time && evt.endtime) {
497             var _time = String(evt.endtime).split(' ')[1];
498             updateParams += '&' + _xml.time + '=' + _time;
499         }
500         // if(_xml.starttime && evt.starttime) {
501         //   updateParams += '&' + _xml.starttime + '=' +evt.starttime;
502         // }
503         if (_xml.endtime && evt.endtime) {
504             updateParams += '&' + _xml.endtime + '=' + evt.endtime;
505         }
506         if (_xml.answertime && evt.answertime) {
507             updateParams += '&' + _xml.answertime + '=' + evt.answertime;
508         }
509         if (_xml.holdtime && evt.holdtime) {
510             updateParams += '&' + _xml.holdtime + '=' + evt.holdtime;
511         }
512         if (_xml.duration && evt.duration) {
513             updateParams += '&' + _xml.duration + '=' + String(evt.duration);
514         }
515         if (_xml.billsec && evt.billableseconds) {
516             updateParams += '&' + _xml.billsec + '=' + String(evt.billableseconds);
517         }
518
519         sforce.interaction.saveLog('Task', encodeURI(updateParams), updateLogCallback); // 'Task' is mandatory also on update
520
521         description = '';
522
523     }
524
525     //***************************************** */
526
527     function updateLogCallback(response) {
528
529         if (_xml.createTask === 'true' && _xml.updateOnHangup === 'true' && _xml.refreshOnHangup === 'true') { // 
530
531             if (response.result) { // boolean
532                 _task = {}; // reset _task object
533                 sforce.interaction.refreshPage(refreshViewCallback); // it refreshes the current active tab
534
535             } else {
536                 console.error('Something went wrong! Errors:', response.errors);
537             }
538         } else {
539             // nessun refresh
540             // resetta _task = {}
541             _task = {}; 
542         }
543     }
544
545     function refreshViewCallback(response) {
546         if (response.result) { // boolean
547             console.log('API refreshView classic executed successfully! returnValue:', response.result);
548         } else {
549             console.error('Something went wrong! Errors:', response.errors);
550         }
551     }
552
553     //***************************************** */
554     // receiveMessage
555     //***************************************** */
556     function receiveMessage(message) {
557         var data = message.data;
558
559         if (agentCallbacks[data.uniqueid]) {
560             agentCallbacks[data.uniqueid](data);
561             delete agentCallbacks[data.uniqueid];
562         } else if (callsCallbacks[data.uniqueid]) {
563             callsCallbacks[data.uniqueid](data);
564             delete callsCallbacks[data.uniqueid];
565         }
566
567         $scope.$apply();
568     }
569
570     $interval(keepalive, 2000);
571     $interval(getCalls, 1000);
572
573     $window.addEventListener('message', receiveMessage, false);
574
575 }