понедельник, 12 мая 2014 г.

Голосового меню (IVR) в ASTERISK.



Опишем создание голосового меню, состоящего из приветствия и после приветствия, переключение на оператора. Файл в котором хранится фраза «Здравствуйте, вы позвонили в нашу компанию» называется welcome.wav и находится в директории /usr/local/etc/asterisk/ivr. Номер, который принимает звонки 444. А выглядеть меню будет так:

[sip-in]
exten => 444,1,Set(home="/usr/local/etc/asterisk/ivr")
exten => 444,2,Wait(1)
exten => 444,3,Playback(${home}/welcome)
exten => 444,4,Dial(SIP/operator)
Функция Playback, предназначена для проигрывания звуковых файлов, файлы должны быть подготовленны заранее, для Asterisk. Есть еще сходная функция Background, она отлдичается от Playback тем, что не блокирует нажатия на кнопки, то есть в момент проигрывания голосовых меню, позволяет реагировать на передаваемые звонившим DTMF.
Это простейший IVR и в нем отсутствует основная особенность IVR, нет никакого выбора. Поэтому приведем пример с диалогом. Тут будет присутствовать вторая начитка: «Для связи того что бы прослушать тарифы нажмите 1, для связи с оператором нажмите 2″. Файл содержащий эту начитку будет называться menu.wav и файл с тарифами соответсвенно tariff.wav. После прочтения инструкции должен осуществляться переход в главное меню.
Выглядит это так:
[sip-in]
exten => 444,1,Goto(menu,s,1)

[menu]
exten => s,1,Set(home="/ usr/local/etc/asterisk/ivr ")
exten => s,2,Wait(1)
exten => s,3,Playback(${home}/welcome)
exten => s,4,Playback(${home}/menu)
exten => s,5,WaitExten()

exten => 1,1,Playback(${home}/tariff)
exten => 1,2,Goto(s,1)

exten => 2,1,Dial(SIP/operator)

exten => t,1,Playback(make_choice)
exten => t,2,Goto(s,1)

exten => i,1,Playback(wrong_choice)
exten => i,2,Goto(s,1)
Goto – функция безусловного перехода. Если в качестве параметров ей передается 3 аргумента, это контекст, екстеншен и метка на которую нужно перейти. Если всего 2 аргумента, то подразумевается, что контекст текущий.
 i – это реакция на неправильно нажатую кнопку, Invalid input
t – реакция на истекшее время ожидания выбора.

Если их не описать то при истечении таймаута или при неправильно нажатой кнопке произойдет обрыв соединения.

четверг, 8 мая 2014 г.

Очереди звонков Asterisk

При телефонизации необходимость создания очереди звонков возникает достаточно часто. Например при наличии нескольких  менеджеров , руководитель хочет, что бы им на отдел поступали звонки и звонки равномерно распределялись по менеджерам, или что бы все звонки поступали ко всем сразу все это работает. Работает с помощью Queue.
С начала добавим в sip.conf наших менеджеров:
[111]
context=support
callerid="111" <111>
username=111
secret=*******
call-limit=1
callgroup=10
pickupgroup=15
dtmfmode=rfc2833
deny = 0.0.0.0/0.0.0.0
permit = 192.168.10.10/255.255.255.255

Теперь создадим очередь и добавим в конце описание нашей очереди. Описывается она в queues.conf:
[general]
persistentmembers = yes
autofill = yes

[queue1] ;Название нашей очереди
music = default ;Во время ожидания будет звучать музыка по умолчанию
strategy = ringall ;В очереди будут звонить все телефоны одновременно
timeout = 60
retry = 5
maxlen = 0
joinempty = yes ;разрешать входить в очередь даже в том случае, если все операторы не доступны
ringinuse = no

;Блок для анонса позиции в очереди
announce-frequency = 30 ;частота анонсов
announce-holdtime = no ;не объявлять приблизительное время ожидания
announce-position = limit ;если очередь слишком велика (более 6 вызовов), то
announce-position-limit = 6 ;информация о позиции выдаваться не будет, что бы
;не пугать пользователей

