Как получить историю звонков из базы данных Asterisk (MySQL/MariaDB) в 1С: Решение проблем с ODBC-драйверами и альтернативные способы интеграции

Программист 1С v8.3 (Управляемые формы) Управленческий учет IT и автоматизация бизнеса
← На главную

Интеграция 1С с телефонией Asterisk — одна из наиболее частых задач при автоматизации отделов продаж и служб поддержки. Самый простой и очевидный путь получения истории звонков — прямое чтение таблиц регистрации вызовов (CDR) из базы данных СУБД Asterisk (обычно это MySQL или MariaDB). Однако при попытке настроить такое подключение через внешние источники данных или ADO разработчики регулярно сталкиваются с ошибками диспетчера драйверов ODBC.

В этой статье мы подробно разберем, как решить проблему с подключением к MySQL/MariaDB из 1С, проанализируем нюансы разрядности драйверов, исправим кодировку кириллицы и рассмотрим альтернативные, более безопасные архитектурные подходы к интеграции.

Почему возникает ошибка «Источник данных не найден и не указан драйвер, используемый по умолчанию»?

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

Рассмотрим ситуацию подробнее. Когда мы работаем в 1С в клиент-серверном режиме, весь код, связанный с получением данных из внешних источников (включая регламентные задания и серверные модули), выполняется непосредственно на сервере приложений 1С:Предприятия.

Если вы установили ODBC-драйвер на свой локальный рабочий компьютер и успешно настроили подключение в тонком клиенте (или через утилиту администрирования ODBC), это еще не значит, что оно взлетит на сервере. Как только управление передается серверной процедуре, система пытается инициализировать подключение на стороне сервера 1С. Если на сервере нужный драйвер отсутствует — вы гарантированно получите ошибку диспетчера драйверов.

Вторым критическим фактором является разрядность:

Пошаговая настройка подключения через ODBC-драйвер MariaDB

База данных современных дистрибутивов Asterisk (например, FreePBX) чаще всего крутится под управлением СУБД MariaDB. Хотя она совместима с MySQL, стандартные старые драйверы MySQL ODBC (особенно версии 5.1) могут работать некорректно. Мы рекомендуем использовать официальный драйвер MariaDB Connector/ODBC.

Выполним настройку по шагам:

  1. Скачайте с официального сайта MariaDB дистрибутив драйвера MariaDB Connector/ODBC нужной разрядности (для 64-битного сервера 1С скачиваем x64-версию).
  2. Установите скачанный драйвер непосредственно на сервере, где запущенна служба 1С:Предприятия.
  3. Для проверки корректности установки откройте утилиту администрирования ODBC на сервере. Обратите внимание на пути к утилитам в 64-битных ОС Windows:
    • Для 64-битных драйверов: C:\Windows\System32\odbcad32.exe
    • Для 32-битных драйверов: C:\Windows\SysWOW64\odbcad32.exe
  4. Убедитесь, что во вкладке «Драйверы» появился пункт MariaDB 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;";

Альтернатива Внешним источникам данных: Подключение через ADO

Использование встроенного механизма 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();

Понимание структуры таблиц Asterisk: CDR или CEL?

Для построения качественных отчетов в 1С важно понимать структуру хранения логов звонков в Asterisk. Существует две основные таблицы:

  1. CDR (Call Detail Records) — содержит агрегированную информацию о звонках. Одна запись в этой таблице представляет собой один завершенный звонок. В ней фиксируется: кто звонил (src), кому (dst), когда начался разговор (calldate), общая длительность (duration), длительность чистого разговора без учета ожидания на линии (billsec) и статус звонка (disposition: ANSWERED, NO ANSWER, BUSY). Это простой и понятный источник данных для большинства стандартных отчетов.
  2. CEL (Channel Event Logging) — таблица детальных событий каналов. Если звонок внутри компании переводился с менеджера на менеджера, удерживался на линии, уходил на голосовую почту или в очередь — в CDR может записаться лишь конечный результат или создастся несколько путаных записей. В CEL же каждое действие фиксируется как отдельное микро-событие (START, ANSWER, TRANSFER, HANGUP) с привязкой к уникальному идентификатору звонка uniqueid или linkedid. Анализ CEL сложнее, но он необходим для построения глубокой сквозной аналитики путей прохождения звонков.

Важная рекомендация по оптимизации производительности: Таблицы CDR и CEL на реально работающих АТС могут расти с огромной скоростью (сотни тысяч записей в месяц). Прямой запрос из 1С без жестких фильтров по дате может перегрузить процессор сервера телефонии и заблокировать таблицы СУБД Asterisk. Всегда используйте фильтрацию по индексированным полям (в первую очередь по дате calldate) и запрашивайте данные только небольшими порциями (например, за последние 10 минут при регулярном опросе).

Безопасные методы интеграции без прямого доступа к MySQL

Прямое подключение к базе данных Asterisk по порту 3306 имеет существенные недостатки с точки зрения информационной безопасности. Вам приходится открывать доступ к СУБД наружу (или настраивать сложные VPN-туннели) и хранить учетные данные администратора базы в коде 1С.

Рассмотрим более современные и безопасные архитектурные альтернативы прямому ODBC-подключению:

1. HTTP/REST API прослойка (Middleware)

На стороне сервера Asterisk (или на отдельном веб-сервере) разворачивается небольшой легковесный скрипт (например, на PHP или Python). Он локально обращается к базе MariaDB, а наружу отдает данные по защищенному протоколу HTTPS в формате JSON только по авторизованным запросам от 1С. В самой 1С подключение реализуется стандартным и быстрым объектом HTTPСоединение, не требующим установки сторонних ODBC-драйверов на сервере приложений.

2. PUSH-модель через Webhooks (CURL в Dialplan)

Вместо того чтобы 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-сервис, который принимает эти параметры в режиме реального времени и сразу регистрирует звонок в информационной базе.

3. Использование событий AMI (Asterisk Manager Interface)

Если на стороне Asterisk активирован модуль cdr_manager, то при завершении каждого звонка система генерирует событие Cdr в интерфейсе AMI (порт 5038). Разработчик может написать внешнюю компоненту или фоновую службу на 1С, которая будет держать постоянное TCP-соединение с портом AMI, «слушать» поток событий и оперативно фиксировать историю звонков в базе данных.

← На главную