Build Slack apps using the Bolt framework across Python, JavaScript, and Java. Covers Block Kit for rich UIs, interactive components, slash commands, event handling, OAuth installation flows, and Workflow Builder integration. Focus on best practices for production-ready Slack apps. Use when: slack bot, slack app, bolt framework, block kit, slash command.
Add this skill
npx mdskills install sickn33/slack-bot-builderComprehensive Slack Bolt framework guide with practical examples and production best practices
1---2name: slack-bot-builder3description: "Build Slack apps using the Bolt framework across Python, JavaScript, and Java. Covers Block Kit for rich UIs, interactive components, slash commands, event handling, OAuth installation flows, and Workflow Builder integration. Focus on best practices for production-ready Slack apps. Use when: slack bot, slack app, bolt framework, block kit, slash command."4source: vibeship-spawner-skills (Apache 2.0)5---67# Slack Bot Builder89## Patterns1011### Bolt App Foundation Pattern1213The Bolt framework is Slack's recommended approach for building apps.14It handles authentication, event routing, request verification, and15HTTP request processing so you can focus on app logic.1617Key benefits:18- Event handling in a few lines of code19- Security checks and payload validation built-in20- Organized, consistent patterns21- Works for experiments and production2223Available in: Python, JavaScript (Node.js), Java242526**When to use**: ['Starting any new Slack app', 'Migrating from legacy Slack APIs', 'Building production Slack integrations']2728```python29# Python Bolt App30from slack_bolt import App31from slack_bolt.adapter.socket_mode import SocketModeHandler32import os3334# Initialize with tokens from environment35app = App(36 token=os.environ["SLACK_BOT_TOKEN"],37 signing_secret=os.environ["SLACK_SIGNING_SECRET"]38)3940# Handle messages containing "hello"41@app.message("hello")42def handle_hello(message, say):43 """Respond to messages containing 'hello'."""44 user = message["user"]45 say(f"Hey there <@{user}>!")4647# Handle slash command48@app.command("/ticket")49def handle_ticket_command(ack, body, client):50 """Handle /ticket slash command."""51 # Acknowledge immediately (within 3 seconds)52 ack()5354 # Open a modal for ticket creation55 client.views_open(56 trigger_id=body["trigger_id"],57 view={58 "type": "modal",59 "callback_id": "ticket_modal",60 "title": {"type": "plain_text", "text": "Create Ticket"},61 "submit": {"type": "plain_text", "text": "Submit"},62 "blocks": [63 {64 "type": "input",65 "block_id": "title_block",66 "element": {67 "type": "plain_text_input",68 "action_id": "title_input"69 },70 "label": {"type": "plain_text", "text": "Title"}71 },72 {73 "type": "input",74 "block_id": "desc_block",75 "element": {76 "type": "plain_text_input",77 "multiline": True,78 "action_id": "desc_input"79 },80 "label": {"type": "plain_text", "text": "Description"}81 },82 {83 "type": "input",84 "block_id": "priority_block",85 "element": {86 "type": "static_select",87 "action_id": "priority_select",8889```9091### Block Kit UI Pattern9293Block Kit is Slack's UI framework for building rich, interactive messages.94Compose messages using blocks (sections, actions, inputs) and elements95(buttons, menus, text inputs).9697Limits:98- Up to 50 blocks per message99- Up to 100 blocks in modals/Home tabs100- Block text limited to 3000 characters101102Use Block Kit Builder to prototype: https://app.slack.com/block-kit-builder103104105**When to use**: ['Building rich message layouts', 'Adding interactive components to messages', 'Creating forms in modals', 'Building Home tab experiences']106107```python108from slack_bolt import App109import os110111app = App(token=os.environ["SLACK_BOT_TOKEN"])112113def build_notification_blocks(incident: dict) -> list:114 """Build Block Kit blocks for incident notification."""115 severity_emoji = {116 "critical": ":red_circle:",117 "high": ":large_orange_circle:",118 "medium": ":large_yellow_circle:",119 "low": ":white_circle:"120 }121122 return [123 # Header124 {125 "type": "header",126 "text": {127 "type": "plain_text",128 "text": f"{severity_emoji.get(incident['severity'], '')} Incident Alert"129 }130 },131 # Details section132 {133 "type": "section",134 "fields": [135 {136 "type": "mrkdwn",137 "text": f"*Incident:*\n{incident['title']}"138 },139 {140 "type": "mrkdwn",141 "text": f"*Severity:*\n{incident['severity'].upper()}"142 },143 {144 "type": "mrkdwn",145 "text": f"*Service:*\n{incident['service']}"146 },147 {148 "type": "mrkdwn",149 "text": f"*Reported:*\n<!date^{incident['timestamp']}^{date_short} {time}|{incident['timestamp']}>"150 }151 ]152 },153 # Description154 {155 "type": "section",156 "text": {157 "type": "mrkdwn",158 "text": f"*Description:*\n{incident['description'][:2000]}"159 }160 },161 # Divider162 {"type": "divider"},163 # Action buttons164 {165 "type": "actions",166 "block_id": f"incident_actions_{incident['id']}",167 "elements": [168 {169 "type": "button",170 "text": {"type": "plain_text", "text": "Acknowledge"},171 "style": "primary",172 "action_id": "acknowle173```174175### OAuth Installation Pattern176177Enable users to install your app in their workspaces via OAuth 2.0.178Bolt handles most of the OAuth flow, but you need to configure it179and store tokens securely.180181Key OAuth concepts:182- Scopes define permissions (request minimum needed)183- Tokens are workspace-specific184- Installation data must be stored persistently185- Users can add scopes later (additive)18618770% of users abandon installation when confronted with excessive188permission requests - request only what you need!189190191**When to use**: ['Distributing app to multiple workspaces', 'Building public Slack apps', 'Enterprise-grade integrations']192193```python194from slack_bolt import App195from slack_bolt.oauth.oauth_settings import OAuthSettings196from slack_sdk.oauth.installation_store import FileInstallationStore197from slack_sdk.oauth.state_store import FileOAuthStateStore198import os199200# For production, use database-backed stores201# For example: PostgreSQL, MongoDB, Redis202203class DatabaseInstallationStore:204 """Store installation data in your database."""205206 async def save(self, installation):207 """Save installation when user completes OAuth."""208 await db.installations.upsert({209 "team_id": installation.team_id,210 "enterprise_id": installation.enterprise_id,211 "bot_token": encrypt(installation.bot_token),212 "bot_user_id": installation.bot_user_id,213 "bot_scopes": installation.bot_scopes,214 "user_id": installation.user_id,215 "installed_at": installation.installed_at216 })217218 async def find_installation(self, *, enterprise_id, team_id, user_id=None, is_enterprise_install=False):219 """Find installation for a workspace."""220 record = await db.installations.find_one({221 "team_id": team_id,222 "enterprise_id": enterprise_id223 })224225 if record:226 return Installation(227 bot_token=decrypt(record["bot_token"]),228 # ... other fields229 )230 return None231232# Initialize OAuth-enabled app233app = App(234 signing_secret=os.environ["SLACK_SIGNING_SECRET"],235 oauth_settings=OAuthSettings(236 client_id=os.environ["SLACK_CLIENT_ID"],237 client_secret=os.environ["SLACK_CLIENT_SECRET"],238 scopes=[239 "channels:history",240 "channels:read",241 "chat:write",242 "commands",243 "users:read"244 ],245 user_scopes=[], # User token scopes if needed246 installation_store=DatabaseInstallationStore(),247 state_store=FileOAuthStateStore(expiration_seconds=600)248 )249)250251# OAuth routes are handled a252```253254## ⚠️ Sharp Edges255256| Issue | Severity | Solution |257|-------|----------|----------|258| Issue | critical | ## Acknowledge immediately, process later |259| Issue | critical | ## Proper state validation |260| Issue | critical | ## Never hardcode or log tokens |261| Issue | high | ## Request minimum required scopes |262| Issue | medium | ## Know and respect the limits |263| Issue | high | ## Socket Mode: Only for development |264| Issue | critical | ## Bolt handles this automatically |265
Full transparency — inspect the skill content before installing.