Как настроить интеграцию 1С с Asterisk через компоненту ROM-Asterisk-Native на платформе x64?

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

Интеграция 1С:Предприятия с телефонией Asterisk — одна из самых востребованных задач при автоматизации бизнес-процессов. Использование Native API компоненты ROM-Asterisk-Native (или BROMAsteriskNative) позволяет организовать стабильное взаимодействие через интерфейс AMI (Asterisk Manager Interface). Однако при переходе на 64-битную платформу программисты часто сталкиваются с тем, что компонента либо не загружается, либо не возвращает события от АТС. В этой статье мы подробно разберем, как правильно инициализировать компоненту, пройти авторизацию и, самое главное, заставить 1С «слышать» входящие звонки.

Подготовка среды и загрузка компоненты

Прежде всего, разберем особенности платформы x64. В отличие от 32-битной версии, компонента Native API для x64 требует наличия соответствующих библиотек среды выполнения Visual C++ (Redistributable) на целевой машине. Если метод ПодключитьВнешнююКомпоненту возвращает Ложь, убедитесь, что установлены пакеты VC++ 2015-2019.

Для создания объекта компоненты используем стандартный синтаксис:


Попытка
    УстановитьВнешнююКомпоненту("ОбщийМакет.ROM_Asterisk_Native");
    ПодключитьВнешнююКомпоненту("ОбщийМакет.ROM_Asterisk_Native", "Asterisk", ТипВнешнейКомпоненты.Native);
    ОбъектКомпоненты = Новый("AddIn.Asterisk.ROM-Asterisk-Native");
Исключение
    Сообщить("Ошибка загрузки компоненты: " + ОписаниеОшибки());
КонецПопытки;

Важно помнить, что в разных сборках идентификатор объекта может отличаться (например, AddIn.Test.ROM-Asterisk-Native). Проанализируем далее процесс установки соединения.

Установка соединения и тонкости протокола AMI

Протокол AMI работает через TCP-сокеты. Для подключения используем метод Connect, передавая IP-адрес и порт (по умолчанию 5038). Проверим успешность подключения:


IP = "10.0.0.10";
Порт = "5038";
ОбъектКомпоненты.Connect(IP, Порт);

Если ОбъектКомпоненты.Подключено Тогда
    Сообщить("Сетевое соединение установлено успешно!");
Иначе
    Сообщить("Не удалось подключиться к серверу Asterisk.");
    Возврат;
КонецЕсли;

После установки соединения необходимо пройти авторизацию. Здесь кроется первая серьезная ошибка: многие забывают о специфике завершения команд в Asterisk. Каждая команда AMI должна заканчиваться парой символов CRLF (Возврат каретки + Перевод строки). А для того чтобы Asterisk понял, что пакет команды завершен, необходимо отправить два таких набора.

Рассмотрим правильный код формирования команды авторизации:


CRLF = Символы.ВК + Символы.ПС;
ТекстКоманды = "Action: Login" + CRLF +
               "Username: " + ЛогинAMI + CRLF +
               "Secret: " + ПарольAMI + CRLF + CRLF; // Важно два CRLF в конце

Флаг = ОбъектКомпоненты.ВыполнитьКоманду(ТекстКоманды);

Обратите внимание, что метод ВыполнитьКоманду часто возвращает Истина сразу, как только пакет данных был успешно отправлен в сокет. Это не означает, что логин и пароль верны. Результат авторизации придет асинхронно во «Внешнее событие».

Активация приема событий: Режим прослушивания

Самая частая проблема, обсуждаемая на форумах: «Я подключился, команды отправляю, но события о входящих звонках в 1С не прилетают». Рассмотрим причину: компонента по умолчанию находится в пассивном режиме. Чтобы она начала транслировать данные из сокета в 1С, необходимо явно включить режим прослушивания и, при необходимости, настроить фильтрацию событий.

Выясним, какие методы за это отвечают:

  1. SetRegEx — устанавливает регулярное выражение для фильтрации строк. Если вы хотите получать абсолютно все события, установите точку или .*.
  2. РежимПрослушивания(Истина) — активирует фоновый поток чтения данных.

Разберем пример настройки после успешного логина:


// Устанавливаем фильтр (регистр важен в некоторых версиях!)
ОбъектКомпоненты.SetRegEx(".*"); 

// Включаем прослушивание событий АТС
ОбъектКомпоненты.РежимПрослушивания(Истина);

Без вызова РежимПрослушивания(Истина) компонента будет игнорировать входящий поток данных от Asterisk, и процедура ВнешнееСобытие в модуле формы или приложения никогда не будет вызвана.

Обработка данных во внешнем событии

Когда Asterisk фиксирует звонок, он отправляет набор событий (Event: Newchannel, Newstate, Dial и т.д.). Компонента перехватывает их и генерирует внешнее событие в 1С. Проанализируем структуру обработки:


Процедура ВнешнееСобытие(Источник, Событие, Данные)
    Если Источник = "ROM-Asterisk-Native" Тогда
        // Событие содержит тип сообщения от компоненты (например, "Connected" или "Event")
        // Данные содержат текстовый блок от Asterisk
        
        Если Найти(Данные, "Event: Newchannel") > 0 Тогда
            // Извлекаем номер телефона
            ПозицияНомера = Найти(Данные, "CallerIDNum: ");
            Если ПозицияНомера > 0 Тогда
                 // Логика обработки входящего звонка
            КонецЕсли;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Рекомендуется использовать построчный разбор переменной Данные, так как Asterisk передает параметры в формате Ключ: Значение, разделенные CRLF.

Поддержание стабильного соединения

Сервер Asterisk может разорвать соединение по таймауту, если в канале долго нет активности. Для предотвращения этого рассмотрим использование команды Ping. Рекомендуется настроить периодическое (раз в 30-60 секунд) выполнение следующей команды через обработчик ожидания 1С:


ТекстПинга = "Action: Ping" + CRLF + CRLF;
ОбъектКомпоненты.ВыполнитьКоманду(ТекстПинга);

Это позволит сокету оставаться активным, а компоненте — оперативно реагировать на входящие вызовы. Также не забудьте проверить настройки AMI на стороне Asterisk (файл manager.conf). У пользователя 1С должны быть права на чтение (read) событий call и system, иначе события Newchannel просто не будут отправляться сервером в сторону 1С.

Таким образом, для успешной работы на x64 платформе мы должны обеспечить три условия: наличие корректной 64-битной библиотеки, правильную терминацию команд двойным CRLF и обязательную активацию режима прослушивания после авторизации.

← На главную