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
SLACK_SHARED_SECRET=your-shared-secret-for-prompt-library
GITHUB_TOKEN=your-github-personal-access-token
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)
Submit valuable Slack messages as prompts to the Lullabot prompt library for future reference and sharing.
Features:
- Takes a Slack message permalink and submits it to the prompt library
- Captures original message content, author, and invoker information
- Validates permalink format and fetches message details
- Secure integration with GitHub repository dispatch system
Examples:
@bot add-prompt https://workspace.slack.com/archives/C1234567890/p1234567890123456
Setup Requirements:
SLACK_SHARED_SECRETenvironment variable must be configuredGITHUB_TOKENenvironment variable with a GitHub Personal Access Token- Shared secret must match the one configured in the prompt_library repository
GitHub Token Setup (Recommended: Fine-grained):
- Go to https://github.com/settings/personal-access-tokens/fine-grained
- Click "Generate new token"
- Give it a descriptive name (e.g., "Lullabot Slack Bot - Add Prompt")
- Set expiration as desired (90 days recommended)
- Under "Repository access", select "Selected repositories" → choose
Lullabot/prompt_library - Grant these minimum required repository permissions:
- ✅ Issues: Write (to create issues from Slack prompts)
- ✅ Metadata: Read (to access basic repository information)
- ✅ Contents: Write (to read/write repository contents)
- Click "Generate token" and copy the token (starts with
github_pat_) - Add to your
.envfile:GITHUB_TOKEN=github_pat_your_token_here
Alternative: Classic Personal Access Token:
- Go to https://github.com/settings/tokens
- Click "Generate new token" → "Generate new token (classic)"
- Select these scopes:
- ✅
repo(full control of private repositories) - ✅
workflow(update GitHub Action workflows)
- ✅
- Add to your
.envfile:GITHUB_TOKEN=ghp_your_token_here
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
.env files to version control.
This project uses environment variables for sensitive configuration:
BOT_TOKEN- Slack Bot User OAuth Token (xoxb-*)SLACK_APP_TOKEN- App-level token (xapp-*)CLIENT_SIGNING_SECRET- Slack app signing secretGITHUB_TOKEN- GitHub Personal Access TokenSLACK_SHARED_SECRET- Shared secret for prompt library
✅ Implemented Security Measures:
- Comprehensive sensitive data redaction in logging
.envfiles excluded from version control- Pre-commit hooks for secret scanning
- Automated security audits in CI/CD
- Dependency vulnerability monitoring with Dependabot
-
Secrets Management:
- Use
.envfiles for local development only - Never hardcode secrets in source code
- Rotate tokens regularly
- Use environment-specific secrets in production
- Use
-
Pre-commit Security:
# Pre-commit hooks automatically run: npx lint-staged # Secret scanning on staged files npm audit --audit-level=high --production # Production dependency vulnerabilities npm test # Test suite
-
Dependency Security:
- Run
npm auditbefore commits - Review and approve Dependabot security updates
- Monitor GitHub security advisories
- Run
-
Production Deployment:
- Use secret management services (AWS Secrets Manager, etc.)
- Enable audit logging
- Implement rate limiting
- Use HTTPS-only endpoints
Please report security vulnerabilities through:
- GitHub Security Advisory (preferred)
- Private communication with maintainers
Do not report security issues in public issues.
For detailed API documentation and examples, refer to the Slack Bolt documentation.