В этой статье я хочу немного расказать об интеграции звездочки с языком программирования php. При этом мы будем использовать класс phpagi.
Под катом я приведу примеры использования нескольких методов этого класса которые помогли мне.
Первым делом качаем последнюю версию phpagi и подключаем его в наш проект, а так же правим файл /etc/asterisk/manager.conf
; ; Asterisk Call Management support ; [general] enabled = yes ; Включаем asterisk manager interface (AMI) port = 5038 bindaddr = 127.0.0.1 ; Доступ только с локалхоста для безопастности webenabled = no ; Each user has a section labeled with the username ; so this is the section for the user named "mark" [user] ; имя пользователя для конекта secret = qwerty ; пароль deny=0.0.0.0/0.0.0.0 ; еще запреты на коннект permit=127.0.0.1/255.255.255.0 read = system,call,log,verbose,command,agent,user,originate ; Права пользователя на выполнение комманд write = system,call,log,verbose,command,agent,user,originate
В архиве с phpagi есть файл phpagi.conf, его нужно скопировать в /etc/asterisk и естественно исправить логин и пароль.
Теперь мы можем смело подключатся к AMI из php скрипта, например так:
include('phpagi.php'); $manager = new AGI_AsteriskManager(); $manager->connect(); // если нет файла phpagi.conf то тут можно указать хост, логин, пароль.
Первым делом я хотел бы расказать о написании простейшего монитора событий asterisk на php.
Как мне кажется это самая полезная функция класса phpagi.
Вот такой у меня вышел монитор событий:
function dump_events($ecode,$data,$server,$port) { $date_now = date('Y-m-d'); $time_now = date('H:i:s'); echo "$time_now : received event '$ecode' from $server:$port\n"; print_r($data); } include('phpagi.php'); $manager = new AGI_AsteriskManager(); $manager->connect(); $manager->add_event_handler('*', 'dump_events'); // цепляем хендлер на все события которые // поступают из AMI и передаем управление // функции описанной выше $manager->wait_response(); // очень полезная вещь, благодаря этой функции скрипт будет // ждать событий и не стопится в отличии от sleep() $manager->disconnect();
Используя этот хендлер можно выполнять какие нибудь действия в зависимости от полученного эвента, например проверять баланс на sim-карте вставленной в модем huawei и подключенной через chan_dongle.
Приведу пример своей реализации используя метод Command:
Первый скрипт ловит событие newussd
function donglenewussd($ecode, $data) { if($model = Trunk::model()->find('value = :value', array( ':value' => $data['Device']))){ if(!empty($data['MessageLine0'])){ $balance = explode(' ', $data['MessageLine0']); switch($model->carrier){ case '0': break; case '1': $model->balance = $balance[0]; $model->save(); echo $balance[0]."\n"; break; case '2': $model->balance = $balance[2]; $model->save(); echo $balance[2]."\n"; break; case '3': preg_match('/[+-]?\d+\.?\d*/', $balance[1], $match); $model->balance = $match[0]; $model->save(); echo $match[0]."\n"; break; } } } } $manager = new AGI_AsteriskManager(); $manager->connect(); $manager->add_event_handler('donglenewussd', 'donglenewussd'); $manager->wait_response(); $manager->disconnect();
Этот скрипт получает событие donglenewussd в котором нам приходит ответ от оператора на основе которого мы заносим в базу информацию о состоянии баланса.
Следующий скрипт будет по крону скажем раз в час отправлять ussd запрос по сотоянию баланса.
$manager = new AGI_AsteriskManager(); $manager->connect(); $trunks =Trunk::model()->findAll(); foreach($trunks as $trunk){ switch($trunk->carrier){ case '1': $manager->Command('dongle ussd '.$trunk->value.' *101#'); break; case '2': $manager->Command('dongle ussd '.$trunk->value.' *111#'); break; case '3': $manager->Command('dongle ussd '.$trunk->value.' *111#'); break; } } $manager->disconnect();
Как вы могли заметить я испоьзую yii framework для своих проектов, у меня есть модель в которой хранятся настройки модема (системное имя, оператор, баланс, состояние и т.д.)
Данный пример работает с Украинскими операторами (МТС, Киевстар и Life)
И на десерт я хочу Вам расказать про метод Originate. Вы еще используете call файлы? тогда мы идем к Вам.
Очень полезная функция которая инициирует звонок используя AMI, а не старый дедовский способ путем копирования call файла в директорию /var/spool/asterisk/outgoing
Все параметры передаваемые в функцию почти такие же как и параметры call файла:
$manager->Originate( 'Канал для вызова, например SIP/1001', 'Экстеншн для диалплана', 'Контекст диалплана', 'Приоритет контекста диалплана', 'Или приложение астериска для запуска, например playback', 'параметры приложения, например пусть к аудиофайлу', 'таймаут', 'Номер абонента от которого идет вызов или имя', 'переменные для диалплана', 'account - незнаю зачем, не использовал еще', 'Синхронный или асинхронный запрос (ждет или не ждет ответа о состоянии запроса)', 'actionid - тоже пока не использовал' );
Ну а что делать с этой функцией я думаю Вы придумаете сами, а если совместить ее с менеджером событий то можно еще и получить очет о выполнении исходящего звонка.
Надеюсь моя статья окажется кому нибудь полезной, так как я не нашел упоминание phpagi на хабре, да и вообще с трудом нашел хоть какие нибудь примеры использования кроме тех что идут в архиве с библиотекой.
Если у кого то есть другие методы работы с этой библиотекой очень буду рад почитать о них в коментариях.
ссылка на оригинал статьи http://habrahabr.ru/post/155111/
Добавить комментарий