How it Works
This bot works by monitoring a website through the HTML status codes which it pings using a time interval(this is set in the websites.json file). This is very handy because if you are using Express with Nodejs all the status codes are taken care of for you, all you need to do is build a new route on your bot to handle the inquiry from the monitor bot(see the code later in the post). The monitor bot looks at the status code response and adjusts the status of you monitored bot accordingly and sends a Spark message when it changes. If you already have an existing website for your bot that is hosted with the same bot application you could use that as well, but I choose to create a new route so in the future I can deliver more JSON data with my response for future features.
Coding the Monitor Bot
The changes I made to the original node-monitor module are pretty minor. I added a new attribute to the constructor to describe the current bot state. I defaulted all bots to down state. Below is a exert of node-monitor file showing the constructor change.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Monitor (opts) { | |
// default http request method | |
this.method = 'GET'; | |
// holds website to be monitored | |
this.website = ''; | |
//Track status | |
this.webStatus = 'down'; | |
// ping intervals in minutes | |
this.interval = 15; | |
// interval handler | |
this.handle = null; | |
// initialize the app | |
this.init(opts); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict"; | |
var config = require('./config.json'); | |
var message = require('./myUtils/sparkMessage'); | |
var botToken = "<Your bot token>"; | |
/* | |
Handles events emitted when a websites stop being monitored | |
@param - (String) website - website url | |
*/ | |
function onStop (website) { | |
var to = config.email; | |
var text = website + ' monitor has stopped'; | |
console.log(JSON.stringify(website)) | |
if(this.webStatus==='up'){ | |
this.webStatus = 'down'; | |
message.newMessage(botToken,text,to); | |
}else{ | |
message.newMessage(botToken,text,to); | |
} | |
}; | |
function onUp (res) { | |
var to = config.email; | |
console.log(JSON.stringify(res)) | |
var text = res.website + ' monitor is up'; | |
text += '<p>Time: ' + res.time; | |
text += '</p><p>Website: ' + res.website; | |
text += '</p><p>Message: ' + res.statusMessage + '</p>'; | |
if(this.webStatus==='down'){ | |
this.webStatus = 'up'; | |
message.newMessage(botToken,text,to); | |
}else{ | |
return console.log(this.webStatus); | |
} | |
}; | |
/* | |
Handles events emitted when a website is down | |
@param - (Object) res - response object return by the Node Monitor object | |
*/ | |
function onDown (res) { | |
var text = ''; | |
var to = config.email; | |
text += '<p>Time: ' + res.time; | |
text += '</p><p>Website: ' + res.website; | |
text += '</p><p>Message: ' + res.statusMessage + '</p>'; | |
if(this.webStatus==='up'){ | |
this.webStatus = 'down'; | |
message.newMessage(botToken,text,to); | |
}else{ | |
this.webStatus = 'down'; | |
message.newMessage(botToken,text,to); | |
} | |
}; | |
/* | |
Handles events emitted when aa error occurs | |
@param - (String) msg - response message | |
*/ | |
function onError (msg) { | |
console.log(msg); | |
} | |
module.exports.onStop = onStop; | |
module.exports.onDown = onDown; | |
module.exports.onError = onError; | |
module.exports.onUp = onUp; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var request = require('request'); | |
var logger = require('log4js'); | |
logger.configure({ | |
appenders: [ | |
{type:'console'}, | |
{type: 'file', filename: 'logs/application.log', catergory:'application'} | |
], | |
replaceConsole: true | |
}); | |
exports.newMessage = function sparkMessage(sparkToken, text, to) { | |
request({ | |
url: 'https://api.ciscospark.com/v1/messages', | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json', | |
'Authorization': 'Bearer ' + sparkToken | |
}, | |
body: | |
JSON.stringify({'toPersonEmail': to, | |
'markdown': text}) | |
}, function (error, response, body) { | |
if (error) { | |
console.log(error); | |
} else { | |
console.log(response.statusCode, body); | |
} | |
}); | |
}; | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict" | |
var Monitor = require('ping-monitor'); | |
var websites = require('./websites'); | |
var http = require('http'); | |
var port = process.env.PORT || 3008; | |
var events = require('./events'); | |
var logger = require('log4js'); | |
logger.configure({ | |
appenders: [ | |
{type:'console'}, | |
{type: 'file', filename: 'logs/application.log', catergory:'application'} | |
], | |
replaceConsole: true | |
}); | |
var urls = []; | |
var monitors = []; | |
/* | |
Loop over all websites and create a Monitor instance for each one. | |
*/ | |
websites.forEach(function (website) { | |
var monitor = new Monitor ({ | |
website: website.url, | |
interval: website.interval | |
}); | |
monitor.on('error', events.onError); | |
monitor.on('stop', events.onStop); | |
monitor.on('down', events.onDown); | |
monitor.on('up', events.onUp); | |
urls.push(website.url); | |
monitors.push(monitor); | |
}); | |
/* | |
Server for responding to http requests | |
*/ | |
http.createServer(function (req, res) { | |
res.end(urls.join('\n')); | |
}).listen(port); | |
console.log('Listening to port %s', port); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Monitoring service route | |
app.get('/monitor', function(req, res){ | |
var json_response = {'name':'JabberAssist'}; | |
res.status(200).json(json_response); | |
}); |
If you want to check out the original Monitor module here is a blog post that describes it. Also here is the GitHub site.
VoIPNorm