Сервер должен быть подготовлен к работе с Wildfly AS.
рекомендуемые минимальные:
2-х ядерный процессор, 4 Gb оперативной памяти, 100Gb hdd.
ПО (минимальные версии): openjdk 8, postgresql 9.5, wildfly 10, asterisk 13.
Клиентским ПО является браузер. Браузер должен поддерживать технологию Websockets. Версии основных браузеров с поддержкой Websockets:
Установка EE приложения производится стандартным деплоером Wildfly. Некоторые предварительные настройки сервера приложений показаны ниже.
На примере Postgresql:
subsystem xmlns=«urn:jboss:domain:datasources:4.0»
<datasources> <datasource jndi-name="java:jboss/datasources/merecrmDS" pool-name="merecrmDS" enabled="true" use-java-context="true"> <connection-url>jdbc:postgresql://127.0.0.1:5432/merecrm</connection-url> <driver>org.postgresql</driver> <pool> <min-pool-size>10</min-pool-size> <max-pool-size>30</max-pool-size> </pool> <security> <user-name>merecrm</user-name> <password>merecrm</password> </security> <validation> <check-valid-connection-sql>SELECT 1</check-valid-connection-sql> <validate-on-match>false</validate-on-match> <background-validation>false</background-validation> </validation> </datasource> </datasources>
subsystem xmlns=«urn:jboss:domain:ejb3:5.0»
<mdb> <resource-adapter-ref resource-adapter-name="activemq-ra"/> <bean-instance-pool-ref pool-name="mdb-strict-max-pool"/> </mdb>
subsystem xmlns=«urn:jboss:domain:messaging-activemq:1.0»
<extension module="org.wildfly.extension.messaging-activemq"/> ... <subsystem xmlns="urn:jboss:domain:messaging-activemq:1.0"> <server name="default"> <security-setting name="#"> <role name="guest" send="true" consume="true" create-non-durable-queue="true" delete-non-durable-queue="true"/> </security-setting> <address-setting name="#" dead-letter-address="jms.queue.DLQ" expiry-address="jms.queue.ExpiryQueue" max-size-bytes="10485760" page-size-bytes="2097152" message-counter-history-day-limit="10"/> <http-connector name="http-connector" socket-binding="http" endpoint="http-acceptor"/> <http-connector name="http-connector-throughput" socket-binding="http" endpoint="http-acceptor-throughput"> <param name="batch-delay" value="50"/> </http-connector> <in-vm-connector name="in-vm" server-id="0"/> <http-acceptor name="http-acceptor" http-listener="default"/> <http-acceptor name="http-acceptor-throughput" http-listener="default"> <param name="batch-delay" value="50"/> <param name="direct-deliver" value="false"/> </http-acceptor> <in-vm-acceptor name="in-vm" server-id="0"/> <jms-queue name="ExpiryQueue" entries="java:/jms/queue/ExpiryQueue"/> <jms-queue name="DLQ" entries="java:/jms/queue/DLQ"/> <jms-queue name="MerecrmQueue" entries="java:/jms/queue/Merecrm"/> <connection-factory name="InVmConnectionFactory" entries="java:/ConnectionFactory" connectors="in-vm"/> <connection-factory name="RemoteConnectionFactory" entries="java:jboss/exported/jms/RemoteConnectionFactory" connectors="http-connector"/> <pooled-connection-factory name="activemq-ra" entries="java:/JmsXA java:jboss/DefaultJMSConnectionFactory" connectors="in-vm" transaction="xa"/> </server> </subsystem>
subsystem xmlns=«urn:jboss:domain:undertow:3.1»
<handlers> <file name="merefiles" path="/var/lib/jboss/merecrm/files" directory-listing="true"/> </handlers>
wildfly.service
[Unit] Description=WildFly application server Wants=network.target After=network.target asterisk.service postgresql.service [Service] Type=simple User=wildfly Group=wildfly ExecStart=/opt/wildfly/bin/standalone.sh #Restart=always #RestartSec=20 [Install] WantedBy=multi-user.target
asterisk.service
[Unit] Description=Asterisk PBX After=network.target postgresql.service [Service] Type=forking User=asterisk Group=asterisk Environment=HOME=/var/lib/asterisk WorkingDirectory=/var/lib/asterisk ExecStart=/usr/sbin/asterisk -C /etc/asterisk/asterisk.conf ExecStop=/usr/sbin/asterisk -rx 'core stop now' ExecReload=/usr/sbin/asterisk -rx 'core reload' PIDFile=/run/asterisk/asterisk.pid [Install] WantedBy=multi-user.target
asterisk.conf
d /var/run/asterisk 0775 asterisk asterisk
[merecrm] secret = merecrm read = all write = all permit= 0.0.0.0/0.0.0.0
[merecrm] ;include => internal exten => _[78]XXXXXXXXXX,1,Set(CALLFILENAME=${UNIQUEID}) exten => _[78]XXXXXXXXXX,n,NoOp(${UNIQUEID}) exten => _[78]XXXXXXXXXX,n,MixMonitor(${CALLFILENAME}.WAV,b) exten => _[78]XXXXXXXXXX,n,Dial(SIP/out-trunk/${EXTEN},30,tT) [out-2] exten => _XXXX.,1,Set(CALLFILENAME=${UNIQUEID}) exten => _XXXX.,n,MixMonitor(${CALLFILENAME}.WAV,b) exten => _XXXX.,n,Queue(out-2)
Имя очереди для predictive, progressive должно совпадать с контекстом.
Имена файлов записей должны совпадать с UNIQUEID канала.
[mytrunk](!) type=friend username=username secret=secret nat=no;force_rport,comedia fromuser=username qualify = yes context=from-mytrunk canreinvite=no disallow=all allow=alaw allow=ulaw host=voip.mytrunk.ru insecure=invite,port [out-trunk](mytrunk)
[out-2] musiconhold = default strategy = rrmemory timeout = 20 announce-holdtime = no joinempty = no timeoutrestart = yes
CREATE ROLE merecrm WITH LOGIN PASSWORD 'merecrm';
CREATE DATABASE merecrm OWNER merecrm;
Пример начального заполнения таблиц:
INSERT INTO company (name) VALUES ('merecrm'); INSERT INTO users (name, secret, ROLE, login, email, phone, idcompany,enabled) VALUES ('admin', '21232f297a57a5a743894a0e4a801fc3','administrator', 'admin', 'info@merecrm.ru', '79094027854', 1, TRUE); INSERT INTO etc (KEY, VALUE, idcompany, idusers) VALUES ('upload','/var/lib/jboss/merecrm/upload/',0,0); INSERT INTO etc (KEY, VALUE, idcompany, idusers) VALUES ('dashboard fields','number;idbase;name;phone;address;nextdate;iduser;lastrestus',1,0); INSERT INTO etc (KEY, VALUE, idcompany, idusers) VALUES ('dashboard count','25',1,0); INSERT INTO etc (KEY, VALUE, idcompany, idusers) VALUES ('astserver','127.0.0.1',0,0); INSERT INTO etc (KEY, VALUE, idcompany, idusers) VALUES ('astmanager','merecrm',0,0); INSERT INTO etc (KEY, VALUE, idcompany, idusers) VALUES ('astsecret','merecrm',0,0); INSERT INTO etc (KEY, VALUE, idcompany, idusers) VALUES ('astexten','0',1,1); INSERT INTO etc (KEY, VALUE, idcompany, idusers) VALUES ('astchannel','SIP/',1,1); INSERT INTO etc (KEY, VALUE, idcompany, idusers) VALUES ('files','/var/lib/jboss/merecrm/files/',0,0); INSERT INTO etc (KEY, VALUE, idcompany, idusers) VALUES ('astcontext','merecrm',1,1); INSERT INTO etc (KEY, VALUE, idcompany, idusers) VALUES ('astmonitor','/var/spool/asterisk/monitor/',0,0); INSERT INTO etc (KEY, VALUE, idcompany, idusers) VALUES ('defaultproduct','1',1,0); INSERT INTO etc (KEY, VALUE, idcompany, idusers) VALUES ('defaultaction','dashboard',1,1); INSERT INTO etc (KEY, VALUE, idcompany, idusers) VALUES ('defaultrestus','1',1,0); INSERT INTO etc (KEY, VALUE, idcompany, idusers) VALUES ('dashboard tooltip fields','1',1,0); INSERT INTO etc (KEY, VALUE, idcompany, idusers) VALUES ('default calling priority','10',1,0); INSERT INTO etc (KEY, VALUE, idcompany, idusers) VALUES ('asttrunk','SIP/out-trunk/',1,0); INSERT INTO etc (KEY, VALUE, idcompany, idusers) VALUES ('default context','merecrm',1,0); INSERT INTO restus (name, enabled, isfinal, idparent, level) VALUES ('Контакт', TRUE, FALSE, 0, 1); INSERT INTO restus (name, enabled, isfinal, idparent, level) VALUES ('Обработка', TRUE, FALSE, 1, 1); INSERT INTO restus (name, enabled, isfinal, idparent, level) VALUES ('Отказ', TRUE, TRUE, 1, 1); INSERT INTO KEYS (name, TYPE, isfilter) VALUES ('Комментарий','text',FALSE); INSERT INTO KEYS (name, TYPE, isfilter) VALUES ('Марка','string',TRUE); INSERT INTO product (name,description) VALUES ('Освежитель','Вонючка');
Для входа в систему необходимо ввести логин и пароль в окне ввода.
Существуют три роли входа: администратор, менеджер, пользователь.
Администратор может управлять всеми предприятиями и пользователями.
Менеджер управляет только своим предприятием и его пользователями.
Пользователь работает с контактами в рамках предприятия.
Администратору доступны действия:
Загрузка базы осуществляется из фалов форматов xlsx, ods(разработка)
Поля базы должны содержать ряд обязательных реквизитов:
Так же в файле могут быть и дополнительные реквизиты.
После выбора файла система проведет анализ первых строк и предложит сопоставить столбцы таблицы с полями системы.
После этого происходит анализ всех строк таблицы на соответствие типов и возможную корректность данных. При нахождении несоответствия выводится предупреждение с номером некорректной строки
После коррекции загружаемого файла будет предложено обозначить продукт и начальный статус-результат контакта.
В данном разделе можно создать и редактировать пользователей системы.
Пользователь имеет следующие реквизиты:
В этом разделе можно создавать и редактировать анкеты. Анкета так же называется Кампанией.
Анкета описывается следующими реквизитами:
Анкету типа predictive, robot, progressive можно Запустить или Остановить.
Анкета может иметь сценарий разговора. Сценарий состоит из вопросов, ответов и действий на возможный выбор ответов.
Автоматические кампании для вычисления коэффициента дозвона используют облачную функцию. В случае отсутствия подключения к облаку с действующим идентификатором он равен 1.
Базы группируют контакты в отдельную сущность.
Каждая настройка имеет свою область применения. Некоторые настройки применимы исключительно к предприятию, некоторые могут быть персональными для пользователей.
Настройка | Описание | Пример | Все | Предприятие | Пользователь |
---|---|---|---|---|---|
upload | Путь для загрузки файлов | /var/lib/jboss/merecrm/upload/ | ✔ | — | — |
astmonitor | Путь записей Asterisk | /var/spool/asterisk/monitor/ | ✔ | — | — |
astserver | Адрес сервера Asterisk | 192.168.27.4 | ✔ | — | — |
astmanager | Пользователь AMI Asterisk | manager | ✔ | — | — |
astsecret | Пароль пользователя AMI Asterisk | secret | ✔ | — | — |
files | Путь хранилища файлов контактов | /var/lib/jboss/merecrm/files/ | ✔ | ✔ | — |
defaultproduct | Продукт по умолчанию | 3 | ✔ | ✔ | — |
dashboard count | Количество строк в списке контактов | 50 | ✔ | ✔ | — |
dashboard fields | Поля списка контактов | number;idbase;1;name;phone;address;3;iduser; | ✔ | ✔ | ✔ |
astchannel | Канал Asterisk для звонков | SIP/ | — | — | ✔ |
astcontext | Контекст Asterisk для звонков | merecrm | — | — | ✔ |
astexten | Экстен Asterisk для звонков | 116 | — | — | ✔ |
defaultrestus | Результат по умолчанию | 2 | — | ✔ | — |
default calling priority | Приоритет звонка по умолчанию | 10 | — | ✔ | — |
defaultaction | Действие по умолчанию | dashboard | ✔ | ✔ | ✔ |
maximum k | Максимальный коэффициент тенденций | 5 | — | ✔ | — |
default context | Контекст по умолчанию | merecrm | — | ✔ | — |
asttrunk | Транк (peer) для вызовов | out-trunk | — | ✔ | — |
dashboard tooltip fields | Подсказка для строки списка контактов | merecrm | ✔ | ✔ | — |
customerunique | Код инсталляции для облака | 5b….44f | ✔ | — | — |
robot user | ID пользователя для кампаний robot | 1 | — | ✔ | — |
predictive user | ID пользователя для кампаний predictive | 1 | — | ✔ | — |
pause robot call | Пауза для кампаний robot | 15 | — | ✔ | — |
default calling priority | Приоритет по умолчанию для заявок | 9 | — | ✔ | — |
Могут содержать через точку с запятой стандартные поля контакта:
или индекс дополнительного поля из таблицы.
Главное рабочее окно системы. Столбцы и строки этой таблицы можно персонально настраивать в соответствующем разделе.
Сортировка списка производится по Дате следующего контакта. Все просроченные по взаимодействию контакты выделяются красным цветом. Рабочие контакты, уже имеющие статус-результат выделяются желтым цветом.
Контакты, имеющие конечный результат-статус в таблице не отображаются.
Пользователь видит только те контакты, для которых он назначен ответственным
В форме контакта выводятся допустимые действия для контакта, такие, как звонок. При осуществлении звонка сначала осуществляется набор оператора, затем контакта. Для каждой попытки контакта формируется заявка.
При инициировании звонка в Asterisk устанавливаются переменные канала:
Основным инструментом работы с контактами являются фильтры. Фильтры работают как по основным реквизитам, так и по дополнительным.
Так же имеются суррогатные показатели:
Действия применяются к выбранной строке контакта либо к отфильтрованному Фильтром набору контактов.
Цепочка работы с контактами при автоматическом методе обзвона:
Импорт—Фильтр—Действие—Анкета—Очередь—Тенденции
Иногда необходимо обработать контакт с привлечением другого сотрудника. Для этого можно делегировать контакт. Делегировать можно любому сотруднику компании, кроме ответственного. В процессе делегирования необходимо указать Причину (описание). При закрытии делегирования необходимо указать Ответ (описание)
Список делегированных контактов отображается ниже основной таблицы. Ответственный за контакт сотрудник может видеть пометку делегированных контактов.
В данном разделе показаны события системы.
События могут быть широковещательными по предприятию и персональными, например простыми сообщениями.
Сообщение можно создать из соответствующей таблицы или из главной, выбрав пункт Сообщить. В таком случае сообщение будет касаться выбранного контакта.
Тенденции показывают текущие рабочие показатели Asterisk.
Таблица каналов содержит текущие активные каналы Asterisk. К каналам администратор может подключаться в режиме подслушивания или шепота.
Таблица тенденций показывает расчетные коэффициенты отзывчивости телефонной базы.
Слишком большие показатели, например 20, говорят о том, что с дозвоном не всё в порядке. на 20 набраных номеров одно или ни одного соединения.
Коэффициент набора вычисляется один раз каждые пять минут для каждой анкеты-кампании и применяется к количеству отправляемых в набор телефонных номеров.
Данный раздел работает с очередями Asterisk. В главной таблице показаны все описанные очереди и их рабочие показатели.
В очередь можно назначать или снимать агентов-операторов, которые будут принимать звонки при наличии кампаний с автоматическим набором.
В системе некоторые функции вынесены в облачное пространство для унификации их функционирования.
В облаке выполняются следующие функции:
Для доступа к облаку необходим действующий идентификатор пользователя системы
Проверить и обновить на один день ключ самостоятельно можно по ссылке: Проверка ключа Самостоятельное обновление допускается до 15 раз.
Все функции устанавливают переменную agiresilt в значения true или fasle
test
ничего не делает, кроме установки результата
getproviderbyphone - возвращает оператора связи и регион работы, если он есть.
exten => _[78]XXXXXXXXXX,n,Agi(agi://127.0.0.1/getproviderbyphone.agi?phone=${EXTEN}) exten => _[78]XXXXXXXXXX,n,NoOp(${provadername}) exten => _[78]XXXXXXXXXX,n,NoOp(${provaderregion1}) exten => _[78]XXXXXXXXXX,n,NoOp(${provaderregion2})
setrestus - устанавливает результат заявки контакта. Значение необходимо брать из базы существующих результатов.
exten => 881,n,Agi(agi://127.0.0.1/setrestus.agi?idrestus=4&idrequest=${idrequest}) exten => 881,n,NoOp(${agiresult})