Asterisk 13 software pbx connect to php

we need to access CDR (Call Details Record) in Asterisk 13 PBX,Is there any PHP script or software like fop2 to access CDR in real-time…?

also is there any API to communicate With Asterisk Management Interface (AMI) with mysql db

CDR records are written when the call ends. You can connect to AMI and capture the call start/hangup in real time.

Here’s what I run on all of my servers. It updates a central database which is queries from a web app.

Add to manager.conf…

[yourAMIuser]
secret = yourAMIpassword
read = call

eventfilter=Event: DeviceStateChange
eventfilter=Event: DialBegin
eventfilter=Event: UnParkedCall

#!/usr/bin/php -q
<?php
ini_set("default_socket_timeout", -1);

include('/opt/asterisk/includes.php');

$web = db_connect_web();

$socket = fsockopen("localhost","5038");
fputs($socket, "Action: Login\r\n");
fputs($socket, "Username: yourAMIuser\r\n");
fputs($socket, "Secret: yourAMIpassword\r\n\r\n");

$event = "";
while($ret = fgets($socket)){        
    if(substr($ret,0,6) == "Event:"){
        $e = explode(':', $ret);
        $event = trim($e[1]);
    }
    
    if($event == "DeviceStateChange"){
        $data = explode(':', $ret);
        
        if($data[0] == "Timestamp"){
            $ts = floor(trim($data[1]));
        }
    
        if($data[0] == "Device" && substr(trim($data[1]),0,3) == 'SIP'){
            $d = explode('/', trim($data[1]));
            $dev = trim($d[1]);
            $device = "";
            
            if(is_numeric($dev)){
                $device = $dev;
            }
        }
    
        if($data[0] == "State" && $device != ""){
            $state = trim($data[1]);
            
            if($state == "NOT_INUSE"){
                //Clear CID fields and update presence state
                $sql = "update asterisk.web_presence set state='$state',cidnum = NULL, cidname = NULL, inorout = NULL, callstart = NULL where ext='$device'";
                mysql_query($sql);
            }else{
                //Update presence state
                $sql = "update asterisk.web_presence set state='$state' where ext='$device'";
                mysql_query($sql);
            }
            
            $event = "";
            $device = "";
        }    
    }
    
    if($event == "DialBegin"){
        $data = explode(':', $ret);
        
        if($data[0] == "Timestamp"){
            $ts = floor(trim($data[1]));
        }
    
        if($data[0] == "Channel"){
            $c = explode('/',trim($data[1]));
            $c2 = explode('-', trim($c[1]));
            $channel = trim($c2[0]);
        }
    
        if($data[0] == "CallerIDNum"){
            $cidnum = trim($data[1]);
        }
    
        if($data[0] == "CallerIDName"){
            $cidname = trim($data[1]);
        }
    
        if($data[0] == "DialString"){
            if(substr(trim($data[1]),0,3) == 'SIP' || is_numeric(trim($data[1]))){                
                if(is_numeric(trim($data[1]))){
                    $exten = trim($data[1]);
                }else{
                    $e = explode('/', trim($data[1]));
                    $exten = trim($e[1]);
                }
                
                //Update inbound presence call
                $sql = "update asterisk.web_presence set cidnum = '$cidnum', cidname = '$cidname', inorout='I', callstart='$ts' where ext='$exten' and cidnum is null";
                mysql_query($sql);    
                
                $sql = "update asterisk.web_presence set cidnum = '$exten', inorout='O', callstart='$ts' where ext='$channel' and cidnum is null";
                mysql_query($sql);            
            }else{
                $e = explode('@', trim($data[1]));
                $dialed = trim($e[0]);
                
                if($channel != 'gateway'){                    
                    //Update outbound presence call
                    $sql = "update asterisk.web_presence set cidnum = '$dialed', inorout='O', callstart='$ts' where ext='$channel'";
                    mysql_query($sql);    
                }                
            }

            $event = "";
            $exten = "";
        }    
    }
        
    if($event == "UnParkedCall"){
        $data = explode(':', $ret);
        
        if($data[0] == "Timestamp"){
            $ts = floor(trim($data[1]));
        }
    
        if($data[0] == "RetrieverChannel"){
            $c = explode('/',trim($data[1]));
            $c2 = explode('-', trim($c[1]));
            $channel = trim($c2[0]);
        }
        
        if($data[0] == "ParkeeCallerIDNum"){
            $cidnum = trim($data[1]);
        }
        
        if($data[0] == "ParkeeCallerIDName"){
            $cidname = trim($data[1]);
        }        
    
        if($data[0] == "ParkingSpace"){
            $dialed = trim($data[1]);
            
            $pickup = "$cidnum ($dialed)";
            
            //Update outbound presence call
            $sql = "update asterisk.web_presence set cidnum = '$pickup', cidname='$cidname', inorout='O', state='INUSE', callstart='$ts' where ext='$channel'";
            mysql_query($sql);    
            
            $event = "";    
            $channel = "";        
        }    
    }        
}

# fputs($socket, "Action: Logoff\r\n\r\n");
mysql_close($web);

sleep(5);

exit;    
?>
1 Like

