Но зачем-то они же звонили! Может, они хотят денег занести в компанию? Попробуем вернуть и клиентов и их деньги на примере 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/
Добавить комментарий