viras777 / asteriskwatch
通过asterisk AMI追踪扩展的条件,并提供状态信息
1.6.3
2022-02-17 10:21 UTC
Requires
- php: >=5.3.0
README
asteriskWatch是一个库,可以轻松获取当前的asterisk扩展状态。
关于
此库处理Newchannel、Hangup、Newstate、ExtensionStatus和Dial等事件。收集并保持每个扩展的状态。能够处理重定向、分组呼叫和会议。
要求
PHP 5.3或更高版本 一个与POSIX兼容的操作系统(Linux、OSX、BSD)
安装
composer require viras777/asteriskWatch
基本用法
例如,获取asterisk状态并将其发送到RabbitMQ
<?php require_once __DIR__ . '/vendor/autoload.php'; use PhpAmqpLib\Connection\AMQPStreamConnection; use PhpAmqpLib\Message\AMQPMessage; use asteriskWatch\asteriskWatch; $amqpConnection = new AMQPStreamConnection($rmq_host, $rmq_port, $rmq_user, $rmq_pass, $rmq_vhost); $channel = $amqpConnection->channel(); $channel->exchange_declare('_sys_phoneEvent', 'direct', false, true, false); if (false === ($server = new asteriskWatch($asterisk_host, $asterisk_port, $asterisk_user, $asterisk_pass))) { echo "Can not connect to the asterisk\n"; return; } if (getenv('asteriskWatch_debug') != '') { switch (getenv('asteriskWatch_debug')) { case asteriskWatch::logInfo: $server->Debug = asteriskWatch::logInfo; break; case asteriskWatch::logDebug: $server->Debug = asteriskWatch::logDebug; break; case asteriskWatch::logTrace: $server->Debug = asteriskWatch::logTrace; break; } } $server->setExtenList(array(100, 101, 102)); $endCallStatus = array( 'ANSWER' => 0, 'BUSY' => 1, 'NOANSWER' => 2 'CANCEL' => 3, 'CONGESTION' => 4, 'CHANUNAVAIL' => 5, 'DONTCALL' => 6, 'TORTURE' => 7, 'INVALIDARGS' => 8, 'VOICEMAIL' => 9, 'REDIREND' => 10 ); $direction = array('in' => 'true', 'out' => 'false'); $saveCDR = function ($event) { global $endCallStatus, $direction; $pgsql = new db($USER, $PASS); $pgsql->prepare_sql('INSERT INTO phoneEventCDR ( fromNum, toNum, direction, endCallStatus, callTimeFrom, talkTimeFrom, callTimeTo, answeredExten, exten, lineNum, secondSideExten, secondSideLineNum) VALUES ( ?, ?, ?::boolean, ?, to_timestamp(?), to_timestamp(?), to_timestamp(?), ?, ?, ?, ?, ?)', array($event['From'], $event['To'], $direction[$event['Direction']], $endCallStatus[$event['EndCallStatus']], $event['CallTimeFrom'], ($event['TalkTimeFrom'] != '' ? $event['TalkTimeFrom'] : NULL), $event['CallTimeTo'], $event['AnsweredExten'], $event['Exten'], $event['LineNum'], $event['SecondSideExten'], $event['SecondSideLineNum']), 'num'); unset($pgsql); }; $server->setFuncSaveCDR($saveCDR); $sendDialEvent = function ($event) use ($channel) { $msg = new AMQPMessage(json_encode($event)); $channel->basic_publish($msg, '_sys_phoneEvent', $event['Exten']); }; $server->setFuncSendDialEvent($sendDialEvent); $timeToReload = strtotime('now')+600; $tick = function () use ($server) { global $timeToReload; if (strtotime('now') < $timeToReload) { return; } $server->setExtenList(array(100, 103)); $timeToReload = strtotime('now')+60; }; $server->setFuncTick($tick); $redis = new Redis(); $redis->connect($redis_host); $redis->select($redis_db); $getAllLine0Status = function ($event, $allLine0Status) use ($redis) { if (isset($event['EndCallStatus'])) { $event['Status'] = asteriskWatch::extenStatusIdle; } if (isset($event['Exten'])) { if (isset($event['LineNum']) && $event['LineNum'] > 0) { if (isset($event['Status']) && $event['Status'] != asteriskWatch::extenStatusIdle && $allLine0Status[$event['Exten']] == asteriskWatch::extenStatusIdle ) { $allLine0Status[$event['Exten']] = $event['Status']; } } else { $allLine0Status[$event['Exten']] = $event['Status']; } } $redis->del('sys_phoneStatus'); //$redis->hMSet('sys_phoneStatus', $allLine0Status); $redis->hMSet('sys_phoneStatus', array_diff($allLine0Status, [asteriskWatch::extenStatusIdle])); $redis->expire('sys_phoneStatus', 60*60*24); }; $server->setFuncGetAllLine0Status($getAllLine0Status); $server->watch();
示例日志
[2020-01-01 00:04:56] sendDialEvent ->
'From' => '84951608738',
'To' => '135',
'Direction' => 'in',
'CallTimeFrom' => '1582466696',
'TalkTimeFrom' => '',
'SecondSideExten' => '0',
'SecondSideLineNum' => '0',
'CallerIDName' => '4951608738',
'Status' => '8',
'StatusTxt' => 'Вызов',
'UniqueID' => '1582466696.72081',
'AnsweredExten' => '',
'Exten' => '135',
'LineNum' => '0'
[2020-01-01 00:05:14] saveCDR ->
'From' => '84951608738',
'To' => '135',
'Direction' => 'in',
'CallTimeFrom' => '1582466696',
'TalkTimeFrom' => '1582466700',
'SecondSideExten' => '0',
'SecondSideLineNum' => '0',
'CallerIDName' => '4951608738',
'Status' => '1',
'StatusTxt' => 'Разговаривает',
'UniqueID' => '1582466696.72081',
'AnsweredExten' => '135',
'Exten' => '135',
'LineNum' => '0',
'CallTimeTo' => '1582466714',
'EndCallStatus' => 'ANSWER'
许可证
asteriskWatch在Apache 2.0许可证下发布。