Интеграция 1С с телефонией Asterisk — одна из наиболее частых задач при автоматизации отделов продаж и служб поддержки. Самый простой и очевидный путь получения истории звонков — прямое чтение таблиц регистрации вызовов (CDR) из базы данных СУБД Asterisk (обычно это MySQL или MariaDB). Однако при попытке настроить такое подключение через внешние источники данных или ADO разработчики регулярно сталкиваются с ошибками диспетчера драйверов ODBC.
В этой статье мы подробно разберем, как решить проблему с подключением к MySQL/MariaDB из 1С, проанализируем нюансы разрядности драйверов, исправим кодировку кириллицы и рассмотрим альтернативные, более безопасные архитектурные подходы к интеграции.
Эта классическая ошибка возникает по двум основным причинам: несоответствие разрядности (битности) приложения и драйвера, либо выполнение кода не на том компьютере, где этот драйвер фактически установлен.
Рассмотрим ситуацию подробнее. Когда мы работаем в 1С в клиент-серверном режиме, весь код, связанный с получением данных из внешних источников (включая регламентные задания и серверные модули), выполняется непосредственно на сервере приложений 1С:Предприятия.
Если вы установили ODBC-драйвер на свой локальный рабочий компьютер и успешно настроили подключение в тонком клиенте (или через утилиту администрирования ODBC), это еще не значит, что оно взлетит на сервере. Как только управление передается серверной процедуре, система пытается инициализировать подключение на стороне сервера 1С. Если на сервере нужный драйвер отсутствует — вы гарантированно получите ошибку диспетчера драйверов.
Вторым критическим фактором является разрядность:
База данных современных дистрибутивов Asterisk (например, FreePBX) чаще всего крутится под управлением СУБД MariaDB. Хотя она совместима с MySQL, стандартные старые драйверы MySQL ODBC (особенно версии 5.1) могут работать некорректно. Мы рекомендуем использовать официальный драйвер MariaDB Connector/ODBC.
Выполним настройку по шагам:
MariaDB Connector/ODBC нужной разрядности (для 64-битного сервера 1С скачиваем x64-версию).C:\Windows\System32\odbcad32.exeC:\Windows\SysWOW64\odbcad32.exeMariaDB ODBC 3.1 Driver (версия может отличаться).Теперь мы можем составить строку подключения. Чтобы избежать привязки к конкретному имени системного источника (DSN) на сервере, лучше использовать прямое подключение (DSN-less connection string). Пример такой строки выглядит следующим образом:
СтрокаПодключения = "DRIVER={MariaDB ODBC 3.1 Driver};TCPIP=1;SERVER=192.168.0.134;PORT=3306;UID=root;PWD=ВашПароль;DATABASE=asteriskcdrdb;";
При чтении текстовых полей из базы Asterisk (например, поля clid, содержащего имя звонящего, или комментариев) в 1С вместо русских букв могут отображаться знаки вопроса или нечитаемые символы («кракозябры»). Это происходит из-за несовпадения кодировки базы данных Asterisk (обычно это UTF-8) и кодировки по умолчанию в драйвере ODBC.
Чтобы решить эту проблему, обязательно добавляйте параметр принудительного указания кодировки соединения. В строке подключения это делается добавлением свойства CharSet=utf8;, либо передачей инициализирующей команды драйверу: STMT=SET NAMES utf8;.
Обновленная строка подключения с поддержкой кириллицы:
СтрокаПодключения = "DRIVER={MariaDB ODBC 3.1 Driver};TCPIP=1;SERVER=192.168.0.134;PORT=3306;UID=root;PWD=ВашПароль;DATABASE=asteriskcdrdb;CharSet=utf8;";
Использование встроенного механизма 1С «Внешние источники данных» требует внесения изменений в метаданные конфигурации, что не всегда удобно (например, если конфигурация находится на поддержке без возможности изменения).
Отличной альтернативой является прямое подключение из кода 1С с помощью COM-объекта ADODB.Connection. Этот способ идеально подходит для регламентных заданий, которые опрашивают базу телефонии по расписанию.
Проанализируем пример кода для получения списка неотвеченных вызовов за текущий день:
// Создаем подключение к СУБД Asterisk
Соединение = Новый COMОбъект("ADODB.Connection");
Соединение.ConnectionString = "DRIVER={MariaDB ODBC 3.1 Driver};TCPIP=1;SERVER=192.168.0.134;PORT=3306;UID=root;PWD=ВашПароль;DATABASE=asteriskcdrdb;CharSet=utf8;";
Попытка
Соединение.Open();
Исключение
ЗаписьЖурналаРегистрации("ИнтеграцияAsterisk", УровеньЖурналаРегистрации.Ошибка, , ,
"Ошибка подключения к БД Asterisk: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
// Формируем запрос к таблице CDR
// Получаем только завершенные вызовы за сегодня, которые не были отвечены (disposition = 'NO ANSWER')
ТекстЗапроса = "SELECT calldate, src, dst, duration, billsec FROM cdr
|WHERE calldate >= CURDATE() AND disposition = 'NO ANSWER'
|ORDER BY calldate DESC";
Recordset = Новый COMОбъект("ADODB.Recordset");
Попытка
Recordset.Open(ТекстЗапроса, Соединение, 0, 1); // 0 = adOpenForwardOnly, 1 = adLockReadOnly
Исключение
Соединение.Close();
ЗаписьЖурналаРегистрации("ИнтеграцияAsterisk", УровеньЖурналаРегистрации.Ошибка, , ,
"Ошибка выполнения запроса к Asterisk: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
// Обходим полученные записи
Пока НЕ Recordset.EOF Цикл
ДатаЗвонка = Recordset.Fields("calldate").Value;
НомерОтправителя = Recordset.Fields("src").Value;
НомерПолучателя = Recordset.Fields("dst").Value;
Длительность = Recordset.Fields("duration").Value;
// Обработка полученных данных, например, создание документа "Событие" или "Звонок" в 1С
// ...
Recordset.MoveNext();
КонецЦикла;
// Закрываем соединения
Recordset.Close();
Соединение.Close();
Для построения качественных отчетов в 1С важно понимать структуру хранения логов звонков в Asterisk. Существует две основные таблицы:
src), кому (dst), когда начался разговор (calldate), общая длительность (duration), длительность чистого разговора без учета ожидания на линии (billsec) и статус звонка (disposition: ANSWERED, NO ANSWER, BUSY). Это простой и понятный источник данных для большинства стандартных отчетов.uniqueid или linkedid. Анализ CEL сложнее, но он необходим для построения глубокой сквозной аналитики путей прохождения звонков.Важная рекомендация по оптимизации производительности: Таблицы CDR и CEL на реально работающих АТС могут расти с огромной скоростью (сотни тысяч записей в месяц). Прямой запрос из 1С без жестких фильтров по дате может перегрузить процессор сервера телефонии и заблокировать таблицы СУБД Asterisk. Всегда используйте фильтрацию по индексированным полям (в первую очередь по дате calldate) и запрашивайте данные только небольшими порциями (например, за последние 10 минут при регулярном опросе).
Прямое подключение к базе данных Asterisk по порту 3306 имеет существенные недостатки с точки зрения информационной безопасности. Вам приходится открывать доступ к СУБД наружу (или настраивать сложные VPN-туннели) и хранить учетные данные администратора базы в коде 1С.
Рассмотрим более современные и безопасные архитектурные альтернативы прямому ODBC-подключению:
На стороне сервера Asterisk (или на отдельном веб-сервере) разворачивается небольшой легковесный скрипт (например, на PHP или Python). Он локально обращается к базе MariaDB, а наружу отдает данные по защищенному протоколу HTTPS в формате JSON только по авторизованным запросам от 1С. В самой 1С подключение реализуется стандартным и быстрым объектом HTTPСоединение, не требующим установки сторонних ODBC-драйверов на сервере приложений.
Вместо того чтобы 1С постоянно опрашивала базу данных Asterisk (PULL-модель), АТС может сама мгновенно сообщать в 1С о завершении каждого звонка. Для этого в диалплане Asterisk (в контексте завершения вызова h) настраивается отправка HTTP-запроса через стандартную утилиту CURL.
Пример настройки в файле extensions.conf:
exten => h,n,Set(res=${CURL(http://1c-server/your_base/hs/asterisk/cdr?uniqueid=${CDR(uniqueid)}&duration=${CDR(duration)}&disposition=${CDR(disposition)})})
На стороне 1С создается собственный HTTP-сервис, который принимает эти параметры в режиме реального времени и сразу регистрирует звонок в информационной базе.
Если на стороне Asterisk активирован модуль cdr_manager, то при завершении каждого звонка система генерирует событие Cdr в интерфейсе AMI (порт 5038). Разработчик может написать внешнюю компоненту или фоновую службу на 1С, которая будет держать постоянное TCP-соединение с портом AMI, «слушать» поток событий и оперативно фиксировать историю звонков в базе данных.