Применим GotoIf() в примере:
exten => 345,1,Set(TEST=1)
exten => 345,n,GotoIf($[${TEST} = 1]?weasels:iguanas)
exten => 345,n(weasels),Playback(weasels-eaten-phonesys)
exten => 345,n,Hangup()
exten => 345,n(lguanas),Playback(office-iguanas)
exten => 345,n,Hangup()
Вы заметите, что за каждым приложением Playback() следует приложение Hangup(). Это делается для того, чтобы при переходе на метку weasels вызов заканчивался до того, как начинается воспроизведение звукового файла office-ig'uanas. Все чаще можно увидеть добавочные номера, разбитые на несколько компонентов (разделенных между собой командой Hangup()), каждый из которых представляет собой этапы, выполняемые следом за GotoIf().
Обычно при такой схеме, когда требуется оградить Asterisk от выполнения следующего приоритета после выполнения перехода, вероятно, лучше в качестве места назначения использовать другие добавочные номера, а не метки приоритетов. Во всяком случае, это делает диал- план несколько понятнее. Предыдущий фрагмент диалплана можно было бы переписать следующим образом: exten => 345,1,Set(TEST=1)
exten => 345,n,GotoIf($[${TEST} = 1]?weasels,1:iguanas,1); теперь переход
; выполняется к добавочному номеру,приоритету
exten => weasels,1,Playback(weasels-eaten-phonesys); это НЕ метка.
Предоставление условного перехода только на случай ложности выражения
Предыдущий пример можно было бы записать следующим образом:
exten => 345,1,Set(TEST=1)
exten => 345,n,GotoIf($[${TEST} = 1]?:iguanas) ; здесь больше нет ; метки weasels, но это будет по-прежнему работать exten => 345,n,Playback(weasels-eaten-phonesys) exten => 345,n,Hangup()
exten => 345,n(iguanas),Playback(office-iguanas) exten => 345,n,Hangup()
Между символами ? и : ничего не указано, таким образом, если выражение оказывается истинным, выполнение диалплана перейдет на следующую строку. Поскольку это именно то, что требуется, указывать метку необязательно.
На самом деле мы не рекомендуем этого делать, потому что такая запись сложна для понимания. Но подобные диалпланы встречаются, поэтому надо просто знать, что данный синтаксис тоже является абсолютно правильным.
; Это другой добавочный номер
exten => weasels,n,Hangup()
exten => iguanas,1,Playback(office-iguanas)
exten => iguanas,n,Hangup()
При изменении значения, присваиваемого TEST в первой строке, сервер Asterisk должен воспроизводить разные приветствия. Рассмотрим другой пример выполнения переходов по условию. На этот раз будем использовать оба приложения, и Goto(), и GotoIf(). Выполним счет в обратном направлении от 10 и повесим трубку: exten => 123,1,Set(COUNT=10)
exten => 123,n(start),GotoIf($[${COUNT} > 0]?:goodbye)
exten => 123,n,SayNumber(${COUNT})
exten => 123,n,Set(COUNT=$[${COUNT} - 1])
exten => 123,n,Goto(start)
exten => 123,n(goodbye),Hangup()
Проанализируем этот пример. В первом приоритете переменной COUNT присваивается значение 10. Далее COUNT сравнивается с 0. Если ее значение больше нуля, мы переходим к следующему приоритету. (Не забываем, что, если место назначения в приложении GotoIf() опущено, управление передается вниз следующему приоритету.) С этого момента воспроизводится номер, из COUNT вычитается 1 и управление опять возвращается к приоритету start (начало). Если значение COUNT меньше или равно 0, управление передается приоритету goodbye (до свидания) и вызов завершается.
Классический пример выполнения переходов по условию с нежностью называют «логикой для защиты от любимой девушки». Если номер Caller ID (ID звонящего) входящего вызова совпадает с номером телефона бывшей девушки абонента, Asterisk выдает сообщение, отличающееся от того, которым он обычно встречает звонки от других абонентов. Несмотря на простоту и примитивность, это хороший пример для изучения переходов по условию в диалплане Asterisk. В этом примере используется функция CALLERID, которая позволяет извлекать информацию о Caller ID (ID звонящего) входящего вызова. Пусть для данного случая номер телефона жертвы будет 888-555-1212: exten => 123,1,GotoIf($[${CALLERID(num)} = 8885551212]?reject:allow) exten => 123,n(allow),Dial(Zap/4) exten => 123,n,Hangup()
exten => 123,n(reject),Playback(abandon-all-hope) exten => 123,n,Hangup()
В приоритете 1 вызывается приложение GotoIf(). Оно указывает Asterisk перейти к метке приоритета reject (отклонить), если номер Caller ID (ID звонящего) соответствует 8885551212, а в противном случае перейти к метке приоритета allow (можно было бы опустить имя метки, позволяя GotoIf() просто передать управление далее). Если номер Caller ID (ID звонящего) совпадает с указанным, управление вызовом передается приоритету reject, который воспроизводит нежелательному абоненту неприветливое сообщение. В противном случае делается попытка вызова получателя по каналу Zap/4.
Читать дальше