S

Specialist Slack Ally

Enterprise-grade agent for agent, developing, slack, applications. Includes structured workflows, validation checks, and reusable patterns for development tools.

AgentClipticsdevelopment toolsv1.0.0MIT
0 views0 copies

Specialist Slack Ally

A Slack integration specialist that helps you build, configure, and optimize Slack apps, bots, and workflows, covering the Bolt SDK, Block Kit UI, slash commands, and event-driven architectures.

When to Use This Agent

Choose Specialist Slack Ally when:

  • Building Slack bots or apps with the Bolt SDK
  • Designing interactive messages and modals with Block Kit
  • Implementing slash commands and event listeners
  • Setting up Slack workflows with external integrations
  • Debugging Slack API issues (OAuth, event subscriptions, rate limits)

Consider alternatives when:

  • Building chat features for your own application (use a general development agent)
  • Setting up Slack notifications from CI/CD (use a DevOps agent)
  • Creating a general-purpose chatbot (use an AI agent builder)

Quick Start

# .claude/agents/specialist-slack-ally.yml name: Specialist Slack Ally description: Build and optimize Slack integrations model: claude-sonnet tools: - Read - Write - Edit - Bash - Glob - Grep - WebSearch

Example invocation:

claude "Build a Slack bot that creates incident channels, notifies the on-call team, and tracks incident status with interactive buttons"

Core Concepts

Slack App Architecture

ComponentPurposeImplementation
Bolt AppSDK framework@slack/bolt
Event ListenerReact to workspace eventsapp.event()
Slash CommandHandle / commandsapp.command()
InteractiveHandle button/modal actionsapp.action()
Block KitRich message UIJSON blocks
MiddlewareAuth, logging, validationapp.use()

Bolt SDK Setup

// src/app.ts — Slack Bolt application import { App, LogLevel } from '@slack/bolt'; const app = new App({ token: process.env.SLACK_BOT_TOKEN, signingSecret: process.env.SLACK_SIGNING_SECRET, socketMode: true, appToken: process.env.SLACK_APP_TOKEN, logLevel: LogLevel.INFO, }); // Slash command handler app.command('/incident', async ({ command, ack, client }) => { await ack(); // Create incident channel const channel = await client.conversations.create({ name: `incident-${Date.now()}`, is_private: false, }); // Post incident details with interactive buttons await client.chat.postMessage({ channel: channel.channel.id, blocks: [ { type: 'header', text: { type: 'plain_text', text: `Incident: ${command.text}` }, }, { type: 'section', text: { type: 'mrkdwn', text: `*Reporter:* <@${command.user_id}>` }, }, { type: 'actions', elements: [ { type: 'button', text: { type: 'plain_text', text: 'Acknowledge' }, action_id: 'incident_ack', style: 'primary', }, { type: 'button', text: { type: 'plain_text', text: 'Resolve' }, action_id: 'incident_resolve', style: 'danger', confirm: { title: { type: 'plain_text', text: 'Resolve incident?' }, text: { type: 'mrkdwn', text: 'This will mark the incident as resolved.' }, confirm: { type: 'plain_text', text: 'Resolve' }, deny: { type: 'plain_text', text: 'Cancel' }, }, }, ], }, ], }); }); // Interactive button handler app.action('incident_ack', async ({ body, ack, client }) => { await ack(); await client.chat.postMessage({ channel: body.channel.id, text: `Incident acknowledged by <@${body.user.id}>`, }); }); (async () => { await app.start(); console.log('Slack bot is running'); })();

Block Kit Message Design

// Rich notification with structured data const deployNotification = { blocks: [ { type: 'header', text: { type: 'plain_text', text: 'Deployment Complete' }, }, { type: 'section', fields: [ { type: 'mrkdwn', text: '*Service:*\ payment-api' }, { type: 'mrkdwn', text: '*Version:*\ v2.4.1' }, { type: 'mrkdwn', text: '*Environment:*\ production' }, { type: 'mrkdwn', text: '*Deployed by:*\ <@U123456>' }, ], }, { type: 'divider' }, { type: 'context', elements: [ { type: 'mrkdwn', text: ':white_check_mark: All health checks passing' }, ], }, ], };

Configuration

ParameterDescriptionDefault
sdkSlack SDK version (bolt-js, bolt-python)bolt-js
connection_modeConnection type (socket-mode, http)socket-mode
token_typeAuth approach (bot-token, user-token)bot-token
block_kitUse Block Kit for rich messagestrue
event_subscriptionsEvent types to listen forApp-specific
rate_limit_handlingAutomatic rate limit retrytrue

Best Practices

  1. Acknowledge slash commands and interactions within 3 seconds. Slack requires a response within 3 seconds or it shows a timeout error to the user. Call await ack() immediately, then perform the actual work asynchronously. For long operations, ack with a "Processing..." message and update it later using client.chat.update(). This prevents timeout errors while preserving responsive UX.

  2. Use Socket Mode for development and internal tools. Socket Mode does not require a public URL or webhook configuration, making it ideal for development and internal bots. It establishes a WebSocket connection from your app to Slack. For production apps with high traffic, switch to HTTP mode with a load-balanced endpoint. Socket Mode has a lower throughput ceiling but is significantly easier to set up.

  3. Design Block Kit messages for scannability, not information density. Slack messages compete for attention in busy channels. Use headers for context, section blocks for key details, and minimize text length. Put secondary information in context blocks (smaller, muted text). Use buttons for actions instead of asking users to type commands. Test your messages by asking: "Can someone glance at this and understand the situation in 3 seconds?"

  4. Implement idempotent event handlers for retry safety. Slack retries event deliveries if your app does not acknowledge within 3 seconds. Without idempotency, the same event is processed multiple times: duplicate messages, duplicate database writes, or duplicate notifications. Track event IDs and skip already-processed events. Use database upserts instead of inserts for event-driven state changes.

  5. Centralize Slack API error handling with middleware. Wrap all Slack API calls in error handling that distinguishes between rate limits (429, retry after delay), auth errors (401/403, alert admin), not-found errors (channel deleted, handle gracefully), and server errors (500, retry with backoff). A shared error handler prevents inconsistent error handling across different commands and listeners.

Common Issues

Bot messages are not appearing in channels despite successful API responses. The bot may not be a member of the channel. Slack bots must be invited to channels (or join via conversations.join) before they can post messages. For private channels, a user must invite the bot. Check that the bot has the chat:write scope and has been added to the target channel. Error responses include not_in_channel when this is the problem.

Event subscriptions receive duplicate events during traffic spikes. Slack retries events when the acknowledgment is delayed, and during high-traffic periods, multiple events may arrive for the same action. Implement deduplication using the event_id field. Store processed event IDs in a cache (Redis with TTL) and skip any event whose ID has already been processed. Set the TTL to 1 hour since Slack stops retrying after that.

Rate limiting causes message delivery failures during notifications to many users. Slack imposes rate limits on API methods (typically 1 request per second for chat.postMessage per channel). Batch notifications to multiple users create bursts that exceed limits. Implement a message queue that processes messages with a delay between each call. Use conversations.list to batch channel lookups rather than making individual calls. When rate-limited, respect the Retry-After header before retrying.

Community

Reviews

Write a review

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

Similar Templates