Колл-центр с ACD, skill-группами и WebRTC-клиентом для обработки входящих звонков

  • Tutorial
Организация очередей звонков и распределение звонков по операторам является одной из основных задач колл-центра, обслуживающего входящие вызовы, когда количество вызовов превышает количество доступных операторов (стандартная ситуация для большинства колл-центров). Звонящего ставят в очередь под определенным номером, о чем ему сообщает IVR, и проигрывают музыку, переодически рассказывая об изменении места в очереди и предполагаемом времени ожидания (до того как ответит оператор). Если повезет, то музыка будет приятной, а ожидание не слишком долгим. Хотите узнать как быстро организовать колл-центр с описанным функционалом, не влезая в дебри и сложности IP-телефонии — добро пожаловать под кат.
Для реализации нашей задачи воспользуемся функционалом платформы VoxImplant, благодаря которому нам потребуется только знание JavaScript, а также мы будем использовать модуль ACD, который подключается прямо в сценарии обработки звонков. Благодаря этому модулю написание кода будет сведено к минимуму.

Если разбить задачу на части, то получится следующий список:
  1. Создаем приложение VoxImplant (можно пафосно назвать его callcenter)
  2. Создаем пользователей и цепляем их приложению (в нашем случае пользователи приложения — операторы колл-центра)
  3. Создаем и настраиваем очередь для нашего приложения
  4. Создаем и настраиваем скилл-группу
  5. Создаем сценарий VoxEngine, который будет обрабатывать входящие звонки: ставить их в очередь, рассказывать сколько еще ждать ответа и т.д.
  6. Отправляем все входящие звонки к нашему сценарию с помощью правила (rule) приложения
  7. Делаем веб-интерфейс оператора с помощью Web SDK

Выглядит страшно, но, как говорится, глаза боятся, а руки делают. Приступим.

Приложение VoxImplant


Открываем раздел Applications/Приложения в панели управления и создаем новое приложение. Давайте назовем его callcenter. Полное название приложения будет выглядеть следующим образом callcenter.имя_вашего_аккаунта.voximplant.com

Пользователи/операторы


Открываем раздел Users/Пользователи и создаем несколько пользователей, можно назвать их operator1, operator2 и т.д. При создании их можно сразу прицеплять к приложению, которое мы создали перед этим.

Создание очереди


Открываем раздел Queues/Очереди (в меню Settings) и создаем новую очередь со следующими параметрами:


Создание скилл-группы


Открываем раздел Skills/Скилл-группы (в меню Settings) и создаем новую группу, указываем очередь и пользователей, которых мы создали ранее:


Создание сценария VoxEngine


Открываем раздел Scenarios/Сценарии и создаем новый сценарий:
// Подключаем модуль ACD
require(Modules.ACD);

var request, // <-- тут будем хранить экземпляр ACDRequest
	originalCall, // <-- входящий звонок
	callerid,
	statusInterval;

// Вешаем обработчик входящего вызова
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 handleCallConnected(e) {
	// Отправляем звонок в очередь '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) {
		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’ и сохраняем. Теперь можно взять какой-нибудь номер телефона в VoxImplant, чтобы все звонки с него отправить в наш IVR с очередью.

Подключаем номер


Открываем раздел Phone numbers/Номера и можно прямо в нем приобрести номер:

В разделе Мои номера цепляем номер к нашему приложению:


Отправляем входящие звонки с номера в сценарий


Идем в раздел Applications/Приложения, заходим в редактирование приложения и открываем раздел Rules/Правила, нажимаем Add Rule/Добавить правило. Можно назвать его InboundCalls, в Pattern вставить приобретенный номер телефона и осталось перетащить наш сценарий ACD в колонку Assigned/Привязанные:

Нажимаем Add и видим только что созданное правило:


Создание интерфейса оператора колл-центра


Последнее, что нужно сделать — создать простой веб-интерфейс, в котором операторы будут работать. Это можно сделать с помощью Web SDK от VoxImplant, в современных браузерах в этом случае будет использоваться WebRTC. Чтобы устанавливать текущий статус оператора в Web SDK доступна функция setOperatorACDStatus, куда мы будем передавать один из статусов из VoxImplant.OperatorACDStatuses. Когда статус установлен в VoxImplant.OperatorACDStatuses.Ready входящие звонки будут распределяться на данного оператора. У нас получится такой простенький интерфейс:

Можно стянуть готовое приложение с GitHub. Только укажите свое имя аккаунта (см. переменную ACCNAME).

P.S. В этом материале специально не рассмотрены более сложные сценарии, когда очередей и скилл-групп несколько, возможность ставить клиента в очередь и давать ему возможность отключаться, чтобы потом сделать callback на телефон, когда очередь подошла и т.д. Все это реально реализовать в рамках функционала VoxImplant.

P.S.S. Важной частью колл-центра является отчетность — она тоже доступна, как из панели управления, так и через HTTP API. Несколько примеров:
Пример 1
Пример 2
Пример 3

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Интересен ли вам данный материал?

Voximplant
95,00
Облачная платформа голосовой и видеотелефонии
Поделиться публикацией

Комментарии 15

    0
    Очень жду момента, когда будет возможность воспользоваться VoxImplant'ом. В описании всё звучит очень здорово! Мне было бы интересно увидеть статьи про более сложные сценарии использования, сейчас всё выглядит волшебно!

    Но возникает вопрос с конфиденциальностью разговоров. В случае, если они проходят через ваш сервис и у вас же записываются, какие есть гарантии того, что записи не уйдут «налево»?
    И второй, связанный с предыдущим вопрос. Планируется ли возможность размещения бэкенда на своих серверах?
      0
      Записи можно делать так, чтобы доступ к ним был только после авторизации через API по https. Всегда их можно скачать к себе и удалить с серверов VoxImplant.
        0
        Ну ок. Спасибо за интересный продукт!
          +1
          Пожалуйста, будем рады если разработчики будут делиться опытом его использования для своих проектов :)
      0
      Подскажите, пожалуйста, можно ли на VoxImplant реализовать следующий сценарий?:

      1. У компании есть небольшой колцентр — несколько операторов. Плюс есть специалисты техподдержки клиентов.
      2. В пределах страны (Украина) выделен телефонный номер 0-800-… для звонков клиентов этой компании.
      3. Хотелось бы:
      1) Переключить этот номер 0-800… на VoxImplant
      2) На VoxImplant настроить IVR (с музыкой и приветствием), который, в зависимости от выбора клиента, переключал бы его звонок на операторов (за справкой), либо на техподдержку.
      3) Получать отчет по звонкам за период: кол-во принятых и сброшенных звонков, их длительность, в разрезе по операторам.
        0
        Можно если номер можно форварднуть по SIP.
          0
          > Можно если номер можно форварднуть по SIP.
          Технари, говорят, что можно ))

          Уточните, пожалуйста, а с VoxImplant договор на обслуживания можно заключить, т.е. оформить отношения официально? Или это можно сделать только в России?
            0
            Ну если можно, то нужно сделать SIP-транк и входящие звонки с номера будут обрабатываться VoxImplantом, а там уже полная свобода творчества в рамках функционала VoxImplant. По договору — можно заключить в России или с американской или с английской компанией, вопрос в том, что необходимо, потому что существуют разные уровни обслуживания.
              0
              ОК.
              Можно с вам по почте списаться?
              Отправил свой контакт в личку.
                0
                А «разные уровни обслуживания», в зависимости от страны/компании — это как?
          0
          Интересно, а появятся ли когда-либо готовые пресеты облачной АТС? Просто у Вас очень широкий функционал, и понятно, что заточка в основном на разработчкиов, но вы бы и кусок консьюмерского рынка могли отхватить. Текущие облачные АТС в большинстве своем чудовищно негибкие, сам к примеру пользую ряд sip-операторов с их АТС и это очень неудобно, мало того, ни один из операторов, на свою облачную атс не дает возможности цеплять чужие транки, и если у тебя несколько облачных провайдеров, то нужна объединяющая их платформа с IVR и так далее.
            0
            В целом, есть вот такой полуфабрикат github.com/voximplant/pbx, описанный в статье habrahabr.ru/post/212713/, у нас есть в планах создание более приличного варианта, но по срокам пока не могу сказать ничего определенного.
              0
              Просто, если Вы сделаете из полуфабриката некое готовое, хотя бы частично, решение, позволяющее цеплять чужие транки в понятную систему маршрутизации (по сути АТС), то будете первыми, наверное, на рынке. А это немало. Сейчас очень у многих в довесок к классическим линиям есть сип-транки от всяких задарма, сипнетов и прочих разных провайдеров. Предлагаемые ими АТС крайне убоги, и по сути, задачам даже малого бизнеса походят слабо.
                0
                Коллеги из Bitrix24 уже сделали нечто подобное www.bitrix24.ru/blogs/howto/update-sip-connector-in-bitrix24.php, но там еще весь Bitrix24 в комплекте :)
                  0
                  Мы пользуемся этим продуктам. Там в целом совсем другой подход. Да и вообще, продукт непростой во всех смыслах. Недавнее обновление парализовало продуктивную работу на 4 суток почти. Я считаю, что пока они не вышли на продакш уровень для внедрения своей системы — слишком высокие риски, слишком неправильные приоритеты. В погоне за красивым дизайном они могут полностью положить базовый функционал сервиса на неделю. Не говоря про то, что не реализован процедурный подход к решению инцедентов. Сбор сообщений о багах в профильном форуме по темам — это несерьезно.

          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

          Самое читаемое