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

irc.js (13659B)


      1 /**
      2  * IRC-ChatBot Module
      3  *
      4  * @module Main
      5  * @class irc
      6  * @submodule irc
      7  * @author Marcel Radzio
      8  */
      9 //Load needed Features
     10 var irc = require('irc');
     11 var request = require('request');
     12 var S = require('string');
     13 var jsonfile = require('jsonfile')
     14 var async = require("async");
     15 var _ = require("lodash");
     16 var rl = require("readline")
     17 
     18 
     19 var command_config = require("../configs/commands.json");
     20 var params_config = require("../configs/ircServer.json");
     21 var getNodes = require('./parseNodes.js');
     22 
     23 //Set Params
     24 /**
     25  * Param Botname
     26  *
     27  * @property botname
     28  * @type String
     29  */
     30 var botname = params_config["botname"];
     31 /**
     32  * Param autoupdate
     33  *
     34  * @property autoupdate
     35  * @type String
     36  */
     37 var autoupdate = params_config["autoupdate"];
     38 /**
     39  * Param disconnect_meassage
     40  *
     41  * @property disconnect_meassage
     42  * @type String
     43  */
     44 var disconnect_meassage = params_config["disconnect_meassage"];
     45 
     46 
     47 /* // TEMPLATE //
     48 for (var key in params_config["servers"]) {
     49   if (params_config["servers"].hasOwnProperty(key)) {
     50     var servername = params_config["servers"][key]["servername"];
     51     var serveraddress = params_config["servers"][key]["serveraddress"];
     52     var main_channel = params_config["servers"][key]["main_channel"];
     53     var nickserv_pass = params_config["servers"][key]["nickserv_pass"];
     54     var active = params_config["servers"][key]["active"];
     55     var debug = params_config["servers"][key]["debug"];
     56     if (debug == 1) {
     57       var debug = true;
     58     }else{
     59       var debug = false;
     60     }
     61   }
     62 }
     63 */
     64 var clients = [];
     65 var bot = [];
     66 _.find(params_config["servers"], function (key) {
     67   serveraddress = key["serveraddress"];
     68   main_channel = key["main_channel"];
     69   active = key["active"];
     70   debug = key["debug"];
     71   if (debug == false) {
     72     console = console || {};
     73     console.log = function(){};
     74   }
     75   if (active === 1) {
     76     bot[key] = new irc.Client(serveraddress, botname, {
     77       debug: debug,
     78       channels: [main_channel],
     79       autoRejoin: true,
     80       autoConnect: false,
     81       messageSplit: 1000000,
     82       floodProtection: true,
     83       floodProtectionDelay: 200
     84     });
     85     clients.push(bot[key]);
     86   }
     87 });
     88 
     89 function addListener(event, callback) {
     90   clients.forEach(function(client) {
     91     client.addListener(event, callback);
     92   });
     93 }
     94 function join(event, callback) {
     95   clients.forEach(function(client) {
     96     client.join(event, callback);
     97   });
     98 }
     99 function list(event, callback) {
    100   clients.forEach(function(client) {
    101     client.list(event, callback);
    102   });
    103 }
    104 function disconnect(event, callback) {
    105   clients.forEach(function(client) {
    106     client.disconnect(event, callback);
    107   });
    108 }
    109 
    110 function connect(event, callback) {
    111   clients.forEach(function(client) {
    112     client.connect(event, callback);
    113   });
    114 }
    115 
    116 function send(event, callback) {
    117   clients.forEach(function(client) {
    118     client.send(event, callback);
    119   });
    120 }
    121 
    122 function say(event, callback) {
    123   clients.forEach(function(client) {
    124     client.say(event, callback);
    125   });
    126 }
    127 module.exports = {
    128 	/**
    129  	* Stops Bot with custom meassage
    130  	*
    131  	* @method ircEndCustom
    132  	* @constructor
    133 	*/
    134 	ircEndCustom: function (meassage) {
    135 		disconnect(meassage);
    136 	},
    137 	/**
    138  	* Connects to Server, logs in to NickServ, sets Name
    139  	*
    140  	* @method ircPreload
    141 	*/
    142 	ircPreload: function () {
    143     addListener('error', function(message) {
    144       setTimeout(function() {
    145         console.log("wait 7sek");
    146       }, 7000);
    147 
    148       send('nick', botname);
    149       _.find(params_config["servers"], function (key) {
    150         /**
    151         * Password for the NickServ
    152         *
    153         * @property nickserv_pass
    154         * @type String
    155         */
    156         var nickserv_pass = key["nickserv_pass"];
    157         say('NickServ', 'identify ' + nickserv_pass);
    158       });
    159 		});
    160 		setTimeout(function() {
    161 			console.log("wait 7sek");
    162 		}, 7000);
    163 		connect(10, function() {
    164 			send('nick', botname);
    165 			_.find(params_config["servers"], function (key) {
    166   			/**
    167 				 * Password for the NickServ
    168 				 *
    169 			   * @property nickserv_pass
    170 			   * @type String
    171 				*/
    172     		var nickserv_pass = key["nickserv_pass"];
    173     		/**
    174 				 * Main Channel of the Bot
    175 				 *
    176 			   * @property main_channel
    177 			   * @type String
    178 				*/
    179     		var main_channel = key["main_channel"];
    180     		say('NickServ', 'identify ' + nickserv_pass);
    181     		join(main_channel);
    182 		  });
    183 			//say(main_channel, 'Door Bot is starting to watch on the Door Status');
    184 		})
    185 	},
    186 	/**
    187  	  * Send DoorStatus to selected Channels
    188  	  *
    189  	  * @method ircSend
    190  	  * @constructor
    191     */
    192 	ircSend: function (door_status) {
    193 		_.find(params_config["servers"], function (key) {
    194       /**
    195         * Main Channel of the Bot
    196         *
    197 		    * @property main_channel
    198 		    * @type String
    199         */
    200   		var main_channel = key["main_channel"];
    201   		say(main_channel, 'Door Status changed to: ' + door_status);
    202   		say("#freifunk-flensburg", 'Door Status changed to: ' + door_status);
    203     });
    204     	//send('topic','#hackerspace "Hackerspace Flensburg - Treffen jeden Montag 18:00 Uhr im Offenen Kanal Flensburg! - Tür Status"' + door_status);
    205     	//console.log("IRC Door Status Chnaged");
    206   },
    207 	/**
    208     * Stops Bot with Stop measseagew freom config file
    209     *
    210     * @method ircStopp
    211     */
    212   ircStopp: function() {
    213     disconnect(disconnect_meassage);
    214   },
    215 	/**
    216     * Handels Commands from the Bot
    217     *
    218     * @method ircBotCommands
    219     */
    220   ircBotCommands: function() {
    221     // Will remove all false values: undefined, null, 0, false, NaN and "" (empty string)
    222     function cleanArray(actual) {
    223     	var newArray = new Array();
    224     	for (var i = 0; i < actual.length; i++) {
    225     		if (actual[i]) {
    226     			newArray.push(actual[i]);
    227     		}
    228     	}
    229     	return newArray;
    230     }
    231 
    232     addListener('message', function (from, to, message) {
    233     	/**
    234    			* Recived meassage
    235    			*
    236     		* @property message
    237     		* @type String
    238    			*/
    239     	message = message.toLowerCase();
    240       async.auto({
    241         commandFile: function (callback) {
    242           _.find(command_config["commands"], function (key) {
    243             if (S(message).contains("!" + key["keyword"])) {
    244               if (key["before"] === "from") {
    245       					if (key["target"] === "from") {
    246       						say(from, from + key["message"]);
    247       					} else {
    248       						say(to, from + key["message"]);
    249       					}
    250       				} else {
    251       					if (!key["before"]) {
    252       						if (key["target"] === "from") {
    253       							say(from, key["message"]);
    254       						} else {
    255       							say(to, key["message"]);
    256       						}
    257       					} else {
    258       						if (key["target"] === "from") {
    259       							say(from, to + key["message"]);
    260       						} else {
    261       							say(to, to + key["message"]);
    262       						}
    263       					}
    264       				}
    265       			}
    266       		});
    267         },
    268         channelList: function (callback) {
    269   		    /**
    270             * List of Channels on Server
    271             *
    272             * @property channel
    273             * @type Array
    274             *
    275             * @beta
    276             */
    277   		    channel = message.split(" ");
    278   		    channel = cleanArray(channel);
    279   		    if (S(channel[0] + " " + channel[1]).contains("!source this")) {
    280             console.log("!source " + channel[1]);
    281             if (channel[1] === "this") {
    282               join(to);
    283               say(to, "You can find the Source of this bot at https://github.com/MTRNord/nordlab-hackerspace-door");
    284             }
    285           }
    286         },
    287         nodes: function (callback) {
    288           if (S(message).contains("!nodes")) {
    289             jsonfile.readFile('handlers/tmp/communities.json', 'utf8', function (err,obj) {
    290               if (err) {throw new Error(err);}
    291               var communities = obj
    292               _.find(communities.communities, function (key) {
    293                 var ccode = key["ccode"];
    294                 if (ccode.toLowerCase() === channel[1]) {
    295                   clients.forEach(function(client) {
    296                     getNodes.countNodes(channel[1], "irc", "", "", "", client, "", to)
    297                   });
    298                 }
    299               });
    300             });
    301           }
    302         },
    303         node: function (callback) {
    304           if (S(message).contains("!node") || !S(message).contains("!nodes")) {
    305             jsonfile.readFile('handlers/tmp/communities.json', 'utf8', function (err,obj) {
    306               if (err) {throw new Error(err);}
    307               var communities = obj
    308               _.find(communities.communities, function (key) {
    309                 var ccode = key["ccode"];
    310                 if (ccode.toLowerCase() === channel[1]) {
    311                   clients.forEach(function(client) {
    312                     if (channel[2] == undefined) {
    313                       channel[2] = "NoArg"
    314                     }
    315                     getNodes.NodeInfo(channel[1], channel[2].toLowerCase(), "irc", "", "", "", client, "", from)
    316                   });
    317                 }
    318               });
    319             });
    320           }
    321         },
    322         communities: function (callback) {
    323           if (S(message).contains("!communities")) {
    324             jsonfile.readFile('handlers/tmp/communities.json', 'utf8', function (err,obj) {
    325               if (err) {throw new Error(err);}
    326               var communities = obj
    327               var communities_list = ""
    328               _.find(communities.communities, function (key) {
    329                 var ccode = key["ccode"]
    330                 var name = key["name"]
    331                 say(from, name + ": " + ccode + "  ")
    332               });
    333             })
    334           }
    335         },
    336         doorstatus: function (callback) {
    337       		if (S(message).contains("!doorstatus")) {
    338       			request.get('http://www.nordlab-ev.de/doorstate/status.txt', function (error, response, body) {
    339       			 if (!error && response.statusCode === 200) {
    340       				/**
    341             		* Content of status_page
    342             		*
    343             		* @property body
    344             		* @type String
    345             		*/
    346       				door_status = body;
    347     	      		console.log(body);
    348     	      	} else {
    349     	      		/**
    350             			* Fired when an error occurs...
    351             			*
    352             			* @property error
    353             			* @type String
    354             			*/
    355     	      		door_status = error;
    356     	      		throw new Error(err);
    357     	      	}
    358               if (!error && response.statusCode === 200) {
    359     	      	  if (door_status === "geschlossen") {
    360     	      	    door_status = "closed";
    361     	      	  } else {
    362     	      		 	door_status = "open";
    363     	      	  }
    364     			     	console.log(from + ' => ' + to + ': ' + message);
    365     			     	say(from, "DoorStatus is: " + door_status);
    366               }else{
    367                 say(from, "DoorStatus is not availible at this time");
    368               }
    369             }).setMaxListeners(0);
    370       		}
    371         },
    372         doorstatusThis: function (callback) {
    373       		if (S(channel[0] + " " + channel[1]).contains("!doorstatus this")) {
    374       			request.get('http://www.nordlab-ev.de/doorstate/status.txt', function (error, response, body) {
    375       				if (!error && response.statusCode === 200) {
    376       					/**
    377             			* Content of status_page
    378             			*
    379             			* @property body
    380             			* @type String
    381             			*/
    382       				  door_status = body;
    383     	      		console.log(body);
    384     	      	} else {
    385     	      		/**
    386             		  * Fired when an error occurs...
    387             		  *
    388             		  * @property error
    389             		  * @type String
    390             		  */
    391     	      		door_status = error;
    392     	      		throw new Error(err);
    393     	      	}
    394               if (!error && response.statusCode == 200) {
    395     	      	  if (door_status === "geschlossen") {
    396                   door_status = "closed";
    397     	      	  } else {
    398     	      		 	door_status = "open";
    399     	      	  }
    400                 console.log(message);
    401                 list();
    402                 console.log(channel[(channel.length-(channel.length-1))+1]);
    403                 console.log(channel.length);
    404                 if (channel[1] !== "this") {
    405                   if (channel[1] !== " ") {
    406                     addListener('channellist', function (channel_list) {
    407                       _.find(channel_list, function (key) {
    408                         if (key["name"] === channel[1]) {
    409                           join(channel[1]);
    410                           say(channel[1], "DoorStatus is: " + door_status);
    411                         }
    412     								  });
    413                     });
    414                   } else {
    415                     say(from, "DoorStatus is: " + door_status);
    416                   }
    417                 } else {
    418                   join(to);
    419                   say(to, "DoorStatus is: " + door_status);
    420                 }
    421               }else{
    422                 say(from, "DoorStatus is not availible at this time");
    423               }
    424             }).setMaxListeners(0);
    425           }
    426         },
    427         kill: function (callback) {
    428           if (S(message).contains("!kill")) {
    429             if ((from === "DasNordlicht") || (from === "MTRNord")) {
    430               console.log(from + ' => ' + to + ': ' + message);
    431         		  if (process.platform === "win32") {
    432         				rl.createInterface({
    433         					input: process.stdin,
    434         					output: process.stdout
    435         				});
    436         				disconnect(disconnect_meassage);
    437         				process.exit();
    438         			}
    439         		}
    440         	}
    441         },
    442         join: function (callback) {
    443           if (S(message).contains("!join")) {
    444             if ((from === "DasNordlicht") || (from === "MTRNord")) {
    445               console.log(from + ' => ' + to + ': ' + message);
    446               join(channel[1]);
    447             }
    448           }
    449         }
    450       },
    451       function(err, result) {
    452         if (err) {
    453           throw new Error(err);
    454         }
    455       }
    456     );
    457   })
    458 },
    459 /**
    460   * Updates the NickName
    461   *
    462   * @method ircNick
    463   */
    464 ircNick: function() {
    465   send('nick', botname);
    466 }
    467 };