viras777/asteriskwatch

通过asterisk AMI追踪扩展的条件,并提供状态信息

1.6.3 2022-02-17 10:21 UTC

This package is auto-updated.

Last update: 2024-09-17 15:49:51 UTC


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许可证下发布。