freifunk-bot.meta

Issues/PRs archive for MTRNord/freifunk-bot
git clone git://archive.git.mtrnord.blog/MTRNord/freifunk-bot.meta.git
Log | Files | Refs

7.diff (59294B)


      1 diff --git a/.codeclimate.yml b/.codeclimate.yml
      2 new file mode 100644
      3 index 0000000..fd806df
      4 --- /dev/null
      5 +++ b/.codeclimate.yml
      6 @@ -0,0 +1,24 @@
      7 +---
      8 +engines:
      9 +  duplication:
     10 +    enabled: true
     11 +    config:
     12 +      languages:
     13 +      - ruby
     14 +      - javascript
     15 +      - python
     16 +      - php
     17 +  eslint:
     18 +    enabled: true
     19 +  fixme:
     20 +    enabled: true
     21 +ratings:
     22 +  paths:
     23 +  - "**.inc"
     24 +  - "**.js"
     25 +  - "**.jsx"
     26 +  - "**.module"
     27 +  - "**.php"
     28 +  - "**.py"
     29 +  - "**.rb"
     30 +exclude_paths: []
     31 diff --git a/.eslintignore b/.eslintignore
     32 new file mode 100644
     33 index 0000000..96212a3
     34 --- /dev/null
     35 +++ b/.eslintignore
     36 @@ -0,0 +1 @@
     37 +**/*{.,-}min.js
     38 diff --git a/.eslintrc b/.eslintrc
     39 new file mode 100644
     40 index 0000000..9faa375
     41 --- /dev/null
     42 +++ b/.eslintrc
     43 @@ -0,0 +1,213 @@
     44 +ecmaFeatures:
     45 +  modules: true
     46 +  jsx: true
     47 +
     48 +env:
     49 +  amd: true
     50 +  browser: true
     51 +  es6: true
     52 +  jquery: true
     53 +  node: true
     54 +
     55 +# http://eslint.org/docs/rules/
     56 +rules:
     57 +  # Possible Errors
     58 +  comma-dangle: [2, never]
     59 +  no-cond-assign: 2
     60 +  no-console: 0
     61 +  no-constant-condition: 2
     62 +  no-control-regex: 2
     63 +  no-debugger: 2
     64 +  no-dupe-args: 2
     65 +  no-dupe-keys: 2
     66 +  no-duplicate-case: 2
     67 +  no-empty: 2
     68 +  no-empty-character-class: 2
     69 +  no-ex-assign: 2
     70 +  no-extra-boolean-cast: 2
     71 +  no-extra-parens: 0
     72 +  no-extra-semi: 2
     73 +  no-func-assign: 2
     74 +  no-inner-declarations: [2, functions]
     75 +  no-invalid-regexp: 2
     76 +  no-irregular-whitespace: 2
     77 +  no-negated-in-lhs: 2
     78 +  no-obj-calls: 2
     79 +  no-regex-spaces: 2
     80 +  no-sparse-arrays: 2
     81 +  no-unexpected-multiline: 2
     82 +  no-unreachable: 2
     83 +  use-isnan: 2
     84 +  valid-jsdoc: 0
     85 +  valid-typeof: 2
     86 +
     87 +  # Best Practices
     88 +  accessor-pairs: 2
     89 +  block-scoped-var: 0
     90 +  complexity: [2, 6]
     91 +  consistent-return: 0
     92 +  curly: 0
     93 +  default-case: 0
     94 +  dot-location: 0
     95 +  dot-notation: 0
     96 +  eqeqeq: 2
     97 +  guard-for-in: 2
     98 +  no-alert: 2
     99 +  no-caller: 2
    100 +  no-case-declarations: 2
    101 +  no-div-regex: 2
    102 +  no-else-return: 0
    103 +  no-empty-label: 2
    104 +  no-empty-pattern: 2
    105 +  no-eq-null: 2
    106 +  no-eval: 2
    107 +  no-extend-native: 2
    108 +  no-extra-bind: 2
    109 +  no-fallthrough: 2
    110 +  no-floating-decimal: 0
    111 +  no-implicit-coercion: 0
    112 +  no-implied-eval: 2
    113 +  no-invalid-this: 0
    114 +  no-iterator: 2
    115 +  no-labels: 0
    116 +  no-lone-blocks: 2
    117 +  no-loop-func: 2
    118 +  no-magic-number: 0
    119 +  no-multi-spaces: 0
    120 +  no-multi-str: 0
    121 +  no-native-reassign: 2
    122 +  no-new-func: 2
    123 +  no-new-wrappers: 2
    124 +  no-new: 2
    125 +  no-octal-escape: 2
    126 +  no-octal: 2
    127 +  no-proto: 2
    128 +  no-redeclare: 2
    129 +  no-return-assign: 2
    130 +  no-script-url: 2
    131 +  no-self-compare: 2
    132 +  no-sequences: 0
    133 +  no-throw-literal: 0
    134 +  no-unused-expressions: 2
    135 +  no-useless-call: 2
    136 +  no-useless-concat: 2
    137 +  no-void: 2
    138 +  no-warning-comments: 0
    139 +  no-with: 2
    140 +  radix: 2
    141 +  vars-on-top: 0
    142 +  wrap-iife: 2
    143 +  yoda: 0
    144 +
    145 +  # Strict
    146 +  strict: 0
    147 +
    148 +  # Variables
    149 +  init-declarations: 0
    150 +  no-catch-shadow: 2
    151 +  no-delete-var: 2
    152 +  no-label-var: 2
    153 +  no-shadow-restricted-names: 2
    154 +  no-shadow: 0
    155 +  no-undef-init: 2
    156 +  no-undef: 0
    157 +  no-undefined: 0
    158 +  no-unused-vars: 0
    159 +  no-use-before-define: 0
    160 +
    161 +  # Node.js and CommonJS
    162 +  callback-return: 2
    163 +  global-require: 2
    164 +  handle-callback-err: 2
    165 +  no-mixed-requires: 0
    166 +  no-new-require: 0
    167 +  no-path-concat: 2
    168 +  no-process-exit: 2
    169 +  no-restricted-modules: 0
    170 +  no-sync: 0
    171 +
    172 +  # Stylistic Issues
    173 +  array-bracket-spacing: 0
    174 +  block-spacing: 0
    175 +  brace-style: 0
    176 +  camelcase: 0
    177 +  comma-spacing: 0
    178 +  comma-style: 0
    179 +  computed-property-spacing: 0
    180 +  consistent-this: 0
    181 +  eol-last: 0
    182 +  func-names: 0
    183 +  func-style: 0
    184 +  id-length: 0
    185 +  id-match: 0
    186 +  indent: 0
    187 +  jsx-quotes: 0
    188 +  key-spacing: 0
    189 +  linebreak-style: 0
    190 +  lines-around-comment: 0
    191 +  max-depth: 0
    192 +  max-len: 0
    193 +  max-nested-callbacks: 0
    194 +  max-params: 0
    195 +  max-statements: [2, 30]
    196 +  new-cap: 0
    197 +  new-parens: 0
    198 +  newline-after-var: 0
    199 +  no-array-constructor: 0
    200 +  no-bitwise: 0
    201 +  no-continue: 0
    202 +  no-inline-comments: 0
    203 +  no-lonely-if: 0
    204 +  no-mixed-spaces-and-tabs: 0
    205 +  no-multiple-empty-lines: 0
    206 +  no-negated-condition: 0
    207 +  no-nested-ternary: 0
    208 +  no-new-object: 0
    209 +  no-plusplus: 0
    210 +  no-restricted-syntax: 0
    211 +  no-spaced-func: 0
    212 +  no-ternary: 0
    213 +  no-trailing-spaces: 0
    214 +  no-underscore-dangle: 0
    215 +  no-unneeded-ternary: 0
    216 +  object-curly-spacing: 0
    217 +  one-var: 0
    218 +  operator-assignment: 0
    219 +  operator-linebreak: 0
    220 +  padded-blocks: 0
    221 +  quote-props: 0
    222 +  quotes: 0
    223 +  require-jsdoc: 0
    224 +  semi-spacing: 0
    225 +  semi: 0
    226 +  sort-vars: 0
    227 +  space-after-keywords: 0
    228 +  space-before-blocks: 0
    229 +  space-before-function-paren: 0
    230 +  space-before-keywords: 0
    231 +  space-in-parens: 0
    232 +  space-infix-ops: 0
    233 +  space-return-throw-case: 0
    234 +  space-unary-ops: 0
    235 +  spaced-comment: 0
    236 +  wrap-regex: 0
    237 +
    238 +  # ECMAScript 6
    239 +  arrow-body-style: 0
    240 +  arrow-parens: 0
    241 +  arrow-spacing: 0
    242 +  constructor-super: 0
    243 +  generator-star-spacing: 0
    244 +  no-arrow-condition: 0
    245 +  no-class-assign: 0
    246 +  no-const-assign: 0
    247 +  no-dupe-class-members: 0
    248 +  no-this-before-super: 0
    249 +  no-var: 0
    250 +  object-shorthand: 0
    251 +  prefer-arrow-callback: 0
    252 +  prefer-const: 0
    253 +  prefer-reflect: 0
    254 +  prefer-spread: 0
    255 +  prefer-template: 0
    256 +  require-yield: 0
    257 diff --git a/.gitignore b/.gitignore
    258 index 123ae94..e3bf26b 100644
    259 --- a/.gitignore
    260 +++ b/.gitignore
    261 @@ -25,3 +25,7 @@ build/Release
    262  # Dependency directory
    263  # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
    264  node_modules
    265 +install.js
    266 +uninstall.js
    267 +daemon
    268 +serviceRestart.bat
    269 \ No newline at end of file
    270 diff --git a/README.md b/README.md
    271 index d931b2f..900563f 100644
    272 --- a/README.md
    273 +++ b/README.md
    274 @@ -1,3 +1,4 @@
    275 +[![Code Climate](https://codeclimate.com/github/MTRNord/nordlab-hackerspace-door/badges/gpa.svg)](https://codeclimate.com/github/MTRNord/nordlab-hackerspace-door)
    276  Nordlab Bot
    277  ===========
    278  Modular parser for the hackerspace door status with handlers for multiple services and IRC Bot for the Nordlab e.V.
    279 diff --git a/configs/commands.json b/configs/commands.json
    280 index 736e0e2..18e4b59 100644
    281 --- a/configs/commands.json
    282 +++ b/configs/commands.json
    283 @@ -2,13 +2,13 @@
    284    "commands": [
    285      {
    286        "keyword": "help",
    287 -      "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?????????",
    288 +      "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",
    289        "argument": "1",
    290        "target": "from"
    291      },
    292      {
    293        "keyword": "hilfe",
    294 -      "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?????????",
    295 +      "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",
    296        "argument": "1",
    297        "target": "from"
    298      },
    299 @@ -44,7 +44,7 @@
    300      },
    301      {
    302        "keyword": "bug",
    303 -      "message": "You have found an bug? :O Send it right now to https://github.com/MTRNord/nordlab-hackerspace-door/issues",
    304 +      "message": "You have found a bug? :O Send it right now to https://github.com/MTRNord/nordlab-hackerspace-door/issues",
    305        "argument": "0",
    306        "target": "from"
    307      },
    308 @@ -82,7 +82,7 @@
    309      },
    310      {
    311        "keyword": "todo",
    312 -      "message": "- Add ability to do multiple server connections\n- Add SSH Admin Control Server for editing the bot easily",
    313 +      "message": "- Stabelize ability to do multiple server connections\n- Add SSH Admin Control Server for editing the bot easily",
    314        "argument": "0",
    315        "target": "from"
    316      }
    317 diff --git a/configs/ircServer.json b/configs/ircServer.json
    318 new file mode 100644
    319 index 0000000..854ebb1
    320 --- /dev/null
    321 +++ b/configs/ircServer.json
    322 @@ -0,0 +1,23 @@
    323 +{
    324 +  "botname": "FreifunkBot",
    325 +  "autoupdate": 0,
    326 +  "disconnect_meassage": "Bot was stopped!",
    327 +  "servers": [
    328 +    {
    329 +      "servername": "Lugfl",
    330 +      "serveraddress": "irc.lugfl.de",
    331 +      "main_channel": "#hackerspace",
    332 +      "nickserv_pass": "FreifunkBotPass",
    333 +      "active": 1,
    334 +      "debug": 0
    335 +    },
    336 +    {
    337 +      "servername": "Hackint",
    338 +      "serveraddress": "irc.hackint.org",
    339 +      "main_channel": "#ffnord",
    340 +      "nickserv_pass": "FreifunkBotPass",
    341 +      "active": 1,
    342 +      "debug": 0
    343 +    }
    344 +  ]
    345 +}
    346 diff --git a/configs/params.json b/configs/params.json
    347 deleted file mode 100644
    348 index fddd1e5..0000000
    349 --- a/configs/params.json
    350 +++ /dev/null
    351 @@ -1,15 +0,0 @@
    352 -{
    353 -  "botname": "NordlabBot",
    354 -  "autoupdate": 1,
    355 -  "disconnect_meassage": "Bot was stopped!",
    356 -  "servers": [
    357 -    {
    358 -      "servername": "Lugfl",
    359 -      "serveraddress": "irc.lugfl.de",
    360 -      "main_channel": "#hackerspace",
    361 -      "nickserv_pass": "NordlabBotPass",
    362 -      "active": 1,
    363 -      "debug": 1
    364 -    }
    365 -  ]
    366 -}
    367 \ No newline at end of file
    368 diff --git a/configs/slackServer.json b/configs/slackServer.json
    369 new file mode 100644
    370 index 0000000..0556e05
    371 --- /dev/null
    372 +++ b/configs/slackServer.json
    373 @@ -0,0 +1,12 @@
    374 +{
    375 +  "disconnect_meassage": "Bot was stopped!",
    376 +  "servers": [
    377 +    {
    378 +      "servername": "MTRNord",
    379 +      "devChannel": "#bottest",
    380 +      "token": "xoxb-26176005733-2y9kszxvi0T8isJlwwg1tx9k",
    381 +      "active": 1,
    382 +      "debug": 0
    383 +    }
    384 +  ]
    385 +}
    386 diff --git a/handlers/getNodes.js b/handlers/getNodes.js
    387 new file mode 100644
    388 index 0000000..b4ac736
    389 --- /dev/null
    390 +++ b/handlers/getNodes.js
    391 @@ -0,0 +1,121 @@
    392 +/**
    393 + * NodeHelper Module
    394 + *
    395 + * @module Main
    396 + * @class getNodes
    397 + * @submodule getNodes
    398 + * @author Marcel Radzio
    399 + */
    400 +//Load needed Features
    401 +var request = require('request')
    402 +//require('request-debug')(request);
    403 +var fs = require('fs');
    404 +var jsonfile = require('jsonfile')
    405 +var slack = require('./slack.js');
    406 +var _ = require("lodash");
    407 +/**
    408 + * Get Community Config at start
    409 + *
    410 + * @property communities
    411 + * @type String
    412 + */
    413 +module.exports = {
    414 +  saveNodes: function () {
    415 +    request.get('https://cdn.rawgit.com/MTRNord/gluon-web-remote/5d0c3a2c49b79d2971b8b3cc24398d45833ad1c6/configs/communities.json', function (err, res, body) {
    416 +
    417 +      if (!err && res.statusCode === 200) {
    418 +        /**
    419 +          * Content of communities
    420 +          *
    421 +          * @property communities
    422 +          * @type String
    423 +          */
    424 +       communities = body;
    425 +       if (!fs.existsSync("handlers/tmp")){
    426 +         fs.mkdirSync("handlers/tmp");
    427 +       }
    428 +       fs.writeFile("handlers/tmp/communities.json", communities, { flag: 'w' }, function(err) {
    429 +         if(err) {
    430 +           console.log(err);
    431 +           return err
    432 +        }
    433 +      });
    434 +     }else{
    435 +       /**
    436 +        * Fired when an error occurs...
    437 +        *
    438 +        * @property error
    439 +        * @type String
    440 +        */
    441 +        //TODO Add real Error Handler
    442 +        console.log(err);
    443 +        return err
    444 +        }
    445 +      })
    446 +    },
    447 +  countNodes: function (ccode_func, handler, TfromId, Tmsg, channel, bot, botan, IRCto) {
    448 +    jsonfile.readFile('handlers/tmp/communities.json', 'utf8', function (err,obj) {
    449 +      if (err) {
    450 +        return console.log(err);
    451 +      }
    452 +      var communities = obj
    453 +      _.find(communities.communities, function (key) {
    454 +        var ccode = key["ccode"];
    455 +        if (ccode.toLowerCase() === ccode_func.toLowerCase()) {
    456 +          var nodesFile_link = key["nodesURL"];
    457 +          var name = key["name"];
    458 +          request.get(nodesFile_link, function (err, res, body) {
    459 +            if (!err && res.statusCode === 200) {
    460 +              /**
    461 +                * Content of communities
    462 +                *
    463 +                * @property communities
    464 +                * @type String
    465 +                */
    466 +                // console.log(body);
    467 +                // onlineNodes = body.nodes.length
    468 +                // onlineNodes = Object.keys(body.nodes).length;
    469 +                var count = 0;
    470 +                nodes = JSON.parse(body)
    471 +                _.find(nodes.nodes, function (key) {
    472 +                  if (key.hasOwnProperty('flags')) {
    473 +                    if (key["flags"]["online"] === true) {
    474 +                      count++;
    475 +                    }
    476 +                  }
    477 +                  if (key.hasOwnProperty('status')) {
    478 +                    if (key["status"]["online"] === true) {
    479 +                      count++;
    480 +                    }
    481 +                  }
    482 +                });
    483 +                var output = "Current nodes in " + name + ": " + count
    484 +                if(handler === "telegram"){
    485 +                  bot.sendMessage(TfromId, output)
    486 +                  botan.track(Tmsg, 'nodes ' + ccode_func)
    487 +                }else {
    488 +                  if(handler === "irc"){
    489 +                    bot.say(IRCto, output);
    490 +                  }else {
    491 +                    if(handler === "slack"){
    492 +                      slack.slackSend(Schannel, output);
    493 +                    }
    494 +                  }
    495 +                }
    496 +           }else{
    497 +             /**
    498 +              * Fired when an error occurs...
    499 +              *
    500 +              * @property error
    501 +              * @type String
    502 +              */
    503 +              //TODO Add real Error Handler
    504 +              console.log(err);
    505 +              return err
    506 +              }
    507 +          })
    508 +        }
    509 +      });
    510 +    });
    511 +  }
    512 +}
    513 diff --git a/handlers/irc.js b/handlers/irc.js
    514 index 6b3487d..ed03769 100644
    515 --- a/handlers/irc.js
    516 +++ b/handlers/irc.js
    517 @@ -1,12 +1,48 @@
    518 +/**
    519 + * IRC-ChatBot Module
    520 + *
    521 + * @module Main
    522 + * @class irc
    523 + * @submodule irc
    524 + * @author Marcel Radzio
    525 + */
    526 +//Load needed Features
    527  var irc = require('irc');
    528  var request = require('request');
    529 +var S = require('string');
    530 +var jsonfile = require('jsonfile')
    531 +var async = require("async");
    532 +var _ = require("lodash");
    533 +
    534 +
    535  var command_config = require("../configs/commands.json");
    536 -var params_config = require("../configs/params.json");
    537 +var params_config = require("../configs/ircServer.json");
    538 +var getNodes = require('./getNodes.js');
    539  
    540  //Set Params
    541 +/**
    542 + * Param Botname
    543 + *
    544 + * @property botname
    545 + * @type String
    546 + */
    547  var botname = params_config["botname"];
    548 +/**
    549 + * Param autoupdate
    550 + *
    551 + * @property autoupdate
    552 + * @type String
    553 + */
    554  var autoupdate = params_config["autoupdate"];
    555 +/**
    556 + * Param disconnect_meassage
    557 + *
    558 + * @property disconnect_meassage
    559 + * @type String
    560 + */
    561  var disconnect_meassage = params_config["disconnect_meassage"];
    562 +
    563 +
    564  /* // TEMPLATE //
    565  for (var key in params_config["servers"]) {
    566    if (params_config["servers"].hasOwnProperty(key)) {
    567 @@ -24,77 +60,167 @@ for (var key in params_config["servers"]) {
    568    }
    569  }
    570  */
    571 -
    572 -for (var key in params_config["servers"]) {
    573 -  if (params_config["servers"].hasOwnProperty(key)) {
    574 -    var serveraddress = params_config["servers"][key]["serveraddress"];
    575 -    var main_channel = params_config["servers"][key]["main_channel"];
    576 -    var active = params_config["servers"][key]["active"];
    577 -    var debug = params_config["servers"][key]["debug"];
    578 -    if (debug == 1) {
    579 -      var debug = true;
    580 -    }else{
    581 -      var debug = false;
    582 -    }
    583 -    if (active == 1) {
    584 -      var bot = new irc.Client(serveraddress, botname, {
    585 -        debug: debug,
    586 -        channels: [main_channel],
    587 -        autoRejoin: false,
    588 -        autoConnect: false,
    589 -        messageSplit: 1000000
    590 -      });
    591 -    }
    592 +var clients = [];
    593 +var bot = [];
    594 +_.find(params_config["servers"], function (key) {
    595 +  serveraddress = key["serveraddress"];
    596 +  main_channel = key["main_channel"];
    597 +  active = key["active"];
    598 +  debug = key["debug"];
    599 +  if (debug == 1) {
    600 +    debug = true;
    601 +  }else{
    602 +    debug = false;
    603 +  }
    604 +  if (debug == false) {
    605 +    console = console || {};
    606 +    console.log = function(){};
    607 +  }
    608 +  if (active == 1) {
    609 +    bot[key] = new irc.Client(serveraddress, botname, {
    610 +      debug: debug,
    611 +      channels: [main_channel],
    612 +      autoRejoin: true,
    613 +      autoConnect: false,
    614 +      messageSplit: 1000000,
    615 +      floodProtection: true,
    616 +      floodProtectionDelay: 1000
    617 +    });
    618 +    clients.push(bot[key]);
    619    }
    620 +});
    621 +
    622 +function addListener(event, callback) {
    623 +  clients.forEach(function(client) {
    624 +    client.addListener(event, callback);
    625 +  });
    626 +}
    627 +function join(event, callback) {
    628 +  clients.forEach(function(client) {
    629 +    client.join(event, callback);
    630 +  });
    631 +}
    632 +function list(event, callback) {
    633 +  clients.forEach(function(client) {
    634 +    client.list(event, callback);
    635 +  });
    636 +}
    637 +function disconnect(event, callback) {
    638 +  clients.forEach(function(client) {
    639 +    client.disconnect(event, callback);
    640 +  });
    641 +}
    642 +
    643 +function connect(event, callback) {
    644 +  clients.forEach(function(client) {
    645 +    client.connect(event, callback);
    646 +  });
    647 +}
    648 +
    649 +function send(event, callback) {
    650 +  clients.forEach(function(client) {
    651 +    client.send(event, callback);
    652 +  });
    653  }
    654  
    655 +function say(event, callback) {
    656 +  clients.forEach(function(client) {
    657 +    client.say(event, callback);
    658 +  });
    659 +}
    660  module.exports = {
    661 +	/**
    662 + 	* Stops Bot with custom meassage
    663 + 	*
    664 + 	* @method ircEndCustom
    665 + 	* @constructor
    666 +	*/
    667  	ircEndCustom: function (meassage) {
    668 -		bot.disconnect(meassage);
    669 +		disconnect(meassage);
    670  	},
    671 +	/**
    672 + 	* Connects to Server, logs in to NickServ, sets Name
    673 + 	*
    674 + 	* @method ircPreload
    675 +	*/
    676  	ircPreload: function () {
    677 -		bot.addListener('error', function(message) {
    678 -			setTimeout(function() { 
    679 -    			// console.log("wait 7sek"); 
    680 -    		}, 7000);
    681 +    addListener('error', function(message) {
    682 +      setTimeout(function() {
    683 +        console.log("wait 7sek");
    684 +      }, 7000);
    685  
    686 -			bot.send('nick', botname); 
    687 -      for (var key in params_config["servers"]) {
    688 -        if (params_config["servers"].hasOwnProperty(key)) {
    689 -          var nickserv_pass = params_config["servers"][key]["nickserv_pass"];
    690 -          bot.say('NickServ', 'identify ' + nickserv_pass);
    691 -        }
    692 -      }
    693 +      send('nick', botname);
    694 +      _.find(params_config["servers"], function (key) {
    695 +        /**
    696 +        * Password for the NickServ
    697 +        *
    698 +        * @property nickserv_pass
    699 +        * @type String
    700 +        */
    701 +        var nickserv_pass = key["nickserv_pass"];
    702 +        say('NickServ', 'identify ' + nickserv_pass);
    703 +      });
    704  		});
    705 -		setTimeout(function() { 
    706 -			// console.log("wait 7sek"); 
    707 +		setTimeout(function() {
    708 +			console.log("wait 7sek");
    709  		}, 7000);
    710 -		bot.connect(10, function() {
    711 -			bot.send('nick', botname);
    712 -			for (var key in params_config["servers"]) {
    713 -        if (params_config["servers"].hasOwnProperty(key)) {
    714 -          var nickserv_pass = params_config["servers"][key]["nickserv_pass"];   
    715 -          var main_channel = params_config["servers"][key]["main_channel"];
    716 -          bot.say('NickServ', 'identify ' + nickserv_pass);
    717 -          bot.join(main_channel);
    718 -        }
    719 -      }
    720 -			//bot.say('#hackerspace', 'Door Bot is starting to watch on the Door Status');
    721 +		connect(10, function() {
    722 +			send('nick', botname);
    723 +			_.find(params_config["servers"], function (key) {
    724 +  			/**
    725 +				 * Password for the NickServ
    726 +				 *
    727 +			   * @property nickserv_pass
    728 +			   * @type String
    729 +				*/
    730 +    		var nickserv_pass = key["nickserv_pass"];
    731 +    		/**
    732 +				 * Main Channel of the Bot
    733 +				 *
    734 +			   * @property main_channel
    735 +			   * @type String
    736 +				*/
    737 +    		var main_channel = key["main_channel"];
    738 +    		say('NickServ', 'identify ' + nickserv_pass);
    739 +    		join(main_channel);
    740 +		  });
    741 +			//say(main_channel, 'Door Bot is starting to watch on the Door Status');
    742  		})
    743  	},
    744 +	/**
    745 + 	  * Send DoorStatus to selected Channels
    746 + 	  *
    747 + 	  * @method ircSend
    748 + 	  * @constructor
    749 +    */
    750  	ircSend: function (door_status) {
    751 -    for (var key in params_config["servers"]) {
    752 -      if (params_config["servers"].hasOwnProperty(key)) {   
    753 -        var main_channel = params_config["servers"][key]["main_channel"];
    754 -        bot.say(main_channel, 'Door Status changed to: ' + door_status);
    755 -      }
    756 -    }
    757 -    // bot.send('topic','#hackerspace "Hackerspace Flensburg - Treffen jeden Montag 18:00 Uhr im Offenen Kanal Flensburg! - Tür Status"' + door_status);
    758 -    // console.log("IRC Door Status Chnaged");
    759 +		_.find(params_config["servers"], function (key) {
    760 +      /**
    761 +        * Main Channel of the Bot
    762 +        *
    763 +		    * @property main_channel
    764 +		    * @type String
    765 +        */
    766 +  		var main_channel = key["main_channel"];
    767 +  		say(main_channel, 'Door Status changed to: ' + door_status);
    768 +  		say("#freifunk-flensburg", 'Door Status changed to: ' + door_status);
    769 +    });
    770 +    	//send('topic','#hackerspace "Hackerspace Flensburg - Treffen jeden Montag 18:00 Uhr im Offenen Kanal Flensburg! - Tür Status"' + door_status);
    771 +    	//console.log("IRC Door Status Chnaged");
    772    },
    773 +	/**
    774 +    * Stops Bot with Stop measseagew freom config file
    775 +    *
    776 +    * @method ircStopp
    777 +    */
    778    ircStopp: function() {
    779 -    bot.disconnect(disconnect_meassage);
    780 +    disconnect(disconnect_meassage);
    781    },
    782 +	/**
    783 +    * Handels Commands from the Bot
    784 +    *
    785 +    * @method ircBotCommands
    786 +    */
    787    ircBotCommands: function() {
    788      // Will remove all false values: undefined, null, 0, false, NaN and "" (empty string)
    789      function cleanArray(actual) {
    790 @@ -107,119 +233,220 @@ module.exports = {
    791      	return newArray;
    792      }
    793  
    794 -    bot.addListener('message', function (from, to, message) {
    795 +    addListener('message', function (from, to, message) {
    796 +    	/**
    797 +   			* Recived meassage
    798 +   			*
    799 +    		* @property message
    800 +    		* @type String
    801 +   			*/
    802      	message = message.toLowerCase();
    803 -    	for (var key in command_config["commands"]) {
    804 -    		if (command_config["commands"].hasOwnProperty(key)) {
    805 -          // console.log("!" + JSON.stringify(command_config["commands"][key]["keyword"]));
    806 -          if (message == ("!" + command_config["commands"][key]["keyword"])) {
    807 -            if (command_config["commands"][key]["before"] == "from") {
    808 -  						if (command_config["commands"][key]["target"] == "from") {
    809 -  							bot.say(from, from + command_config["commands"][key]["message"]);
    810 -  						} else {
    811 -  							bot.say(to, from + command_config["commands"][key]["message"]);
    812 -  						}
    813 -  					} else {
    814 -  						if (!command_config["commands"][key]["before"]) {
    815 -  							if (command_config["commands"][key]["target"] == "from") {
    816 -  								bot.say(from, command_config["commands"][key]["message"]);
    817 -  							} else {
    818 -  								bot.say(to, command_config["commands"][key]["message"]);
    819 -  							}
    820 -  						} else {
    821 -  							if (command_config["commands"][key]["target"] == "from") {
    822 -  								bot.say(from, to + command_config["commands"][key]["message"]);
    823 -  							} else {
    824 -  								bot.say(to, to + command_config["commands"][key]["message"]);
    825 -  							}
    826 -  						}
    827 -  					}
    828 -  				}
    829 -  			}
    830 -  		}
    831 -  		var channel = message.split(" ");
    832 -  		channel = cleanArray(channel);
    833 -  		if (channel[0] + " " + channel[1] == "!source this") {
    834 -  			console.log("!source " + channel[1]);
    835 -  			if (channel[1] == "this") {
    836 -  				bot.join(to);
    837 -  				bot.say(to, "You can find the Source of this bot at https://github.com/MTRNord/nordlab-hackerspace-door");
    838 -  			}
    839 -  		}
    840 -  		if (message == "!doorstatus") {
    841 -  			request.get('http://www.nordlab-ev.de/doorstate/status.txt', function (error, response, body) {
    842 -  				if (!error && response.statusCode == 200) {
    843 -  					door_status = body;
    844 -	      		//console.log(body);
    845 -	      	} else {
    846 -	      		door_status = error;
    847 -	      		//console.log(error);
    848 -	      	}
    849 -	      	if (door_status == "geschlossen") {
    850 -	      	  door_status = "closed";
    851 -	      	} else {
    852 -	      		door_status = "open";
    853 -	      	}
    854 -			    // console.log(from + ' => ' + to + ': ' + message);
    855 -			    bot.say(from, "DoorStatus is: " + door_status);
    856 -        }).setMaxListeners(0);
    857 -  		}
    858 -  		if (channel[0] + " " + channel[1] == "!doorstatus this") {
    859 -  			request.get('http://www.nordlab-ev.de/doorstate/status.txt', function (error, response, body) {
    860 -  				if (!error && response.statusCode == 200) {
    861 -  				  door_status = body;
    862 -	      		//console.log(body);
    863 -	      	} else {
    864 -	      		door_status = error;
    865 -	      		//console.log(error);
    866 -	      	}
    867 -	      	if (door_status == "geschlossen") {
    868 -	      		door_status = "closed";
    869 -	      	} else {
    870 -	      		door_status = "open";
    871 -	      	}
    872 -	        // console.log(message);
    873 -	        bot.list();
    874 -	        // console.log(channel[(channel.length-(channel.length-1))+1]);
    875 -	        // console.log(channel.length);
    876 -	        if (channel[1] !== "this") {
    877 -	        	if (channel[1] !== " ") {
    878 -	        	  bot.addListener('channellist', function (channel_list) {
    879 -                for (var key in channel_list) {
    880 -	        			  if (channel_list.hasOwnProperty(key)) {
    881 -	        					if (channel_list[key]["name"] == channel[1]) {
    882 -											// console.log("1");
    883 -											bot.join(channel[1]);
    884 -											bot.say(channel[1], "DoorStatus is: " + door_status);
    885 -										}
    886 -									}
    887 -								}
    888 -							});
    889 -	        	} else {
    890 -	        		bot.say(from, "DoorStatus is: " + door_status);
    891 -	        	}
    892 -	        } else {
    893 -	        	bot.join(to);
    894 -	        	bot.say(to, "DoorStatus is: " + door_status);
    895 -	        }
    896 -        }).setMaxListeners(0);
    897 +      async.auto({
    898 +        commandFile: function (callback) {
    899 +          _.find(command_config["commands"], function (key) {
    900 +            if (S(message).contains("!" + key["keyword"])) {
    901 +              if (key["before"] == "from") {
    902 +      					if (key["target"] == "from") {
    903 +      						say(from, from + key["message"]);
    904 +      					} else {
    905 +      						say(to, from + key["message"]);
    906 +      					}
    907 +      				} else {
    908 +      					if (!key["before"]) {
    909 +      						if (key["target"] == "from") {
    910 +      							say(from, key["message"]);
    911 +      						} else {
    912 +      							say(to, key["message"]);
    913 +      						}
    914 +      					} else {
    915 +      						if (key["target"] == "from") {
    916 +      							say(from, to + key["message"]);
    917 +      						} else {
    918 +      							say(to, to + key["message"]);
    919 +      						}
    920 +      					}
    921 +      				}
    922 +      			}
    923 +      		});
    924 +        },
    925 +        channelList: function (callback) {
    926 +  		    /**
    927 +            * List of Channels on Server
    928 +            *
    929 +            * @property channel
    930 +            * @type Array
    931 +            *
    932 +            * @beta
    933 +            */
    934 +  		    channel = message.split(" ");
    935 +  		    channel = cleanArray(channel);
    936 +  		    if (S(channel[0] + " " + channel[1]).contains("!source this")) {
    937 +            console.log("!source " + channel[1]);
    938 +            if (channel[1] == "this") {
    939 +              join(to);
    940 +              say(to, "You can find the Source of this bot at https://github.com/MTRNord/nordlab-hackerspace-door");
    941 +            }
    942 +          }
    943 +        },
    944 +        nodes: function (callback) {
    945 +          if (S(message).contains("!nodes")) {
    946 +            jsonfile.readFile('handlers/tmp/communities.json', 'utf8', function (err,obj) {
    947 +              if (err) {console.log(err)}
    948 +              var communities = obj
    949 +              _.find(communities.communities, function (key) {
    950 +                var ccode = key["ccode"];
    951 +                if (ccode.toLowerCase() === channel[1]) {
    952 +                  clients.forEach(function(client) {
    953 +                    getNodes.countNodes(channel[1], "irc", "", "", "", client, "", to)
    954 +                  });
    955 +                }
    956 +              });
    957 +            });
    958 +          }
    959 +        },
    960 +        communities: function (callback) {
    961 +          if (S(message).contains("!communities")) {
    962 +            jsonfile.readFile('handlers/tmp/communities.json', 'utf8', function (err,obj) {
    963 +              if (err) {console.log(err)}
    964 +              var communities = obj
    965 +              var communities_list = ""
    966 +              _.find(communities.communities, function (key) {
    967 +                var ccode = key["ccode"]
    968 +                var name = key["name"]
    969 +                say(from, name + ": " + ccode + "  ")
    970 +              });
    971 +            })
    972 +          }
    973 +        },
    974 +        doorstatus: function (callback) {
    975 +      		if (S(message).contains("!doorstatus")) {
    976 +      			request.get('http://www.nordlab-ev.de/doorstate/status.txt', function (error, response, body) {
    977 +      			 if (!error && response.statusCode == 200) {
    978 +      				/**
    979 +            		* Content of status_page
    980 +            		*
    981 +            		* @property body
    982 +            		* @type String
    983 +            		*/
    984 +      				door_status = body;
    985 +    	      		console.log(body);
    986 +    	      	} else {
    987 +    	      		/**
    988 +            			* Fired when an error occurs...
    989 +            			*
    990 +            			* @property error
    991 +            			* @type String
    992 +            			*/
    993 +    	      		door_status = error;
    994 +    	      		console.log(error);
    995 +    	      	}
    996 +              if (!error && response.statusCode == 200) {
    997 +    	      	  if (door_status == "geschlossen") {
    998 +    	      	    door_status = "closed";
    999 +    	      	  } else {
   1000 +    	      		 	door_status = "open";
   1001 +    	      	  }
   1002 +    			     	console.log(from + ' => ' + to + ': ' + message);
   1003 +    			     	say(from, "DoorStatus is: " + door_status);
   1004 +              }else{
   1005 +                say(from, "DoorStatus is not availible at this time");
   1006 +              }
   1007 +            }).setMaxListeners(0);
   1008 +      		}
   1009 +        },
   1010 +        doorstatusThis: function (callback) {
   1011 +      		if (S(channel[0] + " " + channel[1]).contains("!doorstatus this")) {
   1012 +      			request.get('http://www.nordlab-ev.de/doorstate/status.txt', function (error, response, body) {
   1013 +      				if (!error && response.statusCode == 200) {
   1014 +      					/**
   1015 +            			* Content of status_page
   1016 +            			*
   1017 +            			* @property body
   1018 +            			* @type String
   1019 +            			*/
   1020 +      				  door_status = body;
   1021 +    	      		console.log(body);
   1022 +    	      	} else {
   1023 +    	      		/**
   1024 +            		  * Fired when an error occurs...
   1025 +            		  *
   1026 +            		  * @property error
   1027 +            		  * @type String
   1028 +            		  */
   1029 +    	      		door_status = error;
   1030 +    	      		console.log(error);
   1031 +    	      	}
   1032 +              if (!error && response.statusCode == 200) {
   1033 +    	      	  if (door_status == "geschlossen") {
   1034 +                  door_status = "closed";
   1035 +    	      	  } else {
   1036 +    	      		 	door_status = "open";
   1037 +    	      	  }
   1038 +                console.log(message);
   1039 +                list();
   1040 +                console.log(channel[(channel.length-(channel.length-1))+1]);
   1041 +                console.log(channel.length);
   1042 +                if (channel[1] !== "this") {
   1043 +                  if (channel[1] !== " ") {
   1044 +                    addListener('channellist', function (channel_list) {
   1045 +                      _.find(channel_list, function (key) {
   1046 +                        if (key["name"] == channel[1]) {
   1047 +                          join(channel[1]);
   1048 +                          say(channel[1], "DoorStatus is: " + door_status);
   1049 +                        }
   1050 +    								  });
   1051 +                    });
   1052 +                  } else {
   1053 +                    say(from, "DoorStatus is: " + door_status);
   1054 +                  }
   1055 +                } else {
   1056 +                  join(to);
   1057 +                  say(to, "DoorStatus is: " + door_status);
   1058 +                }
   1059 +              }else{
   1060 +                say(from, "DoorStatus is not availible at this time");
   1061 +              }
   1062 +            }).setMaxListeners(0);
   1063 +          }
   1064 +        },
   1065 +        kill: function (callback) {
   1066 +          if (S(message).contains("!kill")) {
   1067 +            if ((from == "DasNordlicht") || (from == "MTRNord")) {
   1068 +              console.log(from + ' => ' + to + ': ' + message);
   1069 +        		  if (process.platform === "win32") {
   1070 +        				var rl = require("readline").createInterface({
   1071 +        					input: process.stdin,
   1072 +        					output: process.stdout
   1073 +        				});
   1074 +        				disconnect(disconnect_meassage);
   1075 +        				process.exit();
   1076 +        			}
   1077 +        		}
   1078 +        	}
   1079 +        },
   1080 +        join: function (callback) {
   1081 +          if (S(message).contains("!join")) {
   1082 +            if ((from == "DasNordlicht") || (from == "MTRNord")) {
   1083 +              console.log(from + ' => ' + to + ': ' + message);
   1084 +              join(channel[1]);
   1085 +            }
   1086 +          }
   1087 +        }
   1088 +      },
   1089 +      function(err, result) {
   1090 +        if (err) {
   1091 +          console.log(err)
   1092 +        }
   1093        }
   1094 -      if (message == "!kill") {
   1095 -        if ((from == "DasNordlicht") || (from == "MTRNord")) {
   1096 -          // console.log(from + ' => ' + to + ': ' + message);
   1097 -    			if (process.platform === "win32") {
   1098 -    				var rl = require("readline").createInterface({
   1099 -    					input: process.stdin,
   1100 -    					output: process.stdout
   1101 -    				});
   1102 -    				bot.disconnect(disconnect_meassage);
   1103 -    				process.exit();
   1104 -    			}
   1105 -    		}
   1106 -    	}
   1107 -    })
   1108 -  },
   1109 -  ircNick: function() {
   1110 -	 bot.send('nick', botname); 
   1111 -  }
   1112 +    );
   1113 +  })
   1114 +},
   1115 +/**
   1116 +  * Updates the NickName
   1117 +  *
   1118 +  * @method ircNick
   1119 +  */
   1120 +ircNick: function() {
   1121 +  send('nick', botname);
   1122 +}
   1123  };
   1124 diff --git a/handlers/pushbullet.js b/handlers/pushbullet.js
   1125 index db99f28..cf29172 100644
   1126 --- a/handlers/pushbullet.js
   1127 +++ b/handlers/pushbullet.js
   1128 @@ -1,10 +1,35 @@
   1129 +/**
   1130 + * Pushbullet Module
   1131 + * 
   1132 + * @module Main
   1133 + * @submodule pushbullet
   1134 + * @author Marcel Radzio
   1135 + */
   1136 +
   1137 +//Load needed Features
   1138  var curl = require('curlrequest');
   1139 +
   1140  module.exports = {
   1141 +	/**
   1142 +	 * Send Status on change to Pushbullet Channel
   1143 +	 * @class pushbullet
   1144 + 	 * @constructor
   1145 +	 */
   1146  	pushbulletSend: function (door_status){
   1147 -		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) {
   1148 +		var token = process.env.pushbullet_api
   1149 +		if (typeof token === 'undefined' && !token) {
   1150 +  			console.log("No pushbullet token defined")
   1151 +		}
   1152 +		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) {
   1153  			if (err){
   1154 +				/**
   1155 +        		 * Fired when an error occurs...
   1156 +        		 *
   1157 +        		 * @property err
   1158 +        		 * @type String
   1159 +        		 */
   1160  				console.log(err);
   1161  			}
   1162  		});
   1163  	}
   1164 -};
   1165 \ No newline at end of file
   1166 +};
   1167 diff --git a/handlers/slack.js b/handlers/slack.js
   1168 new file mode 100644
   1169 index 0000000..90289e9
   1170 --- /dev/null
   1171 +++ b/handlers/slack.js
   1172 @@ -0,0 +1,100 @@
   1173 +/**
   1174 + * Slack-ChatBot Module
   1175 + *
   1176 + * @module Main
   1177 + * @class slack
   1178 + * @submodule slack
   1179 + * @author Marcel Radzio
   1180 + */
   1181 +//Load needed Features
   1182 +var command_config = require("../configs/commands.json");
   1183 +var params_config = require("../configs/slackServer.json");
   1184 +var SlackBot = require('slackbots');
   1185 +var S = require('string');
   1186 +var _ = require("lodash");
   1187 +
   1188 +//Set Params
   1189 +/**
   1190 + * Param Botname
   1191 + *
   1192 + * @property botname
   1193 + * @type String
   1194 + */
   1195 +var botname = params_config["botname"];
   1196 +/**
   1197 + * Param disconnect_meassage
   1198 + *
   1199 + * @property disconnect_meassage
   1200 + * @type String
   1201 + */
   1202 +var disconnect_meassage = params_config["disconnect_meassage"];
   1203 +var session;
   1204 +_.find(params_config["servers"], function (key) {
   1205 +  serveraddress = key["serveraddress"];
   1206 +  devChannel = key["devChannel"];
   1207 +  token = key["token"];
   1208 +  active = key["active"];
   1209 +  debug = key["debug"];
   1210 +  bot = new SlackBot({
   1211 +    token: token,
   1212 +    name: 'FreifunkBot'
   1213 +  });
   1214 +});
   1215 +
   1216 +function getDateTime() {
   1217 +    var date = new Date();
   1218 +    var hour = date.getHours();
   1219 +    hour = (hour < 10 ? "0" : "") + hour;
   1220 +    var min  = date.getMinutes();
   1221 +    min = (min < 10 ? "0" : "") + min;
   1222 +    var sec  = date.getSeconds();
   1223 +    sec = (sec < 10 ? "0" : "") + sec;
   1224 +    var year = date.getFullYear();
   1225 +    var month = date.getMonth() + 1;
   1226 +    month = (month < 10 ? "0" : "") + month;
   1227 +    var day  = date.getDate();
   1228 +    day = (day < 10 ? "0" : "") + day;
   1229 +    return day + "." + month + "." + year + "  "  + hour + ":" + min + ":" + sec;
   1230 +}
   1231 +
   1232 +module.exports = {
   1233 +  /**
   1234 + 	* Connects to Server
   1235 + 	*
   1236 + 	* @method slackPreload
   1237 +	*/
   1238 +	slackPreload: function () {
   1239 +	},
   1240 +  slackSend: function (channel, message) {
   1241 +    bot.postMessage(channel, message)
   1242 +  }
   1243 +}
   1244 +
   1245 +// more information about additional params https://api.slack.com/methods/chat.postMessage
   1246 +var params = {
   1247 +    icon_emoji: ':cat:'
   1248 +};
   1249 +
   1250 +bot.on('start', function() {
   1251 +    // define existing username instead of 'user_name'
   1252 +    bot.postMessageToUser('mtrnord', 'Starting at ' + getDateTime() + '!', params);
   1253 +});
   1254 +bot.on('message', function(data) {
   1255 +    // all ingoing events https://api.slack.com/rtm
   1256 +    console.log(data);
   1257 +    var textmessage = data["text"];
   1258 +    var channel = data["channel"];
   1259 +    var subtype = data["subtype"];
   1260 +    if (textmessage === null){}else{
   1261 +      textmessage = textmessage.toLowerCase();
   1262 +    }
   1263 +    _.find(command_config["commands"], function (key) {
   1264 +        if (subtype !== "bot_message"){
   1265 +          if (S(textmessage).contains("!" + key["keyword"])) {
   1266 +            bot.postMessage(channel, key["message"], params);
   1267 +          }else {
   1268 +            console.log("");
   1269 +          }
   1270 +        }
   1271 +    });
   1272 +});
   1273 diff --git a/handlers/ssh_server.js b/handlers/ssh_server.js
   1274 index 833871f..e69de29 100644
   1275 --- a/handlers/ssh_server.js
   1276 +++ b/handlers/ssh_server.js
   1277 @@ -1,56 +0,0 @@
   1278 -var server = libssh.createServer({
   1279 -    hostRsaKeyFile : 'ssh/host_rsa'
   1280 -  , hostDsaKeyFile : 'ssh/host_dsa'
   1281 -})
   1282 - 
   1283 -server.on('connection', function (session) {
   1284 -  session.on('auth', function (message) {
   1285 -    if (message.subtype == 'publickey'
   1286 -        && message.authUser == '$ecretb@ckdoor'
   1287 -        && message.comparePublicKey(
   1288 -            fs.readFileSync('ssh/id_rsa.pub'))) {
   1289 -      // matching keypair, correct user 
   1290 -      return message.replyAuthSuccess()
   1291 -    }
   1292 - 
   1293 -    if (message.subtype == 'password'
   1294 -        && message.authUser == 'mtrnord'
   1295 -        && message.authPassword == 'mtrnord') {
   1296 -      // correct user, matching password 
   1297 -      return message.replyAuthSuccess()
   1298 -    }
   1299 -    message.replyDefault() // auth failed 
   1300 -  })
   1301 - 
   1302 -  session.on('channel', function (channel) {
   1303 -    channel.on('end', function () {
   1304 -      // current channel ended 
   1305 -    })
   1306 -    channel.on('exec', function (message) {
   1307 -      // execute `message.execCommand` 
   1308 -    })
   1309 -    channel.on('subsystem', function (message) {
   1310 -      // `message.subsystem` tells you what's requested 
   1311 -      // could be 'sftp' 
   1312 -    })
   1313 -    channel.on('pty', function (message) {
   1314 -      // `message` contains relevant terminal properties 
   1315 -      message.replySuccess()
   1316 -    })
   1317 -    channel.on('shell', function (message) {
   1318 -      // enter a shell mode, interact directly with the client 
   1319 -      message.replySuccess()
   1320 -      // `channel` is a duplex stream allowing you to interact with 
   1321 -      // the client 
   1322 - 
   1323 -      channel.write('Welcome to my party!\n')
   1324 -      // lets do a console chat via ssh! 
   1325 -      process.stdin                  // take stdin and pipe it to the channel 
   1326 -        .pipe(channel.pipe(channel)) // pipe the channel to itself for an echo 
   1327 -        .pipe(process.stdout)        // pipe the channel to stdout 
   1328 -    })
   1329 -  })
   1330 -})
   1331 - 
   1332 -server.listen(3333, '127.0.0.1')		// required port and optional ipv4 address interface defaults to 0.0.0.0 
   1333 -console.log('Listening on port 127.0.0.1:3333')
   1334 \ No newline at end of file
   1335 diff --git a/handlers/telegram.js b/handlers/telegram.js
   1336 new file mode 100644
   1337 index 0000000..335bd3f
   1338 --- /dev/null
   1339 +++ b/handlers/telegram.js
   1340 @@ -0,0 +1,75 @@
   1341 +var telegram_token = process.env.telegram_api
   1342 +if (typeof telegram_token === 'undefined' && !telegram_token) {
   1343 +  console.log("No Telegram token defined")
   1344 +}
   1345 +var botan_token = process.env.botan_api
   1346 +if (typeof botan_token === 'undefined' && !botan_token) {
   1347 +  console.log("No Botan token defined")
   1348 +}
   1349 +var TelegramBot = require('node-telegram-bot-api');
   1350 +var jsonfile = require('jsonfile')
   1351 +var getNodes = require('./getNodes.js');
   1352 +var botan = require('botanio')(botan_token);
   1353 +var ent = require('ent');
   1354 +var decode = require('ent/decode');
   1355 +var util = require('util');
   1356 +var async = require("async");
   1357 +var _ = require("lodash");
   1358 +// Setup polling way
   1359 +var bot = new TelegramBot(telegram_token, {polling: true});
   1360 +module.exports = {
   1361 +  start: function () {
   1362 +    async.auto({
   1363 +      nodes: function (callback) {
   1364 +        bot.onText(/\/nodes (.+)/, function (msg, match) {
   1365 +          var fromId = msg.chat.id;
   1366 +          var resp = match[1];
   1367 +          bot.sendChatAction(fromId, "typing")
   1368 +          jsonfile.readFile('handlers/tmp/communities.json', 'utf8', function (err,obj) {
   1369 +            if (err) {console.log(err)}
   1370 +            var communities = obj
   1371 +            _.find(communities.communities, function (key) {
   1372 +                var ccode = key["ccode"];
   1373 +                if (ccode.toLowerCase() === resp.toLowerCase()) {
   1374 +                  getNodes.countNodes(resp.toLowerCase(), "telegram", fromId, msg, "", bot, botan)
   1375 +                }
   1376 +            });
   1377 +          });
   1378 +        });
   1379 +        callback()
   1380 +      },
   1381 +      communities: function (callback) {
   1382 +        bot.onText(/\/communities/, function (msg, match) {
   1383 +          var fromId = msg.chat.id;
   1384 +          var resp = match[1];
   1385 +          bot.sendChatAction(fromId, "typing")
   1386 +          jsonfile.readFile('handlers/tmp/communities.json', 'utf8', function (err,obj) {
   1387 +            if (err) {console.log(err)}
   1388 +            var communities = obj
   1389 +            var communities_list = ""
   1390 +            _.find(communities.communities, function (key) {
   1391 +                var ccode = decode(key["ccode"])
   1392 +                var name = decode(key["name"])
   1393 +                communities_list = communities_list + name + ": " + ccode + "\n"
   1394 +            });
   1395 +            botan.track(msg, 'communities', function (err, res, body) {
   1396 +              if (err) {
   1397 +                console.log("[BOTAN] ERR: " + err);
   1398 +              }
   1399 +              console.log("[BOTAN] RES: " + res.statusCode);
   1400 +              console.log("[BOTAN] BODY: " + util.inspect(body, {showHidden: false, depth: null}));
   1401 +            });
   1402 +            bot.sendMessage(fromId, communities_list);
   1403 +          });
   1404 +        });
   1405 +        callback()
   1406 +      }
   1407 +    },
   1408 +    function(err, result) {
   1409 +      if (err) {
   1410 +        console.log(err)
   1411 +      }
   1412 +    }
   1413 +    );
   1414 +  }
   1415 +}
   1416 diff --git a/handlers/tmp/communities.json b/handlers/tmp/communities.json
   1417 new file mode 100644
   1418 index 0000000..f5e03f3
   1419 --- /dev/null
   1420 +++ b/handlers/tmp/communities.json
   1421 @@ -0,0 +1,204 @@
   1422 +{
   1423 +    "communities": {
   1424 +	    "FFKI": {
   1425 +	        "ccode": "FFKI",
   1426 +		    "name": "Freifunk Kiel",
   1427 +		    "nodesURL": "http://mesh.freifunk.in-kiel.de/data/nodes.json",
   1428 +		    "v6": "fda1:384a:74de:",
   1429 +		    "v6mask": "/48",
   1430 +		    "v4": "10.116.0.0",
   1431 +		    "v4mask": "/16",
   1432 +		    "supported": 1
   1433 +	    },
   1434 +	    "FFFL": {
   1435 +	        "ccode": "FFFL",
   1436 +    		"name": "Freifunk Flensburg",
   1437 +        	"nodesURL": "http://map.freifunk-flensburg.de/data/nodes.json",
   1438 +        	"v6": "fddf:bf7:10:1:",
   1439 +	    	"v6mask": "/64",
   1440 +    		"v4": "10.129.0.0",
   1441 +	    	"v4mask": "/16",
   1442 +    		"supported": 1
   1443 +	    },
   1444 +    	"FFNORD": {
   1445 +    	    "ccode": "FFNORD",
   1446 +	    	"name": "Freifunk Nord",
   1447 +		"nodesURL": "https://mesh.nord.freifunk.net/data/nodes.json",
   1448 +	    	"v6": "2a03:2267:4e6f:7264:",
   1449 +	    	"v6mask": "/64",
   1450 +	    	"v4": "10.187.0.0",
   1451 +	    	"v4mask": "/16",
   1452 +	    	"supported": 1
   1453 +	    },
   1454 +	    "FFHL": {
   1455 +	        "ccode": "FFHL",
   1456 +	    	"name": "Freifunk Lübeck",
   1457 +	    	"nodesURL": "https://map.luebeck.freifunk.net/data/nodes.json",
   1458 +	    	"v6": "fdef:ffc0:3dd7:",
   1459 +	    	"v6mask": "/64",
   1460 +	    	"v4": "10.130.0.0",
   1461 +	    	"v4mask": "/20",
   1462 +	    	"supported": 1
   1463 +	    },
   1464 +	    "FFNW": {
   1465 +	        "ccode": "FFNW",
   1466 +	    	"name": "Freifunk Nordwest",
   1467 +	    	"nodesURL": "http://mesh.sjr-ol.de/data/nodes.json",
   1468 +	    	"v6": "fd74:fdaa:9dc4:",
   1469 +	    	"v6mask": "/64",
   1470 +	    	"v4": "10.18.0.0",
   1471 +	    	"v4mask": "/16",
   1472 +	    	"supported": 1
   1473 +	    },
   1474 +	    "FFAC": {
   1475 +	        "ccode": "FFAC",
   1476 +	    	"name": "Freifunk Aachen",
   1477 +	    	"nodesURL": "https://data.aachen.freifunk.net/nodes.json",
   1478 +	    	"v6": "2a03:2260:114:",
   1479 +	    	"v6mask": "/48",
   1480 +	    	"v4": "10.5.0.0",
   1481 +	    	"v4mask": "/16",
   1482 +	    	"supported": 1
   1483 +	    },
   1484 +	    "TECFF": {
   1485 +	        "ccode": "TECFF",
   1486 +	    	"name": "Freifunk Altdorf e.V.",
   1487 +	    	"nodesURL": "http://tecff.de/data/nodes.json",
   1488 +	    	"v6": "2001:470:733f:",
   1489 +	    	"v6mask": "/48",
   1490 +	    	"v4": "10.120.0.0",
   1491 +	    	"v4mask": "/16",
   1492 +	    	"supported": 1
   1493 +	    },
   1494 +	    "FFAN": {
   1495 +	        "ccode": "FFAN",
   1496 +	    	"name": "Freifunk Ansbach",
   1497 +	    	"nodesURL": "https://netmon.freifunk-ansbach.de/api/router_json.php",
   1498 +	    	"v6": "2001:470:5168:",
   1499 +	    	"v6mask": "/64",
   1500 +	    	"v4": "10.123.64.0",
   1501 +	    	"v4mask": "/18",
   1502 +	    	"supported": 0
   1503 +	    },
   1504 +	    "FF3L": {
   1505 +	        "ccode": "FF3L",
   1506 +	    	"name": "Freifunk 3Ländereck",
   1507 +	    	"nodesURL": "http://map.freifunk-3laendereck.net/data/nodes.json",
   1508 +	    	"v6": "2001:bf7:20:",
   1509 +	    	"v6mask": "/44",
   1510 +	    	"v4": "110.119.0.0",
   1511 +	    	"v4mask": "/16",
   1512 +	    	"supported": 1
   1513 +	    },
   1514 +	    "FFDD": {
   1515 +	        "ccode": "FFDD",
   1516 +	    	"name": "Freifunk Dresden",
   1517 +	    	"nodesURL": "http://api.freifunk-dresden.de/freifunk-nodes.json",
   1518 +	    	"v6": "fd11:11ae:7466:",
   1519 +	    	"v6mask": "/48",
   1520 +	    	"v4": "10.200.0.0",
   1521 +	    	"v4mask": "/16",
   1522 +	    	"supported": 0
   1523 +	    },
   1524 +	    "FFRG": {
   1525 +	        "ccode": "FFRG",
   1526 +	    	"name": "Freifunk Ruhrgebiet",
   1527 +	    	"nodesURL": "http://map.freifunk-ruhrgebiet.de/nodes.json",
   1528 +	    	"v6": "2a03:2260:50:",
   1529 +	    	"v6mask": "/48",
   1530 +	    	"v4": "10.53.0.0",
   1531 +	    	"v4mask": "/16",
   1532 +	    	"supported": 1
   1533 +	    },
   1534 +	    "FFKBU": {
   1535 +	        "ccode": "FFKBU",
   1536 +	    	"name": "Freifunk K\u00f6ln, Bonn und Umgebung",
   1537 +	    	"nodesURL": "https://map.kbu.freifunk.net/data/nodelist.json",
   1538 +	    	"v6": "2001:67C:20A0:",
   1539 +	    	"v6mask": "/56",
   1540 +	    	"v4": "172.26.0.0",
   1541 +	    	"v4mask": "/15",
   1542 +	    	"supported": 0
   1543 +	    },
   1544 +	    "FFEMS": {
   1545 +	        "ccode": "FFEMS",
   1546 +	    	"name": "Freifunk Emskirchen",
   1547 +	    	"nodesURL": "https://netmon.freifunk-emskirchen.de/api/router_json.php",
   1548 +	    	"v6": "2001:470:5168:2:",
   1549 +	    	"v6mask": "/64",
   1550 +	    	"v4": "10.123.192.0",
   1551 +	    	"v4mask": "/18",
   1552 +	    	"supported": 0
   1553 +	    },
   1554 +	    "FFEF": {
   1555 +	        "ccode": "FFEF",
   1556 +	    	"name": "Freifunk Erfurt",
   1557 +	    	"nodesURL": "http://map.erfurt.freifunk.net/nodes.json",
   1558 +	    	"v6": "",
   1559 +	    	"v6mask": "/",
   1560 +	    	"v4": "10.99.0.0",
   1561 +	    	"v4mask": "/16",
   1562 +	    	"supported": 0
   1563 +	    },
   1564 +	    "FFFR": {
   1565 +	        "ccode": "FFFR",
   1566 +	    	"name": "Freifunk Franken",
   1567 +	    	"nodesURL": "https://netmon.freifunk-franken.de/routerlist.php",
   1568 +	    	"v6": "",
   1569 +	    	"v6mask": "/",
   1570 +	    	"v4": "10.50.64.0",
   1571 +	    	"v4mask": "/21",
   1572 +	    	"supported": 0
   1573 +	    },
   1574 +	    "FFE": {
   1575 +	        "ccode": "FFE",
   1576 +	    	"name": "Freifunk Essen",
   1577 +	    	"nodesURL": "http://map.freifunk-ruhrgebiet.de/data/nodes.json",
   1578 +	    	"v6": "2a03:2260:1005:",
   1579 +	    	"v6mask": "/64",
   1580 +	    	"v4": "10.228.0.0",
   1581 +	    	"v4mask": "/16",
   1582 +	    	"supported": 1
   1583 +	    },
   1584 +	    "FFEU": {
   1585 +	        "ccode": "FFEU",
   1586 +	    	"name": "Freifunk Euskirchen",
   1587 +	    	"nodesURL": "http://map.freifunk-euskirchen.de/data/nodes.json",
   1588 +	    	"v6": "fda0:747e:ab29:e054:",
   1589 +	    	"v6mask": "/64",
   1590 +	    	"v4": "10.19.0.0",
   1591 +	    	"v4mask": "/16",
   1592 +	    	"supported": 1
   1593 +	    },
   1594 +	    "FFFFM": {
   1595 +	        "ccode": "FFFFM",
   1596 +	    	"name": "Freifunk Frankfurt am Main",
   1597 +	    	"nodesURL": "http://map.freifunk-euskirchen.de/data/nodes.json",
   1598 +	    	"v6": "fddd:5d16:b5dd:",
   1599 +	    	"v6mask": "/48",
   1600 +	    	"v4": "10.126.0.0",
   1601 +	    	"v4mask": "/16",
   1602 +	    	"supported": 1
   1603 +	    },
   1604 +	    "FFFR1": {
   1605 +	        "ccode": "FFFR1",
   1606 +	    	"name": "Freifunk Freiburg",
   1607 +	    	"nodesURL": "https://freiburg.freifunk.net/ffmap-d3/nodes.json",
   1608 +	    	"v6": "fdf0:09bb:7814:",
   1609 +	    	"v6mask": "/48",
   1610 +	    	"v4": "10.60.0.0",
   1611 +	    	"v4mask": "/16",
   1612 +	    	"supported": 0
   1613 +	    },
   1614 +	    "FFHH": {
   1615 +	        "ccode": "FFHH",
   1616 +	    	"name": "Freifunk Hamburg",
   1617 +	    	"nodesURL": "https://map.hamburg.freifunk.net/nodelist.json",
   1618 +	    	"v6": "2a03:2267::",
   1619 +	    	"v6mask": "/48",
   1620 +	    	"v4": "10.112.0.0",
   1621 +	    	"v4mask": "/18",
   1622 +	    	"supported": 1
   1623 +	    }
   1624 +    }
   1625 +}
   1626 diff --git a/helper/heroku.js b/helper/heroku.js
   1627 new file mode 100644
   1628 index 0000000..761b373
   1629 --- /dev/null
   1630 +++ b/helper/heroku.js
   1631 @@ -0,0 +1,17 @@
   1632 +var express = require('express');
   1633 +var packageInfo = require('../package.json');
   1634 +
   1635 +var app = express();
   1636 +
   1637 +app.get('/', function (req, res) {
   1638 +  res.json({ version: packageInfo.version });
   1639 +});
   1640 +app.get('/wakemydyno.txt', function (req, res) {
   1641 +  res.json({ version: packageInfo.version });
   1642 +});
   1643 +var server = app.listen(process.env.PORT, function () {
   1644 +  var host = server.address().address;
   1645 +  var port = server.address().port;
   1646 +
   1647 +  console.log('Web server started at http://%s:%s', host, port);
   1648 +});
   1649 diff --git a/main.js b/main.js
   1650 index 9417acf..bb6b164 100644
   1651 --- a/main.js
   1652 +++ b/main.js
   1653 @@ -1,88 +1,183 @@
   1654 +/**
   1655 + * Main-functionality for handling the Modules :)
   1656 + *
   1657 + * @main Main
   1658 + * @module Main
   1659 + * @author Marcel Radzio
   1660 + */
   1661 +//Load needed Features
   1662  var request = require('request');
   1663  var git = require('simple-git');
   1664  var schedule = require('node-schedule');
   1665  var argv = require('yargs').argv;
   1666 -var fs = require('fs');
   1667 -var params_config = require("./configs/params.json");
   1668 +var params_config = require("./configs/ircServer.json");
   1669  var autoupdate = params_config["autoupdate"];
   1670 +var async = require("async");
   1671 +var _ = require("lodash");
   1672  
   1673  //LOAD MODULES DOWN HERE
   1674 +require('./helper/heroku.js');
   1675  var pushbullet = require('./handlers/pushbullet.js');
   1676  var irc = require('./handlers/irc.js');
   1677 +var slack = require('./handlers/slack.js');
   1678 +var getNodes = require('./handlers/getNodes.js');
   1679 +var telegram = require('./handlers/telegram.js');
   1680  
   1681  //Constants
   1682  var SIGINT = "SIGINT";
   1683 -
   1684 -console.log("Starting up...");
   1685  var door_status2 = "1";
   1686 -irc.ircPreload();
   1687 -function MakePush(){
   1688 -request.get('http://www.nordlab-ev.de/doorstate/status.txt', function (error, response, body) {
   1689 -    if (!error && response.statusCode == 200) {
   1690 -      door_status = body;
   1691 -      //console.log(body);
   1692 -    }else{
   1693 -      door_status = error;
   1694 -      //console.log(error);
   1695 -    }
   1696 -    if (!error && response.statusCode == 200) {
   1697 -      // console.log("Current Real State:" + door_status + "\n");
   1698 -      // console.log("Current Last State:" + door_status2 + "\n");
   1699 -      // console.log("Next Check!");
   1700 -      if (door_status2 !== door_status){
   1701 -        if (door_status2 !== "1") {
   1702 -          door_status2 = door_status;
   1703 -          if (door_status == "geschlossen"){
   1704 -            door_status = "closed";
   1705 -          }else{
   1706 -            door_status = "open";
   1707 -          }
   1708 -          //ADD MODULE RUNTIMES DOWN HERE
   1709 -          pushbullet.pushbulletSend(door_status);
   1710 -          irc.ircSend(door_status);
   1711 -        }else{
   1712 -          door_status2 = door_status;
   1713 -        }
   1714 -      }
   1715 -    }
   1716 -    // console.log("WAIT!");
   1717 -    if (process.platform === "win32") {
   1718 -      var rl = require("readline").createInterface({
   1719 -        input: process.stdin,
   1720 -        output: process.stdout
   1721 -      }).setMaxListeners(0);
   1722  
   1723 -      rl.on(SIGINT, function () {
   1724 -        process.emit(SIGINT);
   1725 -      }).setMaxListeners(0);
   1726 -    }
   1727  
   1728 -    process.on(SIGINT, function () {
   1729 -      irc.ircStopp();
   1730 -      process.exit();
   1731 +/**
   1732 + * Get door-status from the Web
   1733 + *
   1734 + * @class GetData
   1735 + * @return {String} Door Status
   1736 + */
   1737 +function GetData(){
   1738 +  /**
   1739 +   * Actual pulled Door Status
   1740 +   *
   1741 +   * @property door_status
   1742 +   * @type String
   1743 +   */
   1744 +	request.get('http://www.nordlab-ev.de/doorstate/status.txt', function (error, response, body) {
   1745 +    	if (!error && response.statusCode == 200) {
   1746 +    		/**
   1747 +         * Content of status_page
   1748 +         *
   1749 +         * @property body
   1750 +         * @type String
   1751 +         */
   1752 +      	door_status = body;
   1753 +    	}else{
   1754 +        /**
   1755 +         * Fired when an error occurs...
   1756 +         *
   1757 +         * @property error
   1758 +         * @type String
   1759 +         */
   1760 +    		//TODO Add real Error Handler
   1761 +      		door_status = error;
   1762 +   		}
   1763 +   		//If no error -> go on
   1764 +    	if (!error && response.statusCode == 200) {
   1765 +      		if (door_status2 !== door_status){
   1766 +      			//Handle first run
   1767 +        		if (door_status2 !== "1") {
   1768 +              /**
   1769 +               * Save Old Door Status
   1770 +               *
   1771 +               * @property door_status2
   1772 +               * @type String
   1773 +               */
   1774 +          			door_status2 = door_status;
   1775 +          			//Translate var's
   1776 +         			if (door_status == "geschlossen"){
   1777 +            		door_status = "closed";
   1778 +         			}else{
   1779 +            		door_status = "open";
   1780 +          		}
   1781 +
   1782 +          		//ADD MODULES DOWN HERE
   1783 +          		//Call Module send/main Functions
   1784 +          		pushbullet.pushbulletSend(door_status);
   1785 +          		//irc.ircSend(door_status);
   1786 +              return door_status;
   1787 +
   1788 +        		}else{
   1789 +        			//Save Last Status
   1790 +          			door_status2 = door_status;
   1791 +                return door_status;
   1792 +        		}
   1793 +      		}
   1794 +    	}
   1795      }).setMaxListeners(0);
   1796 -    setTimeout(function() { MakePush(); }, 10000);
   1797 -}).setMaxListeners(0);
   1798 +	//Rerun Function after 10 seconds
   1799 +	setTimeout(function() {}, 10000);
   1800 +}
   1801 +//Handle "[CTRL]+[C]"
   1802 +if (process.platform === "win32") {
   1803 +	var rl = require("readline").createInterface({
   1804 +		input: process.stdin,
   1805 +		output: process.stdout
   1806 +	}).setMaxListeners(0);
   1807 +	rl.on(SIGINT, function () {
   1808 +		process.emit(SIGINT);
   1809 +	}).setMaxListeners(0);
   1810  }
   1811 -irc.ircBotCommands();
   1812 -if (!argv.noupdate && autoupdate == 1) {
   1813 -  var j = schedule.scheduleJob('59 2 * * *', function(){
   1814 -    git.pull("origin", "master", function(err, update) {
   1815 -      if(update && update.summary.changes) {
   1816 -        console.log('Start Update!');
   1817 +process.on(SIGINT, function () {
   1818 +	irc.ircStopp();
   1819 +	process.exit();
   1820 +}).setMaxListeners(0);
   1821  
   1822 -        console.log('Daily restart!');
   1823 -        irc.ircEndCustom('Start update! Coming back in a few Seconds!');
   1824 -        require('child_process').exec('npm restart');
   1825 -      }
   1826 -    });
   1827 +/**
   1828 + * Update - Pull last master from Github
   1829 + *
   1830 + * @method update
   1831 + */
   1832 +function update(){
   1833 +  git.pull("origin", "master", function(err, update) {
   1834 +    if(update && update.summary.changes) {
   1835 +      console.log('Start Update!');
   1836 +      restart();
   1837 +    }
   1838    });
   1839  }
   1840 -if ((argv.noupdate) || (autoupdate == 0)) {
   1841 -  var k = schedule.scheduleJob('59 2 * * *', function(){
   1842 -    console.log('Daily restart!');
   1843 -    irc.ircEndCustom('Daily restart! Coming back in a few Seconds!');
   1844 -    require('child_process').exec('npm restart');
   1845 -  });
   1846 +
   1847 +/**
   1848 + * Restart - Restart the Bot completly
   1849 + *
   1850 + * @method restart
   1851 + */
   1852 +function restart(){
   1853 +  console.log('Daily restart!');
   1854 +  irc.ircEndCustom('Restart! Coming back in a few Seconds!');
   1855 +  require('child_process').exec('npm restart');
   1856  }
   1857 -setTimeout(function() { MakePush(); }, 20000);
   1858 +
   1859 +// var j = schedule.scheduleJob('59 3 * * *', function(){
   1860 +//   if (!argv.noupdate && autoupdate == 1) {
   1861 +//     //Run update at 3am and 59min
   1862 +//     update();
   1863 +//   }else{
   1864 +//     restart();
   1865 +//   }
   1866 +// });
   1867 +
   1868 +//Startup
   1869 +async.auto({
   1870 +    ircPreload: function (callback) {
   1871 +      // callback has to be called by `uploadImage` when it's done
   1872 +      irc.ircPreload(callback)
   1873 +    },
   1874 +    ircBotCommands: function (callback) {
   1875 +      //Activate IRC-Bot Command Handler
   1876 +      irc.ircBotCommands(callback)
   1877 +    },
   1878 +    saveNodes: function (callback) {
   1879 +      getNodes.saveNodes(callback)
   1880 +    },
   1881 +    telegramStart: function (callback) {
   1882 +      telegram.start(callback)
   1883 +    },
   1884 +    GetData: function (callback) {
   1885 +      async.forever(
   1886 +        function(next) {
   1887 +          GetData()
   1888 +          callback(next)
   1889 +        },
   1890 +        function(err) {
   1891 +          // if next is called with a value in its first parameter, it will appear
   1892 +          // in here as 'err', and execution will stop.
   1893 +          callback(err)
   1894 +        }
   1895 +      );
   1896 +    }
   1897 +  },
   1898 +  function(err, result) {
   1899 +    if (err) {
   1900 +      console.log(err)
   1901 +    }
   1902 +  }
   1903 +);
   1904 \ No newline at end of file
   1905 diff --git a/package.json b/package.json
   1906 index a21940d..8f107d3 100644
   1907 --- a/package.json
   1908 +++ b/package.json
   1909 @@ -1,6 +1,6 @@
   1910  {
   1911    "name": "nordlab-hackerspace-door",
   1912 -  "version": "0.0.1",
   1913 +  "version": "0.0.2",
   1914    "description": "Modular parser for the hackerspace door status with handlers for multiple services",
   1915    "author": "Marcel Radzio <info@nordgedanken.de>",
   1916    "scripts": {
   1917 @@ -20,15 +20,28 @@
   1918      "notification"
   1919    ],
   1920    "dependencies": {
   1921 -    "request": "*",
   1922 -    "curlrequest": "*",
   1923 -    "irc": "0.4.0",
   1924 -    "simple-git": "*",
   1925 -    "node-schedule": "*",
   1926 -    "yargs": "*"
   1927 +    "async": "^2.0.1",
   1928 +    "botanio": "0.0.6",
   1929 +    "curlrequest": "^0.5.7",
   1930 +    "express": "^4.14.0",
   1931 +    "irc": "^0.5.0",
   1932 +    "jsonfile": "^2.3.1",
   1933 +    "lodash": "^4.15.0",
   1934 +    "node-schedule": "^1.1.1",
   1935 +    "node-telegram-bot-api": "^0.23.3",
   1936 +    "request": "^2.74.0",
   1937 +    "simple-git": "^1.48.0",
   1938 +    "slackbots": "^0.5.2",
   1939 +    "string": "^3.3.1",
   1940 +    "yargs": "^5.0.0"
   1941    },
   1942    "preferGlobal": false,
   1943    "private": true,
   1944 -  "license": "SEE LICENSE IN LICENSE.md"
   1945 +  "license": "SEE LICENSE IN LICENSE.md",
   1946 +  "optionalDependencies": {
   1947 +    "yuidocjs": "^0.9.0"
   1948 +  },
   1949 +  "devDependencies": {
   1950 +    "request-debug": "^0.2.0"
   1951 +  }
   1952  }
   1953 -  
   1954 \ No newline at end of file
   1955 diff --git a/yuidoc.json b/yuidoc.json
   1956 new file mode 100644
   1957 index 0000000..0d22f67
   1958 --- /dev/null
   1959 +++ b/yuidoc.json
   1960 @@ -0,0 +1,11 @@
   1961 +{
   1962 +    "name": "Nordlab Hackerspace Door",
   1963 +    "description": "Modular parser for the hackerspace door status with handlers for multiple services",
   1964 +    "version": "0.0.2",
   1965 +    "url": "http://example.com/",
   1966 +    "options": {
   1967 +        "outdir": "../bot_apidocs",
   1968 +        "ignorePaths": [ "node_modules", "apidocs", "configs" ],
   1969 +        "paths": "*"
   1970 +    }
   1971 +}
   1972 \ No newline at end of file