📜 ⬆️ ⬇️

Making a queue of incoming calls with the callback function

When calling to call center companies often have to face long waiting times on the line, many of us listened to an annoying melody for tens of minutes at least once in a lifetime. The most interesting thing is that it is completely unprofitable for the company to call center where you are calling, especially if you are calling 8-800. Fortunately, a way has long been invented to solve this problem - it is a callback or callback. The essence of this method is very simple: the caller is offered to disconnect from the call center while his number remains in the service queue and as soon as his turn comes, he will be automatically dialed and connected to the operator to whom his call was distributed. In this way, we kill several birds with one stone: the call center lines are not engaged, costly 8-800 minutes are not spent, and customers do not experience excessive irritation while waiting for a response. Call-center software vendors want very decent money for such a function, and we will tell under the cut how this functionality is quite simply and quickly implemented using the VoxImplant platform.
Since we have already written about the organization of a call center using VoxImplant, we will not repeat this part in this article, but will focus on the changes that need to be made in the scenarios for implementing the callback function. Immediately, I note that this functionality is only available for scenarios in which the ACD module is used to work with queues. The script responsible for handling incoming calls, taking into account our callback function, will look like this:
//   ACD require(Modules.ACD); var request, // <--     ACDRequest originalCall, // <--   callerid, statusInterval, callback = false; // <--   - //     VoxEngine.addEventListener(AppEvents.CallAlerting, handleInboundCall); //    function handleInboundCall(e) { originalCall = e.call; callerid = e.callerid; //   originalCall.addEventListener(CallEvents.Connected, handleCallConnected); originalCall.addEventListener(CallEvents.PlaybackFinished, handlePlaybackFinished); originalCall.addEventListener(CallEvents.Failed, cleanup); originalCall.addEventListener(CallEvents.Disconnected, cleanup); //    originalCall.answer(); } //   function cleanup(e) { if (request) { //     -  request.cancel(); request = null; } //   if (!callback) VoxEngine.terminate(); } //         function handlePlaybackFinished(e) { e.call.startPlayback("http://cdn.voximplant.com/toto.mp3"); } //     function handleToneReceived(e) { if (e.tone == "#") { callback = true; originalCall.hangup(); // <--        } } //   function handleCallConnected(e) { //       originalCall.handleTones(true); originalCall.addEventListener(CallEvents.ToneReceived, handleToneReceived); //     'MainQueue',       request = VoxEngine.enqueueACDRequest("MainQueue", callerid); //          request.addEventListener(ACDEvents.Queued, function (acdevent) { request.getStatus(); }); //           request.addEventListener(ACDEvents.Waiting, function (acdevent) { var minutesLeft = acdevent.ewt + 1; var minutesWord = " ."; if ((minutesLeft > 10 && minutesLeft < 20) || (minutesLeft % 10 > 4 || minutesLeft % 10 == 0)) { minutesWord = " ."; } else if (minutesLeft % 10 == 1) { minutesWord = " ."; } originalCall.say("      " + acdevent.position + ".       " + (acdevent.ewt + 1) + minutesWord + "                  .", Language.RU_RUSSIAN_FEMALE); }); //    request.addEventListener(ACDEvents.OperatorReached, function (acdevent) { if (callback) { //      ,        ,       acdevent.operatorCall.say(",    .", Language.RU_RUSSIAN_FEMALE); acdevent.operatorCall.addEventListener(CallEvents.Disconnected, VoxEngine.terminate); acdevent.operatorCall.addEventListener(CallEvents.PlaybackFinished, function (callevent) { //  .   caller id  ,       Voximplant. const callerId = "+1234567890" originalCall = VoxEngine.callPSTN(callerid, callerId); originalCall.addEventListener(CallEvents.Connected, function (callevent) { VoxEngine.sendMediaBetween(acdevent.operatorCall, originalCall); clearInterval(statusInterval); }); originalCall.addEventListener(CallEvents.Failed, cleanup); originalCall.addEventListener(CallEvents.Disconnected, cleanup); }); } else { VoxEngine.sendMediaBetween(acdevent.operatorCall, originalCall); acdevent.operatorCall.addEventListener(CallEvents.Disconnected, VoxEngine.terminate); clearInterval(statusInterval); } }); //    -       request.addEventListener(ACDEvents.Offline, function (acdevent) { originalCall.say(" ,    . ,   .", Language.RU_RUSSIAN_FEMALE); originalCall.addEventListener(CallEvents.PlaybackFinished, function (e) { VoxEngine.terminate(); }); }); //      30  statusInterval = setInterval(request.getStatus, 30000); } 

That's all. Having a little corrected the script from the previous tutorial about ACD we got a queue with a callback. The baseline script that we changed is available on github.com/voximplant/acd , as well as the simplest web background for operators.

Work with queue through HTTP API


The previous example was made for the case when there is an incoming call first, in real life there may be cases when a customer orders a callback on the site immediately and we need to place it in the processing queue. In general, a queue is an abstract entity, you can throw not only calls, but also, for example, emails, messages, etc. there for processing. In this situation, the script must be run via the StartScenarios HTTP API method, and the script itself is slightly transformed:
 var displayName, callback = true; //     StartScenarios VoxEngine.addEventListener(AppEvents.Started, function(e) { var data = VoxEngine.customData(); //   script_custom_data         : data = data.split(":"); callerid = data[0]; displayName = data[1]; Logger.write("Put "+displayName+" with number "+callerid+" in a queue"); //     'MainQueue' request = VoxEngine.enqueueACDRequest("MainQueue", callerid); // ...     ,      }); 


PS What if ...


We are sometimes asked: “what if we want to use SIP phones instead of web phones made with the VoxImplant Web SDK in our call center?”
The answer is: "oddly enough, it is possible, but we will tell about it in more detail in a separate article."

')

Source: https://habr.com/ru/post/249647/


All Articles