Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Автообзвон
- Есть задачи реализация которых возможна через автоматический обзвон. Например ?
- Например вы сис.админ, у вас есть локальная сеть и куча оборудования в ней, но вы же не 24/7 на работе, а раз так, то в сети может что то произойти, например событие в системе мониторинга, а вас нет на рабочем месте. Конечно можно отправлять себе SMS, если такая вожможность есть, а имея сервер Asterisk можно и позвонить и самому себе рассказать что же случилось 😉
- Или вам необходима система callback, что бы позвонив на номер заведенный на Asterisk, вы могли получить с него обратный звонок и набрать другой номер.
- Итак, считаем что у вас у уже есть установленный и настроенный сервер Asterisk, который имеет выход в город.
- Что бы совершить автоматический звонок нам потребуется следующие вещи:
- сформировать call файл
- иметь в диалплане (dialplan (определяется в /usr/local/etc/asterisk/extensions.conf)) контекст (context) со списком действий
- Начнем с call файла, его основной синтаксис:
- Channel: <channel> — Какой канал использовать для звонка
- CallerID: «name» <number> — Установить Caller ID, проще сказать тут мы можем выставить АОН (номер с которого мы звоним).
- MaxRetries: <number> — Максимальное кол-во попыток дозвониться, по умолчанию 0, что является одной попыткой.
- RetryTime: <number> — Время в секундах между попытками дозвона, по умолчанию 300 (5 минут).
- WaitTime: <number> — Сколько секунд ожидаем поднятия трубки, по умолчанию 45.
- Context: <context-name> — Какой контекст используем из extensions.conf
- Extension: <ext> — Какой экстеншн используем в выбранном контексте (так же в extensions.conf).
- Priority: <priority> — С какого приоритета начинаем.
- Я привел не полный список, полный список доступен тут. Лично я, для каждого номера, создаю свой контекст в extensions.conf.
- Соответственно зная синтаксис мы теперь сможем сформировать call файл, на примере звонка через SIP канал:
- Channel: SIP/89161112233@sip-provider
- Callerid: 9998877
- MaxRetries: 2
- RetryTime: 20
- WaitTime: 60
- Context: outgoing_to_89161112233
- Extension: s
- Priority: 1
- Для тех кто в танке 🙂 разберем call файл построчно:
- позвонить на SIP номер 89161112233 через провайдера sip-provider (имя из /usr/local/etc/asterisk/sip.conf для выхода в город)
- использовать АОН 9998877
- Максимальное кол-во попыток дозвона 2
- Пауза между попытками 20 секунд
- Ожидать поднятия трубки 60 секунд
- Использовать контекст (context) с именем outgoing_to_89161112233
- Начинать с экстеншена (ext) s
- И начинать с приоритета 1 в экстеншене s
- Сформировав call файл, его необходимо положить в папку: /var/spool/asterisk/outgoing/ сервер Asterisk обнаружив в этой папке файл сразу же попытается отработать его.
- Сразу скажу, что можно и задержать обработку файла, т.е. задержать исх. звонок и отложить его на определенное вами время.
- Сервер Asterisk смотрит на дату создания call файла и если изменить дату создания на дату в будущем, то Asterisk не будет отрабатывать call файл, пока не наступит эта самая дата.
- Как это сделать ? Очень просто, для этого воспользуемся командой touch, которая есть во всех unix системах.
- После того как создали сам call файл берем и меняем дату его создания, шаблон даты такой:
- ГОДМЕСЯЦДЕНЬЧАСЫМИНУТЫ.СЕКУНДЫ (внимание: перед секундами стоит символ точки, это так и нужно, а не опечатка).
- Для примера выставим дату в будущем, скажем это 09.07.2010 19:18:55:
- /usr/bin/touch -t 1007091918.55 /path/to/call/file.call
- Дата создания call файла изменится и если переместить файл в /var/spool/asterisk/outgoing/, то соответственно Asterisk его не обработает до тех пор пока не наступит выставленная дата.
- Совет: генерить call файл лучше в какой то tmp директории, выполнять над ними все необходимые и действия и затем мувить (переносить) в /var/spool/asterisk/outgoing/.
- Теперь посмотрим на сам контекст (context), для системы мониторинга он может быть таким:
- [outgoing_to_89161112233]
- exten => s,1,Answer
- exten => s,n,Wait(1)
- exten => s,n,Background(/usr/local/share/asterisk/sounds/monitoring/welcome)
- exten => s,n,Background(/usr/local/share/asterisk/sounds/monitoring/Down)
- exten => s,n,Background(/usr/local/share/asterisk/sounds/monitoring/provider-a)
- exten => s,n,Background(/usr/local/share/asterisk/sounds/monitoring/bye)
- exten => s,n,hangup
- Исходя из данного контекста Asterisk дозвонившись до 89161112233 (человек взял трубку) выполнит следущее:
- поднимет трубку со своей стороны
- секунду подождет
- проиграет записанные вами звуковые файлы (полные пути к файлам указаны)
- повесит трубку
- Как записать голосовые файлы (то что вы будете проигрывать) вы можете узнать из этой статьи.
- После того как Asterisk полностью отработает call файл, он его удаляет из директории /var/spool/asterisk/outgoing/.
- Специальный экстеншен ‘failed‘
- Если на вызов не ответили, и существует стандартный экстеншен с именем failed и команда с приоритетом 1 в заданном (в .call файле) контексте, управление будет передано этой команде.
- exten => failed,1,Set(NumberDialed=${CUT(PassedInfo,,1)})
- exten => failed,n,SetCDRUserField(${NumberDialed})
- [Добавлено 11.02.2011]
- Может появится ещё одна задача, а именно: если при автодозвоне трубку так и не подняли, то сразу набрать другой номер. Пример такой конструкции:
- сначала набираем внутренний SIP номер (6003) человека
- если внутренний SIP номер не отвечает/занят/недоступен — набираем мобильный номер
- Кажется, ну что может быть проще, написать:
- exten => failed,1,Dial(SIP/89161112233@sip-provider)
- А вот тут то и выяснилось, что не все так просто. На такое действо вы в консоле (выставив core set verbose 3) увидите подобное сообщение:
- — Executing [failed@dialsip:1] Dial(«OutgoingSpoolFailed», «SIP/6003») in new stack
- [Feb 11 16:57:44] WARNING[94371]: channel.c:3441 ast_request: No translator path exists for channel type SIP (native 65535) to 0
- [Feb 11 16:57:44] WARNING[94371]: app_dial.c:1296 dial_exec_full: Unable to create channel of type ‘SIP’ (cause 58 — Bearer capability not available)
- == Everyone is busy/congested at this time (1:0/0/1)
- == Auto fallthrough, channel ‘OutgoingSpoolFailed’ status is ‘CHANUNAVAIL’
- [Feb 11 16:57:54] NOTICE[94371]: pbx_spool.c:356 attempt_thread: Call failed to go through, reason (8) Congestion (circuits busy)
- Усе… приехали…. Лазая по результатам поиска в гугле я натыкался на сообщения:
- Канал получается OutgoingSpoolFailed и именно в него пытается звонить и Dial и играть Playback. Как мне находясь в failed сделать звонок на SIP и проиграть сообщение?
- Собственно точно такой же вопрос задавал себе и я сам, но ответа на него ни в Инете ни у меня не было.
- Так же как и я народ пытался реализовать подобное через failed c Goto, System и т.п., но результат получался таким же — никаким 🙁
- Получается из starndart extention failed сделать набор (Dial) другого номера не получится…..
- Я уже было подумал, что не судьба и мне придется ловить DIALSTATUS, передавать его AGI скрипту (который ещё и писать придется) и тот уже будет решать что с этим делать (создавать новый call файл или ещё что то), но тут родился ещё один вариант:
- core*CLI> core show channeltypes
- Type Description Devicestate Indications Transfer
- ---------- ----------- ----------- ----------- --------
- Skinny Skinny Client Control Protocol (Skinny) no yes no
- SIP Session Initiation Protocol (SIP) yes yes yes
- Console OSS Console Channel Driver no yes no
- MGCP Media Gateway Control Protocol (MGCP) yes yes no
- Local Local Proxy Channel Driver yes yes no
- Zap DAHDI Telephony Driver w/PRI no yes no
- Agent Call Agent Proxy Channel yes yes no
- ----------
- 7 channel drivers registered
- core*CLI> core show channeltype Local
- -- Info about channel driver: Local --
- Device State: yes
- Indication: yes
- Transfer : no
- Capabilities: -1
- Digit Begin: yes
- Digit End: yes
- Send HTML : yes
- Image Support: no
- Text Support: yes
- core*CLI>
- Создаем call-файл уже чуть другого содержания:
- Channel: Local/1@autocaller
- Callerid: 9998877
- Context: outgoing_to_89161112233
- Extension: s
- Priority: 1
- Где autocaller это название контекста, а 1-ца это приоритет в этом контексте. Соответственно делаем в extensions.conf этот контекст:
- [autocaller]
- exten => 1,1,Macro(call6003user,6003)
- Тем самым мы как бы набираем уже не номер, а конкретный exten в контексте и в нем передаем вызов в макро, создаем и макро, которое используется в этом контексте:
- [macro-call6003user]
- exten => s,1,Dial(SIP/${ARG1},15,t)
- exten => s,n,Goto(s-${DIALSTATUS},1)
- exten => s-NOANSWER,1,Dial(SIP/89161112233@sip-provider)
- exten => s-NOANSWER,n,VoiceMail(${ARG1},u)
- exten => s-NOANSWER,n,Hangup()
- exten => s-BUSY,1,VoiceMail(${ARG1},b)
- exten => s-BUSY,n,Hangup()
- exten => _s-.,1,Goto(s-NOANSWER,1)
- Собственно этот макро дает нам возможность уже управлять куда и в каком случае пойдет вызов. Пример конечно «грубый», но главное ведь принцип, а дальше уже ваше творчество 😉
- И вот таким образом мы получаем искомый результат.
- [Конец добавленного 11.02.2011]
- Callback
- Он работает по тому же принципу, что и описанный выше автообзвон, за некоторыми исключениеми:
- генерация call файла происходит при звонке человека на номер выделенный под callback.
- в контексте (context) мы не просто проигрываем звуковые, а предлагаем пользователю ввести номер, на который он хочет позвонить
- Что нам потребуется в этом случае:
- выделить номер для callback и создать контекст (context) под него в extensions.conf.
- «передать» звонок в AGI скрипт, который проверит АОН звонящего на предмет разрешен ли этому номеру callback
- если callback разрешен, то сформирует call файл.
- AGI — это Asterisk Gateway Interface.
- Asterisk Gateway Interface это возможность расширить функционал Asterisk`а с помощью использования скриптов на многих языках программирования. Например Perl, PHP, C, Pascal, Bourne Shell.
- Начнем с номера, допустим это будет гор. номер 84955556677. Добавим в extensions.conf в контекст (context) куда поступают все входящие звонки:
- exten => 84955556677,1,AGI(sms-callback.php)
- exten => 84955556677,n,Hangup()
- Т.е. звонок на экстеншн (ext) 84955556677 будет передан AGI скрипту callback.php, а затем звонок будет сразу же завершен.
- AGI скрипты для Asterisk располагаются в директории /usr/local/share/asterisk/agi-bin/.
- Почему скрипт на PHP ? PHP был выбран для AGI, т.к. callback является неотъемлимой частью проекта написанного на PHP + MySQL, потому решили и AGI пусть на PHP будет.
- Сам скрипт: http://subnets.ru/files/callback.php.txt
- Что происходит с скрипте ?
- определяем необходимые переменные
- получаем данные от Asterisk`а.
- логи, куда же без них. В лог мы поместим все то, то получил AGI скрипт от Asterisk`а, это для дебага, потом можно выключить логирование.
- проверяем номер (АОН) звонящего на доступ к callback
- смотрим нет ли уже call файла для данного номера, если нет, то создаем его
- В переменной $agivar[‘agi_callerid’] и содержится АОН (телефонный номер) звонящего переданного нам Asterisk`ом, что в других передаваемых переменных вы сможете увидеть в log файле.
- Если установить $debug в ноль, то тем самым выключите логирование.
- В массиве $permit_num содержатся номера для которых разрешен callback.
- Ну и осталось дело за малым, а именно что бы был контекст (context) под звонящий номер в extensions.conf.
- Допустим наш callback номер 84955556677 набрали с мобильного 89105647899 и ему разрешен callback (номер84955556677 указан в массиве $permit_num в скрипте), то его контекст может выглядеть вот так:
- [outgoing_to_89105647899]
- exten => s,1,Set(CallbackNumTries=0)
- exten => s,n,Set(CALLERID(num)="9998877")
- exten => s,n(start),Background(vo-vvedite-ton-num-abonent)
- exten => s,n,WaitExten(10)
- exten => 100,1,Dial(SIP/8495${EXTEN}@sip-provider,120)
- exten => _XXXXXXX,1,Dial(SIP/8495${EXTEN}@sip-provider,120)
- exten => _8X.,1,Dial(SIP/${EXTEN}@sip-provider,120)
- exten => i,1,Set(CallbackNumTries=$[${CallbackNumTries} + 1])
- exten => i,n,Playback(vo-nomer-nabran-ne-verno)
- exten => i,n,GotoIf($["${CallbackNumTries}" < "3"]?s|start)
- exten => i,n,Playback(vo-dosvidaniya)
- exten => t,1,Set(CallbackNumTries=$[${CallbackNumTries} + 1])
- exten => t,n,GotoIf($["${CallbackNumTries}" < "3"]?s|start)
- exten => t,n,Playback(vo-dosvidaniya)
- exten => t,n,Hangup()
- устанавливаем число попыток в ноль
- выставляем АОН (под исх. звонок)
- проигрываем записанный текст: «переведите ваш телефон в тональный набор…. бла… бла.. бла…»
- 10 сек. ждем от человека набора номера
- указываем возможный набор номеров: 100 (узнать время ;)), 7-ми значный номер, 8-рка и далее сколько угодно цифр
- даем человеку три попытки на набор номера, если истек таймаут набора номера или номер был набран не верно, то человеку это озвучивается и кол-во попыток увеличивается на 1-цу и наше мини голосовое меню начинается сначала (возврат к метке start)
- если кол-во попыток исчерпано, то Asterisk вешает трубку
- З.Ы. При копировании статьи ссылка на источник ОБЯЗАТЕЛЬНА !
- Автор: Николаев Дмитрий (virus (at) subnets.ru)
- Похожие статьи:
- Не найдено
- Поделиться ссылкой:
- FacebookGoogle
- Прочитано: 104 704 раз(а)
- Ничего не понялТак себе...Не плохоДовольно интересноОтлично ! То что нужно ! (голосов: 19, среднее: 4,95 из 5)
- Отправить на почту Отправить на почту
- Эта статья размещена virus 09.07.2010 в 17:38 в рубриках Asterisk, FreeBSD, VoIP. Метки: AGI, Asterisk, auto-dial, callback, SIP. Вы можете оставить отзыв или trackback с вашего собственного сайта. Отслеживайте все отзывы и комментарии к этой статье при помощи новостной ленты RSS.
- комментария 3
- klim42 сказал:
- Приветствую, вопрос такой, возможно как то реализовать: в случае автообзвона и завершения количества попыток , выполнить скрипт? сейчас сделано костылем попытки пишутся в файл и когда заканчиваются выполняется скрипт.
- 15.02.2020, 18:43
- admin сказал:
- В прямую такой возможности нет.
- Писать самому не обязательно, т.к. есть штатный метод: https://wiki.asterisk.org/wiki/display/AST/Asterisk+Call+Files
- В call файл добавить «Archive: yes» и тогда отработанные файлы будут перемещаться в папку «outgoing_done» с добавлением «Status». Можно вызывать свой скрипт по крону, который будет анализировать файлы в «outgoing_done» и основываясь на «Status» делать то, что вы хотите.
- 16.02.2020, 09:40
- Dreamscapes сказал:
- А не подскажите, где найти sip-provider, если у меня Freepbx, asterisk 16.14.1. Чот никак не найду.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement