这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
TOKEN=YOUR_TOKEN_FROM_SLACK
SLACK_TOKEN=YOUR_TOKEN_FROM_SLACK
DEBUG=false
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ node_modules
.DS_Store
.env
npm-debug.log
debug.log
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
# portnamer
A Slack bot that checks on common network ports such as 80 for HTTP or 22 for SSH.
A bot that can tell you what service is on what port. Gamified!

## Installation
Do you need to install this? Do you want to just add Port Namer to your Slack team or on Messenger? Coming soon!

To install you'll need to:

1. `git clone` this repository.
2. `cp .env.example .env`
3. Enter your bot token you got from Slack and enter it in the .env file
4. Run `npm install`
5. Finally, `npm start`
4. Run `yarn` to install dependencies
5. Finally, `npm start` or `npm run dev`. The difference is the dev script runs nodemon, so any changes to the `/src` dir will cause the app to reload automatically, whereas the start script runs `forever` to make it automatically spin back up after crashes.

## Deploying
We recommend deploying with [now](now.sh). Go to https://my.slack.com/services/new/bot and get a Bot API key. You can also name portnamer. Copy that to your clipboard. Then deploy with one command!

```sh
now -e TOKEN=[your slack token]
now -e SLACK_TOKEN=[your slack token]
```

This will give you a url. You now have a Slackbot living in the cloud!
Expand All @@ -24,10 +26,8 @@ You can either mention `@portnamer` in a channel after you invite it, or DM it d

## TODO
- [ ] Get random port intent - need to conversationalize it
- [ ] Quiz intent - Add a way to keep questions coming
- [ ] Use NLP service instead of Regex

And there's more but too lazy to think about them? :/

## Contributions
There's so many ways to make this better and I have little time to work on it. If you like it and might think of using it for fun or productivity, you should contribute!
Expand Down
9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@
"description": "Checks on common network ports such as 80 for HTTP or 22 for SSH.",
"main": "src/portnamer.js",
"scripts": {
"start": "node src/portnamer.js"
"start": "forever src/portnamer.js",
"dev": "DEBUG=true nodemon src/portnamer.js"
},
"author": "Danny Carrillo <odannycx@gmail.com>",
"license": "MIT",
"devDependencies": {
"nodemon": "^1.11.0"
},
"dependencies": {
"botkit": "^0.4.7",
"dotenv": "^2.0.0"
"dotenv": "^2.0.0",
"forever": "^0.15.3"
}
}
10 changes: 10 additions & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// this syntax is overkill for these simple examples, but extensible
module.exports = (function() {
const greetings = ['hello', 'hi', 'yo', 'whatup', 'hola'];
const helpMessage = 'I am your fiendly port namer bot. You can ask me stuff like:\n```What port does telnet use?\nport 22?\nssh?\nGet me a random port\nLets play a game\nQuiz me```\nSo, what would you like to do ? :)';

return {
greetings,
helpMessage
};
})();
161 changes: 90 additions & 71 deletions src/portnamer.js
Original file line number Diff line number Diff line change
@@ -1,102 +1,121 @@
var Botkit = require('botkit');
var Ports = require('./ports');
var Quiz = require('./quiz');

// load the .env file
require('dotenv').config({silent: true});

var controller = Botkit.slackbot({
debug: false,
});

var bot = controller.spawn({
token: process.env.TOKEN
const os = require('os');
const Botkit = require('botkit');
const Ports = require('./ports');
const Quiz = require('./quiz');
const constants = require('./constants');
require('dotenv').config({silent: true}); // load the .env file

if (!process.env.SLACK_TOKEN) {
console.log('Error: Specify Slack Token in environment or .env');
process.exit(1);
}

const debug = process.env.DEBUG == true ? process.env.DEBUG : false;
const controller = Botkit.slackbot({ debug });
const bot = controller.spawn({
token: process.env.SLACK_TOKEN
}).startRTM();

// Hello
controller.hears(['hello', 'hi'], 'direct_message,direct_mention,mention', function(bot, message) {
bot.api.reactions.add({
timestamp: message.ts,
channel: message.channel,
name: 'robot_face',
}, function(err, res) {
if (err) {
bot.botkit.log('Failed to add emoji reaction :(', err);
const quizHandler = (quiz, convo) => {
return [
{
pattern: 'quit',
callback: (response, convo) => {
convo.say('Okay, thanks for playing!');
convo.next();}
},
{
default: true,
callback: (response, convo) => {
if (quiz.check(response.text)) {
convo.say('You\'re *right*!');
} else {
convo.say('Sorry.. you got it *wrong*... The actual answer is `' + quiz.answer() + '`');
}
});
quiz = new Quiz();
convo.ask(quiz.question(), quizHandler(quiz, convo));
convo.next();
}
}
]
};

// Hello
controller.hears(constants.greetings, 'direct_message,direct_mention,mention', function(bot, message) {
bot.api.reactions.add({
timestamp: message.ts,
channel: message.channel,
name: 'robot_face',
}, function(err, res) {
if (err) {
bot.botkit.log('Failed to add emoji reaction :(', err);
}
});


bot.reply(message, 'Hello. If you\'d like to know how to use me.. ;). Type `help`.');
bot.reply(message, 'Hello. If you\'d like to know how to use me.. ;). Type `help`.');
});

// Help
controller.hears(['help'], 'direct_message,direct_mention,mention', function(bot, message) {
bot.reply(message, 'I am your fiendly port namer bot. You can ask me stuff like:\n```What port does telnet use?\nport 22?\nssh?\nGet me a random port\nLets play a game\nQuiz me```\nSo, what would you like to do ? :)');
bot.reply(message, constants.helpMessage);
});

// check by port
controller.hears(['port (\\d+)', '^(\\d+)\\s*\\?*$'], 'direct_message,direct_mention,mention', function(bot, message) {
var port = message.match[1];
var name = Ports.find('name', port);
const port = message.match[1];
const name = Ports.find('port', port);
let reply = `*Sorry*, I don't have a record for anything on port ${'`' + port + '`'}`

if (name.length > 0) {
var reply = 'Looks like the port ' + port + ' belongs to ' + name[0].Description;
} else {
var reply = '*Sorry*, I couldn\'t find a name that matches port `' + port + '`';
}
if (name.length) {
reply = `Looks like port ${port} belongs to ${name[0].Description}`;
}

bot.reply(message, reply);
bot.reply(message, reply);
});

// check by name
controller.hears(['port (?:does|is|has|have) (\\w+)', '^(\\w+)\\s*\\?*$'], 'direct_message,direct_mention,mention', function(bot, message) {
var name = (message.match[1]).toLowerCase();
var port = Ports.find('port', name);
const name = (message.match[1]).toLowerCase();
const port = Ports.find('name', name);
let reply = `*Sorry*, I don't have a record that matches ${'`' + name + '`'}`;

if (port.length > 0) {
var reply = name + ' uses port ' + port[0].Port;
} else {
var reply = '*Sorry*, I couldn\'t find a port that matches `' + name + '`';
}
if (port.length) {
reply = `${name} uses port ${port[0].Port}`;
}

bot.reply(message, reply);
bot.reply(message, reply);
});

// get a random port
controller.hears(['random', 'fun fact'], 'direct_message,direct_mention,mention', function(bot, message) {
var randomPort = Ports.random();

// Starts the reply string
var reply = `*${randomPort.Description}* is ${randomPort.Status} and uses port ${randomPort.Port} over `;

// Checks if the port uses both udp and tcp
if (randomPort.TCP != '' && randomPort.UDP != '') {
reply = reply + `${randomPort.TCP} and ${randomPort.UDP}.`;
} else if (randomPort.TCP != '') {
reply = reply + `${randomPort.TCP}.`;
} else if (randomPort.UDP != '') {
reply = reply + `${randomPort.UDP}.`;
}
const randomPort = Ports.random();
const protocols = [randomPort.TCP, randomPort.UDP].filter(el => el != '');

bot.reply(message, reply);
const reply = `*${randomPort.Description}* is stupid ${randomPort.Status} and uses port ${randomPort.Port} over ${protocols.join(' and ')}.`;

bot.reply(message, reply);
});

// Quiz time
controller.hears(['quiz me', 'game'], 'direct_message,direct_mention,mention', function(bot, message) {
bot.startConversation(message, function(err, convo) {
if (!err) {
convo.say('Awesome! Let\'s play a game I like to call `Name That Port` :)\nLet\'s start!');

var quiz = new Quiz();
convo.ask(quiz.question(), function (response, convo) {
if (quiz.check(response.text)) {
convo.say('You\'re *right*!');
} else {
convo.say('Sorry.. you got it *wrong*.\nThe actual answer is `' + quiz.answer() + '`.\nGoodluck next time :)\nYou can play again by typing `quiz me`.');
}

convo.next();
});
}
});
bot.startConversation(message, function(err, convo) {
if (!err) {
convo.say('Awesome! Let\'s play a game I like to call `Name That Port` :)\nSay `exit` at any time to quit.');

let quiz = new Quiz();
convo.ask(quiz.question(), quizHandler(quiz, convo));
convo.next();
}
});
});

controller.hears('show url', 'direct_message,direct_mention,mention', (bot, message) => {
const macOrWindows = ['darwin', 'win32'].filter(el => el == os.platform());
const urlMessage = process.env.NOW_URL
? `My URL is ${process.env.NOW_URL}`
: macOrWindows.length > 0
? 'I think I am running locally, as I am on a Mac or Windows machine'
: 'I do not seem to be deployed in the cloud using now.sh, but I am not running on Mac or Windows. Did you deploy me with Heroku or AWS?';
bot.reply(message, urlMessage);
});
69 changes: 34 additions & 35 deletions src/ports.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,42 @@
var PortsDB = require('../assets/ports.json');
const PortsDB = require('../assets/ports.json');

class Ports
{
static random(onlyOfficial) {
do {
var result = PortsDB[Math.floor(Math.random()*PortsDB.length)];
} while (result.Status != 'Official');

return result;
}
/**
* Helper HOF returns a suitable filter function
* @param {String} type Filtering by name or port?
* @param {String} filter Name or port to filter by
* @return {Function} A suitable filter function for use in Ports.find
*/
const filterFunctionFromType = (type = 'name', filter = '22') => {
console.log({type, filter})
if (type == 'port') {
return (el) => el.Port == filter;
}

/**
* Filters out the ports array to find a specified record.
*
* @var string type The type of port to find, can be either port or name
* @var string|int filter The filter keyword, such as '22' or 'SSH'
*/
static find(type, filter) {
if (type == 'name') {
return PortsDB.filter(function (el) {
if (el.Port == filter) {
return true;
}
if (type == 'name') {
return (el) => (new RegExp(`\\b${filter}\\b`)).test((el.Description).toLowerCase());
}
}

return false;
});
}
class Ports
{
static random(onlyOfficial) {
let result;
do {
result = PortsDB[Math.floor(Math.random() * PortsDB.length)];
} while (result.Status != 'Official');

if (type == 'port') {
var regex = new RegExp('\\b' + filter + '\\b');
return PortsDB.filter(function (el) {
if (regex.test((el.Description).toLowerCase())) {
return true;
}
return result;
}

return false;
});
}
}
/**
* Filters out the ports array to find a specified record.
*
* @param {string} type The type of port to find, can be either port or name
* @param {string|int} filter The filter keyword, such as '22' or 'SSH'
*/
static find(type, filter) {
return PortsDB.filter(filterFunctionFromType(type, filter));
}
}

module.exports = Ports;
Loading