asterisk скрипт на событие
Система экстренного оповещения на базе Asterisk
Появилась необходимость реализовать систему звукового оповещения на случай чрезвычайных ситуаций. Т.к. на закупку и монтаж специализированного оборудования денег никто не дал — решили использовать под это дело IP телефонию (Asterisk 13 с аппаратами AudioCodes 420HD и Grandstream GPX-1625).
Суть экстренных оповещений проста — специально обученный человек по факту наступления определенных событий (пожар, потоп, приезд курьера с пиццей) набирает на VOIP-телефоне комбинацию клавиш, которая через Asterisk соединяется со всеми необходимыми номерами, а аппараты автоматически подхватывают вызов и включают громкую связь (speaker).
Технически распределение вызовов делается просто — в нужном контексте extensions.conf заводим необходимую комбинацию клавиш и направляем ее на нужный номер:
В этом случае при наборе комбинации 999 звонок вызывающего абонента попадет на внутренний номер 100. Теперь нам нужно научить его автоматически поднимать трубку.
В большинстве VOIP-телефонов предусмотрена функция автоматического ответа (Auto Answer). Как правило, она отключена и нужно включить ее вручную.
Для AudioCodes 420HD это делается через меню Management — Manual Update — Configuration file. Нужно найти параметр voip/auto_answer/enabled и установить ему значение 1.
Для GrandStream GXP-1625 настройка немного проще: Accounts — Account X — Call Settings — Allow Auto Answer by Call-Info «YES».
Для того, чтобы телефон задействовал функцию Auto Answer необходимо модифицировать SIP-заголовок звонка — добавить к нему информацию о том, что данный вызов подлежит автоматическому ответу. Для AudioCodes это будет выглядеть так:
Для телефонных аппаратов разных вендоров нужно указывать разные SIP-заголовки. Варианты, которые мне удалось нагуглить:
Asterisk и информация о входящих звонках в браузере через Notifications
В нашей компании используется телефон 8800, для того, чтобы клиенты могли сделать заказ без доступа к сайту. Для обслуживания большинства входящих звонков используется call-центр, а также при необходимости происходит перенаправление на внутреннего сотрудника.
Для удобства сотрудников и возможности персонализированного ответа была внедрена система распознавания входящего звонка по внутренней базе клиентов.
Так как cron задания были бы слишком редкими (максимум 1 раз в секунду), то за основу был взят демон на php, который сканирует каналы и отправляет информацию о звонке во временное хранилище. Для временного хранилища был использован memcached.
Используемая версия Asterisk’a — 11.15.1.
В качестве API связки php и Asteriska’a — модуль PAMI.
Существует два возможных варианта распознавания: прослушивание событий каналов и ручной разбор информации в CoreShowChannel, рассмотрим все по порядку.
Прослушивание событий
В конструктор демона добавляем инициализацию слушателя событий AsteriskEventListener:
И соответственно сам класс прослушивания и работы с временным хранилищем:
В данном варианте возможны проблемы при создании каналов. Дело в том, что когда происходит перенаправление звонка между сотрудниками или перенаправление с call-центра на сотрудника оба канала будут созданы в связке с тем, кто перенаправлял, и никакой информации о результирующей связке оператора и клиента не будет.
Ручной разбор информации CoreShowChannel
Для работы данного способа необходимо несколько модифицировать демон, вызываем событие CoreShowChannel принудительно, так как сам Asterisk его не генерирует:
В данном способе есть проблема удаления номера телефона при отключении клиента от канала. Для решения можно использовать событие разрыва соединения:
В итоге оказалось, что второй способ является более эффективным, так как при работе с событиями asterisk часто падал, и, в результате, терялись некоторые звонки. Так же в первом способе не распознавались звонки при перенаправлении с call-центра, так как номер сотрудника и клиента были в разных каналах (Первый канал связывает call-центр и сотрудника, второй канал связывает call-центр и клиента).
Информация о звонке через Notifications
Для получения информации о входящих звонках был использован плагин event-source-polyfill и long-pull запросы на сервер. Напомню мы храним входящие звонки в memcached.
Практика показала, что если сотрудник открывает много вкладок то генерируется большое количество запросов. Для предотвращения этого был использован плагин wormhole, который передает информацию о канале между вкладками.
Расширяем возможности Asterisk, используя PHP
Все слышали про мини-АТС нового поколения имя которой Asterisk. Так уж случилось что я заинтересовался этой системой и даже успел сделать пару коммерческих проектов.
В этой статье я хочу немного расказать об интеграции звездочки с языком программирования php. При этом мы будем использовать класс phpagi.
Под катом я приведу примеры использования нескольких методов этого класса которые помогли мне.
Первым делом качаем последнюю версию phpagi и подключаем его в наш проект, а так же правим файл /etc/asterisk/manager.conf
В архиве с phpagi есть файл phpagi.conf, его нужно скопировать в /etc/asterisk и естественно исправить логин и пароль.
Теперь мы можем смело подключатся к AMI из php скрипта, например так:
Первым делом я хотел бы расказать о написании простейшего монитора событий asterisk на php.
Как мне кажется это самая полезная функция класса phpagi.
Вот такой у меня вышел монитор событий:
Используя этот хендлер можно выполнять какие нибудь действия в зависимости от полученного эвента, например проверять баланс на sim-карте вставленной в модем huawei и подключенной через chan_dongle.
Приведу пример своей реализации используя метод Command:
Первый скрипт ловит событие newussd
Этот скрипт получает событие donglenewussd в котором нам приходит ответ от оператора на основе которого мы заносим в базу информацию о состоянии баланса.
Следующий скрипт будет по крону скажем раз в час отправлять ussd запрос на проверку баланса.
Как вы могли заметить я испоьзую yii framework для своих проектов, у меня есть модель в которой хранятся настройки модема (системное имя, оператор, баланс, состояние и т.д.)
Данный пример работает с Украинскими операторами (МТС, Киевстар и Life)
И на десерт я хочу Вам расказать про метод Originate. Вы еще используете call файлы? тогда мы идем к Вам.
Очень полезная функция которая инициирует звонок используя AMI, а не старый дедовский способ путем копирования call файла в директорию /var/spool/asterisk/outgoing
Все параметры передаваемые в функцию почти такие же как и параметры call файла:
Ну а что делать с этой функцией я думаю Вы придумаете сами, а если совместить ее с менеджером событий то можно еще и получить отчет о выполнении исходящего звонка.
Надеюсь моя статья окажется кому нибудь полезной, так как я не нашел упоминание phpagi на хабре, да и вообще с трудом нашел хоть какие нибудь примеры использования кроме тех что идут в архиве с библиотекой.
Если у кого то есть другие методы работы с этой библиотекой очень буду рад почитать о них в коментариях.
Asterisk. Запуск скрипта при подъеме трубки
Есть asterisk 1.8.11.0
Настроена очередь.
Необходимо, что бы исполнялся скрипт в тот момент, когда трубку поднимает кто-либо из этой очереди. Плюс передача скрипту в параметре номера звонившего, чтоб можно было взять из @ARGV.
Подскажите хотя бы документацию по этой теме или схему, как это можно реализовать.
Что-то вроде такого?
Подскажите хотя бы документацию по этой теме или схему, как это можно реализовать.
Chaser_Andrey
Тебе нужно отслеживать event Bridge.
Не мог бы по-подробнее подсказать? Набросал скриптик, который смотрит за событиями, все(как мне показалось) есть в event Hangup, но там много лишнего. Или я что-то не так понял?
Как это делать в диалплане — я хз, я не занимался настройкой Asterisk, а лишь работал с ним через AMI.
Хотя могут быть другие эвенты/хуки, про которые я не знаю.
При поднятии трубки агентом возникает event AgentConnect.
А еще стоит подумать, а оно надо через AMI делать, если скрипт можно дергать средствами диалплана.
Да я тоже не настраивал Астериск.
Я просто не могу понять как его ловить этот event Bridge
открой исходники Asterisk Test Suite http://svn.asterisk.org/svn/testsuite/asterisk/trunk и получи готовый код бесплатно без смс
скрипт можно дергать средствами диалплана
если у него в диалплане Dial() то дернуть получится только свой болт. Dial() синхронный и выполняется полка трубки не положат.
Subnets.ru blog
Сети, настройка оборудования, сетевые сервисы.
Asterisk: автообзвон (auto-dial out) и обратный звонок (callback) с использованием AGI
Автообзвон
Например вы сис.админ, у вас есть локальная сеть и куча оборудования в ней, но вы же не 24/7 на работе, а раз так, то в сети может что то произойти, например событие в системе мониторинга, а вас нет на рабочем месте. Конечно можно отправлять себе SMS, если такая вожможность есть, а имея сервер Asterisk можно и позвонить и самому себе рассказать что же случилось 😉
Или вам необходима система callback, что бы позвонив на номер заведенный на Asterisk, вы могли получить с него обратный звонок и набрать другой номер.
Итак, считаем что у вас у уже есть установленный и настроенный сервер Asterisk, который имеет выход в город.
Что бы совершить автоматический звонок нам потребуется следующие вещи:
Начнем с call файла, его основной синтаксис:
— С какого приоритета начинаем.
Соответственно зная синтаксис мы теперь сможем сформировать call файл, на примере звонка через SIP канал:
Для тех кто в танке 🙂 разберем call файл построчно:
Сформировав call файл, его необходимо положить в папку: /var/spool/asterisk/outgoing/ сервер Asterisk обнаружив в этой папке файл сразу же попытается отработать его.
Сразу скажу, что можно и задержать обработку файла, т.е. задержать исх. звонок и отложить его на определенное вами время.
Сервер Asterisk смотрит на дату создания call файла и если изменить дату создания на дату в будущем, то Asterisk не будет отрабатывать call файл, пока не наступит эта самая дата.
После того как создали сам call файл берем и меняем дату его создания, шаблон даты такой:
ГОД МЕСЯЦ ДЕНЬ ЧАСЫ МИНУТЫ . СЕКУНДЫ ( внимание: перед секундами стоит символ точки, это так и нужно, а не опечатка ).
Для примера выставим дату в будущем, скажем это 09.07.2010 19:18:55:
Теперь посмотрим на сам контекст (context), для системы мониторинга он может быть таким:
Исходя из данного контекста Asterisk дозвонившись до 89161112233 (человек взял трубку) выполнит следущее:
Как записать голосовые файлы (то что вы будете проигрывать) вы можете узнать из этой статьи.
Может появится ещё одна задача, а именно: если при автодозвоне трубку так и не подняли, то сразу набрать другой номер. Пример такой конструкции:
Кажется, ну что может быть проще, написать:
А вот тут то и выяснилось, что не все так просто. На такое действо вы в консоле (выставив 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 файл или ещё что то), но тут родился ещё один вариант:
Создаем call-файл уже чуть другого содержания:
Тем самым мы как бы набираем уже не номер, а конкретный exten в контексте и в нем передаем вызов в макро, создаем и макро, которое используется в этом контексте:
Собственно этот макро дает нам возможность уже управлять куда и в каком случае пойдет вызов. Пример конечно «грубый», но главное ведь принцип, а дальше уже ваше творчество 😉
И вот таким образом мы получаем искомый результат.
[Конец добавленного 11.02.2011]
Callback
Он работает по тому же принципу, что и описанный выше автообзвон, за некоторыми исключениеми:
Что нам потребуется в этом случае:
AGI — это Asterisk Gateway Interface.
Asterisk Gateway Interface это возможность расширить функционал Asterisk`а с помощью использования скриптов на многих языках программирования. Например Perl, PHP, C, Pascal, Bourne Shell.
Начнем с номера, допустим это будет гор. номер 84955556677. Добавим в extensions.conf в контекст (context) куда поступают все входящие звонки: