Маршрутизация на основе времени и CallerID
Мы уже научились создавать интерактивные голосовые меню и управлять очередями вызовов. Это база. Но в реальной работе статичного распределения мало. Бизнесу нужна гибкость: ночной режим, приоритет для VIP-клиентов и защита от спама.
Чтобы реализовать такую логику, мы выйдем за рамки кнопок FreePBX и заглянем «под капот» — в диалплан Asterisk.
Как Asterisk видит время
Для принятия решений (например, отправить звонок на автоответчик после 18:00) сервер должен знать текущее время и уметь его форматировать. За это отвечает функция STRFTIME.
Внутри Asterisk время хранится в переменной ${EPOCH} — это количество секунд с 1 января 1970 года. Читать его в таком виде невозможно, поэтому мы переводим его в понятный формат.
; Получаем часы и минуты (например, 15:30)
Set(CURRENT_TIME=${STRFTIME(${EPOCH},,%H:%M)})
; Получаем день недели (1 — понедельник, 7 — воскресенье)
Set(CURRENT_DAY=${STRFTIME(${EPOCH},,%u)})
Использование Time в условиях делает сценарии динамичными. Как показано на Схеме 1, процесс всегда идет по цепочке: запрос системных данных → форматирование → сравнение с графиком.
Работа с данными абонента
Второй инструмент умной маршрутизации — обработка по CallerID. В Asterisk за это отвечает функция CALLERID(). У неё есть два ключевых параметра:
CALLERID(num)— номер телефона (например, 79991234567).CALLERID(name)— имя абонента.
Важно: Всегда берите переменные в кавычки в условиях
GotoIf. Если CallerID придет пустым (скрытый номер), Asterisk без кавычек выдаст ошибку и оборвет звонок. Правильно:"$[${CALLERID(num)}" = "79001112233"]".
Практика: Маршрутизация по времени
Настроим «Рабочее время» вручную в файле extensions_custom.conf. Используем оператор ветвления GotoIf.
[office-schedule-custom]
exten => s,1,NoOp(Проверка времени вызова)
; Условие: Пн-Пт (1-5) И время с 09:00 до 17:59
same => n,Set(WorkTime=$[${STRFTIME(,,%u)} < 6 & ${STRFTIME(,,%H%M)} >= 0900 & ${STRFTIME(,,%H%M)} < 1800])
same => n,GotoIf($["${WorkTime}" = "1"]?open:closed)
same => n(open),Log(NOTICE, Офис открыт)
same => n,Dial(PJSIP/100,20)
same => n,Hangup()
same => n(closed),Log(NOTICE, Офис закрыт)
same => n,Playback(vm-goodbye)
same => n,Hangup()
Если условие истинно (равно 1), вызов уходит на метку open, иначе — на closed.
VIP-клиенты и фильтрация
Маршрутизация по времени и номеру позволяет приоритизировать звонки. Можно создать «белый список», чтобы важные клиенты попадали сразу к менеджеру, минуя IVR.
| Метод | Описание | Пример |
|---|---|---|
| Точное совпадение | Сравнение номера целиком | Прямой перевод для директора 🎩 |
| Проверка по маске | Использование шаблонов | Звонки из СПб (_7812X.) — в питерский филиал |
| Проверка на пустоту | Наличие номера | Блокировка анонимов 🕵️ |
Пример VIP-фильтра:
[incoming-filter-custom]
exten => s,1,NoOp(Проверка VIP для ${CALLERID(num)})
; Если номер совпадает с VIP, идем на метку vip-line
same => n,GotoIf($["${CALLERID(num)}" = "79001112233"]?vip-line)
; Если номер начинается на 8800, сбрасываем (спам)
same => n,GotoIf($["${CALLERID(num):0:4}" = "8800"]?block)
same => n,Goto(from-internal,s,1)
same => n(vip-line),Dial(PJSIP/200,30)
same => n,Hangup()
same => n(block),Answer()
same => n,Wait(1)
same => n,Playback(ss-noservice)
same => n,Hangup()
Как не «сломать» диалплан
При ручной правке конфигов легко ошибиться там, где GUI подстраховал бы вас.
- Забудьте про Macro. В современных версиях Asterisk макросы устарели. Используйте
GoSub— это надежнее и современнее. - Кавычки — это закон. Всегда пишите
"$[${VAR} = ...]". Это страховка от пустых значений. - Логируйте действия. Используйте
NoOpилиLog, чтобы в консоли было видно, по какой ветке пошел звонок.
Мы научились строить логику, которая делает АТС «умной». Но что делать, если вызов пошел не по плану? Чтобы не гадать, почему VIP-клиент слышит «гудбай», нужно научиться заглядывать в «мысли» системы.
В следующем уроке разберем, как профессионально читать логи и использовать инструменты поиска, чтобы мгновенно находить ошибки в сценариях.
Понравился урок?
Сохраните прогресс и получите персональный курс по любой теме — без форм и паролей
Продолжить в Telegram