Hi mkozusnik Thanks for your reply :slight_smile:

May i know What is the place that i need to place this script is it need to save in Asterisk server ?
or can we run this out side the server ?
And what is the file name to save this php file ?

After run this code that data goes into CDR table in internal database or should i have to create separate table in internal Database …?

Thanks !

This program is currently set to run on the localhost, but you can run it from any server. The name doesn’t matter. It runs as an upstart job so if it exits, it will restart. Look at the sql. It’s a separate table, not CDR.

Here’s the table layout I use. Just add the extensions you want to monitor. I’ve written into my web gui an insert into this table when we create a new extension.

CREATE TABLE IF NOT EXISTS `web_presence` (
  `ext` varchar(32) NOT NULL,
  `state` varchar(16) NOT NULL,
  `cidnum` varchar(64) DEFAULT NULL,
  `cidname` varchar(64) DEFAULT NULL,
  `inorout` varchar(1) DEFAULT NULL,
  `callstart` int(11) DEFAULT NULL,
  PRIMARY KEY (`ext`),
  KEY `state` (`state`)
) ENGINE=InnoDB

Hi mkozusnik,

Where should i place the file ?

Here i saw "include(’/opt/asterisk/includes.php’); " statement ,
but In the pbx , there is no such a file in the opt/asterisk folder .

Is that a problem ?

That include is for the database connection(s).

<?php

function db_connect_web(){	
	$db = mysql_connect('Host Or IP','username','password') or die ("Could not connect to the Writable MySQL database server");
	mysql_select_db('asterisk');

	return $db;
}

function db_connect_local(){	
	$db = mysql_connect('localhost','username','password') or die ("Could not connect to the Local MySQL database server");
	mysql_select_db('asterisk');

	return $db;
}

?>

I think you’re missing something, that he wants an out of the box solution based on the “where i place the file”. So maybe both need to go some steps behind and ask what does he has and so far what does he understand… just saying.

1 Like

Good point. I was just offering some code he could add to monitor the device states of his devices.

Yohan100…It’s custom PHP code which connects to the AGI. The programs/table are not part of asterisk nor is it considered an API toolkit. You’re welcome to use it/improve it, but will not find a vendor to support it. The programs can be located anywhere on your network. You’d just have to modify the AGI and database connections as well as the include path.

1 Like

Hello mkozusnik :slight_smile:

We are using appliance PBX (Zycoo)
Vendor doesn’t support to this that’s why we find the solution for this
first i put this file in the PBX internal and if it’s working properly we don’t change it
we are creating small CRM program so program has database connection to read PBX internal Database

If i place this PHP file inside the PBX where should i place it ? inside the etc/asterisk folder or some where else ??

Thanks !

I’m not familiar with using appliances, but if it will work, you’ll need to add a user to the AMI, create the database table on any MySQL server in your network, modify the program to point to your database and appliance (for the AMI). The program can be run from an external machine. It doesn’t need to run on the same device as asterisk as long as the AMI can be accessed remotely. This program doesn’t work with the PBX internal database, only MySQL. Also, it’s pre-PHP7 code. So if you’re running it on PHP7, you’ll need to change the mysql functions to mysqli or convert to PDO.

1 Like

Hi mkozusnik,

Thanks for your replies.

I’ll try to configure this. This PBX has MySQL DB inside the PBX.
i’ll try to save to configure to internal database if i couldn’t configure i’ll use separate DB.

Do you know any method to get incoming call numbers in the Queue ?

I found Asterisk event (Event: NewCallerid and ChannelStatusDesc: Up)
i think we can use your code to write a script for this, do you know any other method ?

Hi mkozusnik,

I wrote a script for filter Calls in the queue. we can filter queue calls using event: NewCallerid

if($event == "NewCallerid"){
    $data = explode(':', $ret);

    if($data[0] == "ChannelStateDesc"){
        $cState = trim($data[1]);		
		}
		
		if($data[0] == "CallerIDNum"){
        $cidnum = trim($data[1]);
		}
	
	
	  
	if($cState == "Up" && $cidnum != ""){	

		$sql = "insert into asterisk.test (name) values ('$cidnum')";
                     mysqli_query($web,$sql); 
	

	}
	$cState = "";
	$cidnum = "";
	
} 

But here filtering part does not working
Event: NewCallerid
ChannelStateDesc: Up

these 2 statements should be true.

but here this part does not filtering

if($data[0] == “ChannelStateDesc”){
$cState = trim($data[1]);

Do you where is the issue ?


Event Log

Event: NewCallerid
Privilege: call,all
Timestamp: 1500464334.050365
Channel: DAHDI/2-1
ChannelState: 6
ChannelStateDesc: Up
CallerIDNum: 765653762
CallerIDName: 765653762
ConnectedLineNum:
ConnectedLineName:
Language: en
AccountCode:
Context: app-getcontact
Exten: s
Priority: 2
Uniqueid: 1500464332.55
CID-CallingPres: 0 (Presentation Allowed, Not Screened)

I don’t see an issues with that section, but the word “name” is reserved in MySQL, so you may want to use back ticks. name. You could also run it interactively using echo to show variables at certain points.