freifunk-bot

Modular parser for the hackerspace door status with handlers for multiple services
git clone git://archive.git.mtrnord.blog/MTRNord/freifunk-bot.git
Log | Files | Refs | README | LICENSE

commit ffd8ace9439efb4bba3bde2dce5c450bfba4dd1e
parent 217f29f06e86dbdfc3c23aa1eab3eaa507a13295
Author: MTRNord <mtrnord1@gmail.com>
Date:   Sat, 30 Apr 2016 19:04:09 +0200

add telegram and getNodes and heroku deploy

Diffstat:
Ahandlers/getNodes.js | 123+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mhandlers/irc.js | 41+++++++++++++++++++++++++++++++++++++++++
Mhandlers/slack.js | 5++++-
Ahandlers/telegram.js | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahandlers/tmp/communities.json | 194+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahandlers/tmp/community.json | 2++
Ahelper/heroku.js | 15+++++++++++++++
Mmain.js | 8++++++--
Mpackage.json | 14++++++++++++--
9 files changed, 454 insertions(+), 5 deletions(-)

diff --git a/handlers/getNodes.js b/handlers/getNodes.js @@ -0,0 +1,123 @@ +/** + * NodeHelper Module + * + * @module Main + * @class getNodes + * @submodule getNodes + * @author Marcel Radzio + */ +//Load needed Features +var request = require('request') +//require('request-debug')(request); +var fs = require('fs'); +var jsonfile = require('jsonfile') +var slack = require('./slack.js'); +/** + * Get Community Config at start + * + * @property communities + * @type String + */ +module.exports = { + saveNodes: function () { + request.get('http://cdn.rawgit.com/MTRNord/gluon-web-remote/develop/configs/communities.json', function (err, res, body) { + + if (!err && res.statusCode == 200) { + /** + * Content of communities + * + * @property communities + * @type String + */ + communities = body; + if (!fs.existsSync("handlers/tmp")){ + fs.mkdirSync("handlers/tmp"); + } + fs.writeFile("handlers/tmp/communities.json", communities, { flag: 'w' }, function(err) { + if(err) { + console.log(err); + return err + } + }); + }else{ + /** + * Fired when an error occurs... + * + * @property error + * @type String + */ + //TODO Add real Error Handler + console.log(err); + return err + } + }) + }, + countNodes: function (ccode_func, handler, TfromId, Tmsg, channel, bot, botan, IRCto) { + jsonfile.readFile('handlers/tmp/communities.json', 'utf8', function (err,obj) { + if (err) { + return console.log(err); + } + var communities = obj + for (var key in communities.communities) { + if (communities.communities.hasOwnProperty(key)) { + var ccode = communities.communities[key]["ccode"]; + if (ccode.toLowerCase() === ccode_func.toLowerCase()) { + var nodesFile_link = communities.communities[key]["nodesURL"]; + var name = communities.communities[key]["name"]; + request.get(nodesFile_link, function (err, res, body) { + if (!err && res.statusCode == 200) { + /** + * Content of communities + * + * @property communities + * @type String + */ + // console.log(body); + // onlineNodes = body.nodes.length + // onlineNodes = Object.keys(body.nodes).length; + var count = 0; + for(var key in JSON.parse(body).nodes) { + if(JSON.parse(body).nodes.hasOwnProperty(key)) { + if (JSON.parse(body).nodes[key].hasOwnProperty('flags')) { + if (JSON.parse(body).nodes[key]["flags"]["online"] == true) { + count++; + } + } + if (JSON.parse(body).nodes[key].hasOwnProperty('status')) { + if (JSON.parse(body).nodes[key]["status"]["online"] == true) { + count++; + } + } + } + } + var output = "Current nodes in " + name + ": " + count + if(handler === "telegram"){ + bot.sendMessage(TfromId, output); + botan.track(Tmsg, 'nodes ' + ccode_func) + }else { + if(handler === "irc"){ + bot.say(IRCto, output); + }else { + if(handler === "slack"){ + slack.slackSend(Schannel, output); + } + } + } + }else{ + /** + * Fired when an error occurs... + * + * @property error + * @type String + */ + //TODO Add real Error Handler + console.log(err); + return err + } + }) + } + } + } + }); + } +} diff --git a/handlers/irc.js b/handlers/irc.js @@ -10,8 +10,13 @@ var irc = require('irc'); var request = require('request'); var S = require('string'); +var jsonfile = require('jsonfile') +var ent = require('ent'); +var decode = require('ent/decode'); + var command_config = require("../configs/commands.json"); var params_config = require("../configs/ircServer.json"); +var getNodes = require('./getNodes.js'); //Set Params /** @@ -287,6 +292,42 @@ module.exports = { say(to, "You can find the Source of this bot at https://github.com/MTRNord/nordlab-hackerspace-door"); } } + // TODO ADD !nodes [Community code] + /*getNodes.countNodes("FFFL") + */ + + if (S(message).contains("!nodes")) { + jsonfile.readFile('handlers/tmp/communities.json', 'utf8', function (err,obj) { + var communities = obj + for (var key in communities.communities) { + if (communities.communities.hasOwnProperty(key)) { + var ccode = communities.communities[key].ccode; + if (ccode.toLowerCase() === channel[1]) { + clients.forEach(function(client) { + getNodes.countNodes(channel[1], "irc", "", "", "", client, "", to) + }); + } + } + } + }); + } + + if (S(message).contains("!communities")) { + jsonfile.readFile('handlers/tmp/communities.json', 'utf8', function (err,obj) { + var communities = obj + var communities_list = "" + for (var key in communities.communities) { + if (communities.communities.hasOwnProperty(key)) { + var ccode = decode(communities.communities[key].ccode) + var name = decode(communities.communities[key].name) + communities_list = communities_list + name + ": " + ccode + " " + } + } + say(to, communities_list) + }) + } + + if (S(message).contains("!doorstatus")) { request.get('http://www.nordlab-ev.de/doorstate/status.txt', function (error, response, body) { if (!error && response.statusCode == 200) { diff --git a/handlers/slack.js b/handlers/slack.js @@ -63,7 +63,10 @@ module.exports = { * @method slackPreload */ slackPreload: function () { - } + }, + slackSend: function (channel, message) { + bot.postMessage(channel, message) + } } // more information about additional params https://api.slack.com/methods/chat.postMessage diff --git a/handlers/telegram.js b/handlers/telegram.js @@ -0,0 +1,57 @@ +//TOKEN 165809140:AAEEpJP4hgcEsf6ry1Vd6Lp0_8rfRrXFB3A +var token = '165809140:AAEEpJP4hgcEsf6ry1Vd6Lp0_8rfRrXFB3A'; +var TelegramBot = require('node-telegram-bot-api'); +var jsonfile = require('jsonfile') +var async = require('async') +var getNodes = require('./getNodes.js'); +var fs = require('fs') +var botan = require('botanio')(token); +var ent = require('ent'); +var decode = require('ent/decode'); +// Setup polling way +var bot = new TelegramBot(token, {polling: true}); +module.exports = { + start: function () { + // Matches /echo [whatever] + bot.onText(/\/echo (.+)/, function (msg, match) { + var fromId = msg.from.id; + var resp = match[1]; + bot.sendMessage(fromId, resp); + }); + + bot.onText(/\/nodes (.+)/, function (msg, match) { + var fromId = msg.chat.id; + var resp = match[1]; + bot.sendChatAction(fromId, "typing") + jsonfile.readFile('handlers/tmp/communities.json', 'utf8', function (err,obj) { + var communities = obj + for (var key in communities.communities) { + if (communities.communities.hasOwnProperty(key)) { + var ccode = communities.communities[key].ccode; + if (ccode.toLowerCase() === resp.toLowerCase()) { + getNodes.countNodes(resp.toLowerCase(), "telegram", fromId, msg, "", bot, botan) + } + } + } + }); + }); + bot.onText(/\/communities/, function (msg, match) { + var fromId = msg.chat.id; + var resp = match[1]; + bot.sendChatAction(fromId, "typing") + jsonfile.readFile('handlers/tmp/communities.json', 'utf8', function (err,obj) { + var communities = obj + var communities_list = "" + for (var key in communities.communities) { + if (communities.communities.hasOwnProperty(key)) { + var ccode = decode(communities.communities[key].ccode) + var name = decode(communities.communities[key].name) + communities_list = communities_list + name + ": " + ccode + "\n" + } + } + bot.sendMessage(fromId, communities_list); + botan.track(msg, 'communities'); + }); + }); + } +} diff --git a/handlers/tmp/communities.json b/handlers/tmp/communities.json @@ -0,0 +1,194 @@ +{ + "communities": { + "FFKI": { + "ccode": "FFKI", + "name": "Freifunk Kiel", + "nodesURL": "http://map.ffki.de/nodes.json", + "v6": "fda1:384a:74de:", + "v6mask": "/48", + "v4": "10.116.0.0", + "v4mask": "/16", + "supported": 1 + }, + "FFFL": { + "ccode": "FFFL", + "name": "Freifunk Flensburg", + "nodesURL": "http://map.freifunk-flensburg.de/data/nodes.json", + "v6": "fddf:bf7:10:1:", + "v6mask": "/64", + "v4": "10.129.0.0", + "v4mask": "/16", + "supported": 1 + }, + "FFNORD": { + "ccode": "FFNORD", + "name": "Freifunk Nord", + "nodesURL": "http://mesh.ffnord.net/data/nodes.json", + "v6": "2a03:2267:4e6f:7264:", + "v6mask": "/64", + "v4": "10.187.0.0", + "v4mask": "/16", + "supported": 1 + }, + "FFHL": { + "ccode": "FFHL", + "name": "Freifunk L&uuml;beck", + "nodesURL": "https://map.luebeck.freifunk.net/data/nodes.json", + "v6": "fdef:ffc0:3dd7:", + "v6mask": "/64", + "v4": "10.130.0.0", + "v4mask": "/20", + "supported": 1 + }, + "FFNW": { + "ccode": "FFNW", + "name": "Freifunk Nordwest", + "nodesURL": "http://mesh.sjr-ol.de/data/nodes.json", + "v6": "fd74:fdaa:9dc4:", + "v6mask": "/64", + "v4": "10.18.0.0", + "v4mask": "/16", + "supported": 1 + }, + "FFAC": { + "ccode": "FFAC", + "name": "Freifunk Aachen", + "nodesURL": "http://map.freifunk-aachen.de/v2/data/nodes.json", + "v6": "2a03:2260:114:", + "v6mask": "/48", + "v4": "10.5.0.0", + "v4mask": "/16", + "supported": 1 + }, + "TECFF": { + "ccode": "TECFF", + "name": "Freifunk Altdorf e.V.", + "nodesURL": "http://tecff.de/data/nodes.json", + "v6": "2001:470:733f:", + "v6mask": "/48", + "v4": "10.120.0.0", + "v4mask": "/16", + "supported": 1 + }, + "FFAN": { + "ccode": "FFAN", + "name": "Freifunk Ansbach", + "nodesURL": "https://netmon.freifunk-ansbach.de/api/router_json.php", + "v6": "2001:470:5168:", + "v6mask": "/64", + "v4": "10.123.64.0", + "v4mask": "/18", + "supported": 0 + }, + "FF3L": { + "ccode": "FF3L", + "name": "Freifunk 3Ländereck", + "nodesURL": "http://map.freifunk-3laendereck.net/data/nodes.json", + "v6": "2001:bf7:20:", + "v6mask": "/44", + "v4": "110.119.0.0", + "v4mask": "/16", + "supported": 1 + }, + "FFDD": { + "ccode": "FFDD", + "name": "Freifunk Dresden", + "nodesURL": "http://api.freifunk-dresden.de/freifunk-nodes.json", + "v6": "fd11:11ae:7466:", + "v6mask": "/48", + "v4": "10.200.0.0", + "v4mask": "/16", + "supported": 0 + }, + "FFRG": { + "ccode": "FFRG", + "name": "Freifunk Ruhrgebiet", + "nodesURL": "http://map.freifunk-ruhrgebiet.de/nodes.json", + "v6": "2a03:2260:50:", + "v6mask": "/48", + "v4": "10.53.0.0", + "v4mask": "/16", + "supported": 1 + }, + "FFKBU": { + "ccode": "FFKBU", + "name": "Freifunk K\u00f6ln, Bonn und Umgebung", + "nodesURL": "https://map.kbu.freifunk.net/data/nodelist.json", + "v6": "2001:67C:20A0:", + "v6mask": "/56", + "v4": "172.26.0.0", + "v4mask": "/15", + "supported": 0 + }, + "FFEMS": { + "ccode": "FFEMS", + "name": "Freifunk Emskirchen", + "nodesURL": "https://netmon.freifunk-emskirchen.de/api/router_json.php", + "v6": "2001:470:5168:2:", + "v6mask": "/64", + "v4": "10.123.192.0", + "v4mask": "/18", + "supported": 0 + }, + "FFEF": { + "ccode": "FFEF", + "name": "Freifunk Erfurt", + "nodesURL": "http://map.erfurt.freifunk.net/nodes.json", + "v6": "", + "v6mask": "/", + "v4": "10.99.0.0", + "v4mask": "/16", + "supported": 0 + }, + "FFFR": { + "ccode": "FFFR", + "name": "Freifunk Franken", + "nodesURL": "https://netmon.freifunk-franken.de/routerlist.php", + "v6": "", + "v6mask": "/", + "v4": "10.50.64.0", + "v4mask": "/21", + "supported": 0 + }, + "FFE": { + "ccode": "FFE", + "name": "Freifunk Essen", + "nodesURL": "http://map.freifunk-ruhrgebiet.de/data/nodes.json", + "v6": "2a03:2260:1005:", + "v6mask": "/64", + "v4": "10.228.0.0", + "v4mask": "/16", + "supported": 1 + }, + "FFEU": { + "ccode": "FFEU", + "name": "Freifunk Euskirchen", + "nodesURL": "http://map.freifunk-euskirchen.de/data/nodes.json", + "v6": "fda0:747e:ab29:e054:", + "v6mask": "/64", + "v4": "10.19.0.0", + "v4mask": "/16", + "supported": 1 + }, + "FFFFM": { + "ccode": "FFFFM", + "name": "Freifunk Frankfurt am Main", + "nodesURL": "http://map.freifunk-euskirchen.de/data/nodes.json", + "v6": "fddd:5d16:b5dd:", + "v6mask": "/48", + "v4": "10.126.0.0", + "v4mask": "/16", + "supported": 1 + }, + "FFFR1": { + "ccode": "FFFR1", + "name": "Freifunk Freiburg", + "nodesURL": "https://freiburg.freifunk.net/ffmap-d3/nodes.json", + "v6": "fdf0:09bb:7814:", + "v6mask": "/48", + "v4": "10.60.0.0", + "v4mask": "/16", + "supported": 0 + } + } +} diff --git a/handlers/tmp/community.json b/handlers/tmp/community.json @@ -0,0 +1 @@ +751 +\ No newline at end of file diff --git a/helper/heroku.js b/helper/heroku.js @@ -0,0 +1,15 @@ +var express = require('express'); +var packageInfo = require('../package.json'); + +var app = express(); + +app.get('/', function (req, res) { + res.json({ version: packageInfo.version }); +}); + +var server = app.listen(process.env.PORT, function () { + var host = server.address().address; + var port = server.address().port; + + console.log('Web server started at http://%s:%s', host, port); +}); diff --git a/main.js b/main.js @@ -15,9 +15,12 @@ var params_config = require("./configs/ircServer.json"); var autoupdate = params_config["autoupdate"]; //LOAD MODULES DOWN HERE +require('./helper/heroku.js'); var pushbullet = require('./handlers/pushbullet.js'); var irc = require('./handlers/irc.js'); var slack = require('./handlers/slack.js'); +var getNodes = require('./handlers/getNodes.js'); +var telegram = require('./handlers/telegram.js'); //Constants var SIGINT = "SIGINT"; @@ -25,6 +28,8 @@ var door_status2 = "1"; //Startup irc.ircPreload(); +getNodes.saveNodes() +telegram.start() /** @@ -81,7 +86,7 @@ function GetData(){ //ADD MODULES DOWN HERE //Call Module send/main Functions pushbullet.pushbulletSend(door_status); - irc.ircSend(door_status); + //irc.ircSend(door_status); return door_status; }else{ @@ -113,7 +118,6 @@ process.on(SIGINT, function () { //Activate IRC-Bot Command Handler irc.ircBotCommands(); - /** * Update - Pull last master from Github * diff --git a/package.json b/package.json @@ -20,19 +20,29 @@ "notification" ], "dependencies": { + "async": "^2.0.0-rc.3", + "botanio": "0.0.6", "curlrequest": "*", + "ent": "git+https://github.com/substack/node-ent.git", + "express": "^4.13.4", + "html-entities": "^1.2.0", "irc": "0.4.0", + "jsonfile": "^2.3.0", "node-schedule": "*", + "node-telegram-bot-api": "^0.21.1", "request": "*", - "simple-git": "*", + "simple-git": "^1.31.0", "slackbots": "^0.5.1", "string": "^3.3.1", - "yargs": "*" + "yargs": "^4.3.2" }, "preferGlobal": false, "private": true, "license": "SEE LICENSE IN LICENSE.md", "optionalDependencies": { "yuidocjs": "^0.9.0" + }, + "devDependencies": { + "request-debug": "^0.2.0" } }