 Many of Habr's readers are familiar with modern IP PBXs in the cloud, such as Mango, Oktell, Octoline and others. All of them offer various functions and tariff plans to satisfy the most different customers and meet their requirements, but there are always a number of those who choose Asterisk anyway, because they want to have opportunities for customization and integration, which only Asterisk can offer a few. In addition to Asterisk itself, it will still require a person who will be able to configure everything and support it, a separate connection to the telecom operator via SIP or via a VoIP gateway and so on. When we started to create our own cloud platform for developing VoxImplant communication applications, we, of course, knew that one of the most popular scenarios for its use would be an IP PBX, so we implemented all the necessary functionality for this. Unlike the case of Asterisk, a person who decides to make his IP PBX based on VoxImplant will need only Javascript knowledge, familiarization with this article and free 10-15 minutes to get the first working version of PBX at the output, which can later be integrated with their services and customize in accordance with their requirements. More on this under the cut.
 Many of Habr's readers are familiar with modern IP PBXs in the cloud, such as Mango, Oktell, Octoline and others. All of them offer various functions and tariff plans to satisfy the most different customers and meet their requirements, but there are always a number of those who choose Asterisk anyway, because they want to have opportunities for customization and integration, which only Asterisk can offer a few. In addition to Asterisk itself, it will still require a person who will be able to configure everything and support it, a separate connection to the telecom operator via SIP or via a VoIP gateway and so on. When we started to create our own cloud platform for developing VoxImplant communication applications, we, of course, knew that one of the most popular scenarios for its use would be an IP PBX, so we implemented all the necessary functionality for this. Unlike the case of Asterisk, a person who decides to make his IP PBX based on VoxImplant will need only Javascript knowledge, familiarization with this article and free 10-15 minutes to get the first working version of PBX at the output, which can later be integrated with their services and customize in accordance with their requirements. More on this under the cut.
VoxEngine.forwardCallToUser();  VoxEngine.addEventListener(AppEvents.CallAlerting, function(e) { var newCall = this.callUser(e.destination, e.callerid, e.displayName); VoxEngine.easyProcess(e.call, newCall); });  VoxEngine.addEventListener(AppEvents.CallAlerting, function (e) { var call2 = VoxEngine.callPSTN(e.destination.substring(1), "74957893798"); VoxEngine.easyProcess(e.call, call2); });  //    var callerid, displayName; //          AppEvents.CallAlerting VoxEngine.addEventListener(AppEvents.CallAlerting, function(e) { //  Caller ID callerid = e.callerid; //  displayName -   SIP displayName = e.displayName; //     (     ) e.call.handleTones(true); //       ,        e.call.answer(); });  //     ,         var GMT_offset = 4, workingHours = [ [0, 0], // Sun [10, 19], // Mon [10, 19], // Tue [10, 19], // Wed [10, 19], // Thu [10, 19], // Fri [0, 0] // Sat ], nonWorkingHours = false, workingHoursGreetingURL = 'http://yourdomain.com/ivr.mp3', //<===    URL  MP3-  ( ) nonWorkingHoursGreetingURL = 'http://yourdomain.com/ivr_nwh.mp3'; //<===    URL  MP3-  ( ) e.call.addEventListener(CallEvents.Connected, function(e) { // . /   ,   GMT_offset (GMT+4  ) var d = new Date(new Date().getTime() + GMT_offset * 3600 * 1000), day = d.getUTCDay(), hour = d.getUTCHours(); Logger.write("Day: " + day + " Hour: " + hour); if (hour >= workingHours[day][0] && hour < workingHours[day][1]) { /** *     *    */ e.call.startPlayback(workingHoursGreetingURL, false); e.call.record(); } else { /** *     *    */ nonWorkingHours = true; e.call.startPlayback(nonWorkingHoursGreetingURL, false); } });  e.call.addEventListener(CallEvents.Disconnected, function(e) { //   VoxEngine.terminate(); });  //          var TIMEOUT = 3000, operatorTimer; e.call.addEventListener(CallEvents.PlaybackFinished, function(e) { //      ,   -    ,      if (!nonWorkingHours) { operatorTimer = setTimeout(function() { forwardCallToOperator(e.call); }, TIMEOUT); } else VoxEngine.terminate(); //      -    });  //      var input = ''; e.call.addEventListener(CallEvents.ToneReceived, function(e) { //        e.call.stopPlayback(); //    input += e.tone; if (input.length == 3) { //        3        forwardCallToExtension(e.call, input); } });  var operators = ['101', '102', '103'], // <==    ,    -    operatorCalls = {}, nOperatorCalls = 0, activeOperatorCall; function forwardCallToExtension(call, ext) { clearTimeout(operatorTimer); //       call.handleTones(false); //   (     ) call.playProgressTone("RU"); //  ,     var call2 = VoxEngine.callUser(ext, callerid, displayName); //   call2.addEventListener(CallEvents.Failed, VoxEngine.terminate); call2.addEventListener(CallEvents.Connected, function(e) { //   -      VoxEngine.sendMediaBetween(call, call2); }); call2.addEventListener(CallEvents.Disconnected, VoxEngine.terminate); } function forwardCallToOperator(call) { //       call.handleTones(false); nOperatorCalls = 0; //   (     ) call.playProgressTone("RU"); //      ,    ,  . for (var i in operators) { var j = operators[i]; nOperatorCalls++; operatorCalls[j] = VoxEngine.callUser(j, callerid, displayName); operatorCalls[j].addEventListener(CallEvents.Failed, function(e) { if (typeof activeOperatorCall == "undefined") { delete operatorCalls[e.call.number()]; nOperatorCalls--; if (nOperatorCalls == 0) { call.hangup(); } } }); operatorCalls[j].addEventListener(CallEvents.Connected, function(e) { delete operatorCalls[e.call.number()]; activeOperatorCall = e.call; VoxEngine.sendMediaBetween(call, e.call); activeOperatorCall.addEventListener(CallEvents.Disconnected, VoxEngine.terminate); for (var i in operatorCalls) { operatorCalls[i].hangup(); } operatorCalls = {}; }); } } 


Source: https://habr.com/ru/post/212713/
All Articles