Extension monitoring script- Default and Multi-Tenant

Status
Not open for further replies.

EasyBB

Active Member
Oct 23, 2016
240
33
28
Australia
Though I don't have any use for this script now, I know some of you have customers registering from multiple locations back to your Fusion box. The script requires that you add extensions you want to monitor. You'll only need one or two extensions per location added to the script. If you enter email address for an extension, an alert will be send to the phone operator/site admin as well in addition to the FusionPBX admin.

You may create extenfailalert.php in your home directory (eg. /root) and add an appropriate CRON entry to run the script at regular intervals. If you wish to manually run the script from a web browser, place the script in a location where your webserver can serve it from. For a Fusion box this could be something like /var/www/fusionpbx/scripts/extenfailalert.php Make sure to give www-data user read access to the file.

PHP:
<?php
/* Author: EasyBB on fusionpbxforums.
* Permission is hereby granted to anyone to use this code for any purpose
* they see fit. This code comes with no warranties of any kind,
* implied or expressive and this author is not responsible for any damage
* or loss resulting from using this code directly or indirectly.
* You may edit or modify the code as you like, again, at your own risk.
*/

//************************ extenfailalert.php *****************************
// Last edited: 2018 02 25.
// Tested on: Debian 8 Jessie.
// Dependencies: mail transfer agent (MTA), mailutils, php5+
//
// This PHP script is to be used with FreeSWITCH/ FusionPBX server to send
// email alert when extensions fail to register.
//
// You'll need a working mail transfer agent (ssmtp, sendmail etc) running
// on the FusionPBX server. https://help.ubuntu.com/community/EmailAlerts
// ssmtp is the simplest of all. Remember to disable other MTAs if you wish
// to go with ssmtp:
// http://linuxpitstop.com/install-ssmtp-to-send-emails-to-gmail-and-office3655/
//
// Please note that the script needs to be invoked from CRON.
// Recommended to set 30 min interval.
// e.g. */30 * * * * /usr/bin/php /root/extenfailalert.php > /dev/null 2>&1
//**********************************************************************

/*******************************************
******* EDIT BELOW VALUES TO SUIT *********
******************************************/

// Enter the admin email to receive alerts (mandatory)
$mailto = "admin@example.com";

// Enter the from email address or leave it as it is.
$mailfrom = "fusionpbx@gmail.com";

// Enter a friendly sender name or leave it as it is.
$fromname = "FusionPBX";

// Enter an email subject or leave it as it is.
$mailsub = "[ALERT] FusionPBX Extension Failure!";

// Location of fs_cli command.
$fscli = "/usr/bin/fs_cli";
//$fscli = "/usr/local/fs_cli";

// Enter extension numbers to check and optionally, email address.
// Make sure extension exists
$extensions = array(
    '201' => '',
    '234' => 'bob@example.com',
    '257' => 'mary@test.com'
);

/*******************************************
****** DO NOT EDIT BELOW THIS LINE *******
******************************************/

// Function to check extension registration status
function checkExtn($ext){
    global $fscli;
    $res = shell_exec($fscli . ' -x "sofia status profile internal reg ' . $ext .'"');
    $regex = '/returned:\s(\d+)/';
    preg_match($regex, $res, $matches);
  
    if($matches[1] > 0) {
        return true;
    }else {
        return false;
    }
}

// Function to send email
function sendMail($msg, $clientmail = ''){
    global $fromname, $mailfrom, $mailsub, $mailto;
    // Format from name
    $from = $fromname . "\<" . $mailfrom . "\>";
    // Email command line
    $recipe = 'echo "%s" | mail -a "Content-Type: text/html" -s "%s" -aFrom:%s "%s %s"';
    // Format email command
    $cooked = sprintf($recipe,$msg,$mailsub,$from,$mailto,$clientmail);
    // Send email
    shell_exec($cooked);
}

// Function to check whether FreeSWITCH is running
function checkFS(){
    $fs = trim(shell_exec('pidof "freeswitch"'));
    if(! strlen($fs)){
        return false;
    }else{
         return true;
    }
}

// Set global variable to collect messages
$msg = "";

// Check if FS is running; restart if it isn't
if(! checkFS()){
    $msg .= "FreeSWITCH isn't running, trying a service restart... <br />";
    $msg .= shell_exec('systemctl restart freeswitch.service');
    sleep(5);
    if(! checkFS()){
        $msg .= "<br /> FreeSWITCH wouldn't start; exiting... <br />";
        sendMail($msg);
        exit;
    }else{
        $msg .= "<br /> FreeSWITCH is running... <br />";
        sleep(60);
    }
}

// Iterate through nominated extensions for registration status
foreach($extensions as $ext => $clientmail){
    if(! checkExtn($ext)) {
        if(strlen(trim($clientmail))) {
            $clientmail = ', ' . $clientmail;
        }
          
        sendMail($msg . 'Your phone ' . $ext . ' is offline; please check connectivity.', $clientmail);
    }
}

?>
 
Last edited:

EasyBB

Active Member
Oct 23, 2016
240
33
28
Australia
Alright.....here's another version of the script to check extension availability for multi-tenant Fusion installs. Please keep number of domains and extensions entered in the script to absolute minimum to keep the script execution time in check.

PHP:
<?php
/* Author: EasyBB on fusionpbxforums.
* Permission is hereby granted to anyone to use this code for any purpose
* they see fit. This code comes with no warranties of any kind,
* implied or expressive and this author is not responsible for any damage
* or loss resulting from using this code directly or indirectly.
* You may edit or modify the code as you like, again, at your own risk.
*/

//************************ domain-extenfailalert.php *****************************
// Last edited: 2018 02 27.
// Tested on: Debian 8 Jessie.
// Dependencies: mail transfer agent (MTA), mailutils, php5+
//
// This PHP script is to be used with FreeSWITCH/ FusionPBX server to send
// email alert when extensions under domains fail to register.
//
// You'll need a working mail transfer agent (ssmtp, sendmail etc) running
// on the FusionPBX server. https://help.ubuntu.com/community/EmailAlerts
// ssmtp is the simplest of all. Remember to disable other MTAs if you wish
// to go with ssmtp:
// http://linuxpitstop.com/install-ssmtp-to-send-emails-to-gmail-and-office3655/
//
// Please note that the script needs to be invoked from CRON.
// Recommended to set 30 min interval.
// e.g. */30 * * * * /usr/bin/php /root/domain-extenfailalert.php > /dev/null 2>&1
//**********************************************************************

/*******************************************
******* EDIT BELOW VALUES TO SUIT *********
******************************************/

// Enter the admin email to receive alerts (mandatory)
$mailto = "admin@example.com";

// Enter the from email address or leave it as it is.
$mailfrom = "fusionpbx@gmail.com";

// Enter a friendly sender name or leave it as it is.
$fromname = "FusionPBX";

// Enter an email subject or leave it as it is.
$mailsub = "[ALERT] FusionPBX Extension Failure!";

// Location of fs_cli command.
$fscli = "/usr/bin/fs_cli";
//$fscli = "/usr/local/fs_cli";

// Enter domain name and corresponding extension numbers to check; optionally, email address of the client.
// Make sure extension exists. You need to define one array per domain you wish to monitor.
// This array if domain name is fusion.pbx
$extensions['fusion.pbx'] = array(
    '201' => '',
    '202' => 'bob@example.com'
);

// This array for domain 192.168.1.100 (eg.default domain)
$extensions['192.168.1.100'] = array(
    '446'=> 'mary@example.com',
    '621'=> '',
    '487'=> 'mark@test.com'
);

/*******************************************
****** DO NOT EDIT BELOW THIS LINE *******
******************************************/

