A Slack bot built with the Bolt framework that provides various utility functions for the Lullabot Slack workspace.
This provides a modular architecture for adding new features to the bot.
- Node.js (v18 or higher recommended)
- npm
- A Slack workspace with admin access
- Slack bot token and app-level token
- Clone the repository
- Install dependencies:
npm install-
Create a new Slack app at https://api.slack.com/apps/
-
Configure the app using the provided
slack-app-manifest.jsonfile -
Create an app-level token with these scopes:
- connections:write
- authorizations:read
- app_configurations:write
This will be your
SLACK_APP_TOKEN(starts with xapp-)
-
Under OAuth & Permissions:
- Click "Install to Workspace" to get the OAuth token
- Copy the Bot User OAuth Token - this will be your
BOT_TOKEN(starts with xoxb-)
-
Under Basic Information:
- Find "Signing Secret" in App Credentials section
- Copy the signing secret - this will be your
CLIENT_SIGNING_SECRET
-
Create a
.envfile in the root directory with your Slack tokens:
BOT_TOKEN=xoxb-your-bot-token
SLACK_APP_TOKEN=xapp-your-app-token
CLIENT_SIGNING_SECRET=your-signing-secret
npm run dev # Run in development mode with ts-node
npm run build # Build TypeScript to JavaScript
npm start # Build and run the production version
npm run watch # Watch for changes and rebuildPlugins are written in TypeScript and should be placed in the src/plugins directory. Each plugin should:
- Import required types:
import { App } from '@slack/bolt';
import { Plugin } from '../types';- Export a default function that implements the Plugin type:
const myPlugin: Plugin = async (app: App): Promise<void> => {
// Your plugin code here
};
export default myPlugin;- Use proper type annotations for Slack events:
import { GenericMessageEvent } from '@slack/types/dist/events/message';
import { AppMentionEvent } from '@slack/types/dist/events/app';
app.message(/pattern/, async ({ message, say }) => {
const msg = message as GenericMessageEvent;
// Handle message
});Access documentation and command information for all bot features.
Features:
- Lists all available plugins and their commands
- Provides detailed help for specific plugins
- Responds in threads for better organization
- Supports multiple query formats
Examples:
@bot help # Show all commands
@bot commands # Show all commands
@bot plugins # List available plugins
@bot help factoids # Show factoids help
@bot help karma # Show karma help
Store and retrieve custom responses for frequently asked questions or common information.
Features:
- Store and retrieve custom responses
- Support for direct responses and templated replies
- Update or append to existing factoids
- Interactive buttons for managing factoid updates
- Delete factoids with the 'forget' command
- Trigger factoids by starting a message with the keyword followed by ? or !
Examples:
Query a factoid:
sales? # Show the "sales" factoid
@username? # Show factoid for a user
documentation! # Show the "documentation" factoid (! works same as ?)
Manage factoids:
!factoid: list # List all available factoids
@bot X is Y # Set a new factoid
@bot X is <reply>Y # Set a factoid with direct reply
@bot forget X # Delete a factoid
When setting a factoid, you can use <reply> to make the bot respond with just the content instead of "X is Y":
- Without reply: "sales is Check out https://sales.example.com"
- With reply: "Check out https://sales.example.com"
Thread Support:
- All factoid responses respect message threading
- Updates and management happen in threads when triggered from a thread
Track and manage karma points for users and things in your Slack workspace.
Features:
- Give or take karma points using ++ or --
- Query karma levels for users or items
- Prevents self-karma manipulation
- Supports user mentions and plain text
- Persistent storage per team
- Thread-aware responses
Examples:
Give/Take Karma:
@user++ # Give karma to user
@user-- # Take karma from user
cats++ # Give karma to thing
tacos-- # Take karma from thing
:emoji:++ # Give karma to emoji
Query Karma:
karma @user # Query user's karma
karma cats # Query thing's karma
@bot karma @user # Query via mention
Note: Users cannot give or take karma from themselves.
- Responds to various greeting patterns
- Adds wave reactions to greetings
- Supports both direct messages and mentions
- Fallback to text responses if reactions fail
Examples:
hello!hey!hi!:wave:
- Reports bot uptime statistics
- Shows bot identification information
- Responds to various identity queries
Examples:
uptimeidentify yourselfwho are youwhat is your name
Give the bot a treat and receive a message of gratitude!
Features:
- Responds to "botsnack" with random thank you messages
- Supports both direct messages and mentions
- Includes emoji reactions
Examples:
botsnack # Give the bot a snack
@bot botsnack # Give the bot a snack (with mention)
The bot uses file-based JSON storage in the data directory for:
- Karma points
- Factoids
- Each team's data is stored in separate files
The bot uses a modular plugin system. Each feature is implemented as a separate plugin in the plugins directory. New functionality can be added by creating new plugin files.
- Create a new plugin file in the
pluginsdirectory - Export an async function that takes the Bolt app instance as a parameter
- Use Bolt's event system to handle messages and interactions
- Follow existing patterns for data storage and error handling
The factoid plugin includes a test suite that verifies the pattern matching functionality works correctly. This ensures the bot correctly identifies which messages should trigger factoid lookups and which should be ignored.
To run the factoid tests:
npm testThis will run all test suites, including the factoid pattern tests.
To run just the factoid tests:
npm test -- -t "Factoids Plugin"The test patterns are defined in two arrays in src/plugins/__tests__/factoids.test.ts:
shouldMatchPatterns- Patterns that SHOULD trigger a factoid lookupshouldNotMatchPatterns- Patterns that should NOT trigger a factoid lookup
To add new test patterns:
- Open
src/plugins/__tests__/factoids.test.ts - Add your new pattern to the appropriate array:
// Use these patterns to test if the factoid plugin would trigger
const shouldMatchPatterns = [
'factoid?',
'factoid!',
// Add your new MATCHING pattern here
'your-new-pattern?'
];
// These patterns should NOT trigger the factoid plugin
const shouldNotMatchPatterns = [
'factoid ?',
'factoid !',
// Add your new NON-MATCHING pattern here
'your new pattern that should not match?'
];- Update the corresponding documentation in
src/tests/factoids-pattern-tests.mdto keep it in sync with the actual tests.
The current pattern matching rules are:
- Messages ending with
?or!with no space before the punctuation will trigger factoid lookup - User mentions followed by additional text are ignored
- Messages with more than 5 words are considered too complex and ignored
- Messages with a space before the final punctuation are ignored
The pattern matching logic is implemented in two places:
src/plugins/__tests__/factoids.test.tsin theshouldTriggerFactoidfunction (for testing)src/plugins/factoids.tsin the message handler
If you need to change how patterns are matched, make sure to update both locations to keep them in sync.
- Logs are output to console
- Plugin loading errors are handled gracefully
- Data files are stored in JSON format for easy debugging
- Each plugin handles its own error cases
- @slack/bolt: Slack Bolt framework
- datejs: Date parsing and formatting
- dotenv: Environment variable management
For detailed API documentation and examples, refer to the Slack Bolt documentation.