Настройка уведомлений о пропущенных вызовах в FreePBX

Дмитрий Аверин
31 июля 2020
access_time7 минут
remove_red_eye10146
Компания «Ланкрафт»
Компания «Ланкрафт»

Мы располагаем FreePBX 13.0.197, Asterisk 13.12.1, а также сервером с CentOS 6.6. 

В Asterisk есть IVR (Voice Menu), которое раскидывает поступающие вызовы по очередям (Queues). При этом для каждой из них назначается агент (Operator).

Теоретическая часть

Рассмотрим, какие события происходят в различных частях системы.

Asterisk

При поступлении входящего звонка в Asterisk происходит его передача на IVR. Абонент выбирает определенный пункт путем нажатия клавиши с цифрой на телефонном аппарате. После этого его вызов направляется в заданную очередь, а ее свободным в данный момент агентам в один и тот же момент поступает звонок.

Механизм реализуется предельно просто. При попадании входящего вызова в очередь у свободных агентов переменная Disposition принимает значение NO ANSWER. Возможны и другие варианты. Единственное значение, которое не мог принять в данном случае параметр Disposition, это – ANSWERED.

Исследуя Report CDR, можно увидеть, что при передаче звонка в очередь (в колонке App прописывается значение Queue) у всех событий в колонке System устанавливается значение UniqueID.

Вкратце о CDR

Необходимо иметь представление о том, как функционирует CDR и в какое мгновение туда заносятся сведения, видимые потом нами в Report CDR. Итак, CDR в контексте ОС являет собой базу данных, куда Asterisk помещает детальный отчет по звонкам. В нашей ситуации представлена база под названием asteriskcdrdb, расположенная в Mysql.

Нам удалось показать на практическом примере, что информация о вызове с некоторым uniqueid записывается в asteriskcdrdb не в тот же миг, как возникло определенное событие, а только после того, как система зафиксировала завершение вызова (hangupcall).

Принцип работы решения

Решения представляет собой Bash-скрипт, в который передаются три параметра:

  • UniqueID, чтобы фильтровать информацию, поступающую из CDR;
  • CALLER ID (номер абонента). Необходим, чтобы мы знали, кому необходимо перезванивать;
  • номер очереди, куда был направлен вызов. Этот параметр позволяет определить цель звонившего, узнать, кому требуется направить уведомление по электронной почте о пропущенном звонке.

Скрипт подключается к Asteriskcdrdb в Mysql и берет перечень значений переменной Disposition с указанным UniqueID. Из списка необходимо убрать все значения, кроме ANSWERED (удалить BUSY и другие). Оставшаяся опция будет означать, что на звонок был ответ, либо будет зафиксирован пропущенный вызов. В последнем случае на электронную почту скрипт отправляет соответствующее сообщение.

Несколько опережая события, отметим один нюанс. Asterisk исполняет команды строго в определенной последовательности. Выполнение следующей начинается только после того, как была завершена предыдущая, что вполне вписывается в логику событий. Но производить вызов Bash-скрипта нам придется до момента выполнения команды Hangupcall. Получается, что на временном отрезке, когда скрипт выполняется, CDR еще не содержит сведений о необходимом нам UniqueID. Эти данные еще просто не внесены в БД.

Чтобы решить эту дилемму, вызов скрипта мы будем производить, пользуясь опцией «&». Это позволит Asterisk без задержки приступить к реализации следующего этапа, то есть Hangupcall. В самом скрипте укажем незначительную временную паузу, которая позволит системе записать данные с необходимым нам UniqueID в CDR.

Практическая часть

Как настроить Postfix

Итак, мы располагаем доменом почты lankraft.ru на Яндексе, находящимся в Yandex'е. Выполним настройку почтового сервера postfix в клиентском режиме SMTP для отправки электронной корреспонденции с аккаунта asterisk@lankraft.ru.

В первую очередь займемся установкой / обновлением / проверкой имеющихся пакетов.

