Скрипты php для asterisk

База знаний

Первое правило бизнеса – быть осведомленным о среде PHP. Я НЕ говорю, что вы должны изменить нечто, но вы должны быть осведомленными о ней, возможно некоторое отчаяние, особенно когда вы в гуще вещей. На Debian вам сразу возможно надо получить “php4-cli”, так как типичная усиановка PHP4 предназначается только для сети.

Я наконец-то ухитрился найти проблему с моим PHP AGI скриптом! Вероятно, на моей машине было 2 версии установленных PHP. Одна для CGI и другая для CLI. Не зная, как провести тестирование моего скрипта, я вызsвал версию CLI (/usr/local/bin/php), несмотря на то, что PHP вызывал версию CLI (/usr/local/bin/php). Это повернулось так, что мой скрипт не будет запускаться на CLI версии PHP… Интересно, не так ли?

Да, будьте осведомлены, что завися от ваших настроек, Apache может как читать php.ini, так и заместить ваш сетевой php.ini.
Еще: Используя неправильную версию PHP, может вызвать проблемы при попытки чтения канальных/диалплановских переменных в вашем PHP скрипте, также проверка, если вам надо, например, “#!/usr/bin/php-cgi –q” или “#!/usr/bin/php –q” в первой строке.

Посмотрите на ваш php конфиг файл (в /etc/php.ini или /usr/local/etc/php.ini) для следующего:

ob_implicit_flush(false);
set_time_limit(5);
; error_log = filename
error_reporting(0); //добавлено пользователем: демокрит

Первая строка, ob_implicit_flush-, показывает, должен ли php буферизовать выходные данные; в случае Asterisk agi, если вы буфферизуете выходные данные, Астериск АТС не получит ваши команды долгое время, до тех пор пока вы не очистите ваш буфер вручную (смотри ниже)

Второй элемент, set_time_limit, это максимально возможное время для выполнения вашего php скрипта. Большинство Asterisk agi скриптов будут запускаться без разумного времени, но если у вас есть очень длинный скрипт, который производит необычные ошибки, возможно, что ваш скрипт был завершен преждевременно.

Читайте также:  PostgreSQL PHP Querying Data Demo

Третий элемент – error_log; важен для отладки, но убийца для промышленных систем. Он может быть выключен по умолчанию или вы можете намеренно выключить его и не забыть.

Четвертый элемент, error_repоrting(0), говорит PHP не сообщать об ошибках в течении времени выполнения скрипта. Это важно, потому что любые ошибки (и некоторые предупреждения), которые создал ваш скрипт, будут посланы к STDOUT, тому же самому буферу, к которому посылаются все AGI команды. Поэтому, любые ошибки в вашем скрипте будут посланы к AGI и астреиск будет пытаться прочесть их как AGI команды. В моем эксперименте, это поведение будет выполнять все последующие команды, после того, как ошибка скрипта (неизвестная для вас) вернет “510 invalid command”…
after a script error (unknown to you), return ‘510 invalid command’, although commands like ‘EXEC Playback’ will actually still play back a sound file. For important AGI commands like ‘GET DATA my_file’ and ‘GET DIGIT my_file’, the Asterisk CLI will report «Playing File my_file» but the sound file will not be heard on the channel and no DTMF input can be received by the caller. There is also no way for the script to tell what DTMF keys were pressed since the command returns a «510 invalid’ string. An alternative to using error_reporting(0) at the beginning of your script to help you debug would be to prepend your suspected error-generating commands in your script with @, such as

$rst = @mysql_query($strSQL);
—OR—
$fp = @fopen(«some non-existant file», «r»);

The @ will suppress any errors or warning generated by the statement.
Edit

Поместите ваши скрипты в диреторию /var/lib/asterisk/agi-bin/ и получите их работу сперва перед тем, как вы что-нибудь вообразите.

3.Выполнение разрешения на файлов скрипта

Помните к chmod ВСЕ ваши скрипты к 733 как ниже показано:

4. Интерфейс для команды shell

2 первые строки в вашем скрипте должны быть следующие (при условии что ваша php bindery находится в /usr/bin; дважды проверьте это):

#!/usr/bin/php -q

