Asterisk. Dialplan Askozia 6. Исходящие звонки +7
Разработка систем связи, Asterisk
Рекомендация: подборка платных и бесплатных курсов Smm - https://katalog-kursov.ru/
В статье пойдет речь о бесплатной АТС Askozia версии 6. При разработке телефонной станции одной из первых задач была организация исходящих звонков.
Как это было
В старой версии Askozia использовались стандартные “
шаблоны” dialplan.
- X! — все номера телефонов
- XXX — трехзначные цифровые номера
- .! — абсолютно все номера телефонов
Схематично можно описать пример контекста:
[outgoing]
exten => _XXXXXX!,1,NoOp(Start outgoing calling...)
same => n,Dial…
Нам показался такой подход недостаточно гибким. Нет возможности описать следующее правило:
- Номер начинается с 79
- Далее следует либо 35 либо 26
- Остальная часть номера состоит из 7 цифр
Под катом описан выбранный нами подход и итог разработки.
Текущая реализация
Мы решили реализовать этот функционал по другому, с использованием
REGEX.
Пример шаблона:
79(25|26)[1-9]{7}
- (25|26) — это 25 ИЛИ 26
- [0-9] — цифра от 0 до 9ти, вхождение от 1ого и более раз
- {7} — кол-во вхождений предыдущего символа
Синтаксис функции REGEX:
REGEX("regular expression" string)
Return '1' on regular expression match or '0' otherwise
Пример использования в Askozia 6:
[outgoing]
exten => _X!,1,NoOp(Start outgoing calling...)
same => n,Ringing()
same => n,ExecIf($["${REGEX("^[0-9]{6}$" ${EXTEN})}" == "1"]?Gosub(SIP-PR-1-out,${EXTEN},1))
same => n,ExecIf($["${REGEX("^(7|8)[0-9]{10}$" ${EXTEN})}" == "1"]?Gosub(SIP-PR-2-out,${EXTEN},1))
same => n,Hangup()
Для исходящих звонков организована одна точка входа — контекст “
outgoing”, в нем происходит вызов функции “
ExecIf”:
ExecIf($["${REGEX("^[0-9]{6}$" ${EXTEN})}" == "1"]
Если номер телефона, указанный в переменной “
${EXTEN}”, соответствует шаблону, то вызов направляется в
sub-контекст средствами функции “
Gosub”.
Если в
sub-контекст вызов не был прерван, то набор пойдет по следующему подходящему правилу.
Мы таким образом решили проблему с одноканальными линиями. Если линия занята, то вызов идет через следующую, пока не будет отвечен.
Примеры контекстов:
[SIP-PR-1]
exten => _X!,1,ExecIf($["${number}x" == "x"]?Hangup())
same => n,Dial(SIP/PR-1/${EXTEN},600,TeK))
same => n,ExecIf($["${DIALSTATUS}" = "ANSWER"]?Hangup())
same => n,return
[SIP-PR-2]
exten => _X!,1,ExecIf($["${number}x" == "x"]?Hangup())
same => n,Dial(SIP/PR-2/${EXTEN},600,TeK))
same => n,ExecIf($["${DIALSTATUS}" = "ANSWER"]?Hangup())
same => n,return
Обязательно в “
sub” — контекст производится проверка “
DIALSTATUS”. Если вызов отвечен, то после разговора канал будет завершен средствами функции “
Hangup()”. Если этого не сделать, то при завершении звонка клиентом, может произойти повторный набор номера клиента.
Одна важная тонкость, при использовании “
Gosub” или “
Goto” мы намеренно
не меняем
${EXTEN}. Даже если необходимо модифицировать номер телефона (добавить / удалить префикс).
Дело в том, что при модификации
EXTEN Asterisk будет модифицировать значение переменной
CDR(dst), что приведет к слабо прогнозируемому результату в таблице истории звонков CDR. Считаю, в истории важно сохранять тот номер, который был набран сотрудником.
Будьте аккуратны при описании регулярного выражения. Используйте символы “
^”, начало строки и “
$” — конец строки, иначе можно получить неожиданный результат.
К примеру шаблон “
[0-9]{6}” будет соответствовать всем номерам, где есть 6 и более цифр. Шаблон “
^[0-9]{6}$” соответствует только 6ти значным номерам.
Итоги
Мы получили гибкую подсистему, для описания исходящей маршрутизации на АТС.
Список правил отображаем следующим образом:
Пример карточки конкретного “Правила”:
К сожалению, не доступен сервер mySQL