yum install postfix
yum install mailx
yum install cyrus-sasl cyrus-sasl-lib cyrus-sasl-plain

Мы не станем убирать главный конфигурационный файл postfix/etc/postfix/main.cf, а позаботимся о создании резервной копии.

cp /etc/postfix/main.cf /etc/postfix/main.cf.sav

Выполним редактирование /etc/postfix/main.cf, попробуем привести его к определенному виду.

nano /etc/postfix/main.cf
#####################
relayhost =
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/private/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_sasl_type = cyrus
smtp_sasl_mechanism_filter = login
smtp_sender_dependent_authentication = yes
sender_dependent_relayhost_maps = hash:/etc/postfix/private/sender_relay
smtp_generic_maps = hash:/etc/postfix/generic
smtp_tls_CAfile = /etc/postfix/ca.pem
smtp_use_tls = yes
smtputf8_autodetect_classes = all
#####################

Дальше нам необходимо создать каталог для конфигурационных файлов. Для этого указываем:

mkdir /etc/postfix/private

Отредактируем /etc/postfix/private/sender_relay. Здесь необходимо определить SMTP Server, который будет использоваться для домена почты.

nano /etc/postfix/private/sender_relay
##################
@lankraft.ru smtp.yandex.ru
##################

Выполним редактирование /etc/postfix/private/sasl_passwd. Здесь мы пропишем электронный почтовый ящик, необходимый для отправки в дальнейшем уведомлений. Также укажем Login и пароль рабочего аккаунта.

nano /etc/postfix/private/sasl_passwd
#####################
asterisk@lankraft.ru asterisk@lankraft.ru:password_asterisk
#####################

Выполним также редактирование /etc/postfix/generic. Здесь прописываются правила, на основе которых будет подменяться исходящий адрес.

nano /etc/postfix/generic
#####################
root asterisk@lankraft.ru
root@localhost asterisk@lankraft.ru
root@localhost.localdomain asterisk@lankraft.ru
root@freepbx asterisk@lankraft.ru
root@freepbx.localdomain asterisk@lankraft.ru
root@asterisk asterisk@lankraft.ru
root@asterisk.localdomain asterisk@lankraft.ru
asterisk asterisk@lankraft.ru
asterisk@localhost asterisk@lankraft.ru
asterisk@localhost.localdomain asterisk@lankraft.ru
asterisk@freepbx asterisk@lankraft.ru
asterisk@freepbx.localdomain asterisk@lankraft.ru
asterisk@asterisk asterisk@lankraft.ru
asterisk@asterisk.localdomain asterisk@lankraft.ru
root@localdomain.localdomain asterisk@lankraft.ru
#####################

Первоначально исходящий адрес определяется в /etc/hosts, а также в /etc/hostname. Он находится в зависимости и от пользовательского имени, которое планируется применять в отправке корреспонденции. Получается, что даже при использовании нами SMTP-клиента и отправке уведомлений через asterisk@lankraft.ru в любом случае в поле «Отправитель» Postfix занесет свой вариант, который он выберет с учетом исходных данных. Этот момент подлежит обязательному исправлению посредством конфигурационного файла.

Рассмотрим содержимое /etc/hosts:

cat /etc/hosts
#####################
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 asterisk.localdomain
127.0.0.1 localhost.localdomain localhost
::1 asterisk localhost localhost6
#####################

Важный момент: необходимо, чтобы серверу был присвоен какой-нибудь домен. Такое требование вызвано тем, что почтовая утилита пытается найти доменное имя в /etc/hosts. Если отыскать его немедленно не получается, то программа продолжит находиться в поисковом режиме еще некоторое время (от 3 минут и больше), и лишь затем выполнит отправку письма. Получается, если мы не прописываем домен, то задерживаем пересылку корреспонденции на несколько минут.

Следующее наше действие: перевод подготовленных конфигурационных файлов в БД, прошедшие индексацию. Делается это с помощью следующей команды:

postmap /etc/postfix/generic && postmap /etc/postfix/private/{sasl_passwd,sender_relay}

