История звонков IP-АТС 3CX Phone System v.12 в БД 1С
Загрузить актуальную демонстрационную версию истории звонков вы можете по ссылке http://if56.ru/sites/default/files/download/3cx-cdr-client-1c.zip Ограничения демонстрационной версии — регистрируются не все звонки, регистрация происходит в случайном порядке.
В версии 12 SIP АТС 3CX появился новый клиент - 3CX MyPhone. Функционал клиента впечатляет - состояние телефонов, телефонная книга, просмотр истории звонков с возможностью прослушивания записей и многое другое.
Однако возможности интеграции с другими системами довольно ограничены. Интерфейс 3CX API, как и в прошлых версиях работает только на той же машине, где установлена система 3CX, и довольно сложен для программирования. Кроме API у 3CX Phone System есть еще замечательный интерфейс CallHistory, который ведет «посмертный» учет звонков. Этот интерфейс мы успешно использовали несколько лет в связке с Manageengine ServiceDesk Plus внутри своей компании, благодаря чему нам удалось значительно увеличить эффективность нашей «аутсорсерской» работы.
Т.к. у нас остро встал вопрос о внутреннем внедрении системы сервисдеск с открытым исходным кодом и основное направление деятельности у нас все таки 1С, то в качестве нового ПО были рассмотрены продукты компаний Рарус и Деснол-Софт. Выбор пал на Itilium от Десно-Софт.
Но внедрение Itilium без связки с телефонией для нас не имеет смысла. Поэтому первым этапом мы поставили перед собой задачу хранить в 1С историю звонков, а именно: дату и время звонка; длительность; входящий номер; исходящий номер; событие переадресации на другой номер; событие переадресации с другого номера, ссылка на файл аудиозаписи; возможность прослушивания записи.
Итак мы имеем: установленная и настроенная система 3CX Phone System v.12; установленная и опубликованная на web сервере БД 1С Итилиум. Перейдем к реализации.
1. Делаем дополнительные настройки 3CX CallHistory для наших целей. Нам понадобится файл %3CXData%\Data\CDRTemplates\CDRTemplate-SocketListen.xml (В случае ОС Windows Server 2008 это C:\ProgramData\3CX\Data\CDRTemplates\CDRTemplate-SocketListen.xml).
В строке меняем <CallTemplate Host="127.0.0.1" Port="33555" OutboundOnly="false">
параметр Host на внешний IP адрес машины, на которой запущена система 3CX, например 192.168.11.2. Перезапустим сервис 3CX CallHistory и проверим работу сервиса командой
telnet <ip адрес сервера 3CX> 35555
После завершения любого звонка в окне telnet должна появиться информация по этому звонку. Формат данных зависит от содержимого файла CDRTemplate-SocketListen.xml. В принципе, можно использовать и формат по умолчанию, но с учетом того, что нам эти данные придется парсить, можно упростить себе дальнейшую жизнь. Например, так
<?xml version="1.0" encoding="utf-8"?>
<CallTemplate Host="192.168.11.2" Port="33555" OutboundOnly="false">
<!-- xml header text-->
<Script>
<![CDATA[
String ret="";
ret += "historyid=" + callinfo.sRecCallID;ret +=";";
ret += "callid=" + callinfo.nHistoryID;ret +=";";
ret += "callstart=" + callinfo.tmCallStart.ToString("s");ret +=";";
ret += "callanswered=" + callinfo.tmCallAnswered.ToString("s");ret +=";";
ret += "callended=" + callinfo.tmCallEnded.ToString("s");ret +=";";
ret += "duration=" + callinfo.tmDuration;ret +=";";
ret += "callfrom=" + callinfo.sCallFrom;ret +=";";
ret += "callto=" + callinfo.sCallTo;ret +=";";
ret += "callerid=" + callinfo.sCallerID;ret +=";";
ret += "lastcallerid=" + callinfo.sLastCallerID;ret +=";";
ret += "dialnum=" + callinfo.sDialedNumber;ret +=";";
ret += "lastdialnum=" + callinfo.sLastDialedNumber;ret +=";";
ret += "isansw=" + callinfo.bIsAnswered;ret +=";";
ret += "isfail=" + callinfo.bIsFailed;ret +=";";
ret += "iscompl=" + callinfo.bIsCompleted;ret +=";";
ret += "isout=" + callinfo.bCallFromOutside;ret +=";";
ret += "numdet=" + callinfo.iNumDetails;ret +=";";
ret += "recfile=" + callinfo.sRecFile;ret +=";";
ret+="det=" + details.Count.ToString();ret +=";";
foreach(DetailData3 det in details)
{
ret+="\r\n";
ret += "parentid=" + det.ParentIdx;ret +=";";
ret += "destdn=" + det.DestDN;ret +=";";
ret += "destnum=" + det.DestNum;ret +=";";
ret += "starttime=" + det.StartTime.ToString("s");ret +=";";
ret += "duration=" + det.Dur;ret +=";";
ret += "iscompl=" + det.IsCompl;ret +=";";
ret += "ismediator=" + det.IsMediator;ret +=";";
ret += "istoout=" + det.bCallToOutside;ret +=";";
ret += "idcallhist=" + det.iIdCallHist;ret +=";";
ret += "indet=" + det.iNDetail;ret +=";";
}
return ret;
]]>
</Script>
</CallTemplate>
Такой формат сообщений в дальнейшем сильно упростит работу.
Не забываем после правки CDRTemplate-SocketListen.xml перезапускать 3CXCallHistory сервис. И еще очень важное замечание – храните копию данного файла в другом месте или переименуйте его и установите в 3CX значение параметра CALLHISTTEMPLSOCKLISTEN равное имени вашего файла (Настройка – Дополнительные параметры – Вкладка Пользовательские параметры), т.к. при установке сервиспаков для 3CX файлы в каталоге CDRTemplates перезаписываются дефолтными файлами. Итак, на стороне 3CX сервера пока все...
2. В системе 1С создаем регистр сведений ТФ_ИсторияЗвонков:
Затем создаем Web-сервис CallHistory. В нем создаем метод SaveHistory(Record) который будет на входе получать строку из п.1, парсить ее и создавать записи в регистре сведений ТФ_ИсторияЗвонков. Избегаем в названиях сервисов, методов и параметров русских названий.
3. Рисуем реализацию метода SaveHistory
Как видно , исправление формата сообщений дает возможность упростить парсинг.
Дополнительные функции нужны, т. к. форматы даты и времени 1с и С# отличаются:
Основная функция преобразует строку вида <ключ>=<значение>;<ключ>=<значение> в соответствующую структуру:
Еще одно замечание по хранению аудиозаписей. Их можно хранить в базе, однако при этом размер базы растет как на дрожжах. Поэтому файлы лучше хранить в виде ссылок на сетевой ресурс. Формирование правильных ссылок выполняет очень простая функция (в комментарии только ВИД записи):
С Web-сервисом пока все. Теперь свяжем все это вместе.
Для связки используем C# Visual Studio 2012, хотя можно и любой другой инструмент, которым вы владеете.
Наша программа на C# должна подключиться к порту 3CXCallHistory сервиса и все принятое передавать сервису 1С. Как видим, это предельно просто. Вся обвязка имеет своей целью автоматический перезапуск при обрывах связи или недоступности Web-сервиса.
Программа может быть запущена из командной строки, тогда она будет выдавать в консоль диагностику. Можно установить ее как службу, причем если назвать службу 3CX_CDRClient1C, то она будет видна в консоли управления 3CX Phone System.
Теперь нюансы.
1. Авторизация.
Первый вариант — никаких пользователей в базе. Web-сервис доступен. Но мы не ищем легких путей, тем более что боевая база без пользователей — нонсенс.
Второй вариант — запуск веб-сервера от пользователя ОС IUSR_IIS7, например, плюс заведение в 1С пользователя IUSR_IIS7 с авторизацией ОС и правами РОЛИ на запуск веб-сервиса. На первый взгляд работает, но... При запуске веб-клиента получаем не косяк, а КОСЯК!!! Скриншот не сделали, а возвращать настройки лень, поэтому кому не лень — проверьте, кому лень - поверьте.
Так вот, при запуске веб-клиента окно авторизации 1С не появляется, а в красном квадратике на скриншоте пишет пользователь IUSR_IIS7. К тому же в ПараметрыСеанса.ТекущийПользователь пустое значение и это приводит к ошибке «Попытка обращения к неинициализированному параметру сеанса». Так что мимо авторизации никак.
Третий вариант - http://www.forum.mista.ru/topic.php?id=661110 (за что огромное «Спасибо»!). Использование 3 варианта привело к дополнительным строкам в проекте C# app.config .
Если кто знает, как прочитать - будем рады информации.
В результате получилось вот что:
Имя файла — ссылка. При нажатии открывается плеер:
Интеграция возможна в любую конфигурацию 1С с минимальными изменениями.
Новые комментарии