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

8.diff (74148B)


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