Еще требуется загрузить и скопировать на сервер сертификат smtp.yandex.ru. Для этого вводим:

openssl s_client -starttls smtp -crlf -connect smtp.yandex.ru:25 > /etc/postfix/ca.pem

Здесь следует учесть, что после вывода на дисплей сведений технического характера команда будет пребывать в зависшем состоянии. Для завершения ее работы, воспользуемся комбинацией клавиш Ctrl+C.

Получаем примерно такой результат:

nano /etc/postfix/ca.pem
-----BEGIN CERTIFICATE-----
 MIIGazCCBVOggfhfghgGdfhdhdj5hrtfgdBgkqhkiG9w0BAQsFADBf
...
nRG0DdfYUHJKIfddfPGApFORYe
-----END CERTIFICATE-----

Остается перезапустить Postfix и отправить тестовое письмо. Для этого используем следующие команды:

service postfix restart

echo "Это тело письма" | mail -s "Это тема" admin@lankraft.ru

Первая команда служит для перезагрузки, а вторая реализует механизм отправки электронного письма. Если процедура прошла корректно, то на адрес admin@lankraft.ru должно поступить тестовое уведомление.

На этом этап работы, связанный с настройкой Postfix, можно считать завершенным.

Загрузка Bash-скрипта

Создадим папку для размещения скрипта::

mkdir /home/asterisk/scripts

Создадим файл скрипта:

touch /home/asterisk/scripts/noanswer.sh

Предоставим права, обеспечивающие выполнение команд:

chmod +x /home/asterisk/scripts/noanswer.sh

Текст bash-скрипта доступен по ссылке.

«res_sql="SELECT disposition FROM cdr WHERE uniqueid = '$1'"»:

Запрос в Mysql вынесен в обособленную переменную, что удобнее.

Дальше необходимо сделать запрос в Mysql и отфильтровать результаты. Необходимо удалить все, оставив только ANSWERED. В случае наличия нескольких таких значений требуется оставить одно из них.

БД в нашем случае использовались имя пользователя и пароль, которые уже были нам известны. Для определения пользовательского логина Asterisk в Mysql при пользовании FreePBX необходимо воспользоваться командой:

cat /etc/amportal.conf | grep AMPDBUSER

После этого необходимо также узнать пароль. Пропишем:

cat /etc/amportal.conf | grep AMPDBPASS

Настраиваем Asterisk

Мы работаем с FreePBX, где предусмотрено несколько разновидностей файлов конфигурации. Часть из них подлежит перезаписи после перезапуска системы. Другие сохраняются в том же виде независимо от выключения. Такие виды файлов принято называть «кастомными», поскольку они как раз созданы для редактирования администратором. К этой категории относится extensions_override_freepbx.conf, который мы и будем редактировать.

Введем требуемую команду.

cat /etc/asterisk/extensions.conf | grep extensions_override_freepbx.conf
#####################
#include extensions_override_freepbx.conf
#####################

Отредактируем файл, чтобы привести его в надлежащий вид.

nano /etc/asterisk/extensions_override_freepbx.conf
#####################
[ext-queues]
exten => h,1,System(/home/asterisk/scripts/noanswer.sh ${CDR(uniqueid)} ${CALLERID(num)} ${NODEST} &)
exten => h,2,Macro(hangupcall,)
#####################

Как было сказано выше, обязательно должен присутствовать символ «&».

Учитывая особенности использования информации CDR Bash-скриптом, мы не ждем, пока закончится обработка команды, а переходим к следующему этапу в Asterisk. В самом же скрипте предусматриваем небольшую паузу перед главной частью.

После редактирования файла конфигурации требуется выполнить перезагрузку ядра Asterisk с помощью команды core restart now. После этого изменения вступят в силу.

Эпилог

Приведенная нами методика сбора пропущенных вызовов, разумеется, не является единственной. Возможно, можно найти более оптимальные пути решения этой задачи. Пробуйте, ищите, экспериментируйте, делитесь с нами опытом и идеями.