// Function to check extension registration status
function checkExtn($domain, $ext){
    global $fscli;
    $res = trim(shell_exec($fscli . ' -x "sofia_contact ' . $ext . '@' . $domain . '"'));
    if($res != 'error/user_not_registered') {
        return true;
    }else {
        return false;
    }
}

// Function to send email
function sendMail($msg, $mailaddr = ''){
    global $fromname, $mailfrom, $mailsub, $mailto;
    if(strlen($mailaddr) > 5) {
        $mail_to = $mailaddr;
    }else {
        $mail_to = $mailto;  
    }
    // Format from name
    $from = $fromname . "\<" . $mailfrom . "\>";
    // Email command line
    $recipe = 'echo "%s" | mail -a "Content-Type: text/html" -s "%s" -aFrom:%s "%s"';
    // Format email command
    $cooked = sprintf($recipe,$msg,$mailsub,$from,$mail_to);
    // Send email
    shell_exec($cooked);
}

// Function to check whether FreeSWITCH is running
function checkFS(){
    $fs = trim(shell_exec('pidof "freeswitch"'));
    if(! strlen($fs)){
        return false;
    }else{
         return true;
    }
}

// Set global variable to collect messages
$msg = "";

// Check if FS is running; restart if it isn't
// Comment out the block if you don't want the script to restart FS
if(! checkFS()){
    $msg .= "FreeSWITCH isn't running, trying a service restart... <br />";
    $msg .= shell_exec('systemctl restart freeswitch.service');
    sleep(5);
    if(! checkFS()){
        $msg .= "<br /> FreeSWITCH wouldn't start; exiting... <br />";
        sendMail($msg);
        exit;
    }else{
        $msg .= "<br /> FreeSWITCH is running... <br />";
        sleep(60);
    }
}

// Iterate through nominated extensions for registration status
foreach($extensions as $domain => $ext_data){
    $dom_found = trim(shell_exec($fscli . ' -x "domain_exists ' . $domain . '"'));
    if($dom_found == 'true') {
        foreach($ext_data as $ext => $clientmail){
            if(! checkExtn($domain, $ext)) {
                //Collect message for admin- includes domain name for identification.
                $msg .= 'Phone ' . $ext . '@' . $domain . ' is offline.<br />';
                if(strlen(trim($clientmail)) > 5) {
                    // Send email to client. Domain name is not included.
                    sendMail('Phone ' . $ext . ' is offline; please check connectivity.', trim($clientmail));
                }
            }  
        }
    }
}

// Send email to admin. Note that admin is the last person to receive the alert.
// So be mindful of the script execution time for large number of extensions.
sendMail($msg);

?>
 
Last edited:

Guy Perera

New Member
May 3, 2017
5
0
1
46
Melbourne, Australia
Thank you very much EasyBB for your script. It is very helpful.

Is it possible to have a script to monitor extensions of a multi tenant fusionpbx with email failure notification sent to email address on the voicemail-2-email address of that extension (only if the email address for voicemail-2-email exist)?

Idea is to manage notification emails from extensions setup interface, to have a better control of what extension to monitor from the interface.

Imagine the DB is a MYSQL.

Do you provide your expertise as a paid service? Thank you.
 

EasyBB

Active Member
Oct 23, 2016
240
33
28
Australia
I have the new script with automated domain, extension and email handling working at the moment. It needs a bit of clean up, so hoping post it tomorrow.
 

EasyBB

Active Member
Oct 23, 2016
240
33
28
Australia
Here is a script that does everything automatically based on settings from the GUI.
Please note below caveats:
  1. Extension number must be numeric
  2. Voicemail ID must be numeric and must match extension number
  3. Only MySQL and PostgreSQL are supported. I haven't tested MySQL; please test and give feedback :)
  4. Extension must be enabled and have email address present in voicemail to email field
  5. Domain must be enabled
  6. Test the script after you update FusionPBX
  7. You need a local MTA such as ssmtp or postfix. Test email before deploying the script.
A sample of alert sent to admin:
Code:
Domain: domain1
Extension 302@domain1 is offline.

Domain: test
Extension 201@test is offline.
Extension 203@test is offline.

Client alert is enabled.

The script:
PHP:
<?php
/* Author: EasyBB on fusionpbxforums.
* Permission is hereby granted to anyone to use this code for any purpose
* they see fit. This code comes with no warranties of any kind,
* implied or expressive and this author is not responsible for any damage
* or loss resulting from using this code directly or indirectly.
* You may edit or modify the code as you like, again, at your own risk.
*/

//************************ autodomexfailalert.php *****************************
// Last edited: 2018 04 01 .
// Tested on: Debian 8 Jessie.
// Dependencies: mail transfer agent (MTA), mailutils, php5+
//
// This PHP script is to be used with FreeSWITCH/ FusionPBX server to send
// email alerts when extensions from domains fail to register.
//
// You'll need a working mail transfer agent (ssmtp, postfix etc) running
// on the FusionPBX server. https://help.ubuntu.com/community/EmailAlerts
// ssmtp is the simplest of all. Remember to disable other MTAs if you wish
// to go with ssmtp:
// http://linuxpitstop.com/install-ssmtp-to-send-emails-to-gmail-and-office3655/
//
// Please note that the script needs to be invoked from CRON.
// Recommended to set 30 min interval.
// e.g. */30 * * * * /usr/bin/php /root/autodomexfailalert.php > /dev/null 2>&1
//**********************************************************************

/*******************************************
******* EDIT BELOW VALUES TO SUIT *********
******************************************/

// Enter the admin email to receive alerts (mandatory)
$mailto = "admin@example.com";

// Enter the from email address or leave it as it is.
$mailfrom = "fusionpbx@gmail.com";

// Enter a friendly sender name or leave it as it is.
$fromname = "FusionPBX";

// Enter an email subject or leave it as it is.
$mailsub = "[ALERT] FusionPBX Extension Failure!";

// Location of fs_cli command.
$fscli = "/usr/bin/fs_cli";
//$fscli = "/usr/local/fs_cli";

// Allow script to restart FreeSWITCH if not running (true/false, default: false)
$fs_restart = false;

// Location of config.php (for db access details)
$phpcfg = "/etc/fusionpbx/config.php";

// Enable/disable email alerts to clients
$alert_client = false;

// Enable/disable email alerts to admin
$alert_admin = true;


/*******************************************
****** DO NOT EDIT BELOW THIS LINE *******
******************************************/

// No need to run script if both admin and client alerts are set to false
($alert_client || $alert_admin)?:exit;

// Set green light variable
$proceed = true;

// Set variable to collect message for admin
$msg = '';

// Include config.php
If(! include $phpcfg){
    $msg .= 'Could not load config.php<br />';
    $proceed = false;
}else{
    // Run include variable checks
    if($db_type != 'mysql' && $db_type != 'pgsql') {
        $msg .= 'Only PostgreSQL and MySQL are currently supported.<br />';
        $msg .= 'Your current database type: '.$db_type.'<br />';
        $proceed = false;
    }
 
    if(strlen($db_host) == 0 || strlen($db_port) == 0) {
        $msg .= 'Either or both hostname and db port not set.<br />';
        $proceed = false;
    }
}

// Attempt to connect to database
if($proceed) {
     try{
         $conn_string = $db_type.":host=".$db_host.";port=".$db_port.";dbname=".$db_name;
         $mydb = new PDO($conn_string,$db_username,$db_password);
     }catch(Exception $e){
        $msg .= 'DB connection error! '.$e->getMessage().'<br />';
        $proceed = false;
     }
}

// Function to check extension registration status
function checkExtn($domain, $ext){
    global $fscli;
    $res = trim(shell_exec($fscli . ' -x "sofia_contact ' . $ext . '@' . $domain . '"'));
    if($res != 'error/user_not_registered') {
        return true;
    }else {
        return false;
    }
}

