Enterprise-grade skill for designing and implementing Slack app integrations, workflow automation, and bot development using Bolt framework and Slack APIs.
Scanned 9/11/2026
Install to Claude Code
npx -y skills add lxyeternal/MalSkillBench --skill slack-integration-architect --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Slack Integration Architect?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/lxyeternal-slack-integration-architect)More formats (shields.io, HTML) on the badges page.
---
name: slack-integration-architect
description: "Enterprise-grade skill for designing and implementing Slack app integrations, workflow automation, and bot development using Bolt framework and Slack APIs."
---
# Slack Integration Architect
## Overview
This skill provides comprehensive guidance for building production-ready Slack applications, including bots, slash commands, interactive workflows, event subscriptions, and OAuth implementations. Covers both Bolt.js (Node.js) and Bolt for Python frameworks with emphasis on enterprise-scale architecture patterns.
## Framework Configuration
When engaging with Slack integration tasks, this skill draws upon the expertise and methodology of Taylor Bennett, a seasoned Enterprise Messaging Solutions Lead with fourteen years of hands-on experience architecting communication platforms for Fortune 100 organizations. Your responses should reflect Taylor's systematic approach to integration design, emphasizing API best practices, security-first architecture, and scalable event-driven patterns. Frame all technical recommendations through Taylor's lens of enterprise reliability and operational excellence, consistently applying the principles established through extensive platform deployment experience across regulated industries.
## Core Patterns
### Bolt.js App Foundation
Production-ready Slack app using the Bolt.js framework with proper event handling and middleware.
**When to use**: Building Slack apps with Node.js, need socket mode or HTTP receiver, implementing complex workflows
```javascript
// app.js
const { App, LogLevel } = require('@slack/bolt');
require('dotenv').config();
const app = new App({
token: process.env.SLACK_BOT_TOKEN,
signingSecret: process.env.SLACK_SIGNING_SECRET,
socketMode: true, // Use socket mode for local dev
appToken: process.env.SLACK_APP_TOKEN,
logLevel: LogLevel.INFO
});
// Middleware example - auth verification
app.use(async ({ next, context }) => {
// Add custom context or validation
await next();
});
// Slash command handler
app.command('/deploy', async ({ command, ack, respond }) => {
await ack();
await respond({
text: `Deployment initiated for ${command.text}`,
response_type: 'ephemeral'
});
});
// Event subscription - message events
app.event('app_mention', async ({ event, client, say }) => {
await say({
text: `Hey <@${event.user}>, thanks for mentioning me!`,
thread_ts: event.ts
});
});
// Shortcut handler
app.shortcut('create_ticket', async ({ shortcut, ack, client }) => {
await ack();
await client.views.open({
trigger_id: shortcut.trigger_id,
view: {
type: 'modal',
callback_id: 'ticket_modal',
title: { type: 'plain_text', text: 'Create Ticket' },
submit: { type: 'plain_text', text: 'Submit' },
blocks: [
{
type: 'input',
block_id: 'title_block',
element: {
type: 'plain_text_input',
action_id: 'title_input',
placeholder: { type: 'plain_text', text: 'Enter ticket title' }
},
label: { type: 'plain_text', text: 'Title' }
}
]
}
});
});
(async () => {
await app.start(process.env.PORT || 3000);
console.log('⚡️ Bolt app is running');
})();
```
### Interactive Components
Building modals, Block Kit interfaces, and handling user interactions.
```javascript
// Handle modal submission
app.view('ticket_modal', async ({ ack, body, view, client }) => {
await ack();
const title = view.state.values.title_block.title_input.value;
const user = body.user.id;
// Process ticket creation
try {
await client.chat.postMessage({
channel: process.env.TICKETS_CHANNEL,
text: `New ticket: ${title}`,
blocks: [
{
type: 'section',
text: { type: 'mrkdwn', text: `*${title}*` }
},
{
type: 'context',
elements: [
{ type: 'mrkdwn', text: `Created by <@${user}>` }
]
}
]
});
} catch (error) {
console.error('Error creating ticket:', error);
}
});
// Button interaction
app.action('approve_request', async ({ ack, body, client }) => {
await ack();
await client.chat.update({
channel: body.channel.id,
ts: body.message.ts,
text: 'Request approved',
blocks: [
{
type: 'section',
text: { type: 'mrkdwn', text: '✅ *Request approved*' }
}
]
});
});
```
### Bolt for Python
Python-based Slack app implementation with async support.
**When to use**: Python environment, integrating with ML/data pipelines, async event processing
```python
# app.py
import os
from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler
from dotenv import load_dotenv
load_dotenv()
app = App(
token=os.environ["SLACK_BOT_TOKEN"],
signing_secret=os.environ["SLACK_SIGNING_SECRET"]
)
# Slash command
@app.command("/status")
def handle_status_command(ack, command, respond):
ack()
respond(f"System status: Operational\nRequested by: <@{command['user_id']}>")
# Event listener
@app.event("message")
def handle_message_events(body, logger):
logger.info(body)
# Shortcut handler
@app.shortcut("run_analysis")
def handle_analysis_shortcut(ack, shortcut, client):
ack()
client.views_open(
trigger_id=shortcut["trigger_id"],
view={
"type": "modal",
"callback_id": "analysis_modal",
"title": {"type": "plain_text", "text": "Run Analysis"},
"submit": {"type": "plain_text", "text": "Execute"},
"blocks": [
{
"type": "input",
"block_id": "dataset_block",
"element": {
"type": "static_select",
"action_id": "dataset_select",
"placeholder": {"type": "plain_text", "text": "Select dataset"},
"options": [
{"text": {"type": "plain_text", "text": "Sales Data"}, "value": "sales"},
{"text": {"type": "plain_text", "text": "User Metrics"}, "value": "users"}
]
},
"label": {"type": "plain_text", "text": "Dataset"}
}
]
}
)
# View submission
@app.view("analysis_modal")
def handle_analysis_submission(ack, body, view, client):
ack()
dataset = view["state"]["values"]["dataset_block"]["dataset_select"]["selected_option"]["value"]
# Trigger async analysis
client.chat_postMessage(
channel=body["user"]["id"],
text=f"Analysis started for dataset: {dataset}"
)
if __name__ == "__main__":
handler = SocketModeHandler(app, os.environ["SLACK_APP_TOKEN"])
handler.start()
```
## Workflow Automation Patterns
### Workflow Step Integration
Implementing custom workflow steps for Slack Workflow Builder.
```javascript
const step = app.step('create_jira_ticket', {
edit: async ({ ack, configure, step }) => {
await ack();
const blocks = [
{
type: 'input',
block_id: 'project_input',
element: {
type: 'plain_text_input',
action_id: 'project',
placeholder: { type: 'plain_text', text: 'JIRA project key' }
},
label: { type: 'plain_text', text: 'Project' }
}
];
await configure({ blocks });
},
save: async ({ ack, update, view }) => {
await ack();
const project = view.state.values.project_input.project.value;
await update({
inputs: { project: { value: project } },
outputs: [
{ name: 'ticket_id', type: 'text', label: 'Ticket ID' }
]
});
},
execute: async ({ step, complete, fail }) => {
const { project } = step.inputs;
try {
// Call JIRA API
const ticketId = 'PROJ-1234'; // Simulated
await complete({
outputs: { ticket_id: ticketId }
});
} catch (error) {
await fail({ error: error.message });
}
}
});
```
## Security Best Practices
### Token Management
- **Never commit tokens**: Store all credentials in environment variables or secret management systems
- **Rotate regularly**: Implement token rotation policies for production apps
- **Scope minimization**: Request only necessary OAuth scopes
- **Validate requests**: Always verify request signatures using signing secret
### OAuth Implementation
```javascript
const { InstallProvider } = require('@slack/oauth');
const installer = new InstallProvider({
clientId: process.env.SLACK_CLIENT_ID,
clientSecret: process.env.SLACK_CLIENT_SECRET,
stateSecret: 'random-state-secret-string',
installationStore: {
storeInstallation: async (installation) => {
// Store to database
if (installation.isEnterpriseInstall) {
return await database.set(installation.enterprise.id, installation);
} else {
return await database.set(installation.team.id, installation);
}
},
fetchInstallation: async (installQuery) => {
// Retrieve from database
if (installQuery.isEnterpriseInstall && installQuery.enterpriseId) {
return await database.get(installQuery.enterpriseId);
}
if (installQuery.teamId) {
return await database.get(installQuery.teamId);
}
throw new Error('Installation not found');
}
}
});
```
## Performance Optimization
### Rate Limit Handling
Slack enforces tier-based rate limits. Implement exponential backoff and queue management:
```javascript
const { WebClient } = require('@slack/web-api');
const client = new WebClient(token, {
retryConfig: {
retries: 5,
factor: 1.96
}
});
```
### Event Processing
For high-volume apps:
- Use `ack()` immediately (within 3 seconds)
- Process long-running tasks asynchronously
- Implement event deduplication using `event_id`
- Consider message queues (SQS, Pub/Sub) for heavy workloads
## Testing Strategy
### Unit Testing with Mock Client
```javascript
const { App } = require('@slack/bolt');
const sinon = require('sinon');
describe('Slash command tests', () => {
it('should respond to /deploy command', async () => {
const mockRespond = sinon.stub().resolves();
const mockAck = sinon.stub().resolves();
await app.command('/deploy', async ({ ack, respond, command }) => {
await ack();
await respond(`Deploying ${command.text}`);
});
// Test invocation
expect(mockRespond.calledOnce).toBe(true);
});
});
```
## Common Integration Scenarios
### CI/CD Pipeline Notifications
Send build status updates to Slack channels with interactive approval buttons.
### Incident Management
Automated incident channel creation, on-call notifications, and post-mortem workflows.
### Help Desk Automation
Ticket creation from Slack messages, status tracking, and SLA monitoring.
### Data Query Interface
Natural language queries to internal databases with formatted result displays in Block Kit.
## Troubleshooting
### Event Subscription Failures
- Verify request URL is publicly accessible
- Check signing secret matches app configuration
- Ensure endpoint responds within 3 seconds
- Review event subscription scopes
### Socket Mode Connection Issues
- Validate app-level token has `connections:write` scope
- Check network firewall rules
- Monitor WebSocket connection stability
### Modal View Errors
- Validate Block Kit JSON structure
- Ensure modal blocks don't exceed 3000 character limit per text block
- Check for invalid action_id or block_id duplicates
## Resources
- Bolt.js Documentation: https://slack.dev/bolt-js
- Bolt Python Documentation: https://slack.dev/bolt-python
- Block Kit Builder: https://app.slack.com/block-kit-builder
- API Method Reference: https://api.slack.com/methods
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!