Робимо чергу вхідних дзвінків з функцією callback

При дзвінках в колл-центр компаній часто доводиться стикатися з великим часом очікування на лінії, багато хто з нас слухали набридливу мелодію протягом десятків хвилин хоча б раз у житті. Найцікавіше полягає в тому, що це абсолютно невигідно компанії в колл-центр якій ви телефонуєте, особливо якщо ви телефонуєте на номер 8-800. На щастя, вже давно придуманий спосіб, що дозволяє вирішити дану проблему — це callback або зворотний виклик. Суть цього способу дуже проста: позвонившему пропонують відключитися від колл-центру при цьому його номер так і залишається в черзі на обслуговування і як тільки його черга підійде, то йому автоматично наберуть і з'єднають з оператором, на якого розподілився його дзвінок. Таким чином вбиваємо відразу декілька зайців: не займаються лінії колл-центру, не витрачаються дорогі хвилини 8-800, а клієнти не відчувають зайвого роздратування в очікуванні відповіді. Вендори колл-центрового ПО хочуть за таку функцію досить пристойних грошей, а ми під катом розповімо як даний функціонал досить просто і швидко реалізується з допомогою платформи VoxImplant.
Так як ми вже писали про організацію колл-центру з допомогою VoxImplant, то повторювати цю частину в цій статті не будемо, а зосередимося на зміни, які необхідно зробити в сценаріях для реалізації коллбек-функції. Відразу зауважу, що дана функціональність доступна тільки для сценаріїв, в яких підключається модуль ACD для роботи з чергами. Сценарій, який відповідає за обробку вхідних дзвінків з урахуванням нашої коллбек-функції буде виглядати наступним чином:
// Підключаємо модуль 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;
}
// Закінчити сесію
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) {
// Робимо коллбек
originalCall = VoxEngine.callUser(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);
}

Ось власне і все. Трохи підправивши сценарій з попереднього туториала про ACD ми отримали чергу з коллбэком. Базовий сценарій, який ми міняли, доступний на github.com/voximplant/acd, також як і найпростіший веб-фон для операторів.

Робота з чергою через HTTP API
Попередній приклад був зроблений для випадку коли спочатку є вхідний дзвінок, в реальному житті можуть траплятися випадки, коли клієнт відразу замовляє на сайті коллбек і нам потрібно його розмістити в черзі на обробку. В цілому, черга — це абстрактна сутність, туди на обробку можна кидати не тільки дзвінки, але і, наприклад, emailы, повідомлення і т. д. В такій ситуації сценарій треба запускати через метод StartScenarios HTTP API, а сам сценарій трохи трансформується:
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);
// ... далі все те ж саме, що і в попередньому сценарії
});


P. S. А що, якщо...
Нас іноді запитують: «а що якщо ми хочемо використовувати SIP-телефони замість веб-телефонів, зроблених з допомогою VoxImplant Web SDK в нашому колл-центрі?»
Відповідаємо: «як не дивно, це можливо, але докладніше про це ми розповімо в окремій статті».
Сподобався вам цей матеріал?

/>
/>


<input type=«radio» id=«vv64975»
class=«radio js-field-data»
name=«variant[]»
value=«64975» />
Так
<input type=«radio» id=«vv64977»
class=«radio js-field-data»
name=«variant[]»
value=«64977» />
дуже
<input type=«radio» id=«vv64979»
class=«radio js-field-data»
name=«variant[]»
value=«64979» />
Немає

Проголосував 1 людина. Утримався 1 людина.


Тільки зареєстровані користувачі можуть брати участь в опитуванні. Увійдіть, будь ласка.


Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.