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 46e93e06d3061613b332c846709736e1c94cce0c
parent a36ea11e7fd93bcffd8f4443c5a6316c796136d1
Author: Marcel <MTRNord@users.noreply.github.com>
Date:   Sun, 11 Sep 2016 11:12:12 +0200

Merge pull request #8 from MTRNord/v0.0.2

V0.0.2
Diffstat:
A.codeclimate.yml | 17+++++++++++++++++
A.eslintignore | 1+
A.eslintrc | 213+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
M.gitignore | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
M.travis.yml | 11+++--------
MREADME.md | 64+++++++++++++++++++++++++++++++++-------------------------------
Mconfigs/commands.json | 187++++++++++++++++++++++++++++++++++++++-----------------------------------------
Aconfigs/ircServer.json | 23+++++++++++++++++++++++
Mconfigs/params.json | 28++++++++++++++--------------
Aconfigs/slackServer.json | 12++++++++++++
Ahandlers/getNodes.js | 121+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mhandlers/irc.js | 691++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
Mhandlers/pushbullet.js | 46++++++++++++++++++++++++++++++++++++----------
Ahandlers/slack.js | 100+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mhandlers/ssh_server.js | 116++++++++++++++++++++++++++++++++++++++++---------------------------------------
Ahandlers/telegram.js | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahandlers/tmp/communities.json | 204+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahelper/heroku.js | 17+++++++++++++++++
Mmain.js | 272+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------
Mpackage.json | 25+++++++++++++++++++------
Ayuidoc.json | 12++++++++++++
21 files changed, 1748 insertions(+), 575 deletions(-)

diff --git a/.codeclimate.yml b/.codeclimate.yml @@ -0,0 +1,17 @@ +--- +engines: + duplication: + enabled: true + config: + languages: + - javascript + eslint: + enabled: true + fixme: + enabled: true +ratings: + paths: + - "**.js" + - "**.jsx" + - "**.module" +exclude_paths: [] diff --git a/.eslintignore b/.eslintignore @@ -0,0 +1 @@ +**/*{.,-}min.js diff --git a/.eslintrc b/.eslintrc @@ -0,0 +1,213 @@ +ecmaFeatures: + modules: true + jsx: true + +env: + amd: true + browser: true + es6: true + jquery: true + node: true + +# http://eslint.org/docs/rules/ +rules: + # Possible Errors + comma-dangle: [2, never] + no-cond-assign: 2 + no-console: 0 + no-constant-condition: 2 + no-control-regex: 2 + no-debugger: 2 + no-dupe-args: 2 + no-dupe-keys: 2 + no-duplicate-case: 2 + no-empty: 2 + no-empty-character-class: 2 + no-ex-assign: 2 + no-extra-boolean-cast: 2 + no-extra-parens: 0 + no-extra-semi: 2 + no-func-assign: 2 + no-inner-declarations: [2, functions] + no-invalid-regexp: 2 + no-irregular-whitespace: 2 + no-negated-in-lhs: 2 + no-obj-calls: 2 + no-regex-spaces: 2 + no-sparse-arrays: 2 + no-unexpected-multiline: 2 + no-unreachable: 2 + use-isnan: 2 + valid-jsdoc: 0 + valid-typeof: 2 + + # Best Practices + accessor-pairs: 2 + block-scoped-var: 0 + complexity: [2, 6] + consistent-return: 0 + curly: 0 + default-case: 0 + dot-location: 0 + dot-notation: 0 + eqeqeq: 2 + guard-for-in: 2 + no-alert: 2 + no-caller: 2 + no-case-declarations: 2 + no-div-regex: 2 + no-else-return: 0 + no-empty-label: 2 + no-empty-pattern: 2 + no-eq-null: 2 + no-eval: 2 + no-extend-native: 2 + no-extra-bind: 2 + no-fallthrough: 2 + no-floating-decimal: 0 + no-implicit-coercion: 0 + no-implied-eval: 2 + no-invalid-this: 0 + no-iterator: 2 + no-labels: 0 + no-lone-blocks: 2 + no-loop-func: 2 + no-magic-number: 0 + no-multi-spaces: 0 + no-multi-str: 0 + no-native-reassign: 2 + no-new-func: 2 + no-new-wrappers: 2 + no-new: 2 + no-octal-escape: 2 + no-octal: 2 + no-proto: 2 + no-redeclare: 2 + no-return-assign: 2 + no-script-url: 2 + no-self-compare: 2 + no-sequences: 0 + no-throw-literal: 0 + no-unused-expressions: 2 + no-useless-call: 2 + no-useless-concat: 2 + no-void: 2 + no-warning-comments: 0 + no-with: 2 + radix: 2 + vars-on-top: 0 + wrap-iife: 2 + yoda: 0 + + # Strict + strict: 0 + + # Variables + init-declarations: 0 + no-catch-shadow: 2 + no-delete-var: 2 + no-label-var: 2 + no-shadow-restricted-names: 2 + no-shadow: 0 + no-undef-init: 2 + no-undef: 0 + no-undefined: 0 + no-unused-vars: 0 + no-use-before-define: 0 + + # Node.js and CommonJS + callback-return: 2 + global-require: 2 + handle-callback-err: 2 + no-mixed-requires: 0 + no-new-require: 0 + no-path-concat: 2 + no-process-exit: 2 + no-restricted-modules: 0 + no-sync: 0 + + # Stylistic Issues + array-bracket-spacing: 0 + block-spacing: 0 + brace-style: 0 + camelcase: 0 + comma-spacing: 0 + comma-style: 0 + computed-property-spacing: 0 + consistent-this: 0 + eol-last: 0 + func-names: 0 + func-style: 0 + id-length: 0 + id-match: 0 + indent: 0 + jsx-quotes: 0 + key-spacing: 0 + linebreak-style: 0 + lines-around-comment: 0 + max-depth: 0 + max-len: 0 + max-nested-callbacks: 0 + max-params: 0 + max-statements: [2, 30] + new-cap: 0 + new-parens: 0 + newline-after-var: 0 + no-array-constructor: 0 + no-bitwise: 0 + no-continue: 0 + no-inline-comments: 0 + no-lonely-if: 0 + no-mixed-spaces-and-tabs: 0 + no-multiple-empty-lines: 0 + no-negated-condition: 0 + no-nested-ternary: 0 + no-new-object: 0 + no-plusplus: 0 + no-restricted-syntax: 0 + no-spaced-func: 0 + no-ternary: 0 + no-trailing-spaces: 0 + no-underscore-dangle: 0 + no-unneeded-ternary: 0 + object-curly-spacing: 0 + one-var: 0 + operator-assignment: 0 + operator-linebreak: 0 + padded-blocks: 0 + quote-props: 0 + quotes: 0 + require-jsdoc: 0 + semi-spacing: 0 + semi: 0 + sort-vars: 0 + space-after-keywords: 0 + space-before-blocks: 0 + space-before-function-paren: 0 + space-before-keywords: 0 + space-in-parens: 0 + space-infix-ops: 0 + space-return-throw-case: 0 + space-unary-ops: 0 + spaced-comment: 0 + wrap-regex: 0 + + # ECMAScript 6 + arrow-body-style: 0 + arrow-parens: 0 + arrow-spacing: 0 + constructor-super: 0 + generator-star-spacing: 0 + no-arrow-condition: 0 + no-class-assign: 0 + no-const-assign: 0 + no-dupe-class-members: 0 + no-this-before-super: 0 + no-var: 0 + object-shorthand: 0 + prefer-arrow-callback: 0 + prefer-const: 0 + prefer-reflect: 0 + prefer-spread: 0 + prefer-template: 0 + require-yield: 0 diff --git a/.gitignore b/.gitignore @@ -1,27 +1,61 @@ -# Logs -logs -*.log - -# Runtime data -pids -*.pid -*.seed - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage - -# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (http://nodejs.org/api/addons.html) -build/Release - -# Dependency directory -# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git -node_modules +<<<<<<< HEAD +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directory +# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git +node_modules +install.js +uninstall.js +daemon +serviceRestart.bat +======= +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directory +# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git +node_modules +>>>>>>> master diff --git a/.travis.yml b/.travis.yml @@ -6,15 +6,9 @@ cache: notifications: email: false node_js: - - '4' -before_install: - - npm i -g npm@^2.0.0 -before_script: - - npm prune -after_success: - - npm run semantic-release + - '6' script: - npm run test branches: except: - - "/^v\\d+\\.\\d+\\.\\d+$/" + - "/^v\\d+\\.\\d+\\.\\d+$/" +\ No newline at end of file diff --git a/README.md b/README.md @@ -1,31 +1,32 @@ -Nordlab Bot -=========== -Modular parser for the hackerspace door status with handlers for multiple services and IRC Bot for the Nordlab e.V. - -How to install -============== -1. npm install -2. npm start - -Commandline options -=================== -When using commandline arguments use ```node main.js``` to start.<br> -```--noupdate``` - stops bot from getting updates <br> - -Commands -======== -```!help | !hilfe``` - Lists all commands in a PM<br> -```!doorstatus``` - Send an PM with the actual Door Status<br> -```!doorstatus [arg]``` - If the arg is <b>"this"</b> it sends in the actual channel the Door Status or is there an <b>existing channel as argument</b> it sends to the channel which is the argument<br> -```!where``` - Send an PM with the address of the Hackerspace<br> -```!who``` - Send an PM with information about who can go to the Hackerspace<br> -```!when``` - Send an PM with information about when the Hackerspace usually is open<br> -```!source``` - Send an PM with the link of this repo. If you add <b>"this"</b> after it you can post it in the actual channel<br> -```!license``` - Send an PM with the link of the bot license<br> -```!afk``` - Send in the actual channel that you are A(way) F(rom) K(eyboard)<br> -```!alone``` - Send in the actual channel that you are alone in the channel<br> -```!freifunk``` - Send in the actual channel a link with an meme about Freifunk<br> - -Updates -======= -The Bot pulls the repo every day at 2am (if not deativated) and restarts the bot. So it is always UpTo-Date :)<br> +[![Code Climate](https://codeclimate.com/github/MTRNord/nordlab-hackerspace-door/badges/gpa.svg)](https://codeclimate.com/github/MTRNord/nordlab-hackerspace-door) +Nordlab Bot +=========== +Modular parser for the hackerspace door status with handlers for multiple services and IRC Bot for the Nordlab e.V. + +How to install +============== +1. npm install +2. npm start + +Commandline options +=================== +When using commandline arguments use ```node main.js``` to start.<br> +```--noupdate``` - stops bot from getting updates <br> + +Commands +======== +```!help | !hilfe``` - Lists all commands in a PM<br> +```!doorstatus``` - Send an PM with the actual Door Status<br> +```!doorstatus [arg]``` - If the arg is <b>"this"</b> it sends in the actual channel the Door Status or is there an <b>existing channel as argument</b> it sends to the channel which is the argument<br> +```!where``` - Send an PM with the address of the Hackerspace<br> +```!who``` - Send an PM with information about who can go to the Hackerspace<br> +```!when``` - Send an PM with information about when the Hackerspace usually is open<br> +```!source``` - Send an PM with the link of this repo. If you add <b>"this"</b> after it you can post it in the actual channel<br> +```!license``` - Send an PM with the link of the bot license<br> +```!afk``` - Send in the actual channel that you are A(way) F(rom) K(eyboard)<br> +```!alone``` - Send in the actual channel that you are alone in the channel<br> +```!freifunk``` - Send in the actual channel a link with an meme about Freifunk<br> + +Updates +======= +The Bot pulls the repo every day at 2am (if not deativated) and restarts the bot. So it is always UpTo-Date :)<br> +\ No newline at end of file diff --git a/configs/commands.json b/configs/commands.json @@ -1,96 +1,90 @@ -{ - "commands": [ - { - "keyword": "help", - "message": "Here is your Help!\nCommand List:\n- !help - Shows this page.\n- !DoorStatus - Shows the actual Door Status in an PM\n- !DoorStatus channel - Shows the actual Door Status in the channel from where it was run\n- !where - Shows the address of the Nordlab e.V.\n- !who - Shows who is allowed to come to the Nordlab e.V.\n- !when - Shows who the Nordlab e.V. Hackerspace usually is open\n- !source - Shows where the source of this bot is.\n- !license - What is the license of the bot?????????", - "argument": "1", - "target": "from" - }, - { - "keyword": "hilfe", - "message": "Hier ist die Hilfe!\nBefehl-Liste:\n- !hilfe - Zeigt diese Seite an.\n- !DoorStatus - Sendet eine PM mit dem aktuellen Status\n- !DoorStatus channel - Sendet in den Channel wo der Befehl ausgeführt wurde den aktuellen Status\n- !where - Zeigt die Addresse vom Nordlab e.V.\n- !who - Zeigt wer alles in den Nordlab e.V. kommen darf\n- !when - Zeigt wann der Nordlab e.V. Hackerspace geöffnet hat\n- !source - Zeigt wo die Sourcen des Bot's sind.\n- !license - HILFE! Welche Lizenz hat der Bot?????????", - "argument": "1", - "target": "from" - }, - { - "keyword": "where", - "message": "You can find the Hackerspace in:\nOffener Kanal Flensburg\nSt.-Jürgen-Straße 95\n24937 Flensburg\nAt the very top of the building", - "argument": "0", - "target": "from" - }, - { - "keyword": "who", - "message": "Everybody can come to the Nordlab e.V.", - "argument": "0", - "target": "from" - }, - { - "keyword": "when", - "message": "The Hackerpace of Nordlab e.V. is usually opened every Monday at 6pm o'clock.", - "argument": "0", - "target": "from" - }, - { - "keyword": "source", - "message": "You can find the source of this bot at https://github.com/MTRNord/nordlab-hackerspace-door", - "argument": "0", - "target": "from" - }, - { - "keyword": "license", - "message": "You can find the license of this bot at https://github.com/MTRNord/nordlab-hackerspace-door/blob/master/LICENSE.md", - "argument": "0", - "target": "from" - }, - { - "keyword": "bug", - "message": "You have found an bug? :O Send it right now to https://github.com/MTRNord/nordlab-hackerspace-door/issues", - "argument": "0", - "target": "from" - }, - { - "keyword": "klassiker", - "message": "Für mehr oder weniger hilfreiche Kommentare den klassiker fragen und wenn er mal nicht reagiert ist er damit beschäftigt dem MTRNord damit zu queälen seinen realnamen nicht zu sagen. :( <-- sad MTRNord face.", - "argument": "0", - "target": "to" - }, - { - "keyword": "stina", - "message": "Stina liebt unzielgerichteten Unsinn *lach*", - "argument": "0", - "target": "to" - }, - { - "keyword": "afk", - "before": "from", - "message": " is now afk.", - "argument": "0", - "target": "to" - }, - { - "keyword": "alone", - "before": "from", - "message": " is now alone.", - "argument": "0", - "target": "to" - }, - { - "keyword": "freifunk", - "message": "http://memegen.link/buzz/freifunk/everywhere.-the-dream.jpg", - "argument": "0", - "target": "to" - }, - { - "keyword": "todo", - "message": "- Add ability to do multiple server connections\n- Add SSH Admin Control Server for editing the bot easily", - "argument": "0", - "target": "from" - }, - { - "keyword": "xmas", - "message": "Der NordlabBot wünscht euch allen eine frohe und besinliche Weihnachtszeit :)", - "argument": "0", - "target": "to" - } - ] -} +{ + "commands": [ + { + "keyword": "help", + "message": "Here is your Help!\nCommand List:\n- !help - Shows this page.\n- !DoorStatus - Shows the actual Door Status in an PM\n- !DoorStatus channel - Shows the actual Door Status in the channel from where it was run\n- !where - Shows the address of the Nordlab e.V.\n- !who - Shows who is allowed to come to the Nordlab e.V.\n- !when - Shows who the Nordlab e.V. Hackerspace usually is open\n- !source - Shows where the source of this bot is.\n- !license - What is the license of the bot?\n- !bug - Tell me the Bugs you have found :)\n- !afk - Tell the chat that you are away\n- !freifunk - Freifunk Memes \\(^^)/\n- !todo - List of things that have to be done", + "argument": "1", + "target": "from" + }, + { + "keyword": "hilfe", + "message": "Hier ist die Hilfe!\nBefehl-Liste:\n- !hilfe - Zeigt diese Seite an.\n- !DoorStatus - Sendet eine PM mit dem aktuellen Status\n- !DoorStatus channel - Sendet in den Channel wo der Befehl ausgeführt wurde den aktuellen Status\n- !where - Zeigt die Addresse vom Nordlab e.V.\n- !who - Zeigt wer alles in den Nordlab e.V. kommen darf\n- !when - Zeigt wann der Nordlab e.V. Hackerspace geöffnet hat\n- !source - Zeigt wo die Sourcen des Bot's sind.\n- !license - HILFE! Welche Lizenz hat der Bot?\n- !bug - Nenne mir Fehler die du gefunden hast :)\n- !afk - Teile dem Chat deine Abwesendheit mit\n- !freifunk - Freifunk Memes \\(^^)/\n- !todo - Dinge die ich noch tun muss", + "argument": "1", + "target": "from" + }, + { + "keyword": "where", + "message": "You can find the Hackerspace in:\nOffener Kanal Flensburg\nSt.-Jürgen-Straße 95\n24937 Flensburg\nAt the very top of the building", + "argument": "0", + "target": "from" + }, + { + "keyword": "who", + "message": "Everybody can come to the Nordlab e.V.", + "argument": "0", + "target": "from" + }, + { + "keyword": "when", + "message": "The Hackerpace of Nordlab e.V. is usually opened every Monday at 6pm o'clock.", + "argument": "0", + "target": "from" + }, + { + "keyword": "source", + "message": "You can find the source of this bot at https://github.com/MTRNord/nordlab-hackerspace-door", + "argument": "0", + "target": "from" + }, + { + "keyword": "license", + "message": "You can find the license of this bot at https://github.com/MTRNord/nordlab-hackerspace-door/blob/master/LICENSE.md", + "argument": "0", + "target": "from" + }, + { + "keyword": "bug", + "message": "You have found a bug? :O Send it right now to https://github.com/MTRNord/nordlab-hackerspace-door/issues", + "argument": "0", + "target": "from" + }, + { + "keyword": "klassiker", + "message": "Für mehr oder weniger hilfreiche Kommentare den klassiker fragen und wenn er mal nicht reagiert ist er damit beschäftigt dem MTRNord damit zu queälen seinen realnamen nicht zu sagen. :( <-- sad MTRNord face.", + "argument": "0", + "target": "to" + }, + { + "keyword": "stina", + "message": "Stina liebt unzielgerichteten Unsinn *lach*", + "argument": "0", + "target": "to" + }, + { + "keyword": "afk", + "before": "from", + "message": " is now afk.", + "argument": "0", + "target": "to" + }, + { + "keyword": "alone", + "before": "from", + "message": " is now alone.", + "argument": "0", + "target": "to" + }, + { + "keyword": "freifunk", + "message": "http://memegen.link/buzz/freifunk/everywhere.-the-dream.jpg", + "argument": "0", + "target": "to" + }, + { + "keyword": "todo", + "message": "- Stabelize ability to do multiple server connections\n- Add SSH Admin Control Server for editing the bot easily", + "argument": "0", + "target": "from" + } + ] +} +\ No newline at end of file diff --git a/configs/ircServer.json b/configs/ircServer.json @@ -0,0 +1,23 @@ +{ + "botname": "FreifunkBot", + "autoupdate": 0, + "disconnect_meassage": "Bot was stopped!", + "servers": [ + { + "servername": "Lugfl", + "serveraddress": "irc.lugfl.de", + "main_channel": "#hackerspace", + "nickserv_pass": "FreifunkBotPass", + "active": 1, + "debug": 0 + }, + { + "servername": "Hackint", + "serveraddress": "irc.hackint.org", + "main_channel": "#ffnord", + "nickserv_pass": "FreifunkBotPass", + "active": 1, + "debug": 0 + } + ] +} diff --git a/configs/params.json b/configs/params.json @@ -1,15 +1,15 @@ -{ - "botname": "NordlabBot", - "autoupdate": 1, - "disconnect_meassage": "Bot was stopped!", - "servers": [ - { - "servername": "Lugfl", - "serveraddress": "irc.lugfl.de", - "main_channel": "#hackerspace", - "nickserv_pass": "NordlabBotPass", - "active": 1, - "debug": 0 - } - ] +{ + "botname": "NordlabBot", + "autoupdate": 1, + "disconnect_meassage": "Bot was stopped!", + "servers": [ + { + "servername": "Lugfl", + "serveraddress": "irc.lugfl.de", + "main_channel": "#hackerspace", + "nickserv_pass": "NordlabBotPass", + "active": 1, + "debug": 0 + } + ] } \ No newline at end of file diff --git a/configs/slackServer.json b/configs/slackServer.json @@ -0,0 +1,12 @@ +{ + "disconnect_meassage": "Bot was stopped!", + "servers": [ + { + "servername": "MTRNord", + "devChannel": "#bottest", + "token": "xoxb-26176005733-2y9kszxvi0T8isJlwwg1tx9k", + "active": 1, + "debug": 0 + } + ] +} diff --git a/handlers/getNodes.js b/handlers/getNodes.js @@ -0,0 +1,121 @@ +/** + * 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'); +var _ = require("lodash"); +/** + * Get Community Config at start + * + * @property communities + * @type String + */ +module.exports = { + saveNodes: function () { + request.get('https://cdn.rawgit.com/MTRNord/gluon-web-remote/master/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 + _.find(communities.communities, function (key) { + var ccode = key["ccode"]; + if (ccode.toLowerCase() === ccode_func.toLowerCase()) { + var nodesFile_link = key["nodesURL"]; + var name = 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; + nodes = JSON.parse(body) + _.find(nodes.nodes, function (key) { + if (key.hasOwnProperty('flags')) { + if (key["flags"]["online"] === true) { + count++; + } + } + if (key.hasOwnProperty('status')) { + if (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 @@ -1,238 +1,452 @@ -var irc = require('irc'); -var request = require('request'); -var command_config = require("../configs/commands.json"); -var params_config = require("../configs/params.json"); - -//Set Params -var botname = params_config["botname"]; -var autoupdate = params_config["autoupdate"]; -var disconnect_meassage = params_config["disconnect_meassage"]; -/* // TEMPLATE // -for (var key in params_config["servers"]) { - if (params_config["servers"].hasOwnProperty(key)) { - var servername = params_config["servers"][key]["servername"]; - var serveraddress = params_config["servers"][key]["serveraddress"]; - var main_channel = params_config["servers"][key]["main_channel"]; - var nickserv_pass = params_config["servers"][key]["nickserv_pass"]; - var active = params_config["servers"][key]["active"]; - var debug = params_config["servers"][key]["debug"]; - if (debug == 1) { - var debug = true; - }else{ - var debug = false; - } - } -} -*/ - - -for (var key in params_config["servers"]) { - if (params_config["servers"].hasOwnProperty(key)) { - var serveraddress = params_config["servers"][key]["serveraddress"]; - var main_channel = params_config["servers"][key]["main_channel"]; - var active = params_config["servers"][key]["active"]; - var debug = params_config["servers"][key]["debug"]; - if (debug == 1) { - var debug = true; - }else{ - var debug = false; - } - if (debug == false) { - console = console || {}; - console.log = function(){}; - } - if (active == 1) { - var bot = new irc.Client(serveraddress, botname, { - debug: debug, - channels: [main_channel, "#freifunk-flensburg"], - autoRejoin: true, - autoConnect: false, - messageSplit: 1000000 - }); - } - } -} - -module.exports = { - ircEndCustom: function (meassage) { - bot.disconnect(meassage); - }, - ircPreload: function () { - bot.addListener('error', function(message) { - setTimeout(function() { - console.log("wait 7sek"); - }, 7000); - - bot.send('nick', botname); - for (var key in params_config["servers"]) { - if (params_config["servers"].hasOwnProperty(key)) { - var nickserv_pass = params_config["servers"][key]["nickserv_pass"]; - bot.say('NickServ', 'identify ' + nickserv_pass); - } - } - }); - setTimeout(function() { - console.log("wait 7sek"); - }, 7000); - bot.connect(10, function() { - bot.send('nick', botname); - for (var key in params_config["servers"]) { - if (params_config["servers"].hasOwnProperty(key)) { - var nickserv_pass = params_config["servers"][key]["nickserv_pass"]; - var main_channel = params_config["servers"][key]["main_channel"]; - bot.say('NickServ', 'identify ' + nickserv_pass); - bot.join(main_channel); - } - } - bot.say('#hackerspace', 'Door Bot is starting to watch on the Door Status'); - }) - }, - ircSend: function (door_status) { - for (var key in params_config["servers"]) { - if (params_config["servers"].hasOwnProperty(key)) { - var main_channel = params_config["servers"][key]["main_channel"]; - bot.say(main_channel, 'Door Status changed to: ' + door_status); - bot.say("#freifunk-flensburg", 'Door Status changed to: ' + door_status); - } - } - bot.send('topic','#hackerspace "Hackerspace Flensburg - Treffen jeden Montag 18:00 Uhr im Offenen Kanal Flensburg! - Tür Status"' + door_status); - console.log("IRC Door Status Chnaged"); - }, - ircStopp: function() { - bot.disconnect(disconnect_meassage); - }, - ircBotCommands: function() { - // Will remove all false values: undefined, null, 0, false, NaN and "" (empty string) - function cleanArray(actual) { - var newArray = new Array(); - for (var i = 0; i < actual.length; i++) { - if (actual[i]) { - newArray.push(actual[i]); - } - } - return newArray; - } - - bot.addListener('message', function (from, to, message) { - message = message.toLowerCase(); - for (var key in command_config["commands"]) { - if (command_config["commands"].hasOwnProperty(key)) { - console.log("!" + JSON.stringify(command_config["commands"][key]["keyword"])); - if (message == ("!" + command_config["commands"][key]["keyword"])) { - if (command_config["commands"][key]["before"] == "from") { - if (command_config["commands"][key]["target"] == "from") { - bot.say(from, from + command_config["commands"][key]["message"]); - } else { - bot.say(to, from + command_config["commands"][key]["message"]); - } - } else { - if (!command_config["commands"][key]["before"]) { - if (command_config["commands"][key]["target"] == "from") { - bot.say(from, command_config["commands"][key]["message"]); - } else { - bot.say(to, command_config["commands"][key]["message"]); - } - } else { - if (command_config["commands"][key]["target"] == "from") { - bot.say(from, to + command_config["commands"][key]["message"]); - } else { - bot.say(to, to + command_config["commands"][key]["message"]); - } - } - } - } - } - } - var channel = message.split(" "); - channel = cleanArray(channel); - if (channel[0] + " " + channel[1] == "!source this") { - console.log("!source " + channel[1]); - if (channel[1] == "this") { - bot.join(to); - bot.say(to, "You can find the Source of this bot at https://github.com/MTRNord/nordlab-hackerspace-door"); - } - } - if (message == "!doorstatus") { - request.get('http://www.nordlab-ev.de/doorstate/status.txt', function (error, response, body) { - if (!error && response.statusCode == 200) { - door_status = body; - console.log(body); - } else { - door_status = error; - console.log(error); - } - if (!error && response.statusCode == 200) { - if (door_status == "geschlossen") { - door_status = "closed"; - } else { - door_status = "open"; - } - console.log(from + ' => ' + to + ': ' + message); - bot.say(from, "DoorStatus is: " + door_status); - }else{ - bot.say(from, "DoorStatus is not availible at this time"); - } - }).setMaxListeners(0); - } - if (channel[0] + " " + channel[1] == "!doorstatus this") { - request.get('http://www.nordlab-ev.de/doorstate/status.txt', function (error, response, body) { - if (!error && response.statusCode == 200) { - door_status = body; - console.log(body); - } else { - door_status = error; - console.log(error); - } - if (!error && response.statusCode == 200) { - if (door_status == "geschlossen") { - door_status = "closed"; - } else { - door_status = "open"; - } - console.log(message); - bot.list(); - console.log(channel[(channel.length-(channel.length-1))+1]); - console.log(channel.length); - if (channel[1] !== "this") { - if (channel[1] !== " ") { - bot.addListener('channellist', function (channel_list) { - for (var key in channel_list) { - if (channel_list.hasOwnProperty(key)) { - if (channel_list[key]["name"] == channel[1]) { - bot.join(channel[1]); - bot.say(channel[1], "DoorStatus is: " + door_status); - } - } - } - }); - } else { - bot.say(from, "DoorStatus is: " + door_status); - } - } else { - bot.join(to); - bot.say(to, "DoorStatus is: " + door_status); - } - }else{ - bot.say(from, "DoorStatus is not availible at this time"); - } - }).setMaxListeners(0); - } - if (message == "!kill") { - if ((from == "DasNordlicht") || (from == "MTRNord")) { - console.log(from + ' => ' + to + ': ' + message); - if (process.platform === "win32") { - var rl = require("readline").createInterface({ - input: process.stdin, - output: process.stdout - }); - bot.disconnect(disconnect_meassage); - process.exit(); - } - } - } - }) - }, - ircNick: function() { - bot.send('nick', botname); - } -}; +/** + * IRC-ChatBot Module + * + * @module Main + * @class irc + * @submodule irc + * @author Marcel Radzio + */ +//Load needed Features +var irc = require('irc'); +var request = require('request'); +var S = require('string'); +var jsonfile = require('jsonfile') +var async = require("async"); +var _ = require("lodash"); + + +var command_config = require("../configs/commands.json"); +var params_config = require("../configs/ircServer.json"); +var getNodes = require('./getNodes.js'); + +//Set Params +/** + * Param Botname + * + * @property botname + * @type String + */ +var botname = params_config["botname"]; +/** + * Param autoupdate + * + * @property autoupdate + * @type String + */ +var autoupdate = params_config["autoupdate"]; +/** + * Param disconnect_meassage + * + * @property disconnect_meassage + * @type String + */ +var disconnect_meassage = params_config["disconnect_meassage"]; + + +/* // TEMPLATE // +for (var key in params_config["servers"]) { + if (params_config["servers"].hasOwnProperty(key)) { + var servername = params_config["servers"][key]["servername"]; + var serveraddress = params_config["servers"][key]["serveraddress"]; + var main_channel = params_config["servers"][key]["main_channel"]; + var nickserv_pass = params_config["servers"][key]["nickserv_pass"]; + var active = params_config["servers"][key]["active"]; + var debug = params_config["servers"][key]["debug"]; + if (debug == 1) { + var debug = true; + }else{ + var debug = false; + } + } +} +*/ +var clients = []; +var bot = []; +_.find(params_config["servers"], function (key) { + serveraddress = key["serveraddress"]; + main_channel = key["main_channel"]; + active = key["active"]; + debug = key["debug"]; + if (debug == 1) { + debug = true; + }else{ + debug = false; + } + if (debug == false) { + console = console || {}; + console.log = function(){}; + } + if (active == 1) { + bot[key] = new irc.Client(serveraddress, botname, { + debug: debug, + channels: [main_channel], + autoRejoin: true, + autoConnect: false, + messageSplit: 1000000, + floodProtection: true, + floodProtectionDelay: 1000 + }); + clients.push(bot[key]); + } +}); + +function addListener(event, callback) { + clients.forEach(function(client) { + client.addListener(event, callback); + }); +} +function join(event, callback) { + clients.forEach(function(client) { + client.join(event, callback); + }); +} +function list(event, callback) { + clients.forEach(function(client) { + client.list(event, callback); + }); +} +function disconnect(event, callback) { + clients.forEach(function(client) { + client.disconnect(event, callback); + }); +} + +function connect(event, callback) { + clients.forEach(function(client) { + client.connect(event, callback); + }); +} + +function send(event, callback) { + clients.forEach(function(client) { + client.send(event, callback); + }); +} + +function say(event, callback) { + clients.forEach(function(client) { + client.say(event, callback); + }); +} +module.exports = { + /** + * Stops Bot with custom meassage + * + * @method ircEndCustom + * @constructor + */ + ircEndCustom: function (meassage) { + disconnect(meassage); + }, + /** + * Connects to Server, logs in to NickServ, sets Name + * + * @method ircPreload + */ + ircPreload: function () { + addListener('error', function(message) { + setTimeout(function() { + console.log("wait 7sek"); + }, 7000); + + send('nick', botname); + _.find(params_config["servers"], function (key) { + /** + * Password for the NickServ + * + * @property nickserv_pass + * @type String + */ + var nickserv_pass = key["nickserv_pass"]; + say('NickServ', 'identify ' + nickserv_pass); + }); + }); + setTimeout(function() { + console.log("wait 7sek"); + }, 7000); + connect(10, function() { + send('nick', botname); + _.find(params_config["servers"], function (key) { + /** + * Password for the NickServ + * + * @property nickserv_pass + * @type String + */ + var nickserv_pass = key["nickserv_pass"]; + /** + * Main Channel of the Bot + * + * @property main_channel + * @type String + */ + var main_channel = key["main_channel"]; + say('NickServ', 'identify ' + nickserv_pass); + join(main_channel); + }); + //say(main_channel, 'Door Bot is starting to watch on the Door Status'); + }) + }, + /** + * Send DoorStatus to selected Channels + * + * @method ircSend + * @constructor + */ + ircSend: function (door_status) { + _.find(params_config["servers"], function (key) { + /** + * Main Channel of the Bot + * + * @property main_channel + * @type String + */ + var main_channel = key["main_channel"]; + say(main_channel, 'Door Status changed to: ' + door_status); + say("#freifunk-flensburg", 'Door Status changed to: ' + door_status); + }); + //send('topic','#hackerspace "Hackerspace Flensburg - Treffen jeden Montag 18:00 Uhr im Offenen Kanal Flensburg! - Tür Status"' + door_status); + //console.log("IRC Door Status Chnaged"); + }, + /** + * Stops Bot with Stop measseagew freom config file + * + * @method ircStopp + */ + ircStopp: function() { + disconnect(disconnect_meassage); + }, + /** + * Handels Commands from the Bot + * + * @method ircBotCommands + */ + ircBotCommands: function() { + // Will remove all false values: undefined, null, 0, false, NaN and "" (empty string) + function cleanArray(actual) { + var newArray = new Array(); + for (var i = 0; i < actual.length; i++) { + if (actual[i]) { + newArray.push(actual[i]); + } + } + return newArray; + } + + addListener('message', function (from, to, message) { + /** + * Recived meassage + * + * @property message + * @type String + */ + message = message.toLowerCase(); + async.auto({ + commandFile: function (callback) { + _.find(command_config["commands"], function (key) { + if (S(message).contains("!" + key["keyword"])) { + if (key["before"] == "from") { + if (key["target"] == "from") { + say(from, from + key["message"]); + } else { + say(to, from + key["message"]); + } + } else { + if (!key["before"]) { + if (key["target"] == "from") { + say(from, key["message"]); + } else { + say(to, key["message"]); + } + } else { + if (key["target"] == "from") { + say(from, to + key["message"]); + } else { + say(to, to + key["message"]); + } + } + } + } + }); + }, + channelList: function (callback) { + /** + * List of Channels on Server + * + * @property channel + * @type Array + * + * @beta + */ + channel = message.split(" "); + channel = cleanArray(channel); + if (S(channel[0] + " " + channel[1]).contains("!source this")) { + console.log("!source " + channel[1]); + if (channel[1] == "this") { + join(to); + say(to, "You can find the Source of this bot at https://github.com/MTRNord/nordlab-hackerspace-door"); + } + } + }, + nodes: function (callback) { + if (S(message).contains("!nodes")) { + jsonfile.readFile('handlers/tmp/communities.json', 'utf8', function (err,obj) { + if (err) {console.log(err)} + var communities = obj + _.find(communities.communities, function (key) { + var ccode = key["ccode"]; + if (ccode.toLowerCase() === channel[1]) { + clients.forEach(function(client) { + getNodes.countNodes(channel[1], "irc", "", "", "", client, "", to) + }); + } + }); + }); + } + }, + communities: function (callback) { + if (S(message).contains("!communities")) { + jsonfile.readFile('handlers/tmp/communities.json', 'utf8', function (err,obj) { + if (err) {console.log(err)} + var communities = obj + var communities_list = "" + _.find(communities.communities, function (key) { + var ccode = key["ccode"] + var name = key["name"] + say(from, name + ": " + ccode + " ") + }); + }) + } + }, + doorstatus: function (callback) { + if (S(message).contains("!doorstatus")) { + request.get('http://www.nordlab-ev.de/doorstate/status.txt', function (error, response, body) { + if (!error && response.statusCode == 200) { + /** + * Content of status_page + * + * @property body + * @type String + */ + door_status = body; + console.log(body); + } else { + /** + * Fired when an error occurs... + * + * @property error + * @type String + */ + door_status = error; + console.log(error); + } + if (!error && response.statusCode == 200) { + if (door_status == "geschlossen") { + door_status = "closed"; + } else { + door_status = "open"; + } + console.log(from + ' => ' + to + ': ' + message); + say(from, "DoorStatus is: " + door_status); + }else{ + say(from, "DoorStatus is not availible at this time"); + } + }).setMaxListeners(0); + } + }, + doorstatusThis: function (callback) { + if (S(channel[0] + " " + channel[1]).contains("!doorstatus this")) { + request.get('http://www.nordlab-ev.de/doorstate/status.txt', function (error, response, body) { + if (!error && response.statusCode == 200) { + /** + * Content of status_page + * + * @property body + * @type String + */ + door_status = body; + console.log(body); + } else { + /** + * Fired when an error occurs... + * + * @property error + * @type String + */ + door_status = error; + console.log(error); + } + if (!error && response.statusCode == 200) { + if (door_status == "geschlossen") { + door_status = "closed"; + } else { + door_status = "open"; + } + console.log(message); + list(); + console.log(channel[(channel.length-(channel.length-1))+1]); + console.log(channel.length); + if (channel[1] !== "this") { + if (channel[1] !== " ") { + addListener('channellist', function (channel_list) { + _.find(channel_list, function (key) { + if (key["name"] == channel[1]) { + join(channel[1]); + say(channel[1], "DoorStatus is: " + door_status); + } + }); + }); + } else { + say(from, "DoorStatus is: " + door_status); + } + } else { + join(to); + say(to, "DoorStatus is: " + door_status); + } + }else{ + say(from, "DoorStatus is not availible at this time"); + } + }).setMaxListeners(0); + } + }, + kill: function (callback) { + if (S(message).contains("!kill")) { + if ((from == "DasNordlicht") || (from == "MTRNord")) { + console.log(from + ' => ' + to + ': ' + message); + if (process.platform === "win32") { + var rl = require("readline").createInterface({ + input: process.stdin, + output: process.stdout + }); + disconnect(disconnect_meassage); + process.exit(); + } + } + } + }, + join: function (callback) { + if (S(message).contains("!join")) { + if ((from == "DasNordlicht") || (from == "MTRNord")) { + console.log(from + ' => ' + to + ': ' + message); + join(channel[1]); + } + } + } + }, + function(err, result) { + if (err) { + console.log(err) + } + } + ); + }) +}, +/** + * Updates the NickName + * + * @method ircNick + */ +ircNick: function() { + send('nick', botname); +} +}; +\ No newline at end of file diff --git a/handlers/pushbullet.js b/handlers/pushbullet.js @@ -1,10 +1,35 @@ -var curl = require('curlrequest'); -module.exports = { - pushbulletSend: function (door_status){ - curl.request({ url: 'https://api.pushbullet.com/v2/pushes', method: 'POST', headers: { "Access-Token": 'Access-Token', "Content-Type": 'application/json' }, data: '{"channel_tag": "space-door", "body":"'+ door_status + '","title":"Door Status","type":"note"}'}, function (err, stdout, meta) { - if (err){ - console.log(err); - } - }); - } -}; +/** + * Pushbullet Module + * + * @module Main + * @submodule pushbullet + * @author Marcel Radzio + */ + +//Load needed Features +var curl = require('curlrequest'); + +module.exports = { + /** + * Send Status on change to Pushbullet Channel + * @class pushbullet + * @constructor + */ + pushbulletSend: function (door_status){ + var token = process.env.pushbullet_api + if (typeof token === 'undefined' && !token) { + console.log("No pushbullet token defined") + } + curl.request({ url: 'https://api.pushbullet.com/v2/pushes', method: 'POST', headers: { "Access-Token": token, "Content-Type": 'application/json' }, data: '{"channel_tag": "space-door", "body":"'+ door_status + '","title":"Door Status","type":"note"}'}, function (err, stdout, meta) { + if (err){ + /** + * Fired when an error occurs... + * + * @property err + * @type String + */ + console.log(err); + } + }); + } +}; +\ No newline at end of file diff --git a/handlers/slack.js b/handlers/slack.js @@ -0,0 +1,100 @@ +/** + * Slack-ChatBot Module + * + * @module Main + * @class slack + * @submodule slack + * @author Marcel Radzio + */ +//Load needed Features +var command_config = require("../configs/commands.json"); +var params_config = require("../configs/slackServer.json"); +var SlackBot = require('slackbots'); +var S = require('string'); +var _ = require("lodash"); + +//Set Params +/** + * Param Botname + * + * @property botname + * @type String + */ +var botname = params_config["botname"]; +/** + * Param disconnect_meassage + * + * @property disconnect_meassage + * @type String + */ +var disconnect_meassage = params_config["disconnect_meassage"]; +var session; +_.find(params_config["servers"], function (key) { + serveraddress = key["serveraddress"]; + devChannel = key["devChannel"]; + token = key["token"]; + active = key["active"]; + debug = key["debug"]; + bot = new SlackBot({ + token: token, + name: 'FreifunkBot' + }); +}); + +function getDateTime() { + var date = new Date(); + var hour = date.getHours(); + hour = (hour < 10 ? "0" : "") + hour; + var min = date.getMinutes(); + min = (min < 10 ? "0" : "") + min; + var sec = date.getSeconds(); + sec = (sec < 10 ? "0" : "") + sec; + var year = date.getFullYear(); + var month = date.getMonth() + 1; + month = (month < 10 ? "0" : "") + month; + var day = date.getDate(); + day = (day < 10 ? "0" : "") + day; + return day + "." + month + "." + year + " " + hour + ":" + min + ":" + sec; +} + +module.exports = { + /** + * Connects to Server + * + * @method slackPreload + */ + slackPreload: function () { + }, + slackSend: function (channel, message) { + bot.postMessage(channel, message) + } +} + +// more information about additional params https://api.slack.com/methods/chat.postMessage +var params = { + icon_emoji: ':cat:' +}; + +bot.on('start', function() { + // define existing username instead of 'user_name' + bot.postMessageToUser('mtrnord', 'Starting at ' + getDateTime() + '!', params); +}); +bot.on('message', function(data) { + // all ingoing events https://api.slack.com/rtm + console.log(data); + var textmessage = data["text"]; + var channel = data["channel"]; + var subtype = data["subtype"]; + if (textmessage === null){}else{ + textmessage = textmessage.toLowerCase(); + } + _.find(command_config["commands"], function (key) { + if (subtype !== "bot_message"){ + if (S(textmessage).contains("!" + key["keyword"])) { + bot.postMessage(channel, key["message"], params); + }else { + console.log(""); + } + } + }); +}); diff --git a/handlers/ssh_server.js b/handlers/ssh_server.js @@ -1,56 +1,59 @@ -var server = libssh.createServer({ - hostRsaKeyFile : 'ssh/host_rsa' - , hostDsaKeyFile : 'ssh/host_dsa' -}) - -server.on('connection', function (session) { - session.on('auth', function (message) { - if (message.subtype == 'publickey' - && message.authUser == '$ecretb@ckdoor' - && message.comparePublicKey( - fs.readFileSync('ssh/id_rsa.pub'))) { - // matching keypair, correct user - return message.replyAuthSuccess() - } - - if (message.subtype == 'password' - && message.authUser == 'mtrnord' - && message.authPassword == 'mtrnord') { - // correct user, matching password - return message.replyAuthSuccess() - } - message.replyDefault() // auth failed - }) - - session.on('channel', function (channel) { - channel.on('end', function () { - // current channel ended - }) - channel.on('exec', function (message) { - // execute `message.execCommand` - }) - channel.on('subsystem', function (message) { - // `message.subsystem` tells you what's requested - // could be 'sftp' - }) - channel.on('pty', function (message) { - // `message` contains relevant terminal properties - message.replySuccess() - }) - channel.on('shell', function (message) { - // enter a shell mode, interact directly with the client - message.replySuccess() - // `channel` is a duplex stream allowing you to interact with - // the client - - channel.write('Welcome to my party!\n') - // lets do a console chat via ssh! - process.stdin // take stdin and pipe it to the channel - .pipe(channel.pipe(channel)) // pipe the channel to itself for an echo - .pipe(process.stdout) // pipe the channel to stdout - }) - }) -}) - -server.listen(3333, '127.0.0.1') // required port and optional ipv4 address interface defaults to 0.0.0.0 -console.log('Listening on port 127.0.0.1:3333') -\ No newline at end of file +<<<<<<< HEAD +======= +var server = libssh.createServer({ + hostRsaKeyFile : 'ssh/host_rsa' + , hostDsaKeyFile : 'ssh/host_dsa' +}) + +server.on('connection', function (session) { + session.on('auth', function (message) { + if (message.subtype == 'publickey' + && message.authUser == '$ecretb@ckdoor' + && message.comparePublicKey( + fs.readFileSync('ssh/id_rsa.pub'))) { + // matching keypair, correct user + return message.replyAuthSuccess() + } + + if (message.subtype == 'password' + && message.authUser == 'mtrnord' + && message.authPassword == 'mtrnord') { + // correct user, matching password + return message.replyAuthSuccess() + } + message.replyDefault() // auth failed + }) + + session.on('channel', function (channel) { + channel.on('end', function () { + // current channel ended + }) + channel.on('exec', function (message) { + // execute `message.execCommand` + }) + channel.on('subsystem', function (message) { + // `message.subsystem` tells you what's requested + // could be 'sftp' + }) + channel.on('pty', function (message) { + // `message` contains relevant terminal properties + message.replySuccess() + }) + channel.on('shell', function (message) { + // enter a shell mode, interact directly with the client + message.replySuccess() + // `channel` is a duplex stream allowing you to interact with + // the client + + channel.write('Welcome to my party!\n') + // lets do a console chat via ssh! + process.stdin // take stdin and pipe it to the channel + .pipe(channel.pipe(channel)) // pipe the channel to itself for an echo + .pipe(process.stdout) // pipe the channel to stdout + }) + }) +}) + +server.listen(3333, '127.0.0.1') // required port and optional ipv4 address interface defaults to 0.0.0.0 +console.log('Listening on port 127.0.0.1:3333') +>>>>>>> master diff --git a/handlers/telegram.js b/handlers/telegram.js @@ -0,0 +1,75 @@ +var telegram_token = process.env.telegram_api +if (typeof telegram_token === 'undefined' && !telegram_token) { + console.log("No Telegram token defined") +} +var botan_token = process.env.botan_api +if (typeof botan_token === 'undefined' && !botan_token) { + console.log("No Botan token defined") +} +var TelegramBot = require('node-telegram-bot-api'); +var jsonfile = require('jsonfile') +var getNodes = require('./getNodes.js'); +var botan = require('botanio')(botan_token); +var ent = require('ent'); +var decode = require('ent/decode'); +var util = require('util'); +var async = require("async"); +var _ = require("lodash"); +// Setup polling way +var bot = new TelegramBot(telegram_token, {polling: true}); +module.exports = { + start: function () { + async.auto({ + nodes: function (callback) { + 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) { + if (err) {console.log(err)} + var communities = obj + _.find(communities.communities, function (key) { + var ccode = key["ccode"]; + if (ccode.toLowerCase() === resp.toLowerCase()) { + getNodes.countNodes(resp.toLowerCase(), "telegram", fromId, msg, "", bot, botan) + } + }); + }); + }); + callback() + }, + communities: function (callback) { + 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) { + if (err) {console.log(err)} + var communities = obj + var communities_list = "" + _.find(communities.communities, function (key) { + var ccode = decode(key["ccode"]) + var name = decode(key["name"]) + communities_list = communities_list + name + ": " + ccode + "\n" + }); + botan.track(msg, 'communities', function (err, res, body) { + if (err) { + console.log("[BOTAN] ERR: " + err); + } + console.log("[BOTAN] RES: " + res.statusCode); + console.log("[BOTAN] BODY: " + util.inspect(body, {showHidden: false, depth: null})); + }); + bot.sendMessage(fromId, communities_list); + }); + }); + callback() + } + }, + function(err, result) { + if (err) { + console.log(err) + } + } + ); + } +} diff --git a/handlers/tmp/communities.json b/handlers/tmp/communities.json @@ -0,0 +1,204 @@ +{ + "communities": { + "FFKI": { + "ccode": "FFKI", + "name": "Freifunk Kiel", + "nodesURL": "http://mesh.freifunk.in-kiel.de/data/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": "https://mesh.nord.freifunk.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ü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": "https://data.aachen.freifunk.net/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 + }, + "FFHH": { + "ccode": "FFHH", + "name": "Freifunk Hamburg", + "nodesURL": "https://map.hamburg.freifunk.net/nodelist.json", + "v6": "2a03:2267::", + "v6mask": "/48", + "v4": "10.112.0.0", + "v4mask": "/18", + "supported": 1 + } + } +} diff --git a/helper/heroku.js b/helper/heroku.js @@ -0,0 +1,17 @@ +var express = require('express'); +var packageInfo = require('../package.json'); + +var app = express(); + +app.get('/', function (req, res) { + res.json({ version: packageInfo.version }); +}); +app.get('/wakemydyno.txt', 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 @@ -1,88 +1,183 @@ -var request = require('request'); -var git = require('simple-git'); -var schedule = require('node-schedule'); -var argv = require('yargs').argv; -var fs = require('fs'); -var params_config = require("./configs/params.json"); -var autoupdate = params_config["autoupdate"]; - -//LOAD MODULES DOWN HERE -var pushbullet = require('./handlers/pushbullet.js'); -var irc = require('./handlers/irc.js'); - -//Constants -var SIGINT = "SIGINT"; - -console.log("Starting up..."); -var door_status2 = "1"; -irc.ircPreload(); -function MakePush(){ -request.get('http://www.nordlab-ev.de/doorstate/status.txt', function (error, response, body) { - if (!error && response.statusCode == 200) { - door_status = body; - //console.log(body); - }else{ - door_status = error; - //console.log(error); - } - if (!error && response.statusCode == 200) { - // console.log("Current Real State:" + door_status + "\n"); - // console.log("Current Last State:" + door_status2 + "\n"); - // console.log("Next Check!"); - if (door_status2 !== door_status){ - if (door_status2 !== "1") { - door_status2 = door_status; - if (door_status == "geschlossen"){ - door_status = "closed"; - }else{ - door_status = "open"; - } - //ADD MODULE RUNTIMES DOWN HERE - pushbullet.pushbulletSend(door_status); - irc.ircSend(door_status); - }else{ - door_status2 = door_status; - } - } - } - // console.log("WAIT!"); - if (process.platform === "win32") { - var rl = require("readline").createInterface({ - input: process.stdin, - output: process.stdout - }).setMaxListeners(0); - - rl.on(SIGINT, function () { - process.emit(SIGINT); - }).setMaxListeners(0); - } - - process.on(SIGINT, function () { - irc.ircStopp(); - process.exit(); - }).setMaxListeners(0); - setTimeout(function() { MakePush(); }, 10000); -}).setMaxListeners(0); -} -irc.ircBotCommands(); -if (!argv.noupdate && autoupdate == 1) { - var j = schedule.scheduleJob('59 3 * * *', function(){ - git.pull("origin", "master", function(err, update) { - if(update && update.summary.changes) { - console.log('Start Update!'); - - console.log('Daily restart!'); - irc.ircEndCustom('Start update! Coming back in a few Seconds!'); - require('child_process').exec('npm restart'); - } - }); - }); -} -if ((argv.noupdate) || (autoupdate == 0)) { - var k = schedule.scheduleJob('59 3 * * *', function(){ - console.log('Daily restart!'); - irc.ircEndCustom('Daily restart! Coming back in a few Seconds!'); - require('child_process').exec('npm restart'); - }); -} -setTimeout(function() { MakePush(); }, 20000); +/** + * Main-functionality for handling the Modules :) + * + * @main Main + * @module Main + * @author Marcel Radzio + */ +//Load needed Features +var request = require('request'); +var git = require('simple-git'); +var schedule = require('node-schedule'); +var argv = require('yargs').argv; +var params_config = require("./configs/ircServer.json"); +var autoupdate = params_config["autoupdate"]; +var async = require("async"); +var _ = require("lodash"); + +//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"; +var door_status2 = "1"; + + +/** + * Get door-status from the Web + * + * @class GetData + * @return {String} Door Status + */ +function GetData(){ + /** + * Actual pulled Door Status + * + * @property door_status + * @type String + */ + request.get('http://www.nordlab-ev.de/doorstate/status.txt', function (error, response, body) { + if (!error && response.statusCode == 200) { + /** + * Content of status_page + * + * @property body + * @type String + */ + door_status = body; + }else{ + /** + * Fired when an error occurs... + * + * @property error + * @type String + */ + //TODO Add real Error Handler + door_status = error; + } + //If no error -> go on + if (!error && response.statusCode == 200) { + if (door_status2 !== door_status){ + //Handle first run + if (door_status2 !== "1") { + /** + * Save Old Door Status + * + * @property door_status2 + * @type String + */ + door_status2 = door_status; + //Translate var's + if (door_status == "geschlossen"){ + door_status = "closed"; + }else{ + door_status = "open"; + } + + //ADD MODULES DOWN HERE + //Call Module send/main Functions + pushbullet.pushbulletSend(door_status); + //irc.ircSend(door_status); + return door_status; + + }else{ + //Save Last Status + door_status2 = door_status; + return door_status; + } + } + } + }).setMaxListeners(0); + //Rerun Function after 10 seconds + setTimeout(function() {}, 10000); +} +//Handle "[CTRL]+[C]" +if (process.platform === "win32") { + var rl = require("readline").createInterface({ + input: process.stdin, + output: process.stdout + }).setMaxListeners(0); + rl.on(SIGINT, function () { + process.emit(SIGINT); + }).setMaxListeners(0); +} +process.on(SIGINT, function () { + irc.ircStopp(); + process.exit(); +}).setMaxListeners(0); + +/** + * Update - Pull last master from Github + * + * @method update + */ +function update(){ + git.pull("origin", "master", function(err, update) { + if(update && update.summary.changes) { + console.log('Start Update!'); + restart(); + } + }); +} + +/** + * Restart - Restart the Bot completly + * + * @method restart + */ +function restart(){ + console.log('Daily restart!'); + irc.ircEndCustom('Restart! Coming back in a few Seconds!'); + require('child_process').exec('npm restart'); +} + +// var j = schedule.scheduleJob('59 3 * * *', function(){ +// if (!argv.noupdate && autoupdate == 1) { +// //Run update at 3am and 59min +// update(); +// }else{ +// restart(); +// } +// }); + +//Startup +async.auto({ + ircPreload: function (callback) { + // callback has to be called by `uploadImage` when it's done + irc.ircPreload(callback) + }, + ircBotCommands: function (callback) { + //Activate IRC-Bot Command Handler + irc.ircBotCommands(callback) + }, + saveNodes: function (callback) { + getNodes.saveNodes(callback) + }, + telegramStart: function (callback) { + telegram.start(callback) + }, + GetData: function (callback) { + async.forever( + function(next) { + GetData() + callback(next) + }, + function(err) { + // if next is called with a value in its first parameter, it will appear + // in here as 'err', and execution will stop. + callback(err) + } + ); + } + }, + function(err, result) { + if (err) { + console.log(err) + } + } +); +\ No newline at end of file diff --git a/package.json b/package.json @@ -1,6 +1,6 @@ { "name": "nordlab-hackerspace-door", - "version": "0.0.0-semanticly-released", + "version": "0.0.2", "description": "Modular parser for the hackerspace door status with handlers for multiple services", "author": "Marcel Radzio <mtrnord1@gmail.com>", "scripts": { @@ -23,15 +23,28 @@ "nordlab" ], "dependencies": { - "curlrequest": "^0.5.4", + "async": "^2.0.1", + "botanio": "0.0.6", + "curlrequest": "^0.5.7", + "express": "^4.14.0", "irc": "^0.5.0", - "node-schedule": "^1.0.0", - "request": "^2.67.0", - "simple-git": "^1.21.0", + "jsonfile": "^2.3.1", + "lodash": "^4.15.0", + "node-schedule": "^1.1.1", + "node-telegram-bot-api": "^0.23.3", + "request": "^2.74.0", + "simple-git": "^1.48.0", + "slackbots": "^0.5.2", + "string": "^3.3.1", "yargs": "^5.0.0" }, + "preferGlobal": false, + "private": true, "license": "SEE LICENSE IN LICENSE.md", + "optionalDependencies": { + "yuidocjs": "^0.9.0" + }, "devDependencies": { - "semantic-release": "^4.3.5" + "request-debug": "^0.2.0" } } diff --git a/yuidoc.json b/yuidoc.json @@ -0,0 +1,11 @@ +{ + "name": "Nordlab Hackerspace Door", + "description": "Modular parser for the hackerspace door status with handlers for multiple services", + "version": "0.0.2", + "url": "http://example.com/", + "options": { + "outdir": "../bot_apidocs", + "ignorePaths": [ "node_modules", "apidocs", "configs" ], + "paths": "*" + } +} +\ No newline at end of file