• agi_context – Иточник контекста
• agi_extension – Номер вызывающего
• agi_priority – Приоритет, он может выполняться в dial plan
• agi_accountcode – Учетный код канала источника, например, joesoap1

Для использования простого вызова переменной и ключа… например. Если вы хотите, чтобы вызывающий номер просто использовал переменную $agivar[agi_extension] в вашем PHP коде…

Другие AGI заголовки, прермещенные Астериском (входы среды)

• agi_calleridname – Имя вызывающего, например, Joe Soap
• agi_callingpres — Представление для callerid в ZAP канале
• agi_callingani2 — неизвестно
• agi_callington — неизвестно
• agi_callingtns — неизвестно
• agi_dnid – id номер dialed
• agi_rdnis — Посланное DNIS число
• agi_enhanced – Значение флага – 1.0, если стартует как EAGI скрипт

Замечание: если id номер вызывающего не установлен в sip.conf, agi_callerid будет иметь то же значение, что и agi_calleridname.

7. Начало использования AGI канала

Это точка, где вы можете начать разговор с астериском. Используйте fputs для того, чтобы отправить * agi команды. Вы можете также использовать echo команду.

fputs($stdout,»SAY NUMBER 1234567 ’79#’ \n»);
fflush($stdout);

• Замечание: Используйте fflush() regardless of php.ini setting just to be safe. If you don’t fflush() (авто или вручную), Asterisk не будет принимать команду и ваша прога будет stuck там до таймаута.

© 2008 — 2023 Asterisk.ru
Digium, Asterisk and AsteriskNOW are registered trademarks of Digium, Inc.
Design and development by OOO PostMet-R

Источник

Расширяем возможности 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 на хабре, да и вообще с трудом нашел хоть какие нибудь примеры использования кроме тех что идут в архиве с библиотекой.

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

Источник

Рассказываем про Asterisk Gateway Interface (AGI)

img

Дорогой читатель! В поисках полезной автоматизации и кастомизации своего Asterisk продвинутые администраторы прибегают к использованию различных скриптов. Это может быть PHP, Perl C, Pascal или Shell. Для использования скриптов, написанных на одном из перечисленных языков программирования в диалплане Asterisk используется AGI (Asterisk Gateway Interface) – о нем и поговорим.

Как это работает?

AGI — это прослойка между скриптом и диалпланом (планом набора) в Asterisk. В скрипт мы можем передавать различные переменные, а можем получать какие — то значения из скрипта. Когда Asterisk инициирует запуск скрипта через AGI, он передает в него набор переменных. Все переменные обладают префиксом agi_:

Переменная Описание Пример
agi_request Имя файла исполняемого скрипта trunk.php
agi_channel Канал, инициирующий звонок Local/89123456789@from-internal-00000002;2
agi_language Языковой код en
agi_type Тип канала, инициирующий вызов Local
agi_uniqueid Уникальный идентификатор звонка 1497364935.15
agi_version Версия Asterisk 13.10.0
agi_callerid Номер звонящего (CID Number) 89123456789
agi_calleridname Имя звонящего (CID Name) 89123456789
agi_dnid Набранный номер unknown
agi_context Контекст обработки вызова macro-dialout-trunk

Как вызвать AGI в диалплане?

Вызвать AGI скрипт очень просто: предварительно, загрузите скрипт в директорию /var/lib/asterisk/agi-bin/ . После этого, скрипту необходимо дать права и собственника. Предположим, наш скрипт называется trunk.php:

chmod 755 /var/lib/asterisk/agi-bin/trunk.php chown asterisk:asterisk /var/lib/asterisk/agi-bin/trunk.php

Теперь, чтобы скрипт был вызван в диалплане, просто добавьте следующую конструкцию:

Просто, не правда ли? А если мы хотим передать переменную в скрипт? Просто добавьте ее после запятой:

Asterisk Gateway Interface (AGI)

А как же написать скрипт?

Теперь к самому скрипту – напишем его на PHP. Пусть нам нужно отправлять письмо с номером звонящего. Выглядеть скрипт будет так:

#!/usr/bin/php -q request['agi_callerid']; // берем из AGI номер звонящего mail("info@merionet.ru", 'Привет!', 'Вот и номер звонящего:', $cid); //отправляем в письме

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

Источник

Оцените статью