--- /dev/null
+'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