Как стать автором
Обновить

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

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

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

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



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

Интерфейс.


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



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


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

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

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

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

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

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

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

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

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

Asterisk. Настройки


Для работы с описываемым интерфейсом потребуется Asterisk версии 1.8 и выше. На АТС должно быть настроено ведение таблиц cdr, cel и 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 — dev.mysql.com/downloads/file/?id=461779

распаковал либы в /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. Таблицу cel
mysql>CREATE TABLE `cel` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `eventtype` varchar(30) NOT NULL,
  `eventtime` datetime NOT NULL,
  `cid_name` varchar(80) NOT NULL,
  `cid_num` varchar(80) NOT NULL,
  `cid_ani` varchar(80) NOT NULL,
  `cid_rdnis` varchar(80) NOT NULL,
  `cid_dnid` varchar(80) NOT NULL,
  `exten` varchar(80) NOT NULL,
  `context` varchar(80) NOT NULL,
  `channame` varchar(80) NOT NULL,
  `src` varchar(80) DEFAULT NULL,
  `dst` varchar(80) DEFAULT NULL,
  `channel` varchar(80) DEFAULT NULL,
  `dstchannel` varchar(80) DEFAULT NULL,
  `appname` varchar(80) NOT NULL,
  `appdata` varchar(80) NOT NULL,
  `amaflags` int(11) NOT NULL,
  `accountcode` varchar(20) NOT NULL,
  `uniqueid` varchar(32) NOT NULL,
  `linkedid` varchar(32) NOT NULL,
  `peer` varchar(80) NOT NULL,
  `userdeftype` varchar(255) NOT NULL,
  `eventextra` varchar(255) DEFAULT NULL,
  `userfield` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `uniqueid_index` (`uniqueid`),
  KEY `linkedid_index` (`linkedid`),
  KEY `eventtime` (`eventtime`),
  KEY `exten` (`exten`),
  KEY `eventtype` (`eventtype`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;

6. Теперь создадим табличку queue_log
mysql> CREATE TABLE IF NOT EXISTS `queue_log` (
id int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
time timestamp NULL DEFAULT '0000-00-00 00:00:00',
callid varchar(32) NOT NULL default '',
queuename varchar(32) NOT NULL default '',
agent varchar(32) NOT NULL default '',
event varchar(32) NOT NULL default '',
data1 varchar(100) NOT NULL default '',
data2 varchar(100) NOT NULL default '',
data3 varchar(100) NOT NULL default '',
data4 varchar(100) NOT NULL default '',
data5 varchar(100) NOT NULL default '',
PRIMARY KEY (`id`)
) 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, т.е. на вашу АТС устанавливается клиент для синхронизации БД и записей звонков.

После регистрации (не думаю, что стоит на ней подробно останавливаться — там все как обычно), нужно зайти в личный кабинет по адресу 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

За сим позвольте закончить. Благодарю за внимание!
Теги:
Хабы:
+23
Комментарии 24
Комментарии Комментарии 24

Публикации

Истории

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн