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