Created
September 9, 2019 08:40
-
-
Save yaron-idan/e38de24133841ccfda4f0be75d45034e to your computer and use it in GitHub Desktop.
Botkit Duplicate messages
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// __ __ ___ ___ | |
// |__) / \ | |__/ | | | |
// |__) \__/ | | \ | | | |
// This is the main file for the mock-bot bot. | |
// Import Botkit's core features | |
const { Botkit, BotkitConversation } = require('botkit'); | |
const { BotkitCMSHelper } = require('botkit-plugin-cms'); | |
// Import a platform-specific adapter for slack. | |
const { SlackAdapter, SlackMessageTypeMiddleware, SlackEventMiddleware } = require('botbuilder-adapter-slack'); | |
const { MongoDbStorage } = require('botbuilder-storage-mongodb'); | |
// Load process.env values from .env file | |
require('dotenv').config(); | |
let storage = null; | |
if (process.env.MONGO_URI) { | |
storage = mongoStorage = new MongoDbStorage({ | |
url : process.env.MONGO_URI, | |
}); | |
} | |
const adapter = new SlackAdapter({ | |
// REMOVE THIS OPTION AFTER YOU HAVE CONFIGURED YOUR APP! | |
enable_incomplete: true, | |
// parameters used to secure webhook endpoint | |
verificationToken: process.env.verificationToken, | |
clientSigningSecret: process.env.clientSigningSecret, | |
// auth token for a single-team app | |
botToken: process.env.botToken, | |
// credentials used to set up oauth for multi-team apps | |
clientId: process.env.clientId, | |
clientSecret: process.env.clientSecret, | |
scopes: ['bot'], | |
redirectUri: process.env.redirectUri, | |
// functions required for retrieving team-specific info | |
// for use in multi-team apps | |
getTokenForTeam: getTokenForTeam, | |
getBotUserByTeam: getBotUserByTeam, | |
}); | |
// Use SlackEventMiddleware to emit events that match their original Slack event types. | |
adapter.use(new SlackEventMiddleware()); | |
// Use SlackMessageType middleware to further classify messages as direct_message, direct_mention, or mention | |
adapter.use(new SlackMessageTypeMiddleware()); | |
const controller = new Botkit({ | |
webhook_uri: '/api/messages', | |
adapter: adapter, | |
storage | |
}); | |
if (process.env.cms_uri) { | |
controller.usePlugin(new BotkitCMSHelper({ | |
uri: process.env.cms_uri, | |
token: process.env.cms_token, | |
})); | |
} | |
// Once the bot has booted up its internal services, you can use them to do stuff. | |
controller.ready(() => { | |
// load traditional developer-created local custom feature modules | |
controller.loadModules(__dirname + '/features'); | |
/* catch-all that uses the CMS to trigger dialogs */ | |
if (controller.plugins.cms) { | |
controller.on('message,direct_message', async (bot, message) => { | |
let results = false; | |
results = await controller.plugins.cms.testTrigger(bot, message); | |
if (results !== false) { | |
// do not continue middleware! | |
return false; | |
} | |
}); | |
} | |
}); | |
controller.webserver.get('/', (req, res) => { | |
res.send(`This app is running Botkit ${ controller.version }.`); | |
}); | |
controller.webserver.get('/install', (req, res) => { | |
// getInstallLink points to slack's oauth endpoint and includes clientId and scopes | |
res.redirect(controller.adapter.getInstallLink()); | |
}); | |
controller.webserver.get('/install/auth', async (req, res) => { | |
try { | |
const results = await controller.adapter.validateOauthCode(req.query.code); | |
console.log('FULL OAUTH DETAILS', results); | |
// Store token by team in bot state. | |
tokenCache[results.team_id] = results.bot.bot_access_token; | |
// Capture team to bot id | |
userCache[results.team_id] = results.bot.bot_user_id; | |
res.json('Success! Bot installed.'); | |
} catch (err) { | |
console.error('OAUTH ERROR:', err); | |
res.status(401); | |
res.send(err.message); | |
} | |
}); | |
let tokenCache = {}; | |
let userCache = {}; | |
if (process.env.TOKENS) { | |
tokenCache = JSON.parse(process.env.TOKENS); | |
} | |
if (process.env.USERS) { | |
userCache = JSON.parse(process.env.USERS); | |
} | |
const MY_DIALOG_ID = 'my-dialog-name-constant'; | |
let convo = new BotkitConversation(MY_DIALOG_ID, controller); | |
convo.addAction('my_thread'); | |
convo.addMessage("My thread starts here", "my_thread"); | |
// do a simple conditional branch looking for user to say "no" | |
convo.addQuestion("Would you like this thread to wait a bit?", [{ | |
pattern: 'no', | |
handler: async (response, convo, bot) => { | |
// if user says no, process to create repo. | |
} | |
}, | |
{ | |
pattern: 'yes', | |
handler: async (response, convo, bot) => { | |
// if user says yes, create the namespace. | |
console.log("Waiting a bit..."); | |
let initResponse = await funcThatWaits(); | |
let initMessage = await bot.say(initResponse); | |
await bot.say("Leaving the thread"); | |
} | |
}, | |
{ | |
default: true, | |
handler: async (response, convo, bot) => { | |
// do nothing, allow convo to complete. | |
} | |
} | |
], 'confirm', 'my_thread'); | |
convo.addMessage("end of thread and convo", "my_thread"); | |
convo.addAction('complete'); | |
controller.addDialog(convo); | |
async function funcThatWaits() | |
{ | |
const timeout = ms => new Promise(res => setTimeout(res, ms)) | |
console.log("Let's wait"); | |
await timeout(5000); | |
console.log("Finished waiting"); | |
return "Finished waiting"; | |
} | |
async function getTokenForTeam(teamId) { | |
if (tokenCache[teamId]) { | |
return new Promise((resolve) => { | |
setTimeout(function() { | |
resolve(tokenCache[teamId]); | |
}, 150); | |
}); | |
} else { | |
console.error('Team not found in tokenCache: ', teamId); | |
} | |
} | |
async function getBotUserByTeam(teamId) { | |
if (userCache[teamId]) { | |
return new Promise((resolve) => { | |
setTimeout(function() { | |
resolve(userCache[teamId]); | |
}, 150); | |
}); | |
} else { | |
console.error('Team not found in userCache: ', teamId); | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { SlackDialog } = require('botbuilder-adapter-slack'); | |
const { BotkitConversation } = require('botkit'); | |
//TODO: This constant should be defined once, maybe in configuration | |
const MY_DIALOG_ID = 'my-dialog-name-constant'; | |
module.exports = function(controller) { | |
controller.hears('waiting_on_a_thread', 'direct_message', async(bot, message) => { | |
await bot.startConversationInThread(message.channel, message.user, message.incoming_message.channelData.ts); | |
await bot.beginDialog(MY_DIALOG_ID); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment