Skip to content

Instantly share code, notes, and snippets.

@avimar
Created February 15, 2019 08:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save avimar/9645dd3134476d458e68cca077f4ed16 to your computer and use it in GitHub Desktop.
Save avimar/9645dd3134476d458e68cca077f4ed16 to your computer and use it in GitHub Desktop.
FreeSWITCH de-register monitor
#! /usr/bin/node
var nodemailer = require("nodemailer");
var transport = nodemailer.createTransport("sendmail");
function fix_len(num, len){
if(len<=5) return ("00000" + num).slice(-len);
else {
var seed="0000000000";
while(seed.length<len) seed+=seed;
return (seed + num).slice(-len);
}
}
function show_now(){
var date = new Date();
d = [
date.getFullYear()
,date.getMonth()+1
,date.getDate()
,date.getHours()
,date.getMinutes()
,date.getSeconds()
,date.getMilliseconds()
];
return d[0]+'-'+fix_len(d[1],2)+'-'+fix_len(d[2],2)+' '+fix_len(d[3],2)+':'+fix_len(d[4],2)+':'+fix_len(d[5],2) + '.' + fix_len(d[6],3)+ ' ';
}
var esl = require('esl');
var esl_handle;
console.log(show_now() + 'Initiation: ESL: Loading module');
var client = esl.createClient();
console.log(show_now() + 'Initiation: ESL: Attempting connection...');
client.connect(8021, '127.0.0.1');// --> gets esl auth request.
client.on('esl_auth_request',doAuth);
function doAuth(call){
//console.log("ESL: received password challange, attempting to auth...");
call.auth('ClueCon',isConnected);//@TODO: this should be an event // emitter. Or just abstract out the entire connect like in https://github.com/demchenkoe/njs-freeswitch-esc
}
function isConnected(call){//@TODO: this should be an event // emitter.
console.log(show_now() + 'Initiation: ESL: Authed. Saving handle.');
esl_handle=call;
esl_handle.event_json('CUSTOM sofia::register sofia::unregister sofia::register_attempt sofia::expire',nowWatching);//HEARTBEAT
}
function nowWatching(result){
console.log(show_now() + 'Initiation: ESL: response to subscribe: ' + result.headers['Reply-Text']);
//console.log(result.headers);
}
var regex_account_matches=/Total items returned: (\d+)/;
function getRegistrationsCount(account, callback){
esl_handle.api('sofia status profile internal reg ' + account, function(res) {
//console.log(res.body);
var registrationCount=regex_account_matches.exec(res.body);
if(registrationCount && registrationCount[1]) callback(null,registrationCount[1]);
else callback(err);
});
}
var regexExpireContactIP=/@([^:]*):(\d*)/;
client.on('CUSTOM',function show_heartbeat(data){
if(data.body['Event-Subclass']=="sofia::register"){
console.log(show_now() + 'sofia register for user ' + data.body.username+ ' from ' +data.body['network-ip']);
//console.log(data.body);
}
else if(data.body['Event-Subclass']=="sofia::unregister"){
console.log(show_now() + 'sofia DE-register for user ' + data.body.username);
//console.log(data.body);
}
else if(data.body['Event-Subclass']=="sofia::register_attempt"){
console.log(show_now() + 'sofia register_attempt for user ' + data.body.username+ ' from ' +data.body['network-ip']);
//console.log(data.body);
}
else if(data.body['Event-Subclass']=="sofia::expire"){
var ip;
if(data.body && data.body.contact) ip=regexExpireContactIP.exec(data.body.contact);
if(!ip[1]) ip[1]='';
if(!ip[2]) ip[2]='';
//console.log(data.body);
console.log(show_now() + 'sofia EXPIRE for user ' + data.body.user + ', was via ' + ip[1]+':' + ip[2] + ', agent of ' + data.body['user-agent']);//@data.host
setTimeout(function (){//if we try it immediately, they still exist!
getRegistrationsCount(data.body.user, function(err, res){
if(err) console.log(err);
else if(res>0) console.log(show_now() + "EXPIRE Don't worry, " + data.body.user + " still has " + res + " registration(s).");
else if(data.body.user==1947) console.log(show_now() + "EXPIRE Don't worry, " + data.body.user + " is using a softphone inconsistently.");
else {
console.log(show_now() + "EXPIRE. " + data.body.user + " has no other active registration!!");
// setup e-mail data with unicode symbols
var mailOptions = {
from: "", // sender address
to: "", // list of receivers
subject: "EXPIRE for "+data.body.user, // Subject line
text: show_now() + 'sofia EXPIRE for user ' + data.body.user + ', was via ' + ip[1]+':' + ip[2] + ', agent of ' + data.body['user-agent']
//html: "<b>Hello world ✔</b>" // html body
};
// send mail with defined transport object
transport.sendMail(mailOptions, function(error, response){
if(error){
console.log(error);
}else{
console.log("Message sent: " + response.message);
}
// if you don't want to use this transport object anymore, uncomment following line
//smtpTransport.close(); // shut down the connection pool, no more messages
});
}
});
}, 2000);
}
else {
//console.log(show_now() + 'Generic CUSTOM event:');
//console.log(data.body);
//console.log();
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment