How to Make a Slack Command That Summarizes a Thread With AI
Build a /summarize slash command that pulls a thread's messages and returns an AI recap.
Long Slack threads are where decisions go to hide. A /summarize command that reads the current thread and posts a tidy recap saves everyone the scroll. This guide wires a slash command to the conversations.replies API and feeds the messages to an LLM.
What you need
- A Slack app with Socket Mode and a Bolt project (see the Bolt bot guide)
- The bot scopes
commands,channels:historyandchat:write - An AI API key
- Node 18+ installed
Step 1: Create the slash command
In your Slack app config open Slash Commands, click Create New Command, and set the command to /summarize. With Socket Mode on, the Request URL field can be left as a placeholder because events travel over the socket.
Step 2: Fetch the thread messages
A slash command fired inside a thread does not automatically include the thread. You read it with conversations.replies using the channel id and the thread timestamp. Acknowledge the command first so Slack does not show a timeout error.
app.command("/summarize", async ({ command, ack, client, respond }) => {
await ack();
const history = await client.conversations.history({
channel: command.channel_id,
limit: 50,
});
const transcript = history.messages
.reverse()
.map((m) => `${m.user || "bot"}: ${m.text}`)
.join("\n");
const res = await ai.chat.completions.create({
model: "gpt-5-mini",
messages: [
{
role: "system",
content:
"Summarize this Slack channel into 3 bullet points and one action item.",
},
{ role: "user", content: transcript },
],
});
await respond({
response_type: "in_channel",
text: res.choices[0].message.content,
});
});Step 3: Choose who sees the result
The response_type field controls visibility. Use in_channel so everyone sees the recap, or ephemeral to show it only to the person who ran the command. Ephemeral is handy while you are still testing.
Result
Anyone can now type /summarize and get a three-bullet recap plus an action item posted back to the channel. Cap the message limit and trim very long transcripts so you stay inside the model's context window and your token budget.
Watch related tutorials
22:00
20:00
05:00
30:00
26:00
5:42