Как стать автором
Обновить

Нетривиальная задача с callback + DID в Asterisk

Время на прочтение 3 мин
Количество просмотров 17K
Здравствуйте, уважаемые хабравчане и любители астериска!
Хочу поделиться интересной задачей и вариантом её решения. Итак, вот условия задачи.
Имеем:
— модифицированный дистрибутив Elastix 2.3
— asterisk 1.8.13.1
— FreePBX 2.8.1
— 24 номера подключением по sip и 30 каналов
— ~40 различных ООО в составе холдинга
Текущая задача:
— сделать callback сервис для каждого номера DID (и соответственно от каждого ООО)

Казалось бы, «это же freePBX — там всё делается мышкой». Это не совсем так.

Шаг первый. Осознание проблемы.


Я использую веб интерфейс elastix для настройки. Он мне очень нравится.
Идём в PBX->PBX Configuration->Callback и заполняем данные для калбэка.
Идём в раздел IVR, выбираем нужное меню и настраиваем, например на «9» наш callback.
Проверяю — всё работает. Позвонил с 28-xx-yy — вызов вернулся с 28-xx-yy
Сделал аналогично для IVR на номере 28-xx-xx — вызов вернулся с 28-xx-yy
Согласитесь, как то нелогично получается, когда ты звонишь заказать продукты, а тебе перезванивают с номера какого то завода. А у меня таких организаций довольно много.
Отсюда и вытекла текущая задача: нужно, чтобы позвонив на 28-xx-xx — вызов возвращался с номера 28-xx-xx

Шаг второй. Поиск решения из веб интерфейса elastix/FreePBX


Скажу сразу. Может оно и есть, но я его не обнаружил.

Шаг третий. Изучение конфигурационных файлов напрямую


Контекст для callback находится в файле extensions_additional.conf
[callback]
include => callback-custom
exten => 1,1,Set(CALL=${CALLERID(number)})
exten => 1,n,Set(DESTINATION=ivr-5.s.1)
exten => 1,n,Set(SLEEP=1)
exten => 1,n,System(/var/lib/asterisk/bin/callback ${CALL} ${DESTINATION} ${SLEEP} &)
exten => 1,n,Hangup

Видим что вызов осуществляется из php скрипта /var/lib/asterisk/bin/callback
Полистав его, узнаём, что вызов осуществляется с канала Local, и уходит по правилам исходящих маршрутов (Outbound Routes)
И спустя рабочий день попутных раздумий меня посетила идея — сделать нужный DID на основе префиксов при наборе из callback.

Шаг четвёртый. Решение задачи


Для понятности приведу такую логическую схему:
  • прописываем для номера 28-xx-xx в Outbound Routes в поле prefix наш номер 28-xx-xx
  • приходит вызов с 55-xy-xx на 28-xx-xx
  • передаём 55-xy-xx и 28-xx-xx в скрипт callback
  • набираем номер в формате 28ххxx55xyxx
  • астериск загоняет номер 28ххxx55xyxx в Outbound Routes и срезает 28xxxx, набирая 55xyxx с номера 28xxxx
  • PROFIT!


Техническая сторона оказалось весьма «сложнее». Как известно, FreePBX перезатирает extensions_additional.conf при любом своём сохранении. Добавил нового пользователя через веб — применяй свои контексты заного.
Решением этого является использование файла extensions_override_freepbx.conf — но у меня так и не получилось. Не стал тратить более часа на изучение — ведь решение главной задачи уже летало где то в воздухе. Я инстинктивно осознавал, что причина скорее всего в том, что на сервере уже много что переписано.

Смотрим контекст [callback]
Нам нужно передать DID в переменную CALL. Через callback-custom это делать бесполезно — всё равно переменная переназначится ниже по основному контексту. И тогда, я вспомнил полезную статью.
Добавляем в extensions_custom.conf контекст [callback-az], сделанный копированием [callback] и добавляем FROM_DID в переменную CALL
[callback-az]
exten => 1,1,Set(CALL=${FROM_DID}${CALLERID(number)})
exten => 1,n,Set(DESTINATION=ivr-5.s.1)
exten => 1,n,Set(SLEEP=1)
exten => 1,n,Set(DESC='callb_CRT')
exten => 1,n,System(/var/lib/asterisk/bin/callback ${CALL} ${DESTINATION} ${SLEEP} ${DESC}  &)

Замечу, что у моих операторов на телефонах высвечивается звонящий просто — "Callback"
Забегу вперёд, это вызвало панику — ведь они обслуживают кучу организаций, и хотят видеть — куда пришёл звонок. Логично, не поспоришь.
Поэтому в контексте выше я добавил переменную DESC, текстом, и отправил её в скрипт callback. Это всех устроило.

Дальше модифицируем сам скрипт /var/lib/asterisk/bin/callback — как уже было сказано, это простой php скрипт.
Думаю, все уже поняли, что будет дальше.
Ищем
$callback_number = $args[0];
$callback_destination = $args[1];
$pause_seconds = $args[2];

Вставляем ниже
$callback_desc = $args[3];

Ищем
$callerid = "Callback"

заменяем на
$callerid = $callback_desc;

Готово. Дальше нужно правильно делать вызов в контекст.
Вспомню вышеприведённую полезную статью и картинки к ней.
В Elastix нет модуля Custom Destinations, поэтому лезем непосредственно в FreePBX. Он находится по адресу:
ip-add/admin
логин и пароль стандартные, легко гуглятся.

Делаем вот так:

Разъясню. Первая «1» в строке callback-az,1,1 это номер callback из контекста [callback-az] — у нас получится несколько callback в контексте (по 1 на каждый DID). Вторая «1» — это номер приоритета.

Ну и финальный штрих — указываем в IVR у нашего DID на цифру 9 — наш Custom Destination

И так делается для каждого DID и Callback

Не забудьте добавить префикс в исходящие маршруты! Об этом не буду рассказывать, вот именно это легко можно сделать мышкой.

Заключение


Я не считаю себя гуру астериска. Уверен, что кто то знает способ как сделать лучше и правильнее. Я нашёл свой способ и хочу поделиться им с сообществом.
Всем спасибо.
Теги:
Хабы:
+7
Комментарии 14
Комментарии Комментарии 14

Публикации

Истории

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн