Skip to content

Commit

Permalink
πŸ“•πŸŒ Updated with Glitch
Browse files Browse the repository at this point in the history
  • Loading branch information
System committed Jul 28, 2017
1 parent 466a316 commit b37686c
Show file tree
Hide file tree
Showing 30 changed files with 1,508 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.db
node_modules
components/routes/_*
Empty file added .glitch-assets
Empty file.
2 changes: 0 additions & 2 deletions README.md

This file was deleted.

26 changes: 26 additions & 0 deletions app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"name": "Botkit Starter Kit",
"description": "A starting point for building custom Slack applications",
"repository": "https://github.com/howdyai/botkit-starter-slack",
"keywords": ["node", "bots", "slack","botkit"],
"website": "https://studio.botkit.ai/",
"success_url":"/",
"addons":[
{
"plan": "mongolab",
"as": "MONGO"
}
],
"env": {
"clientId": {
"description": "Client ID provided by Slack"
},
"clientSecret": {
"description": "Client Secret provided by Slack"
},
"studio_token": {
"description": "Token associated with your bot in Botkit Studio",
"required":false
}
}
}
161 changes: 161 additions & 0 deletions bot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
______ ______ ______ __ __ __ ______
/\ == \ /\ __ \ /\__ _\ /\ \/ / /\ \ /\__ _\
\ \ __< \ \ \/\ \ \/_/\ \/ \ \ _"-. \ \ \ \/_/\ \/
\ \_____\ \ \_____\ \ \_\ \ \_\ \_\ \ \_\ \ \_\
\/_____/ \/_____/ \/_/ \/_/\/_/ \/_/ \/_/
This is a sample Slack bot built with Botkit.
This bot demonstrates many of the core features of Botkit:
* Connect to Slack using the real time API
* Receive messages based on "spoken" patterns
* Reply to messages
* Use the conversation system to ask questions
* Use the built in storage system to store and retrieve information
for a user.
# RUN THE BOT:
Create a new app via the Slack Developer site:
-> http://api.slack.com
Get a Botkit Studio token from Botkit.ai:
-> https://studio.botkit.ai/
Run your bot from the command line:
clientId=<MY SLACK TOKEN> clientSecret=<my client secret> PORT=<3000> studio_token=<MY BOTKIT STUDIO TOKEN> node bot.js
# USE THE BOT:
Navigate to the built-in login page:
https://<myhost.com>/login
This will authenticate you with Slack.
If successful, your bot will come online and greet you.
# EXTEND THE BOT:
Botkit has many features for building cool and useful bots!
Read all about it here:
-> http://howdy.ai/botkit
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
var env = require('node-env-file');
env(__dirname + '/.env');


if (!process.env.clientId || !process.env.clientSecret || !process.env.PORT) {
console.log('Error: Specify clientId clientSecret and PORT in environment');
usage_tip();
process.exit(1);
}

var Botkit = require('botkit');
var debug = require('debug')('botkit:main');

var bot_options = {
clientId: process.env.clientId,
clientSecret: process.env.clientSecret,
// debug: true,
scopes: ['bot'],
studio_token: process.env.studio_token,
studio_command_uri: process.env.studio_command_uri
};

// Use a mongo database if specified, otherwise store in a JSON file local to the app.
// Mongo is automatically configured when deploying to Heroku
if (process.env.MONGO_URI) {
var mongoStorage = require('botkit-storage-mongo')({mongoUri: process.env.MONGO_URI});
bot_options.storage = mongoStorage;
} else {
bot_options.json_file_store = __dirname + '/.data/db/'; // store user data in a simple JSON format
}

// Create the Botkit controller, which controls all instances of the bot.
var controller = Botkit.slackbot(bot_options);

controller.startTicking();

// Set up an Express-powered webserver to expose oauth and webhook endpoints
var webserver = require(__dirname + '/components/express_webserver.js')(controller);

// Set up a simple storage backend for keeping a record of customers
// who sign up for the app via the oauth
require(__dirname + '/components/user_registration.js')(controller);

// Send an onboarding message when a new team joins
require(__dirname + '/components/onboarding.js')(controller);

// no longer necessary since slack now supports the always on event bots
// // Set up a system to manage connections to Slack's RTM api
// // This will eventually be removed when Slack fixes support for bot presence
// var rtm_manager = require(__dirname + '/components/rtm_manager.js')(controller);
//
// // Reconnect all pre-registered bots
// rtm_manager.reconnect();

// Enable Dashbot.io plugin
require(__dirname + '/components/plugin_dashbot.js')(controller);


var normalizedPath = require("path").join(__dirname, "skills");
require("fs").readdirSync(normalizedPath).forEach(function(file) {
require("./skills/" + file)(controller);
});



// This captures and evaluates any message sent to the bot as a DM
// or sent to the bot in the form "@bot message" and passes it to
// Botkit Studio to evaluate for trigger words and patterns.
// If a trigger is matched, the conversation will automatically fire!
// You can tie into the execution of the script using the functions
// controller.studio.before, controller.studio.after and controller.studio.validate
if (process.env.studio_token) {
controller.on('direct_message,direct_mention,mention', function(bot, message) {
controller.studio.runTrigger(bot, message.text, message.user, message.channel).then(function(convo) {
if (!convo) {
// no trigger was matched
// If you want your bot to respond to every message,
// define a 'fallback' script in Botkit Studio
// and uncomment the line below.
// controller.studio.run(bot, 'fallback', message.user, message.channel);
} else {
// set variables here that are needed for EVERY script
// use controller.studio.before('script') to set variables specific to a script
convo.setVar('current_time', new Date());
}
}).catch(function(err) {
bot.reply(message, 'I experienced an error with a request to Botkit Studio: ' + err);
debug('Botkit Studio: ', err);
});
});
} else {
console.log('~~~~~~~~~~');
console.log('NOTE: Botkit Studio functionality has not been enabled');
console.log('To enable, pass in a studio_token parameter with a token from https://studio.botkit.ai/');
}




function usage_tip() {
console.log('~~~~~~~~~~');
console.log('Botkit Starter Kit');
console.log('Execute your bot application like this:');
console.log('clientId=<MY SLACK CLIENT ID> clientSecret=<MY CLIENT SECRET> PORT=3000 studio_token=<MY BOTKIT STUDIO TOKEN> node bot.js');
console.log('Get Slack app credentials here: https://api.slack.com/apps')
console.log('Get a Botkit Studio token here: https://studio.botkit.ai/')
console.log('~~~~~~~~~~');
}
55 changes: 55 additions & 0 deletions components/express_middleware/register_with_studio.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
var request = require('request');
var debug = require('debug')('botkit:register_with_studio');
module.exports = function(webserver, controller) {

var registered_this_session = false;

if (webserver && controller.config.studio_token) {
webserver.use(function(req, res, next) {
if (!registered_this_session) {
// get URL from the request
var host = req.get('host');

// information about this instance of Botkit
// send to Botkit Studio in order to display in the hosting tab
var instance = {
url: host,
version: controller.version(),
ts: new Date(),
}

request({
method: 'post',
uri: (controller.config.studio_command_uri || 'https://studio.botkit.ai') + '/api/v1/bots/phonehome?access_token=' + controller.config.studio_token,
form: instance,
},function(err, res, body) {

registered_this_session = true;

if (err) {
debug('Error registering instance with Botkit Studio', err);
} else {

var json =null;
try {
json = JSON.parse(body);
} catch(err) {
debug('Error registering instance with Botkit Studio', err);
}

if (json) {
if (json.error) {
debug('Error registering instance with Botkit Studio', json.error);
}
}
}

});

}
next();
});

}

}
38 changes: 38 additions & 0 deletions components/express_webserver.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
var express = require('express');
var bodyParser = require('body-parser');
var querystring = require('querystring');
var debug = require('debug')('botkit:webserver');

module.exports = function(controller) {


var webserver = express();
webserver.use(bodyParser.json());
webserver.use(bodyParser.urlencoded({ extended: true }));

// import express middlewares that are present in /components/express_middleware
var normalizedPath = require("path").join(__dirname, "express_middleware");
require("fs").readdirSync(normalizedPath).forEach(function(file) {
require("./express_middleware/" + file)(webserver, controller);
});

webserver.use(express.static('public'));


webserver.listen(process.env.PORT || 3000, null, function() {

debug('Express webserver configured and listening at http://localhost:' + process.env.PORT || 3000);

});

// import all the pre-defined routes that are present in /components/routes
var normalizedPath = require("path").join(__dirname, "routes");
require("fs").readdirSync(normalizedPath).forEach(function(file) {
require("./routes/" + file)(webserver, controller);
});

controller.webserver = webserver;

return webserver;

}
31 changes: 31 additions & 0 deletions components/onboarding.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
var debug = require('debug')('botkit:onboarding');

module.exports = function(controller) {

controller.on('onboard', function(bot) {

debug('Starting an onboarding experience!');

if (controller.config.studio_token) {
bot.api.im.open({user: bot.config.createdBy}, function(err, direct_message) {
if (err) {
debug('Error sending onboarding message:', err);
} else {
controller.studio.run(bot, 'onboarding', bot.config.createdBy, direct_message.channel.id).catch(function(err) {
debug('Error: encountered an error loading onboarding script from Botkit Studio:', err);
});
}
});
} else {
bot.startPrivateConversation({user: bot.config.createdBy},function(err,convo) {
if (err) {
console.log(err);
} else {
convo.say('I am a bot that has just joined your team');
convo.say('You must now /invite me to a channel so that I can be of use!');
}
});
}
});

}
14 changes: 14 additions & 0 deletions components/plugin_dashbot.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module.exports = function(controller) {

// Dashbot is a turnkey analytics platform for bots.
// Sign up for a free key here: https://www.dashbot.io/ to see your bot analytics in real time.
if (process.env.DASHBOT_API_KEY) {
var dashbot = require('dashbot')(process.env.DASHBOT_API_KEY).slack;
controller.middleware.receive.use(dashbot.receive);
controller.middleware.send.use(dashbot.send);
controller.log.info('Thanks for using Dashbot. Visit https://www.dashbot.io/ to see your bot analytics in real time.');
} else {
controller.log.info('No DASHBOT_API_KEY specified. For free turnkey analytics for your bot, go to https://www.dashbot.io/ to get your key.');
}

}
18 changes: 18 additions & 0 deletions components/routes/incoming_webhooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
var debug = require('debug')('botkit:incoming_webhooks');

module.exports = function(webserver, controller) {

debug('Configured /slack/receive url');
webserver.post('/slack/receive', function(req, res) {

// NOTE: we should enforce the token check here

// respond to Slack that the webhook has been received.
res.status(200);

// Now, pass the webhook into be processed
controller.handleWebhookPayload(req, res);

});

}
Loading

0 comments on commit b37686c

Please sign in to comment.