// Function to send email
function sendMail($msg, $mailaddr = ''){
    global $fromname, $mailfrom, $mailsub, $mailto;
    if(strlen($mailaddr) > 6) {
        $mail_to = $mailaddr;
    }else {
        $mail_to = $mailto;
    }
    // Format from name
    $from = $fromname . "\<" . $mailfrom . "\>";
    // Email command line
    $recipe = 'echo "%s" | mail -a "Content-Type: text/html" -s "%s" -aFrom:%s "%s"';
    // Format email command
    $cooked = sprintf($recipe,$msg,$mailsub,$from,$mail_to);
    // Send email
    shell_exec($cooked);
}

// Function to check whether FreeSWITCH is running
function checkFS(){
    $fs = trim(shell_exec('pidof "freeswitch"'));
    if(! strlen($fs)){
        return false;
    }else{
         return true;
    }
}

// Check if FS is running; restart if it isn't
if($proceed && ! checkFS()){
    $msg .= "FreeSWITCH isn't running.<br />";
    $proceed = false;
    if($fs_restart) {
        $msg .= "Attempting to restart FreeSWITCH service... <br />";
        $msg .= shell_exec('systemctl restart freeswitch');
        sleep(15);
        if(! checkFS()){
            $msg .= "<br /> FreeSWITCH wouldn't start; exiting... <br />";
        }else{
            $msg .= "<br /> FreeSWITCH is running...script will wait a while before checking extensions.<br />";
            sleep(30);
            $proceed = true;
        }
    }
}

// Call db connection and iterate through domains and extensions
if($proceed) {
    $sql_dom = "SELECT domain_name, domain_uuid FROM v_domains WHERE domain_enabled='true'";
    $query_dom = $mydb->prepare($sql_dom);
    $query_dom->execute();
 
    while($res = $query_dom->fetch(PDO::FETCH_OBJ)) {
        $msg .= '<br /><b>Domain: '.$res->domain_name.'</b><br />'; //Add domain name as sub-heading
        $sql_ext = ("SELECT v_extensions.extension, v_voicemails.voicemail_mail_to FROM v_extensions
                         LEFT JOIN v_voicemails
                         ON v_extensions.extension = cast(v_voicemails.voicemail_id AS varchar)
                         AND v_extensions.domain_uuid = v_voicemails.domain_uuid
                         WHERE v_extensions.domain_uuid = '".$res->domain_uuid."'
                         AND v_extensions.enabled = 'true' AND v_voicemails.voicemail_mail_to <> ''");
        $query_ext = $mydb->prepare($sql_ext);
        $query_ext->execute();
     
        while($ext = $query_ext->fetch(PDO::FETCH_OBJ)) {
            if(! checkExtn($res->domain_name, $ext->extension)) {
                //Collect message for admin- includes domain name for identification.
                $msg .= 'Extension ' . $ext->extension . '@' . $res->domain_name . ' is offline.<br />';
             
                // If enabled, send email to client. Domain name is not included.
                if($alert_client && strlen(trim($ext->voicemail_mail_to)) > 6) {
                    sendMail('Phone extension ' . $ext->extension . ' is offline; please check connectivity.', trim($ext->voicemail_mail_to));
                }
            }
        }
     
        $sql_ext = null;
        $query_ext = null;
    }
 
    $sql_dom = null;
    $query_dom = null;
    $mydb = null;
}

// Send email to admin. Note that admin will be the last person to receive alert.
// So be mindful of the time it takes to process large number of domains/extensions.
if($alert_admin && strlen(trim($msg)) > 0) {
    $msg .= '<br />Client alert';
    $msg .= ($alert_client) ? ' is enabled.' : ' is not enabled.';
    sendMail($msg);
}

?>
 
Last edited:

EasyBB

Active Member
Oct 23, 2016
240
33
28
Australia
Can I please request someone running MySQL/MariaDB to test this script and give me feedback? Thanks!
 
Status
Not open for further replies.