AI-powered Slack bot for drafting replies, RAG-assisted context, and skill-based automation.
- Reply with Open Slack CoPilot
- Install the Slack App
- Install Slack CoPilot
- Run Slack CoPilot
- Define Skills
For examples of useful skills, see docs/examples/.
A development manager posts a message to a user group asking everyone to complete a task (e.g. update on-call rotations, review a document, acknowledge a policy change). Instead of manually chasing people, the manager asks CoPilot to handle follow-ups.
Follow Up is a reply skill: install it under ~/.open_slack_copilot/skills/reply/follow_up/ (copy from skill_examples/reply/follow_up/). If you still have it under skills/watcher/follow_up, move it to skills/reply/follow_up so progressive disclosure can load it. Reply skills are chosen on the same flows as any draft — @CoPilot, the Draft with CoPilot message shortcut (opens a dialog for your instruction, then drafts), and /copilot in a thread.
- Manager sends a message in a channel mentioning a user group:
@backend-teamPlease review the RFC and mark ✅ when done. - In the thread, the manager writes:
@CoPilotplease follow up - Progressive disclosure can include the Follow Up reply skill when it matches the thread and instruction; the model then follows that skill (schedule checks, DMs, etc.).
- Infers check frequency — hourly, daily, or a specific date based on urgency and any stated deadline (default: daily).
- Resolves target users — reads
<@U…>mentions from thread text where applicable, or useslist_usergroup_membersfor user groups (requires bot scopeusergroups:read). - Determines completion criteria — infers the appropriate signal from context: an emoji reaction (e.g. ✅), a thread reply, or an external status update (e.g. Jira ticket).
- Creates a scheduled prompt — calls the
schedule_prompttool (prompt,cron, optionalexpires_in_days) so the check repeats until the job expires. - On each scheduled run — checks every user against the criteria and sends a friendly DM reminder to anyone who hasn't completed, with a link back to the original thread.
Example DM: "Hi! Friendly reminder — the backend team was asked to review the RFC. It looks like you haven't confirmed yet. Here's the original thread: [link]"
See the full skill definition at skill_examples/reply/follow_up/SKILL.md.
Go to a message you were mentioned in (or any message you want to draft a reply for):
- Hover over the message in Slack.
- Click the ⋮ (three-dot menu) on the right side of the message.
- Connect to apps → Draft with CoPilot.
- A dialog opens. Edit Instruction for the LLM if you want; it defaults to Draft reply on my behalf for this thread. Click Submit.
- Expect an ephemeral message from the bot with the suggested reply.
- Click Revise to open a modal, edit the instruction (the default includes the current draft), and submit to regenerate the reply. Posting the draft to the channel as you is not implemented yet.
In a channel where the app is invited, you can @mention the bot (for example @CoPilot) on a message:
- Type your mention in the message (optionally add instructions after it, same idea as text after
/copilot). - Send the message.
- You get an ephemeral draft in the thread under that message, like the shortcut flow (use Revise on that ephemeral as above).
Context: On a channel root message (not in a thread), the draft uses the most recent messages in the channel (see copilot_channel_context_limit in config/default.yaml). Inside a thread, the draft uses that thread’s messages.
- Go to api.slack.com/apps and click Create New App.
- Choose From a manifest and select your workspace.
- Switch the format selector to JSON and paste the manifest below.
- Click Create and then Install to Workspace when prompted.
- Install App on workspace: OAuth & Permissions → OAuth Tokens → Install
Paste this when creating the app from a manifest:
{
"display_information": {
"name": "Open Slack CoPilot",
"description": "AI-powered copilot for drafting Slack replies",
"background_color": "#1a1a2e"
},
"features": {
"bot_user": {
"display_name": "CoPilot",
"always_online": true
},
"shortcuts": [
{
"name": "Draft thread reply",
"type": "message",
"callback_id": "slack_copilot_draft_with_copilot",
"description": "Draft a reply for this thread"
},
{
"name": "Follow up",
"type": "message",
"callback_id": "slack_copilot_follow_up",
"description": "Follow up with mentioned users on the thread"
}
],
"slash_commands": [
{
"command": "/copilot",
"description": "Draft an AI reply in the current thread",
"usage_hint": "[optional instruction]",
"should_escape": false
}
]
},
"oauth_config": {
"redirect_urls": [
"http://127.0.0.1:8765/slack/oauth/callback"
],
"scopes": {
"bot": [
"app_mentions:read",
"chat:write",
"commands",
"channels:history",
"groups:history",
"usergroups:read",
"users:read"
],
"user": [
"chat:write"
]
},
"pkce_enabled": false
},
"settings": {
"event_subscriptions": {
"bot_events": [
"app_mention"
]
},
"interactivity": {
"is_enabled": true
},
"org_deploy_enabled": false,
"socket_mode_enabled": true,
"token_rotation_enabled": false,
"is_mcp_enabled": false
}
}Message shortcuts must use callback_id slack_copilot_ + the reply skill folder name (same name as under ~/.open_slack_copilot/skills/reply/, only a-z, A-Z, _, -). The app registers one Bolt listener for that pattern; shortcuts without the prefix or without a matching SKILL.md are ignored silently. See Add a skill as a message shortcut.
After creating and installing the app, collect three tokens:
| Variable | Where to find it | Format |
|---|---|---|
SLACK_BOT_TOKEN |
OAuth & Permissions → Bot User OAuth Token | xoxb-... |
SLACK_USER_TOKEN |
OAuth & Permissions → User OAuth Token | xoxp-... |
SLACK_APP_TOKEN |
Basic Information → App-Level Tokens → Generate (scope: connections:write) |
xapp-... |
OPENAI_API_KEY |
platform.openai.com/api-keys | sk-... |
cp .env.example .envEdit .env with your tokens. The bot will refuse to start if any are missing.
If you used the manifest above, Socket Mode is already enabled. To verify or enable manually:
- In your app settings, go to Socket Mode in the sidebar.
- Toggle Enable Socket Mode on.
- Make sure you have an App-Level Token with
connections:writescope (see step 2).
- Secrets: Loaded from
.env(keys:SLACK_BOT_TOKEN,SLACK_APP_TOKEN,OPENAI_API_KEY). Seeconfig/default.yamlfor the mapping. - Defaults:
config/default.yaml(model, RAG settings) - LLM model:
gpt-4o - RAG: In-memory Qdrant; configure
rag.slackfor channel RAG - Skills:
~/.open_slack_copilot/skills/(see Define Skills)
git clone <your-repo-url>
cd open_slack_copilot
make installmake runOnly needed if you want CoPilot to send messages on your behalf (e.g. post a thread reply or DM from your Slack account via the send_thread_reply_on_behalf_of_requester tool). If you stick to the default send_dm_as_app, skip this section.
-
In your Slack app → Basic Information, copy Client ID and Client Secret into
.env:SLACK_CLIENT_ID=... SLACK_CLIENT_SECRET=... -
In your Slack app → OAuth & Permissions:
- Add redirect URL:
http://127.0.0.1:8765/slack/oauth/callback - Under User Token Scopes, add
chat:write.
- Add redirect URL:
-
Start the localhost OAuth server (in a separate terminal):
make oauth-server
-
Open
http://127.0.0.1:8765/slack/oauth/startin your browser and complete the Slack consent. The user token is persisted at~/.open_slack_copilot/slack_user_oauth/<user_id>.jsonand picked up automatically by the bot.
Skills are freeform markdown instructions that guide the bot's reply behavior. They live in:
~/.open_slack_copilot/
skills/
reply/
default.md # optional — overrides the built-in default instruction
<skill_name>/
SKILL.md
- Default skill — To override the built-in default reply instruction, create
~/.open_slack_copilot/skills/reply/default.mdwith your own markdown. When no skill matches a thread, this file is used instead of the bundled default. - Additional skills — Add folders under
~/.open_slack_copilot/skills/reply/. Each folder contains aSKILL.mdfile. The bot uses progressive disclosure to automatically select relevant skills per thread (including on@CoPilotand/copilot).
For examples of useful skills, see docs/examples/ and the Follow Up reply skill at skill_examples/reply/follow_up/SKILL.md.
- Create
~/.open_slack_copilot/skills/reply/<skill_directory>/SKILL.md(seeskill_examples/reply/follow_up/SKILL.md). - api.slack.com/apps → your app → Features → Shortcuts → Create New Shortcut → On messages. Callback ID must match
slack_copilot_<skill_directory>(e.g.slack_copilot_follow_upforreply/follow_up/). Reinstall the app. - On a message: ⋯ → your shortcut → Submit.