Skip to content

Instantly share code, notes, and snippets.

@Ferbla
Forked from lgaetz/remotehintpoll.php
Last active March 12, 2020 17:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Ferbla/523b15b9e13275c3b7510be45643c225 to your computer and use it in GitHub Desktop.
Save Ferbla/523b15b9e13275c3b7510be45643c225 to your computer and use it in GitHub Desktop.
Simple PHP script that checks the extension status at a remote PBX and updates a custom hint on the local pbx for proper BLF operation.
<?php
/**** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****
* remotehintpoll.php
*
* Created by Lorne Gaetz lgaetz@sangoma.com
*
* Licensed under GNU GPL version 2 or any later verison.
*
* Usage:
* This script is intended to be used on a local FreePBX system running version 2.9 or higher. When
* executed, the script polls a remote Asterisk server using remote Asterisk Manager Interface
* (AMI) credentials, checks the status of a specific extension number on the remote server, and
* then updates a local hint to the same value.
*
* Asterisk configuration:
* Define a dynamic hint on the local system of the same format as what is dialled to reach an
* extension on the remote system. If remote extensions are of the format 10XX and you use a dial
* prefix of 55 to dial remote extensions, the local dynamic hint is defined in extensions_custom.conf as:
*
* [from-internal-custom]
* exten => _5510XX,hint,Custom:Remote${EXTEN:2} // program BLF with e.g. 551001
*
* If you don't dial a prefix to reach the remote extensions from the local pbx, the hint looks like:
*
* [from-internal-custom]
* exten => _10XX,hint,Custom:Remote${EXTEN} // program BLF with e.g. 1001
*
* Version history:
* 2014-01-21 Initial commit for single extension
* 2017-06-22 Add support to poll a range of extensions and update a local dynamic hint
*
**** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** **** ****/
// set to true to echo debug
$debug=true;
// Set the local device prefix for the local hint, must match what is defined in extensions_custom.conf for the hint
// the $device_prefix will be used to prefix the remote extension number for the hint
$device_prefix = "Custom:Remote";
// Remote server host/IP, AMI credentials and
$remote_server = "hostname_placeholder";
$remote_name = "name";
$remote_secret = "password";
$remote_context = "from-internal";
// file containing numbers either in range form ####, #### or for single extensions ####,
$extension_file='data.csv';
if(file_exists($extension_file)) {
$extension_file_raw=file($extension_file);
foreach($extension_file_raw as $line) {
$exension_list = explode(',', $line);
$remote_extension_start=preg_replace('/\s+/', '', $exension_list[0]);
// if the end extension is blank, just assume we want to check one
if(empty($exension_list[1])) {
$remote_extension_end=$remote_extension_start;
} else {
$remote_extension_end=preg_replace('/\s+/', '', $exension_list[1]);
}
// Connect to local machine with FreePBX bootstrap, requires FreePBX 2.9 or higher
if (!@include_once(getenv('FREEPBX_CONF') ? getenv('FREEPBX_CONF') : '/etc/freepbx.conf')) {
include_once('/etc/asterisk/freepbx.conf');
}
// connect to remote Asterisk machine using AMI credentials and get status of Extension 103
$remote = new AGI_AsteriskManager();
if ($remote->connect($remote_server, $remote_name, $remote_secret)) {
for ($remote_extension=$remote_extension_start; $remote_extension<=$remote_extension_end; $remote_extension++) {
$foo[$remote_extension] = $remote->ExtensionState($remote_extension, $remote_context);
}
$remote->disconnect();
}
else {
output("Can not connect to remote AGI");
}
// print_r($foo); //for debug
// Based on value of remote extension status, change local custom device state to match
// edit $device to reflect name of local custom device as defined in extensions_custom.conf
// in the [from-internal-custom] section add a line similar to:
// exten => 103,hint,Custom:Remote103
// Make sure that the number does not conflict with something else
if($astman->connected()) {
for ($remote_extension=$remote_extension_start; $remote_extension<=$remote_extension_end; $remote_extension++) {
switch ($foo[$remote_extension]['Status']) {
case -1:
output("$remote_extension Extension not found");
$cmd = $astman->Command('devstate change '.$device_prefix.$remote_extension.' UNKNOWN');
break;
case 0:
output("$remote_extension Idle");
$cmd = $astman->Command('devstate change '.$device_prefix.$remote_extension.' NOT_INUSE');
break;
case 1:
output("$remote_extension In Use");
$cmd = $astman->Command('devstate change '.$device_prefix.$remote_extension.' INUSE');
break;
case 2:
output("$remote_extension Busy");
$cmd = $astman->Command('devstate change '.$device_prefix.$remote_extension.' BUSY');
break;
case 4:
output("$remote_extension Unavailable");
$cmd = $astman->Command('devstate change '.$device_prefix.$remote_extension.' UNAVAILABLE');
break;
case 8:
output("$remote_extension Ringing");
$cmd = $astman->Command('devstate change '.$device_prefix.$remote_extension.' RINGING');
break;
case 9:
output("$remote_extension Ringing");
$cmd = $astman->Command('devstate change '.$device_prefix.$remote_extension.' RINGING');
break;
case 16:
output("$remote_extension On Hold");
$cmd = $astman->Command('devstate change '.$device_prefix.$remote_extension.' ONHOLD');
break;
default:
output("$remote_extension Extension not found");
$cmd = $astman->Command('devstate change '.$device_prefix.$remote_extension.' UNKNOWN');
}
}
} else {
output("Can not connect to local AGI");
}
}
}
function output($string){
global $debug;
if ($debug) {
echo $string."\n";
}
}
@juesor
Copy link

juesor commented Aug 10, 2017

OMG Ferbla this is awesome. All I had to do was create a data.csv with two column's.

Layout was as follows.

1100,1120
1122
1124,1150
2100,2150

Now I am watching 1100-1150 omitting 1121 and 1123 and 2100-2150

@geforce28
Copy link

geforce28 commented Aug 16, 2017

Hello and thank you for this great Script.

I have 2 Asterisk Servers connected via IAX and wants to monitor device states with your script.
I dont want to generate traffic with your script by croning your script every 2-5 Seconds...

Is there any idea to do this via Dialplan, if a call comes in, is ringing, answered and so on ??..
Or any other idea to solve it ?

How did you solve it ?

Thank you, and greetings from Germany ;)

@juesor
Copy link

juesor commented Aug 23, 2017

I generated the traffic between two servers it turned out to be minimal traffic every 2 seconds and the script responded quickly depending on how many extensions you want to watch.

@26tajeen
Copy link

26tajeen commented Mar 12, 2020

Anyone know how to call this script so it's able to provide timely information about the status of extensions? Is it OK to just repeatedly call it or can I somehow loop it?!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment