Мы располагаем 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
. После этого изменения вступят в силу.
Эпилог
Приведенная нами методика сбора пропущенных вызовов, разумеется, не является единственной. Возможно, можно найти более оптимальные пути решения этой задачи. Пробуйте, ищите, экспериментируйте, делитесь с нами опытом и идеями.