Расширяем возможности Asterisk, используя PHP

от автора

Все слышали про мини-АТС нового поколения имя которой Asterisk. Так уж случилось что я заинтересовался этой системой и даже успел сделать пару коммерческих проектов.

В этой статье я хочу немного расказать об интеграции звездочки с языком программирования 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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *