Skip to main content
slack-expert Expert-level Slack platform development using Bolt SDK — build Slack apps with slash commands, interactive components (buttons, modals, shortcuts), home tabs, event subscriptions, workflows, Socket Mode, and Block Kit. Use for building Slack bots, workflow automation, and rich interactive Slack experiences.
Aller à l'installation Skills Marketplace Découvrez et explorez les compétences IA créées par la communauté.
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Copier le promptAfficher les détails du prompt Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
npx skills add https://github.com/oimiragieo/agent-studio --skill slack-expertLa commande reste sur une seule ligne. Faites défiler horizontalement pour la vérifier avant de la copier.
Vous préférez une copie locale ? Téléchargez les fichiers actuellement disponibles dans SkillsMP.
Télécharger Zip Téléchargement... Métiers associés SOC
Basé sur la classification professionnelle SOC
Explorateur de fichiers
10 fichiers name slack-expert description Expert-level Slack platform development using Bolt SDK — build Slack apps with slash commands, interactive components (buttons, modals, shortcuts), home tabs, event subscriptions, workflows, Socket Mode, and Block Kit. Use for building Slack bots, workflow automation, and rich interactive Slack experiences. version 1.0.0 model sonnet invoked_by both user_invocable true tools ["Bash","Read","Write","Edit","WebFetch"] best_practices ["Always use Bolt SDK (not raw HTTP) for new Slack apps","Prefer Socket Mode for internal tools; HTTP for public apps","Validate request signatures before processing payloads","Use lazy listeners for long-running operations","Store OAuth tokens in a secure database, never env-vars for multi-workspace apps"] error_handling graceful streaming supported verified false lastVerifiedAt "2026-03-14T00:00:00.000Z" source builtin trust_score 100 provenance_sha 5d2e560139ce9700
Slack Expert Skill
Overview
Full-platform Slack development using the Bolt SDK. Covers interactive app development beyond basic messaging — slash commands, modals, shortcuts, home tabs, event subscriptions, workflow steps, and multi-workspace OAuth.
Related skill: slack-notifications — use that skill for simple one-way messaging/alerts. Use slack-expert when building interactive Slack apps or bots.
Requirements
Variable Purpose Required SLACK_BOT_TOKENBot OAuth token (xoxb-...) Yes (single workspace) SLACK_SIGNING_SECRETRequest signature verification Yes SLACK_APP_TOKENSocket Mode app-level token (xapp-...) Socket Mode only SLACK_CLIENT_IDOAuth client ID Multi-workspace only SLACK_CLIENT_SECRETOAuth client secret Multi-workspace only SLACK_STATE_SECRETOAuth state token Multi-workspace only
Quick Start — Bolt App (Node.js)
const { App } = require ('@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 ,
});
app. ( , ({ command, ack, respond }) => {
();
( );
});
app. ( , ({ body, ack, client }) => {
();
client. . ({
: body. ,
: confirmationModal,
});
});
app. ( , ({ event, say }) => {
({ : , : event. });
});
( () => {
app. (process. . || );
. ( );
})();
command
'/hello'
async
await
ack
await
respond
`Hello <@${command.user_id} >!`
action
'approve_button'
async
await
ack
await
views
open
trigger_id
trigger_id
view
event
'app_mention'
async
await
say
text
`Hello <@${event.user} >!`
thread_ts
ts
async
await
start
env
PORT
3000
console
log
'Bolt app running'
Core Concepts
Listeners
app.message (/deploy/ , async ({ message, say }) => {
await say ('Triggering deployment...' );
});
app.command ('/status' , async ({ ack, respond, command }) => {
await ack ();
respond ({ text : 'Checking status...' , response_type : 'ephemeral' });
const status = await fetchStatus ();
await respond ({ text : `Status: ${status} ` });
});
app.shortcut ('create_ticket' , async ({ shortcut, ack, client }) => {
await ack ();
await client.views .open ({
trigger_id : shortcut.trigger_id ,
view : ticketModal,
});
});
Modals (Views) const modal = {
type : 'modal' ,
callback_id : 'ticket_submission' ,
title : { type : 'plain_text' , text : 'Create Ticket' },
submit : { type : 'plain_text' , text : 'Submit' },
close : { type : 'plain_text' , text : 'Cancel' },
blocks : [
{
type : 'input' ,
block_id : 'title_block' ,
element : {
type : 'plain_text_input' ,
action_id : 'title_input' ,
placeholder : { type : 'plain_text' , text : 'Ticket title' },
},
label : { type : 'plain_text' , text : 'Title' },
},
{
type : 'input' ,
block_id : 'priority_block' ,
element : {
type : 'static_select' ,
action_id : 'priority_select' ,
options : [
{ text : { type : 'plain_text' , text : 'High' }, value : 'high' },
{ text : { type : 'plain_text' , text : 'Medium' }, value : 'medium' },
{ text : { type : 'plain_text' , text : 'Low' }, value : 'low' },
],
},
label : { type : 'plain_text' , text : 'Priority' },
},
],
};
app.view ('ticket_submission' , async ({ ack, view, client, body }) => {
await ack ();
const title = view.state .values .title_block .title_input .value ;
const priority = view.state .values .priority_block .priority_select .selected_option .value ;
await createTicket ({ title, priority, userId : body.user .id });
});
Block Kit — Rich Messages const richMessage = {
blocks : [
{
type : 'header' ,
text : { type : 'plain_text' , text : 'Deployment Ready' },
},
{
type : 'section' ,
fields : [
{ type : 'mrkdwn' , text : '*Service:*\napi-gateway' },
{ type : 'mrkdwn' , text : '*Version:*\nv1.2.3' },
{ type : 'mrkdwn' , text : '*Environment:*\nProduction' },
{ type : 'mrkdwn' , text : '*Requested by:*\n<@U1234567>' },
],
},
{ type : 'divider' },
{
type : 'actions' ,
block_id : 'deploy_actions' ,
elements : [
{
type : 'button' ,
text : { type : 'plain_text' , text : 'Approve' },
style : 'primary' ,
action_id : 'approve_deploy' ,
value : 'v1.2.3' ,
confirm : {
title : { type : 'plain_text' , text : 'Confirm Deploy' },
text : { type : 'mrkdwn' , text : 'Deploy *v1.2.3* to production?' },
confirm : { type : 'plain_text' , text : 'Deploy' },
deny : { type : 'plain_text' , text : 'Cancel' },
},
},
{
type : 'button' ,
text : { type : 'plain_text' , text : 'Reject' },
style : 'danger' ,
action_id : 'reject_deploy' ,
value : 'v1.2.3' ,
},
],
},
],
};
App Home Tab
app.event ('app_home_opened' , async ({ event, client }) => {
if (event.tab !== 'home' ) return ;
await client.views .publish ({
user_id : event.user ,
view : {
type : 'home' ,
blocks : [
{
type : 'header' ,
text : { type : 'plain_text' , text : 'My App Dashboard' },
},
{
type : 'section' ,
text : { type : 'mrkdwn' , text : 'Welcome to your app home!' },
accessory : {
type : 'button' ,
text : { type : 'plain_text' , text : 'Refresh' },
action_id : 'refresh_home' ,
},
},
],
},
});
});
Lazy Listeners (Long-Running Operations)
app.command (
'/report' ,
async ({ command, ack, respond, say }) => {
await ack ();
},
async ({ command, respond }) => {
const report = await generateReport (command.text );
await respond ({ text : report, response_type : 'in_channel' });
}
);
Socket Mode (Internal Tools)
const app = new App ({
token : process.env .SLACK_BOT_TOKEN ,
signingSecret : process.env .SLACK_SIGNING_SECRET ,
socketMode : true ,
appToken : process.env .SLACK_APP_TOKEN ,
});
OAuth (Multi-Workspace Apps) const { App , ExpressReceiver } = require ('@slack/bolt' );
const { FileInstallationStore } = require ('@slack/oauth' );
const receiver = new ExpressReceiver ({
signingSecret : process.env .SLACK_SIGNING_SECRET ,
clientId : process.env .SLACK_CLIENT_ID ,
clientSecret : process.env .SLACK_CLIENT_SECRET ,
stateSecret : process.env .SLACK_STATE_SECRET ,
scopes : ['chat:write' , 'channels:read' , 'commands' ],
installationStore : new FileInstallationStore (),
});
const app = new App ({ receiver });
Workflow Steps (Deprecated → Automations)
const ws = new WorkflowStep ('copy_review' , {
edit : async ({ ack, step, configure }) => {
await ack ();
await configure ({ blocks : editBlocks });
},
save : async ({ ack, step, view, update }) => {
await ack ();
const { values } = view.state ;
await update ({ inputs : {}, outputs : [] });
},
execute : async ({ step, complete, fail }) => {
try {
await complete ({ outputs : {} });
} catch (err) {
await fail ({ error : { message : err.message } });
}
},
});
app.step (ws);
Scopes Reference Capability Required Scopes Post messages chat:writeRead channels channels:read, groups:readRead messages channels:history, groups:historySlash commands commandsReact to messages reactions:writeUpload files files:writeRead user profiles users:read, users:read.emailHome tab im:historyBot mentions app_mentions:readDMs im:write, mpim:write
Common Patterns
Approval Workflow app.command ('/approve-request' , async ({ command, ack, client }) => {
await ack ();
await client.chat .postMessage ({
channel : '#approvals' ,
text : `<@${command.user_id} > requests approval` ,
blocks : buildApprovalBlocks (command),
});
});
app.action ('approve_action' , async ({ action, body, ack, client }) => {
await ack ();
const requestId = action.value ;
await markApproved (requestId, body.user .id );
await client.chat .update ({
channel : body.channel .id ,
ts : body.message .ts ,
text : `Approved by <@${body.user.id} >` ,
blocks : buildApprovedBlocks (requestId),
});
});
User Lookup async function lookupUser (client, email ) {
const result = await client.users .lookupByEmail ({ email });
return result.user .id ;
}
Error Handling app.error (async error => {
console .error ('Global error handler' , error);
await app.client .chat .postMessage ({
channel : process.env .ADMIN_CHANNEL ,
text : `App error: ${error.message} ` ,
});
});
Security
Always verify SLACK_SIGNING_SECRET to authenticate requests from Slack
Never log raw payloads (may contain user PII)
Use response_type: 'ephemeral' for sensitive command responses
Store tokens in encrypted secrets manager, not .env in production
Scope bot tokens to minimum required permissions
Rotate signing secrets if compromised — requires reinstalling the app
Debugging
DEBUG=bolt:* node app.js
slack run
slack triggers create --trigger-def "triggers/trigger.json"
slack events replay
Related