Built xcally-motion-dialpad from commit 141221b.|1.0.96
[dialpad.git] / js / controllers / lightning.controller.js
diff --git a/js/controllers/lightning.controller.js b/js/controllers/lightning.controller.js
new file mode 100644 (file)
index 0000000..9e8d895
--- /dev/null
@@ -0,0 +1,603 @@
+'use strict';
+
+angular
+    .module('motion')
+    .controller('lightningController', lightningController);
+
+function lightningController($scope, $window, $interval, $location, angularLoad, $http) {
+
+    var vm = this;
+    var agentCallbacks = {};
+    var callsCallbacks = {};
+    // Socket object
+    var socket = null;
+    // Data
+    vm.timer = '';
+    vm.phone = ''; // used inside DOM
+    vm.inCall = false; // used inside DOM
+    // task
+    var _task = {}; // global
+    var _xml = {};
+    // Methods
+    vm.compose = compose;
+    vm.remove = remove;
+    vm.hangup = hangup;
+    vm.dial = dial;
+    var dialCount = 0;
+
+    //********************************************* */
+    var scriptTag = angular.element(document.createElement('base'));
+    scriptTag.href = window.location.pathname;
+
+    //*****************************************//
+    // LOADING
+    //********************************************* */
+
+    angularLoad
+        .loadScript(window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) + '/js/salesforce/lightning.js') //
+        .then(function () {
+            console.log('Salesforce Lightning');
+            sforce.opencti.getCallCenterSettings({
+                callback: getCallCenterSettingsCallback
+            });
+            sforce.opencti.enableClickToDial({
+                callback: enableClickToDialCallback
+            });
+        }).catch(function (err) {
+            console.error(err);
+        });
+
+    function enableClickToDialCallback(response) {
+        console.log('enableClickToDialCallback', response);
+        if (response.success) {
+            sforce.opencti.onClickToDial({
+                listener: onClickToDialListener_lightning
+            });
+        } else {
+            console.error('Something went wrong! Errors:', response.errors);
+        }
+    }
+
+    //*****************************************//
+    // getCallCenterSettingsCallback
+    //*****************************************//
+    function getCallCenterSettingsCallback(response) {
+
+        if (response.success) {
+
+            vm.host = response.returnValue['/Motion/Host'];
+            //_xml.host = _parsedXml['/Motion/Host'];
+
+            _xml.createTask = response.returnValue['/ManageTask/createTask'];
+            _xml.createTask = _xml.createTask ? _xml.createTask : 'false';
+
+            _xml.createOnAnswer = response.returnValue['/ManageTask/createOnAnswer'];
+            _xml.createOnAnswer = _xml.createOnAnswer ? _xml.createOnAnswer : 'false';
+
+            _xml.updateOnHangup = response.returnValue['/ManageTask/updateOnHangup'];
+            _xml.updateOnHangup = _xml.updateOnHangup ? _xml.updateOnHangup : 'false';
+
+            _xml.refreshOnHangup = response.returnValue['/ManageTask/refreshOnHangup'];
+            _xml.refreshOnHangup = _xml.refreshOnHangup ? _xml.refreshOnHangup : 'false';
+
+            _xml.defaultCreateStatus = response.returnValue['/ManageTask/defaultCreateStatus'];
+            _xml.defaultCreateStatus = _xml.defaultCreateStatus ? _xml.defaultCreateStatus : 'In Progress';
+
+            _xml.defaultUpdateStatus = response.returnValue['/ManageTask/defaultUpdateStatus'];
+            _xml.defaultUpdateStatus = _xml.defaultUpdateStatus ? _xml.defaultUpdateStatus : 'Completed';
+
+            _xml.uniqueid = response.returnValue['/FieldMapping/uniqueid'];
+            _xml.uniqueid = _xml.uniqueid ? _xml.uniqueid : null;
+            _xml.agent = response.returnValue['/FieldMapping/agent'];
+            _xml.agent = _xml.agent ? _xml.agent : null;
+            _xml.callerid = response.returnValue['/FieldMapping/callerid'];
+            _xml.callerid = _xml.callerid ? _xml.callerid : null;
+            _xml.date = response.returnValue['/FieldMapping/date'];
+            _xml.date = _xml.date ? _xml.date : null;
+            _xml.time = response.returnValue['/FieldMapping/time'];
+            _xml.time = _xml.time ? _xml.time : null;
+            _xml.starttime = response.returnValue['/FieldMapping/starttime'];
+            _xml.starttime = _xml.starttime ? _xml.starttime : null;
+            _xml.endtime = response.returnValue['/FieldMapping/endtime'];
+            _xml.endtime = _xml.endtime ? _xml.endtime : null;
+            _xml.answertime = response.returnValue['/FieldMapping/answertime'];
+            _xml.answertime = _xml.answertime ? _xml.answertime : null;
+            _xml.holdtime = response.returnValue['/FieldMapping/holdtime'];
+            _xml.holdtime = _xml.holdtime ? _xml.holdtime : null;
+            _xml.duration = response.returnValue['/FieldMapping/duration'];
+            _xml.duration = _xml.duration ? _xml.duration : null;
+            _xml.billsec = response.returnValue['/FieldMapping/billsec'];
+            _xml.billsec = _xml.billsec ? _xml.billsec : null;
+
+        } else {
+            console.error('Something went wrong! Errors:', response.errors);
+        }
+    }
+
+    //*****************************************//
+    // onClickToDialListener LIGHTNING
+    //*****************************************//
+    function onClickToDialListener_lightning(data) {
+
+        if (dialCount < 1) {
+            if (vm.online && data.number) {
+                vm.phone = data.number;
+
+                _task.endUserPhone = angular.copy(data.number);
+                // _task.endUserPhone is now indipendent from both vm.phone & data.phone
+                _task.endUserObjectType = data.objectType;
+                _task.endUserId = data.recordId;
+                _task.endUserName = data.recordName;
+                vm.dial();
+
+                dialCount++; // impedisce di creare eventi dial() dopo il primo click
+            }
+        }
+    }
+
+    //*****************************************//
+    // display
+    //*****************************************//
+
+    function display(task) {
+        sforce.opencti.screenPop({
+            type: sforce.opencti.SCREENPOP_TYPE.SOBJECT, //Review the arguments section.
+            params: {
+                recordId: task.recordId
+            }
+        });
+    }
+
+    //****************************************************** */
+    // compose
+    //****************************************************** */
+    function compose(value) {
+        vm.phone = vm.phone.concat(value);
+    }
+
+    //****************************************************** */
+    // remove
+    //****************************************************** */
+    function remove() {
+        vm.phone = vm.phone.substring(0, vm.phone.length - 1);
+    }
+
+    //****************************************************** */
+    //  KEEPALIVE
+    //****************************************************** */
+    function keepalive() {
+
+        var uniqueid = Date.now();
+
+        $http.get('http://localhost:9888/api/agent')
+            .then(agentCallbacks[uniqueid] = function (result) {
+                if (result && result.status >= 200 && result.status < 300) {
+                    var message = result.data;
+                    vm.id = message.id;
+                    vm.name = message.name;
+                    vm.fullname = message.fullname;
+                    vm.internal = String(message.internal);
+                    vm.online = true;
+
+                    //****************************************************** */
+                    if (!socket) {
+                        if (vm.host && vm.id) {
+                            socket = io(vm.host, {
+                                query: {
+                                    id: vm.id
+                                },
+                                autoConnect: false,
+                                transports: ['websocket', 'polling']
+                            });
+
+                            // NOTE: RIVEDERE CON ANDREA
+                            socket.on('trigger:salesforce:display', display);
+
+                            //****************************************************** */
+                            // connessione socket OUTBOUND CHANNEL
+
+                            // socket.on to launch saveLog()
+
+                            socket.on('voice_outbound_channel:save', function (evt) {
+                                // evento
+                                if (evt.destexten && evt.destexten === String(_task.endUserPhone) &&
+                                    !evt.dialstatus) { // simple ring
+                                    if (_xml.createTask === 'true' && _xml.createOnAnswer === 'false') { // creazione task
+                                        saveLog(evt);
+                                    }
+                                }
+
+                                // evento
+                                if (evt.destexten && evt.destexten === String(_task.endUserPhone) &&
+                                    evt.dialstatus && evt.dialstatus === 'ANSWER') { // on answer
+                                    if (_xml.createTask === 'true' && _xml.createOnAnswer === 'true') { // creazione task
+                                        saveLog(evt);
+                                    }
+                                }
+                            });
+
+                            // socket.on to launch updateLog()
+
+                            socket.on('voice_outbound_channel:remove', function (evt) {
+
+                                vm.phone = '';
+                                
+                                if (evt.destexten && evt.destexten === String(_task.endUserPhone)) {
+                                    // attende evento hangup prima di farlo 
+                                    // controlla che riguardi la nostra telefonata
+                                    if (_xml.createTask === 'true' && _xml.updateOnHangup === 'true') { // 
+                                        // esegue solo se updateOnHungup = true
+                                        updateLog(evt);
+                                    } else {
+                                        // si incarica di resettare _task = {}
+                                        _task = {};
+                                    }
+                                }
+                            });
+                        }
+                    }
+                    //****************************************************** */
+                    if (socket && socket.disconnected) {
+                        socket.connect();
+                    }
+                } else {
+                    vm.online = false;
+                }
+            })
+            .catch(function(err){
+                console.error(err);
+            });
+    }
+
+    //****************************************************** */
+    //  getCalls (checking status)
+    //****************************************************** */
+
+    function getCalls() {
+        var uniqueid = Date.now();
+
+        $http.get('http://localhost:9888/api/calls')
+        .then(
+            callsCallbacks[uniqueid] = function (result) {
+                if (result && result.status >= 200 && result.status < 300) {
+                    var message = result.data;
+                    if (_.isArray(message) && _.find(message, {
+                            stateId: 8
+                        })) {
+                        //******************************** */
+                        // activeDuration exists
+                        vm.timer = parseTime(message[0].callingNumber, message[0].activeDuration);
+                        //******************************** */
+                        vm.inCall = true;
+                    } else {
+                        // activeDuration undefined
+                        vm.inCall = false;
+                        vm.timer = '';
+                    }
+                } else {
+                    vm.inCall = false;
+                    vm.timer = '';
+                }
+            }
+        )
+        .catch(function(err){
+            console.error(err);
+        });
+    }
+
+    function parseTime(cl_n, aD) {
+        var parsedTime = cl_n + ' ACTIVE  (';
+        parsedTime += aD.hours < 10 ? '0' : '';
+        parsedTime += aD.hours;
+        parsedTime += ':';
+        parsedTime += aD.minutes < 10 ? '0' : '';
+        parsedTime += aD.minutes;
+        parsedTime += ':';
+        parsedTime += aD.seconds < 10 ? '0' : '';
+        parsedTime += aD.seconds;
+        parsedTime += ')';
+
+        return parsedTime;
+    }
+
+    //******************************** */
+    //  DIAL
+    //******************************** */
+    function dial() {
+
+        //var uniqueid = Date.now();
+
+        $http.get('http://localhost:9888/api/originate/' + vm.phone);
+
+        $http.get('http://localhost:9888/api/answer');
+
+        getUser_Apex(); // logged user UserId
+    }
+
+    function getUser_Apex() {
+        //Invokes API method
+        var objectParams = {
+            apexClass: 'UserInfo',
+            methodName: 'getUserId', 
+            callback: getUser_ApexCallback
+        };
+        sforce.opencti.runApex(objectParams);
+    }
+
+    function getUser_ApexCallback(response) {
+
+        if (response.success) {
+            _task.userId = String(response.returnValue.runApex);
+            //saveLog(); // ora gestito da evento socket.on in keepalive
+        } else {
+            console.error('Something went wrong! Errors:', response.errors);
+        }
+    }
+
+    //******************************** */
+    //  SAVELOG
+    //******************************** */
+
+    function saveLog(evt) {
+
+        _task.activityDate = moment().utc(); //
+
+        // 00Q means a lead.. adding this to support logging on leads as well as contacts.
+
+        var endUserIdSubstr = _task.endUserId.substr(0, 3);
+        var description = '';
+        description += '*** Call Info ***\n';
+        description += 'Called Number: ' + _task.endUserPhone + '\n';
+        description += 'Member Name: ' + evt.membername + '\n';
+        description += 'UniqueId: ' + evt.uniqueid + '\n';
+        description += 'Date: ' + evt.starttime + '\n'; // creato alla chiamata
+        // if(evt.evt.answertime) {
+        //   description += 'Date: ' + evt.answertime + '\n'; // creato alla risposta
+        // }
+        description += '*** Time Info ***\n';
+        if (evt.answertime) {
+            description += 'Answer Time: ' + evt.answertime + '\n'; // creato alla risposta
+        }
+        var obj_saveLog = { //
+            //entityApiName: 'Task', //Optional, on CREATE
+            //Id: string, //Optional, on UPDATE
+            OwnerId: _task.userId, // different from ProfileId [ERROR: invalid field input type]
+            //WhoId: _task.endUserId,
+            ActivityDate: _task.activityDate, //
+            IsReminderSet: false,
+            IsRecurrence: false,
+            Subject: 'Outbound Call [xCALLY Ticket] ' + _task.endUserPhone,
+            Description: description,
+            Priority: 'Normal',
+            Type: 'Call',
+            //Status: 'In Progress' // or Status: 'Not Started'
+            Status: _xml.defaultCreateStatus
+        };
+
+        obj_saveLog.entityApiName = 'Task'; // CREATE
+        if (endUserIdSubstr === '003' || endUserIdSubstr === '00Q') {
+            obj_saveLog.WhoId = _task.endUserId;
+        } else {
+            obj_saveLog.WhatId = _task.endUserId;
+        }
+
+        if (_xml.uniqueid && evt.uniqueid) {
+            obj_saveLog[_xml.uniqueid] = String(evt.uniqueid);
+        }
+        // if (_xml.agent && evt.membername) {
+        //     obj_saveLog[_xml.agent] = evt.membername;
+        // }
+        if (_xml.agent && vm.fullname) {
+            obj_saveLog[_xml.agent] = vm.fullname;
+        }
+        if (_xml.callerid && evt.calleridnum) {
+            obj_saveLog[_xml.callerid] = evt.calleridnum;
+        }
+        if (_xml.date && evt.starttime) {
+            var date = String(evt.starttime).split(' ')[0];
+            obj_saveLog[_xml.date] = date;
+        }
+        if (_xml.time && evt.starttime) {
+            var time = String(evt.starttime).split(' ')[1];
+            obj_saveLog[_xml.time] = time;
+        }
+        if (_xml.starttime && evt.starttime) {
+            obj_saveLog[_xml.starttime] = evt.starttime;
+        }
+        if (_xml.answertime && evt.answertime) {
+            obj_saveLog[_xml.answertime] = evt.answertime;
+        }
+
+        sforce.opencti.saveLog({
+            value: JSON.parse(JSON.stringify(obj_saveLog)),
+            callback: saveLogCallback //Optional
+        });
+        description = '';
+    }
+
+    function saveLogCallback(response) {
+
+        if (response.success) { // boolean
+            _task.Id = response.returnValue.recordId; //
+            dialCount = 0; // reset click count to 0 (new dial possible)
+            
+            saveScreenPop();
+
+        } else {
+            console.error('Something went wrong! Errors:', response.errors);
+        }
+    }
+
+    function saveScreenPop() {
+        sforce.opencti.screenPop({
+            type: sforce.opencti.SCREENPOP_TYPE.SOBJECT, //Review the arguments section.
+            params: {
+                recordId: _task.Id
+            }, //Depends on the SCREENPOP_TYPE. Review the arguments section.
+            callback: screenPopCallback
+        });
+
+    }
+
+    function screenPopCallback(response) {
+        if (response.success) {
+            console.log('API screenPop executed successfully!');
+        } else {
+            console.error('Something went wrong! Errors:', response.errors);
+        }
+    }
+
+    //***************************************** */
+    // HANGUP
+    //***************************************** */
+
+    function hangup() {
+        vm.phone = '';
+        $http.get('http://localhost:9888/api/hangup');
+
+        // hangup comunicato alla phonebar
+        // phonebar comunica a asterisk* che invia evt relativo all'hangup
+        // intercettiamo hangup via socket - verifichiamo il numero della chiamata
+    }
+
+    //***************************************** */
+    // UPDATELOG
+    //***************************************** */
+
+    // keepalive lancia la funzione updateLog
+
+    function updateLog(evt) {
+        _task.activityDate = moment().utc(); //
+        var description = '';
+        description += '*** Call Info ***\n';
+        description += 'Called Number: ' + _task.endUserPhone + '\n';
+        description += 'Member Name: ' + evt.membername + '\n';
+        description += 'UniqueId: ' + evt.uniqueid + '\n';
+        description += 'Date: ' + evt.endtime + '\n'; // creato alla chiusura
+        description += '*** Time Info ***\n';
+        if (evt.answertime) {
+            description += 'Answer Time: ' + evt.answertime + '\n';
+        }
+        if (evt.endtime) {
+            description += 'End Time: ' + evt.endtime + '\n';
+        }
+        if (evt.holdtime) {
+            description += 'Hold Time: ' + evt.holdtime + '\n';
+        }
+        if (evt.duration) {
+            description += 'Duration: ' + evt.duration + '\n';
+        }
+        if (evt.billableseconds) {
+            description += 'Billable Seconds: ' + evt.billableseconds + '\n';
+        }
+        //var endUserIdSubstr = _task.endUserId.substr(0, 3);
+        var obj_updateLog = { //
+            Id: _task.Id, // on UPDATE
+            ActivityDate: _task.activityDate, // update
+            Status: _xml.defaultUpdateStatus,
+            Description: description
+        };
+
+        // if(_xml.uniqueid && evt.uniqueid) {
+        //   obj_updateLog[_xml.uniqueid] = String(evt.uniqueid);
+        // }
+        // if(_xml.agent && evt.membername) {
+        //   obj_updateLog[_xml.agent] = evt.membername;
+        // }
+        // if (_xml.agent && vm.fullname) {
+        //     obj_updateLog[_xml.agent] = vm.fullname;
+        // }
+        // if(_xml.callerid && evt.calleridnum) {
+        //   obj_updateLog[_xml.callerid] = evt.calleridnum;
+        // }
+        if (_xml.date && evt.endtime) {
+            var date = String(evt.endtime).split(' ')[0];
+            console.log("TCL: updateLog -> date", date);
+            obj_updateLog[_xml.date] = date;
+        }
+        if (_xml.time && evt.endtime) {
+            var time = String(evt.endtime).split(' ')[1];
+            console.log("TCL: updateLog -> time", time);
+            obj_updateLog[_xml.time] = time;
+        }
+        // if(_xml.starttime && evt.starttime) {
+        //   obj_updateLog[_xml.starttime] = evt.starttime;
+        // }
+        if (_xml.endtime && evt.endtime) {
+            obj_updateLog[_xml.endtime] = evt.endtime;
+        }
+        if (_xml.answertime && evt.answertime) {
+            obj_updateLog[_xml.answertime] = evt.answertime;
+        }
+        if (_xml.holdtime && evt.holdtime) {
+            obj_updateLog[_xml.holdtime] = String(evt.holdtime);
+        }
+        if (_xml.duration && evt.duration) {
+            obj_updateLog[_xml.duration] = String(evt.duration);
+        }
+        if (_xml.billsec && evt.billableseconds) {
+            obj_updateLog[_xml.billsec] = String(evt.billableseconds);
+        }
+
+        console.log(obj_updateLog);
+        sforce.opencti.saveLog({
+            value: JSON.parse(JSON.stringify(obj_updateLog)),
+            callback: updateLogCallback //Optional
+        });
+
+        description = '';
+    }
+
+    //***************************************** */
+
+    function updateLogCallback(response) {
+
+        if (_xml.createTask === 'true' && _xml.updateOnHangup === 'true' && _xml.refreshOnHangup === 'true') { //
+
+            if (response.success) {
+                _task = {}; 
+                sforce.opencti.refreshView({
+                    callback: refreshViewCallback
+                });
+            } else {
+                console.error('Something went wrong! Errors:', response.errors);
+            }
+        } else {
+            _task = {};
+        }
+    }
+
+    function refreshViewCallback(response) {
+        console.log('API refreshView classic executed successfully! returnValue:', response);
+
+        if (response.success) { // boolean
+            console.log('API refreshView lightning executed successfully!');
+        } else {
+            console.error('Something went wrong! Errors:', response.errors);
+        }
+
+    }
+
+    //***************************************** */
+    // RECEIVE MESSAGE
+    //***************************************** */
+
+    function receiveMessage(message) {
+        var data = message.data;
+
+        if (agentCallbacks[data.uniqueid]) {
+            agentCallbacks[data.uniqueid](data);
+            delete agentCallbacks[data.uniqueid];
+        } else if (callsCallbacks[data.uniqueid]) {
+            callsCallbacks[data.uniqueid](data);
+            delete callsCallbacks[data.uniqueid];
+        }
+
+        $scope.$apply();
+    }
+
+    $interval(keepalive, 2000);
+    $interval(getCalls, 1000);
+
+    $window.addEventListener('message', receiveMessage, false);
+}
\ No newline at end of file