Asterisk и отправка пропущенных в Telegram/Slack/E-mail

от автора

Есть колл-центр. Есть Asterisk/FreePBX с настроенными очередями. Есть агенты, которые должны обслуживать вызовы. Но потенциальных клиентов так много, а агентов так мало, что первые никак не могут дозвониться до вторых — повисят-повисят в очереди минуту, да и отключаются.

Но зачем-то они же звонили! Может, они хотят денег занести в компанию? Попробуем вернуть и клиентов и их деньги на примере FreePBX.

В настройках очереди можно указать Fail Over Destination — то, куда направлять вызов, когда очередь переполнена, истекло время ожидания и т.п. Но зачастую бывает так, что звонивший отключается раньше, чем его успевает перенаправить в Fail Over Destination — мало ли, связь оборвалась. Готового решения для таких случаев нет. Поэтому идём под кат и пишем своё — с отправкой оповещения в Telegram/Slack/E-mail/куда-то там еще.

И первое, что нам надо понять — как FreePBX пишет логи очередей. В самом простом случае это текстовый файл /var/log/asterisk/queue_log.

Так в лог пишется обычный звонок от абонента 8964467ХХХХ, позвонившего по номеру 302221ХХХХ, попавшего в очередь №603 на первую позицию, которому через 8 секунд ответил Agent Girl. Они проговорили 133 секунды и первым трубку положил абонент — всем бы таких вежливых менеджеров!

1584318765|1584318747.89449|603|NONE|DID|302221ХХХХ 1584318765|1584318747.89449|603|NONE|ENTERQUEUE||8964467ХХХХ|1 1584318774|1584318747.89449|603|Agent Girl|CONNECT|9|1584318765.89450|8 1584318907|1584318747.89449|603|Agent Girl|COMPLETECALLER|9|133|1

А вот немного другая история, когда абонент 8996453ХХХХ дозвонился по номеру 302257ХХХХ, повисел 10 секунд в очереди №210 в первой позиции и отключился. Даже голосовое меню не дослушал!

1581728710|1581728690.59367|210|NONE|DID|302257ХХХХ 1581728710|1581728690.59367|210|NONE|ENTERQUEUE||8996453ХХХХ|1 1581728720|1581728690.59367|210|NONE|ABANDON|1|1|10

Вот про него-то мы и напишем в мессенджер.

Для этого нам надо отловить появление события ABANDON в файле лога. Я долго ломал себе голову как это можно сделать, но потом совершенно случайно наткнулся на прекрасный инструмент — MONIT. В нашем случае он будет следить за логом очередей, и как только в нём появится строка «ABANDON» будет вызывать скрипт обработки данного события.

Для этого после установки пакета:

yum install monit

Настроим его — создадим файл /etc/monit.d/queue_log и запишем в него буквально три строчки:

check file queue_log with path /var/log/asterisk/queue_log     if content = "ABANDON" then         exec "/var/lib/asterisk/agi-bin/qlogevent.sh $EVENT"

Таким образом, при появлении слова «ABANDON» в логе очередей, что говорит нам о преждевременном отключении абонента, будет вызван скрипт /var/lib/asterisk/agi-bin/qlogevent.sh с параметром $EVENT, что есть ничто иное, как полностью строка, в которой это слово появилось.
Это просто.

А теперь начинаются не шахматы — тут думать надо.

В строке, переданной в скрипт, отсутствует информация о номере звонившего:

1581728720|1581728690.59367|210|NONE|ABANDON|1|1|10

В ней есть только Timestamp (1581728720), уникальный ID звонка (1581728690.59367), номер очереди (210), само событие и еще несколько несущественных параметров. Т.е. искать номер абонента придется нам самим. А каким же образом? А очень просто, ведь UID звонка у нас есть!

Обратимся опять к логу данного звонка, конкретно — к строке, в которой абонент попадает в очередь:

1581728710|1581728690.59367|210|NONE|ENTERQUEUE||8996453ХХХХ|1

При возникновении события «ENTERQUEUE» один из параметров — необходимый нам номер абонента. Нам остается только отыскать данную строку в файле queue_log. Этим как раз занимается скрипт на bash, который MONIT нам заботливо вызвал:

#!/bin/bash #MONIT_DESCRITION - строка, которая передана как параметр в скрипт. #Преобразуем timestamp в человеческое представление даты-времени (параметр №1). timedate=$(echo $MONIT_DESCRIPTION | cut -d\| -f1 | cut -d\: -f2 | gawk '{print strftime("%d.%m.%Y %H:%M:%S",$0);}') #Получаем UID (параметр №2) call_id=$(echo $MONIT_DESCRIPTION | cut -d\| -f2) #и номер очереди (параметр №3) qnum=$(echo $MONIT_DESCRIPTION | cut -d\| -f3)  #По номеру очереди присваиваем ей человеческое имя case $qnum in     210)         qname="Очередь 1"         ;;     220)         qname="Очередь 2"         ;; esac  #И ищем в логе строку с UID, номером очереди и событием ENTERQUEUE str=$(grep "|$call_id|$qnum|.*|ENTERQUEUE" /var/log/asterisk/queue_log) #Получаем из неё номер позвонившего абонента (параметр №7) caller_id=$(echo $str | cut -d\| -f7) #Время его попадания в очередь (паоаметр №1) time_enter=$(echo $str | cut -d\| -f1) #И время пропадания из очедери (параметр №1 из события ABANDON) time_abandon=$(echo $MONIT_DESCRIPTION | cut -d\| -f1 | cut -d\: -f2) #Формируем сообщение data="Абонент $caller_id $timedate позвонил в $qname, не дождался ответа и отбился через $(($time_abandon-$time_enter)) сек." #И отправляем его в мессенджер/почту. В данном случае это Slack. /usr/bin/curl -X POST -H 'Content-type: application/json' --data '{"text":"'"$data"'"}' "https://hooks.slack.com/services/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

Собственно, и всё!

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

ссылка на оригинал статьи https://habr.com/ru/post/492728/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *