blog.vistep.ru
Блог компании ViStep.RU

Новый web-интерфейс статистики и прослушивания вызовов для IP АТС Asterisk

21 февраля 2017 г. Asterisk » НовостиОбсудить

Идея написания web-интерфейса статистики и прослушивания вызовов для IP АТС Asterisk не покидала меня вот уже несколько лет. Решения, найденные в Интернет, не устраивали по тем или иным критериям - где-то не хватало функционала, какие-то из них совсем не радовали глаз.

И вот, вооружившись стеком технологий и оседлав боевого коня, предоставленного компанией ServerClub, я отправился в путь.

Результатом моего путешествия стал новый интерфейс, с диаграммами, графиками и возможностью скачивать и прослушивать вызовы. Не стану далее утомлять вас словесами, вот пара скриншотов:

А под катом вас ждет видео-гайд по интерфейсу, необходимые настройки и подробное описание всего доступного функционала.

Интерфейс.

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

https://www.youtube.com/watch?v=6vUE8TqxOPA

Описание. Что уже готово, планы.

На текущий момент реализован следующий функционал:

Входящие вызовы:

  • Отчет - Количество звонков в очереди за период (всего/непринятые/отвеченные/не дождались ответа)
  • Диаграмма - Принятые/Непринятые
  • Диаграмма - Принятые, распределение по операторам
  • Диаграмма - Неотвеченные, распределение по операторам
  • Отчет - Статистика по операторам. Кто и сколько принял/не принял вызовов
  • Отчет - Причина разъединения (оператор/клиент)
  • Отчет - Вызовы. Сколько на дату Поступило/Отвеченных/Неотвеченных
  • Поиск записей в БД. Прослушивание и скачивание записей разговров

Исходящие вызовы:

  • Отчет - Всего звонков, неотвеченные/отвеченные/занято(ошибка вызова), общая продолжительность и распределение вызовов по длительности (см. след. пункт).
  • Диаграмма - Распределения вызовов по длительности: до 30с, от 30с до 90с, от 90с
  • Диаграмма - Количество звонков, распределение по менеджерам
  • Отчет - распределение звонков по длительности между менеджерами/операторами
  • Отчет - Вызовы. Сколько было совершено вызовов на дату (считаем только отвеченные*)
  • Поиск записей в БД. Прослушивание и скачивание записей разговров

*отчеты по исходящим строятся только по звонкам во мир, т.е. внутренние звонки между сотрудниками не учитываются

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

*реализовано в настройках, но пока нет в интерфейсе

В ближайших планах добавить:

  • возможность группировать менеджеров/операторов и строить отчеты по группам
  • возможность создавать пользователей и разграничивать их права в просмотре отчетов по группам
  • построение отчетов, если на Asterisk не используются очереди
  • поиск, прослушивание и скачивание записей во всей БД, без фильтров "Входящие/Исходящие" (чтобы видеть и внутренние звонки)

Asterisk. Настройки

Для работы с описываемым интерфейсом потребуется Asterisk версии 1.8 и выше. На АТС должно быть настроено ведение записей CDR и queue_log в БД MySQL. Если вы это еще не сделали, то я расскажу как.

Так же я приведу пример настройки диалплана Asterisk, для организации сохранения записей разговоров.

Настраиваем Asterisk для работы с MySQL

1. Устанавливаем необходимые пакеты (для примера в Debian/Ubuntu)

aptitude install unixodbc-dev libmyodbc

2. Asterisk должен быть собран со следующими опциями

3. Далее редактируем несколько конфиг-файлов

Небольшой хинт, если odbc-коннектор не цепляется.

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

Core was generated by `asterisk -cvvvvvvvgd'.
Program terminated with signal 8, Arithmetic exception.
#0 0x00007ff4cc77a61b in sqlchar_as_sqlwchar () from /usr/lib/x86_64-linux-gnu/odbc/libmyodbc.so

решил тем, что скачал последнюю версию с сайта MySQL

распаковал либы в /usr/lib/x86_64-linux-gnu/odbc/

и чуть подправил конфиг

/etc/odbcinst.ini
[MySQL] Descripti driver
Driver = /usr/lib/x86_64-linux-gnu/odbc/libmyodbc5w.so
Setup = /usr/lib/x86_64-linux-gnu/odbc/libodbcmy5S.so 
CPTimeout =
CPReuse =

В итоге конфиги приняли вид:

/etc/asterisk/res_odbc.conf
[asterisk]
enabled => yes
dsn => MySQL-asterisk
username => asterisk_user
password => 232d2edxse3e
cdr_adaptive_odbc.conf
[cdr_adaptive_connection]
connection=asterisk
table=cdr
alias start => calldate
# раскоментируй, если хочешь видеть реальный номер, накоторый пришел вызов, а не номер оператора очереди
#alias dst => does_not_exist
#alias realdst => dst
/etc/odbc.ini
[MySQL-asterisk]
Description = MySQL Asterisk database
;Trace = Off
;TraceFile = stderr
Driver = MySQL
Server = localhost
User = asterisk_user
Password = 232d2edxse3e
;Port = 3306
Socket = /var/run/mysqld/mysqld.sock
Database = asterisk
Charset = utf8
/etc/odbcinst.ini
[MySQL]
Description = MySQL driver
Driver = /usr/lib/odbc/libmyodbc.so
Setup = /usr/lib/odbc/libodbcmyS.so
CPTimeout =
CPReuse =

*для x64

[MySQL]
Description = MySQL driver
Driver = /usr/lib/x86_64-linux-gnu/odbc/libmyodbc.so
Setup = /usr/lib/x86_64-linux-gnu/odbc/libodbcmyS.so
CPTimeout =
CPReuse =

в конец

cdr_mysql.conf

добавить

alias filename => filename

4. Создадим БД и таблицу cdr в MYSQL

mysql> create database asterisk;
mysql> use asterisk;
mysql> CREATE TABLE `cdr` ( `id` int(9) unsigned NOT NULL AUTO_INCREMENT,
                    `calldate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
                    `clid` varchar(80) NOT NULL DEFAULT '',
                    `src` varchar(80) NOT NULL DEFAULT '',
                    `dst` varchar(80) NOT NULL DEFAULT '',
                    `dcontext` varchar(80) NOT NULL DEFAULT '',
                    `channel` varchar(80) NOT NULL DEFAULT '',
                    `dstchannel` varchar(80) NOT NULL DEFAULT '',
                    `lastapp` varchar(80) NOT NULL DEFAULT '',
                    `lastdata` varchar(80) NOT NULL DEFAULT '',
                    `duration` int(11) NOT NULL DEFAULT '0',
                    `billsec` int(11) NOT NULL DEFAULT '0',
                    `disposition` varchar(45) NOT NULL DEFAULT '',
                    `amaflags` int(11) NOT NULL DEFAULT '0',
                    `accountcode` varchar(20) NOT NULL DEFAULT '',
                    `uniqueid` varchar(32) NOT NULL DEFAULT '',
                    `userfield` varchar(255) NOT NULL DEFAULT '',
                    `filename` varchar(255) NOT NULL DEFAULT '',
                    PRIMARY KEY (`id`),
                    KEY `calldate` (`calldate`),
                    KEY `accountcode` (`accountcode`),
                    KEY `uniqueid` (`uniqueid`),
                    KEY `dst` (`dst`),
                    KEY `src` (`src`) ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;
mysql> grant all on asterisk.* to 'asterisk_user'@'localhost' identified by '232d2edxse3e';

5. Теперь создадим табличку queue_log

mysql> CREATE TABLE IF NOT EXISTS `queue_log` (
`time` varchar(32) DEFAULT NULL,
`callid` char(64) DEFAULT NULL,
`queuename` char(64) DEFAULT NULL,
`agent` char(64) DEFAULT NULL,
`event` char(32) DEFAULT NULL,
`data` char(64) DEFAULT NULL,
`data1` char(64) DEFAULT NULL,
`data2` char(64) DEFAULT NULL,
`data3` char(64) DEFAULT NULL,
`data4` char(64) DEFAULT NULL,
`data5` char(64) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
mysql> \q
Bye

6. Внесем в /etc/asterisk/extconfig.conf

строку

queue_log => odbc,asterisk

7. Перезагружаем Asterisk и проверяем подключение

*CLI> odbc show asterisk 
ODBC DSN Settings
-----------------
  Name:   asterisk
  DSN:    MySQL-asterisk
    Last connection attempt: 1970-01-01 07:00:00
  Pooled: No
  Connected: Yes

8. Так же стоит позвонить и проверить попадают ли данные в БД

Диалплан Asterisk - выдержка из /etc/asterisk/extensions.ael

globals {
    WAV=/var/calls; //Временный каталог с WAV
    MP3=/var/calls; //Куда выгружать mp3 файлы
    RECORDING=1; // Запись, 1 - включена.
};
macro recording (calling,called) {
        if ("${RECORDING}" = "1"){
              Set(fname=${UNIQUEID}-${STRFTIME(${EPOCH},,%Y-%m-%d-%H_%M)}-${calling}-${called});
	      Set(datedir=${STRFTIME(${EPOCH},,%Y/%m/%d)});
	      System(mkdir -p ${MP3}/${datedir});
	      System(mkdir -p ${WAV}/${datedir});
              Set(monopt=nice -n 19 /usr/bin/lame -b 32  --silent "${WAV}/${datedir}/${fname}.wav"  "${MP3}/${datedir}/${fname}.mp3" && rm -f "${WAV}/${fname}.wav" && chmod o+r "${MP3}/${datedir}/${fname}.mp3");
              Set(CDR(filename)=${fname}.mp3);
	      Set(CDR(recordingfile)=${fname}.wav);
              Set(CDR(realdst)=${called});
              MixMonitor(${WAV}/${datedir}/${fname}.wav,b,${monopt});
       };
};
_XXXXXX => {
&recording(${CALLERID(number)},${EXTEN});
Dial(SIP/83843${EXTEN}@multifon,180,tT);
HangUP();
} // end of _XXXXXX

Файлы записей разговоров попадают прямиков в

/var/calls

где имеют следующую иерархию

ls /var/calls/2016/ -l
total 24
drwxr-xr-x 19 asterisk asterisk 4096 May 31 10:10 05
drwxr-xr-x 30 asterisk asterisk 4096 Jun 30 10:02 06
drwxr-xr-x 31 asterisk asterisk 4096 Jul 31 10:18 07
drwxr-xr-x 31 asterisk asterisk 4096 Aug 31 09:00 08
drwxr-xr-x 26 asterisk asterisk 4096 Sep 26 09:51 09

Asterisk. Подключение к интерфейсу статистики

Настало время развеять некоторые сомнения, или же подтвердить некоторые догадки. Да - на текущий момент сервис предоставляется по модели SAAS, т.е. на вашу АТС устанавливается клиент для синхронизации БД и записей звонков.

После регистрации (не думаю, что стоит на ней подробно останавливаться - там все как обычно), нужно зайти в личный кабинет по адресу https://stat.vistep.ru, перейти в настройки, указать путь к файлам записей и нажать "Сохранить". После чего будет доступна ссылка на скачивание скрипта-клиента.

Для установки скрипта нужно выполнить следующие шаги:

1. Установить на сервер nodejs и менеджер пакетов npm , если они еще не установлены (с помощью yum или apt/aptitude/apt-get )

2. Установить pm2

npm install -g pm2

3. Создать и перейти в папку /opt/stat.vistep.ru

mkdir /opt/stat.vistep.ru
cd /opt/stat.vistep.ru

4. Поместить архив со скриптом в папку, созданную шагом ранее, и распаковать его

unzip skript_name.zip

5. Отредактировать скрипт, внеся изменения в строки 393 - 397 (и 398 - опционально, если вам знакомы regexp), а именно

"dbhost":"localhost",
"dbuser":"asterisk_user",
"dbpassword":"232w2edxse3e",
"db":"asterisk", 
"timezone":"Asia/Novokuznetsk", // <--- часовой пояс
"fileMask":  /\.*/  //

6. Запустить скрипт на выполнение:

pm2 start stat.vistep.ru.js --name "ViStep.RU stat"

7. Настроить автозапуск/останов скрипта синхронизации вместе с ОС:

pm2 startup ubuntu #или centos, gentoo
pm2 save

С настройками на этом все. Осталось дождаться загрузки данных на сервер статистики и начать пользоваться!

Условия предоставления сервиса

На текущий момент мы предлагаем 2 варианта сотрудничества по продукту Stat.ViStep.RU:

- Локальная версия, в постоянное пользование.

Все обновления будут доступны Вам без дополнительных оплат.

- Облачная версия.

Обновления включены в абонентскую плату.

Помощь в установке/настройке продукта бесплатна в обоих вариантах.

Все подробности вы можете узнать написав нам на sales@vistep.ru

Заключение

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

За помощью в настройке Asterisk милости прошу писать нам на support@vistep.ru.

Ежели вопрос по сотрудничеству, условиям предоставления сервиса или еще какая оказия, то жду писем на sales@vistep.ru

Так же все мои контакты есть в профиле и, конечно, я с удовольствием отвечу на ваши вопросы в комментариях.

Демо доступы:

support@vistep.ru
0jnoiLJNFDr4-3r2f4

За сим позвольте закончить. Благодарю за внимание!

Перенос БД с одного сервера на другой с помощью netcat

24 августа 2016 г. РазноеОбсудить

Все просто )

на старом сервере запускаем:

mysqldump -uUser -pPassword database | gzip -c | nc IP_нового_сервера 6625 <-порт

на новом

nc -l -p 6625 | gunzip -c | mysql -uUser -pPassword database

Asterisk: Обеспечим VIP-клиентам первое место в очереди звонков, а так же свяжем клиента с конкретным оператором на заданное время

3 июня 2015 г. Asterisk16

Asterisk — это fun!

Каждый раз сталкиваясь с какой-то нестандартной задачей я радуюсь, радуюсь возможности снова погрузиться с головой в это чудесное состояние творчества, работы мысли. В последнее время такие задачи появляются часто и это здорово.

Обозначенные в заголовке были реализованы и работают, а значит пришло время поделиться с сообществом своими решениями.

Расскажу немного подробнее о каждой.

1. Организовать список номеров телефонов VIP-клиентов.

Звонки от VIP-клиентов должны попадать на первое место в очереди Asterisk, для скорейшей обработки именно их обращения. Так же нужно иметь возможность удобно добавлять и удалять контрагентов из этого списка.

2. Связать звонок клиента с конкретным оператором очереди на заданное время.

Настроить Asterisk так, чтобы в его «памяти», на какое-то заданное время, оставалась информация о том, какой из операторов очереди принял вызов. Позвонил человек с номера 8913*75*5*0 и попадает к оператору очереди Алёна и нужно сделать так, чтобы в течение, например суток, входящие звонки с этого номера принимала только Алёна и никто другой.

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

С вступлением на этом заканчиваю, немного Python, MySQL и хитрого dialplan ждут вас под катом.

Далее...