Настройка ODBC-подключения и получение данных из БД
Ранее мы научились строить логику диалплана на условиях и переходах. Но до сих пор данные были «зашиты» в конфиги. В больших системах это неудобно: любое изменение требует правки файлов. Чтобы АТС стала гибкой, она должна общаться с внешним миром.
Разберем, как подключить Asterisk к внешней базе данных (MariaDB или PostgreSQL). Это обеспечит динамическое подключение: логика звонка изменится сразу после обновления строки в таблице, без перезагрузки модулей.
Архитектура: как данные попадают в звонок
Asterisk связывается с базой через стандарт ODBC (Open Database Connectivity). Это универсальный переходник: Asterisk не важно, какая СУБД стоит «на той стороне», он общается с драйвером.
Взаимодействие устроено как иерархия уровней, показанная на Схеме 1.
- OS (Linux): Драйвер
unixODBCи конфиг/etc/odbc.ini. Проверяем, видит ли система базу. - Ресурсы Asterisk: Модуль
res_odbc.conf. Создает пул соединений, чтобы не тратить время на авторизацию при каждом вызове. - Функции диалплана: Модуль func_odbc. Превращает SQL-запрос в функцию, понятную Asterisk.
Шаг 1: Настройка res_odbc.conf
Допустим, в Linux уже настроен DSN (источник данных) с именем asterisk-connector. Теперь пропишем его в Asterisk.
Во FreePBX правки вносим в файлы с суффиксом _custom, чтобы интерфейс их не затер. Откройте /etc/asterisk/res_odbc_custom.conf:
[asterisk-db]
enabled => yes
dsn => asterisk-connector
username => asterisk_user
password => your_strong_password
pre-connect => yes
max_connections => 20
connect_timeout => 5
on_reconnect => SET NAMES utf8mb4 ; работаем с кириллицей корректно
⚡️ Важно: Параметр
pre-connect => yesзаставляет Asterisk держать соединение активным. Если база «проснется» только в момент звонка, абонент услышит тишину из-за задержки.
Проверьте статус в консоли Asterisk: odbc show. Если видите Connected — мост работает.
Шаг 2: Создание функций в func_odbc.conf
Инструмент func_odbc — это обертка. Вы описываете SQL-запрос, даете ему имя, а в диалплане используете его как переменную.
Создадим проверку статуса клиента. Если в базе стоит blocked, звонок не пройдет. В файле /etc/asterisk/func_odbc_custom.conf пишем:
[CHECK_STATUS]
dsn=asterisk-db
readsql=SELECT status FROM clients WHERE phone='${SQL_ESC(${ARG1})}'
- readsql: запрос на чтение (SELECT).
- ${ARG1}: первый аргумент, который мы передадим (номер телефона).
- SQL_ESC(): 🛡 Защита. Экранирует спецсимволы, предотвращая SQL-инъекции. Всегда оборачивайте внешние переменные в эту функцию.
Шаг 3: Логика в диалплане
Теперь используем функцию в extensions_custom.conf. Код становится чище: данные живут отдельно, логика — отдельно.
[from-internal-custom]
exten => _XXXX,1,NoOp(Проверка абонента ${CALLERID(num)})
; Вызываем функцию и пишем результат в переменную
same => n,Set(USER_STATUS=${ODBC_CHECK_STATUS(${CALLERID(num)})})
; Проверяем статус
same => n,GotoIf($["${USER_STATUS}" = "blocked"]?denied:allow)
same => n(denied),Playback(service-is-unavailable)
same => n,Hangup()
same => n(allow),Dial(PJSIP/${EXTEN},30)
Если менеджер в CRM заблокирует клиента, Asterisk узнает об этом мгновенно при следующем звонке.
💡 Совет эксперта: Всегда продумывайте план «Б». Если база недоступна и
${USER_STATUS}пуст, лучше пропустить звонок по стандартному пути, чем оборвать связь.
Отладка
Проверить работу можно прямо из консоли (CLI) без совершения звонка:
odbc read ODBC_CHECK_STATUS 79991234567 exec
Если запрос верный, Asterisk выведет значение из колонки status.
Мы научили систему «советоваться» с базой данных. В следующей теме применим это на практике: настроим динамическую маршрутизацию, VIP-очереди и перевод звонка на «своего» менеджера.
Понравился урок?
Сохраните прогресс и получите персональный курс по любой теме — без форм и паролей
Продолжить в Telegram