@shopkeep/bot-scripts v1.2.0
bot-scripts
Common functionality for botkit slack bots
Installation
npm install @shopkeep/bot-scriptsQuick Start
Copy an example from the examples/ directory and use as a starting point for
your next bot project. Rename the .env.example file to .env and get the bot
set up by adding a SLACK_BOT_TOKEN into the .env.
Run npm install to install the dependencies and then start your bot with
npm start. For any further requirements, check the README.md file of your
chosen example.
What's Provided
bot-scripts aims to extact common functionality and tooling, used by botkit
slack bots, into a centralised repository. It provides three commands:
bot-scripts lintprovides consistent tooling versions and configuration for linting rules using ESLint (and associated plugins) and Prettier.bot-scripts testprovides consistent tooling versions and configuration for running tests using Jest.bot-scripts startprovides consistent tooling versions and configuration for Botkit, as well as setting up boilerplate functionality and starting your bot.
Bot Slack Commands
All bots using this set of scripts will have these slack commands by default:
pingslack command- eg.
@your-bot ping - Bot will reply with
pong
- eg.
helpslack command- eg.
@your-bot help - Bot will reply a list of slack commands, using the
## Commandssection of the README as the source of this data. (Seeexamples/for readme files where this has been used.)
- eg.
statusslack command- eg.
@your-bot status - Bot will reply with useful status information including host name, IP address and bot-scripts version. Additional data can be added to this response.
- eg.
Development Functionality
Your bot should have an entry point at src/index.js which exports a function.
On start, bot-scripts will call this function and provide it with a
setupBot function as a single parameter.
Basic Example:
You can get a complete runnable setup of this example at
examples/basic-example/
// This emoji will prefix the slack command in the `help` slack command output
const customEmojis = {
"my name is": ":wave:"
};
// This will be visible in the `status` slack command output
const statusData = {
isExampleBot: true
};
// The bot will listen to slack commands prefixed with the botname string;
// This means you can call the bot without directly mentioning it.
// eg. If you had a bot under the handle `@HiBot` you could still call this bot
// via `example-bot my name is Alice`. This can be of use as part of reminders.
const botname = "example-bot";
module.exports = function(setupBot) { // Function called by bot-scripts start
logger.debug("Setting up clients"); // Global `logger` object available
// Bot instance and `listen` function provided from `setupBot`
const { bot, listen } = setupBot({ botname, customEmojis, statusData });
// Sets up case insensitive listener for "my name is" slack command
// This can be called via a direct message, @ mention in a channel
// or when it's prefixed by the `botname`
listen("my name is (.+)", function(bot, message) {
// Implement your slack command logic here, eg:
// https://botkit.ai/docs/core.html#botreply
bot.reply(message, `Hi ${message.match[1]}!`);
});
};Initial Setup
Your entry point function will be provided with a setupBot function. This
function should be called with an object, which can contain:
botname- (optional) Name of the bot when called ambiently- Defaults to
bot - eg.
bot pingwould call thepingslack command
- Defaults to
customEmojis- (optional) Mapping of slack command string to emoji forhelpoutput- Used to prefix slack commands with memorable emoji in
helpoutput. Defaults to:point_right:. For simplicity, this will match on slack commands starting with the provided object key, so the entire slack command string isn't required.
- Used to prefix slack commands with memorable emoji in
statusData- (optional) Object of data to add tostatusoutput
This function returns an object containing the bot BotKit instance and a
listen function.
- Generally the
botBotKit instance won't be used; but it can be required as a parameter by some of the utility functions (documented later). - The
listenfunction is used to add slack commands to your bot. The providedlistenfunction takes a string to listen for (which can contain regex syntax), which is then converted to a case insensitive regular expression and bound to both targetted means of communication (direct message, direct mention, etc.) and ambient targetting based on the providedbotname(defaults to "bot"). This allows for calling the bot as part of Slacks reminder functionality.
Logging
A global logger variable is provided to output a standard log format to the
console. Log level output can be set via environment variable:
LOGGING_LEVEL- (optional) Level of logging to output.- Defaults to
info(supportsdebugfor verbose logging) - Follows the Syslog severity levels.
- Defaults to
Utils
There are some helpful utilities available which can be imported separately.
These are provided under @shopkeep/bot-scripts/utils which will provide a
single util object containing:
getUserfunction takes a bot instance and a user ID and returns a promise which will resolve to a standardised user object, which looks like:{ id, name, handle, email, avatar, tz }- User ID most commonly comes from
message.user, when looking up the caller
outputErrorfunction takes a bot instance, the message and an error message (or error object) and will reply to the user with the error details.generateListenerfunction takes the bot name, a bot instance and an array of the means by which it should listen and returns a function which can be used to set up listeners (like thelistenfunction provided bysetupBot).- This should be used when the provided
listenfunction isn't suitable and a custom setup for the listen function is required. Example:
const { generateListener } = require("@shopkeep/bot-scripts/utils"); const botname = "example-bot"; module.exports = function(setupBot) { const { bot } = setupBot(); const directListener = generateListener(botname, bot, [ // You can add as many or few message events here as you want to bind to // https://botkit.ai/docs/core.html#incoming-message-events 'direct_message' // This listener will only bind to direct messages ]); directListener("my name is (.+)", function(bot, message) { bot.reply(message, `Hi ${message.match[1]}!`); }); };
- This should be used when the provided
Infrastructure Support
A healthcheck endpoint is exposed which can be used to determine the health of
the bot. This returns a 200 when the Slack real-time messaging websocket
connection available, and a 503 when it is not.
HEALTH_CHECK_PORT- (optional) Port used for health check endpoint.- Defaults to
9000
- Defaults to
Contributing
Pull requests on this repository are very welcome. There is test and linting tooling in place. Formatting is provided by prettier. This project uses the same linting and testing tooling as provided to any bots which use these scripts.
Docker
Use docker-compose to build the environment, and run tests and lint.
docker-compose build test
docker-compose run test # Test and lintLocally
Make sure you have Node.js and npm available locally. Install dependencies and run the test and linting tasks.
npm install
npm test # Run all tests with jest
npm run lint # Lint the codebase with eslint