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

    Идея написания 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

    За сим позвольте закончить. Благодарю за внимание!
    Поделиться публикацией

    Комментарии 22

      +1
      Вы бы предоставили демо доступ к ссылочке, что есть в статье — большинство заинтересованных сказало бы Вам огромное спасибо!
        0
        Упустил из виду этот момент.
        Подготовлю в течение пары часов демо-доступ и обновлю статью.
          0
          Добавил демо доступы в конце статьи.
          0
          Я так и не понял… Статистика просматривается с Вашего сервера? или она на нашем сервере астериск работает?
            0
            Сервис saas, т.е. статистика просматривается с нашего сервера.
              0
              ясно
                0
                Над локальной версией работаем, как только она будет доступна, обновим статью.
                  0
                  а если ее купить сколько она стоит?
                    0
                    Я смогу ответить на этот вопрос, когда мы закончим работу над локальной версией
                    Напишите нам, пожалуйста, на sales@vistep.ru
                    Как только все будет готово, мы Вам напишем.
              0
              Это ж AdminLTE. Любой школьник может его правильно настроить и прикрутить бэк. А дев уж и подавно. Ничего нового, собственно.
                +1
                Да, возможно вы правы.
                Ждем ответа от школьников. Посмотрим, что получится у них.
                +1
                Было бы чудесно увидеть отчёт по входу выходу агентов из очереди.
                  0
                  Запишу в TODO, спасибо.
                  0
                  Работает только с mysql?
                    0
                    Да, пока реализована только поддержка MySQL
                    +1
                    Нужно больше фильтров для поиска звонков, как во freepbx или elastix.
                    Для компаний, у которых по 5000 звонков в день не подходит. Хотя выглядит очень презентабельно.
                      0
                      Спасибо за Ваш отзыв.
                      Будем работать над интерфейсом.
                      0
                      Допустим есть система с freepbx… большая, развесистая, как туда подключить вашу статистику?
                        0
                        В статье есть подробная инструкция.
                        Попробуйте выполнить, если что-то не получится, пишите нам на support@vistep.ru — проконсультируем и поможем с настройкой.
                        0
                        Планируются ли:

                        1. Среднее время обработки оператором вход/исход звонка

                        2. Кол-во пропущенных звонков менеджерами ОП (поступившие от операторов) (Операторы — одна очередь, менеджеры — другая очередь)
                          0
                          1. Да.
                          Подобный модуль уже написан, доведем до ума в dev-ветке проекта и добавим в основную версию.

                          2. Есть такой отчет (точнее диаграмма)

                          * если я Вас правильно понял
                          0
                          1. В целом идея хорошая. Через известный домен получать доступ к отчетам по своей АТС из любой точки мира.
                          Жаль, что придется сливать свои данные в ваш сервис, но c другой стороны множество клиентов облачных АТС вообще не парятся над тем, что есть история звонков с записями где-то там на серверах.

                          2. Как имеющий свой астериск (freepbx) человек уже имею систему просмотра звонков. Подключаться к вашей нет особого резона, не так ли? Брать локальную версию? М-м.., а она у вас будет платная? Чем тогда ваша система лучше? Кроме красивых круговых диаграмм, конечно: )

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

                          Самое читаемое