S

Slack Bot Smart

Streamline your workflow with this build, slack, apps, using. Includes structured workflows, validation checks, and reusable patterns for enterprise communication.

SkillClipticsenterprise communicationv1.0.0MIT
0 views0 copies

Slack Bot Smart

A comprehensive skill for building Slack bots using the Bolt framework — covering app setup, event handling, slash commands, interactive components, message formatting with Block Kit, middleware patterns, and deployment to production.

When to Use This Skill

Choose Slack Bot Smart when you need to:

  • Build a Slack bot with slash commands and event listeners
  • Create interactive workflows with buttons, modals, and menus
  • Integrate external services with Slack notifications
  • Build message formatting with Block Kit
  • Deploy a production-ready Slack application

Consider alternatives when:

  • You need a simple webhook notification (use Slack webhooks directly)
  • You're building a Discord bot (use a Discord bot skill)
  • You need a Microsoft Teams bot (use a Teams bot skill)

Quick Start

# Initialize a Slack bot project mkdir my-slack-bot && cd my-slack-bot npm init -y npm install @slack/bolt dotenv
// app.js — Bolt app setup const { App } = require("@slack/bolt"); require("dotenv").config(); const app = new App({ token: process.env.SLACK_BOT_TOKEN, signingSecret: process.env.SLACK_SIGNING_SECRET, socketMode: true, appToken: process.env.SLACK_APP_TOKEN, }); // Slash command app.command("/hello", async ({ command, ack, respond }) => { await ack(); await respond({ text: `Hey <@${command.user_id}>! How can I help?`, response_type: "ephemeral", }); }); // Message event listener app.message("hello bot", async ({ message, say }) => { await say({ text: `Hi <@${message.user}>! šŸ‘‹`, blocks: [ { type: "section", text: { type: "mrkdwn", text: `Hi <@${message.user}>! How can I help you today?`, }, accessory: { type: "button", text: { type: "plain_text", text: "Get Help" }, action_id: "help_button", }, }, ], }); }); // Button interaction app.action("help_button", async ({ body, ack, respond }) => { await ack(); await respond("Here's what I can do: `/hello`, `/status`, `/deploy`"); }); (async () => { await app.start(3000); console.log("⚔ Slack bot is running on port 3000"); })();

Core Concepts

Bolt App Architecture

ComponentPurposeHandler Type
CommandsSlash command handlersapp.command()
EventsMessage and workspace eventsapp.event()
ActionsButton, menu, and select interactionsapp.action()
ViewsModal submissions and updatesapp.view()
ShortcutsGlobal and message shortcutsapp.shortcut()
MiddlewareCross-cutting concernsapp.use()

Block Kit Message Formatting

// Rich message with Block Kit const statusMessage = { blocks: [ { type: "header", text: { type: "plain_text", text: "Deployment Status" }, }, { type: "section", fields: [ { type: "mrkdwn", text: "*Service:*\napi-gateway" }, { type: "mrkdwn", text: "*Environment:*\nproduction" }, { type: "mrkdwn", text: "*Version:*\nv2.3.1" }, { type: "mrkdwn", text: "*Status:*\nāœ… Deployed" }, ], }, { type: "divider" }, { type: "actions", elements: [ { type: "button", text: { type: "plain_text", text: "View Logs" }, action_id: "view_logs", url: "https://logs.example.com/api-gateway", }, { type: "button", text: { type: "plain_text", text: "Rollback" }, action_id: "rollback", style: "danger", confirm: { title: { type: "plain_text", text: "Confirm Rollback" }, text: { type: "mrkdwn", text: "Roll back to v2.3.0?" }, confirm: { type: "plain_text", text: "Rollback" }, deny: { type: "plain_text", text: "Cancel" }, }, }, ], }, ], };
// Open a modal from a slash command app.command("/feedback", async ({ command, ack, client }) => { await ack(); await client.views.open({ trigger_id: command.trigger_id, view: { type: "modal", callback_id: "feedback_modal", title: { type: "plain_text", text: "Submit Feedback" }, submit: { type: "plain_text", text: "Submit" }, blocks: [ { type: "input", block_id: "category", element: { type: "static_select", action_id: "category_select", options: [ { text: { type: "plain_text", text: "Bug" }, value: "bug" }, { text: { type: "plain_text", text: "Feature" }, value: "feature" }, { text: { type: "plain_text", text: "Other" }, value: "other" }, ], }, label: { type: "plain_text", text: "Category" }, }, { type: "input", block_id: "details", element: { type: "plain_text_input", action_id: "details_input", multiline: true, }, label: { type: "plain_text", text: "Details" }, }, ], }, }); }); // Handle modal submission app.view("feedback_modal", async ({ ack, body, view }) => { await ack(); const category = view.state.values.category.category_select.selected_option.value; const details = view.state.values.details.details_input.value; console.log(`Feedback: ${category} — ${details}`); });

Configuration

ParameterDescriptionExample
bot_tokenSlack Bot User OAuth Tokenprocess.env.SLACK_BOT_TOKEN
signing_secretSlack app signing secretprocess.env.SLACK_SIGNING_SECRET
app_tokenApp-level token for Socket Modeprocess.env.SLACK_APP_TOKEN
socket_modeUse Socket Mode instead of HTTPtrue
portHTTP server port (if not Socket Mode)3000
log_levelLogging verbosity"info" / "debug"

Best Practices

  1. Use Socket Mode during development, HTTP endpoints in production — Socket Mode requires no public URL and works behind firewalls, making it perfect for development. For production, switch to HTTP endpoints behind a load balancer for reliability and observability.

  2. Always ack() interactions within 3 seconds — Slack requires acknowledgment of every interaction within 3 seconds. Call ack() immediately, then process the request asynchronously. Failing to ack causes the user to see a timeout error even if your bot eventually responds.

  3. Use Block Kit Builder to prototype messages visually — Slack's Block Kit Builder (app.slack.com/block-kit-builder) lets you design and preview message layouts visually, then copy the JSON into your code. Building complex Block Kit JSON by hand is error-prone and slow.

  4. Store tokens in environment variables with clear naming — Slack apps use multiple tokens (bot token, signing secret, app token). Name them clearly (SLACK_BOT_TOKEN, SLACK_SIGNING_SECRET) and never commit them to source control. Rotate tokens immediately if exposed.

  5. Implement error handling middleware — Add a global error handler with app.error() that logs errors with context (user, command, channel) and sends a user-friendly ephemeral message. Unhandled errors cause silent failures that are difficult to debug.

Common Issues

Bot doesn't receive messages in channels — The bot must be invited to a channel to receive message events there. Additionally, ensure the channels:history and chat:write scopes are added, and the message.channels event is subscribed in your app configuration.

Slash commands work in DM but not in channels — Verify that the command is registered in the Slack app configuration (not just in your code). Also check that the request URL (for HTTP mode) is publicly accessible and correctly configured in the Slack API dashboard.

Modal fails to open with "expired trigger_id" — Trigger IDs expire after 3 seconds. If your command handler does any processing before calling views.open(), the trigger ID may expire. Call views.open() as early as possible in the handler, or use ack() with a response_action to update the view.

Community

Reviews

Write a review

No reviews yet. Be the first to review this template!

Similar Templates