;Описываются пути к речевым файлам,
;которые используются для нашей простой очереди
queue-youarenext = /etc/asterisk/sounds/support/queue-youarenext
queue-thereare = /etc/asterisk/sounds/support/queue-thereare
queue-callswaiting = /etc/asterisk/sounds/support/queue-callswaiting
queue-thankyou = /etc/asterisk/sounds/support/queue-thankyou

;Описываем телефоны, которые будут принимать вызовы.
member=>SIP/111
member=>SIP/112
member=>SIP/113
member=>SIP/114

А теперь осталось направить входящие звонки на Queue. Для этого в extensions.conf, в том контексте в котором должны поступать звонки на очередь, прописываем:

exten => 101,1,Answer() 
exten => 101,n,Background(/etc/asterisk/sounds/support/ivr-techpodderzhka)
exten => 101,n,WaitExten(5)
exten => 101,n,Dial(${SIP/500,120,r)
exten => 1,1, Dial(${SIP/500,120,r)
exten => i,1, Dial(${SIP/501,120,r) ; если клиент набрал несуществующий номер пункта меню

exten => 2,1,Dial(SIP/111&SIP/112&SIP/113&SIP/114,r)
exten => 2,n,Playback(/etc/asterisk/sounds/support/queue-vsezanyaty)
exten => 2,n,Queue(queue1,t,,,300) 

среда, 7 мая 2014 г.

sip.conf

Перенаправление звонков


Согласно нашему плану трехзначных номеров, вызываемый абонент должен снять
трубку в течение 10 секунд. Давайте настроим перенаправление звонка на мобильный
телефон пользователя, если он не ответил на звонок в течение этого периода. В Asterisk
есть несколько способов реализации этого алгоритма, в том числе с использованием
приложения FollowMe. В файле конфигурации этого приложения для каждого
пользователя можно определить список номеров телефонов, по которым можно его найти.

admin@asterisk:~$ echo > /etc/asterisk/followme.conf
admin@asterisk:~$ ee /etc/asterisk/followme.conf
[101]
number=>89161111111,30
number=>89122222222,30
context=>default
[102]
number=>89111111111,30
number=>89222222222,30
context=>default

В квадратных скобках указывается имя пользователя, Использование в качестве имени
номера телефона позволит упростить описание плана звонков. Далее следуют номера
телефонов на которые будут перенаправляться вызовы и время в секундах в течении
которого ожидается ответ. Параметр context определяет секцию в файле плана звонков,
обрабатывающую вызов указанного номера.

Давайте добавим вызов приложения FollowMe в конец обработки вызова
трехзначных номеров в файле, описывающем план звонков:

admin@asterisk:~$ ee /etc/asterisk/extensions.conf

;...
exten => _1XX,1,Dial(SIP/${EXTEN},10)
 same => n,FollowMe(${EXTEN})
;...

Приложению FollowMe в качестве аргумента передается имя пользователя, описанного в
файле followme.conf, и, в нашем случае, имя совпадает с номером, набранным

вызывающим абонентом.

Cтандартные расширения диалплана


a: Вызывается, когда пользователь нажимает '*' во время проигрывания приветствия системы голосовой почты.
h: Вызывается, по завершению вызова.
i: Вызывается, при попытке вызова неизвестного екстеншена.
o: Расширение оператора, используется для обработки нажатия нуля в системе голосовой почты.
s: Стартовое расширение в контексте.
t: Вызывается, при наступлении состояния таймаута.
T: Вызывается, при наступлении состояния абсолютного таймаута, заданного функцией AbsolutTimeout.
e: Перехват расширений i,t и T для обработки ошибки в едином месте. Для выяснения типа ошибки может быть использована функция EXCEPTION()
failed: Используется, если auto-dial out вызов завершился неудачно (который имеет определённый контекст, приоритет и расширение).
fax: Используется для определения факса на Zap каналах.

talk: Используется в конъюнкции с BackgroundDetect.

Команды Goto и GotoIf в диалплане

Goto
Назначение
Переход на указанный приоритет, екстеншен или контекст

Описание
Goto([[context|]extension|]priority)

Устанавливает текущей приоритет выполнения команды в заданное значение, дополнительно можно указать екстеншен и контекст для совершения перехода. Специальное имя екстеншена BYEXTENSION используется в тех случаях, когда Вы хотите совершить переход с использованием текущего имени екстеншена, в другой контекст. Обратите внимание, что можно опустить необязательные параметры команды только в КОНЦЕ списка аргументов, нельзя опустить необязательный аргумент, идущий до или между заданными параметрами.

Варианты использования:
Goto(context,extension,priority)
Goto(extension,priority)
Goto(priority)

Примеры:
exten => 1,1,Goto(submenu,s,1) ; переход в контекст "submenu", на екстеншен "s", к команде с приоритетом 1
exten => 600,4,Goto(s,6) ; переход в текущем контексте, к екстеншену "s", к команде с приоритетом 6

exten => s,1,Dial(${ARG2},20,r)
exten => s,2,Goto(s-${DIALSTATUS},1)
exten => s-NOANSWER,1,Voicemail(u${ARG1})
exten => s-CHANUNAVAIL,1,Voicemail(b${ARG1})
exten => s-BUSY,1,Voicemail(b${ARG1})
exten => _s-.,1,Voicemail(u${ARG1})
Команда GotoIf()

Назначение
Переход по условию

GotoIf
Описание
GotoIf(condition?label1[:label2])

Переход к команде label1, если условие condition истина, или выполнение следующей, по приоритету, команды (или, если определено, переход к команде label2) если условие condition ложно, или:

GotoIf(condition?[label1]:label2)

Выполнение следующей, по приоритету, команды (или команды label1, если определено) если условие condition истина, или переход к команде label2, если условие condition ложно.

Параметры label1 или label2 могут быть опущены (в этом случае, ветвление возможно только по одному из условий). Отсутствие обоих точек перехода не допускается.

Условие condition - это текстовая строка. Если строка пустая или содержит "0", то условие будет считаться ложью. Если она содержит что-то другое, то условие будет истиной. Это сделано для совместимости с механизмом регулярных выражений, используемых в Asterisk.

Метка перехода задается в виде '[[контекст,]екстеншен,]приоритет. Итак, для нее мы можем задать следующие комбинации: (a) только приоритет, (b) екстеншен и приоритет, или (c) контекст, екстеншен и приоритет. Этот формат такой же, как и формат аргумента команды Goto.

Пример 1
  exten => 206,1,GotoIf($["${CALLERIDNUM}" = "303"]?3:2)
  exten => 206,2,GotoIf($["${CALLERIDNUM}" = "304"]?5:7)
  exten => 206,3,Dial(${SPHONE1},15,rt)
  exten => 206,4,Hangup
  exten => 206,5,Dial(${PHONE2},15,rt)
  exten => 206,6,Hangup
  exten => 206,7,MusicOnHold(default)

Пример 2
 ; Надо определить, являются ли первые три символа, полученного значения в переменной
; ${ENUM}, значениями SIP или IAX. Если нет, игнорируем эту переменную и переходим к
; приоритету 4, где осуществляем стандартный набор номера
 exten => _011X.,2,GotoIf($[$["${ENUM:0:3}" = "SIP"] | $["${ENUM:0:3}" = "IAX"]]?3:4)



Пример 3
  ; Этот пример проверяет на пустое значение callerID или на номер 800 серии.
  ; Вызывающим абонентам с номерами на 800 (обычно "telemarketers") или
  ; те, у которых не представлено caller ID, будет предложено нажать 1 для разговора.
  exten => s,1,NoOp(${CALLERID}) ; просто смотрим на callerID
  ; проверяем callerID. Если не задан, предлагаем абоненту нажать 1.
  exten => s,2,GotoIf($["${CALLERIDNUM}" = ""]?s|1000)
  ; Если номер начинается на 800, предлагаем абоненту нажать 1.
  exten => s,3,GotoIf($["${CALLERIDNUM:0:3}" = "877"]?s|1000)
  exten => s,4,GotoIf($["${CALLERIDNUM:0:3}" = "800"]?s|1000)
  ; OK, тут у нас нормальный callerID и точно не номер из 800 серии.
  ; Теперь вызываем нужный нам телефон:
  exten => s,5,Dial(SIP/604&SIP/602,25,tr)

  exten => s,1000,Background(press1tospeaktome)

взято с http://asterisk.ru/

Команды плана набора IP АТС Asterisk

Команды плана набора IP АТС Asterisk