Awesome-omni-skill slack-chat
communicate via slack-chat channels and direct messages with users
git clone https://github.com/diegosouzapw/awesome-omni-skill
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data-ai/slack-chat" ~/.claude/skills/diegosouzapw-awesome-omni-skill-slack-chat && rm -rf "$T"
skills/data-ai/slack-chat/SKILL.mdSlack Chat
Overview
The
slack command is installed globally (located in the $PATH).
It is a dual-mode Slack client with offline-first architecture:
- Online Mode: Pull messages from Slack to local Markdown storage, resolve IDs
- Offline Mode: Query and manage stored messages without Slack connectivity
The system is designed for AI agents to integrate Slack processing into workflows, supporting:
- Batch message ingestion with deduplication
- Message marking (read/unread) with offline metadata
- ID resolution caching (users, channels)
- Integration with other tools and scripts
Uses browser-use (via Chrome DevTools Protocol) for Slack API access.
Core Concepts
Message IDs
- Slack ID:
orchannel_id:timestamp
for threadschannel_id:timestamp@thread_ts - SHA1 Hash: 40-character hex hash of Slack ID, used as filename
- Short ID: First 6 characters of hash (e.g.,
), used for Git-like partial matchingb89c7a
Example:
Slack ID: C01TECH01:1767815267.099869 SHA1 Hash: b89c7a14755df6dca57ece8e14f38652e727cbd8 Short ID: b89c7a # Thread reply: Slack ID: G01GROUP01:1765909149.353759@1765321208.614079 SHA1 Hash: 4cea849d8625c020f8716b8024e256942d6b440b Short ID: 4cea84
Storage Format
Each message is stored as a Markdown file in
storage/ with YAML front matter containing metadata, and rendered content below:
--- channel_id: C01TECH01 timestamp: '1767815267.099869' thread_ts: null user_id: WNARLG5HB type: message text: Thank you all! permalink: https://bigco-producta.slack.com/archives/C01TECH01/p1767815267099869 reactions: [] attachments: [] files: [] _stored_id: b89c7a14755df6dca57ece8e14f38652e727cbd8 _stored_at: '2026-01-07T20:06:28.667864+00:00' offline: read: false --- # Message in C01TECH01 **From:** WNARLG5HB **Channel:** C01TECH01 **Timestamp:** 1767815267.099869 **Permalink:** [https://...](https://...) --- Thank you all!
ID Matching (Git-style)
All CLI commands support partial IDs. The system matches the longest unique prefix:
# These all refer to the same message: slack-chat inbox view b89c7a14755df6dca57ece8e14f38652e727cbd8 # Full (40 chars) slack-chat inbox view b89c7a14 # 8 chars slack-chat inbox view b89c7a # 6 chars (short) slack-chat inbox view b89c # 4 chars (if unique)
Error on ambiguity:
❌ Ambiguous ID 'b8' matches: b89c7a14..., b8a3f2c1...
ID Resolution Cache
User and channel IDs are cached to
storage/_cache/ to reduce API calls:
storage/_cache/ ├── users.yml # User ID → full profile └── channels.yml # Channel ID → full info
When you run
slack-chat user resolve or slack-chat channel resolve, the result is cached. Subsequent lookups hit the cache first.
Quick Reference
| Task | Command |
|---|---|
| Server | |
| Start Server | |
| Stop Server | |
| Server Status | |
| Pull (Online) | |
| Pull Messages | |
| Inbox (Offline) | |
| Summary | |
| List | |
| View | |
| Mark Read | |
| Mark Thread Read | |
| Mark Channel Read | |
| Mark Unread | |
| Resolve (Online, Cached) | |
| Resolve Channel | |
| Resolve User | |
| Lookup (Offline) | |
| List Channels | |
| Find Channels | |
| List Users | |
| Find Users | |
| Context (Online) | |
| Message Around | |
| View Thread | |
| Write (Online) | |
| Reply | |
| React | |
| Mute Channel | |
| Post Message | |
| Reply to Thread | |
| Add Reaction | |
Online Mode: Fetching Messages from Slack
Command: slack-chat pull
slack-chat pullPurpose: Fetch unread messages from Slack, store locally as Markdown files.
IMPORTANT: Always fetch with reasonable limits. Use
or--limit 10for controlled processing. This ensures manageable batches for review.--limit 20
Command:
slack-chat pull --since <date> [--limit N] [--type TYPE]
Parameters:
: Required. Fetch messages received on/after this date--since <date>- Formats:
,YYYY-MM-DD
,yesterday
,"7 days ago""1 day ago"
- Formats:
: Optional. Max messages per category (default: 100)--limit <n>
: Optional. Filter:--type <type>
,channels
,dms
,threads
,mentions
(default:all
)all
: Suppress verbose output--quiet
Behavior:
- Fetches unread channels, DMs, subscribed threads, and @mentions
- Skips already-stored files (deduplication via SHA1)
- Stores each message as Markdown under
storage/<id>.md - Does NOT mark as read on Slack (that's done via
)inbox read - Prints progress for each stored message
Examples:
# Pull from last 24 hours slack-chat pull --since "1 day ago" --limit 10 # Pull only threads slack-chat pull --since yesterday --type threads # Pull everything from past week (use with caution) slack-chat pull --since "7 days ago" # Quiet mode for scripts slack-chat pull --since yesterday --limit 50 --quiet
Output Example:
📥 Pulling messages since 2026-01-06... 📢 Fetching channel messages... + 19aaf82d... (C02PROJ01) + 60e86087... (CL80UCYF5) 💬 Fetching DM messages... 🧵 Fetching thread replies... + e04ada37... (thread in C0919MFSA4X) + 8e206898... (thread in C098Q7ALDNU) 📣 Fetching mentions... + b89c7a14... (mention) ✅ Done: 11 stored, 0 skipped, 23 fetched total
Best Practices:
- Use
or--limit 10
for manageable batches--limit 20 - Use
for daily processing--since "1 day ago" - After pulling, use
to review new messagesslack-chat inbox list - The
field in stored files opens the message in Slackpermalink
Offline Mode: Analysis & Metadata
All
slack-chat inbox commands work offline, reading/writing files in storage/.
Command: slack-chat inbox summary
slack-chat inbox summaryPurpose: Get overall message statistics from local storage.
Command:
slack-chat inbox summary
Output:
summary: unread: 11 read: 0 total: 11 by_type: channel: 6 dm: 0 thread: 5 mention: 0
Use Cases:
- Verify message counts before processing
- Track unread vs read ratio
- Check if pull was successful
Online Mode: Add
--online to fetch live counts from Slack API instead.
Command: slack-chat inbox list
slack-chat inbox listPurpose: List messages with filtering.
Command:
slack-chat inbox list [--type TYPE] [--limit N] [--since DATE] [--all]
Options:
: Filter by type (-t, --type <type>
,channels
,dms
,threads
,mentions
)all
: Max results (default: 20)-n, --limit <n>
: Filter messages after date--since <date>
: Include read messages (default: unread only)-a, --all
: Use live API instead of local storage--online
Output Format:
<short_id> / <date> / <channel_id> / <user_id> (type) <text preview>
Output Example:
Showing 5 of 11 messages: b89c7a / 2026-01-07 19:47 / C01TECH01 / WNARLG5HB Thank you all! 4aab08 / 2026-01-07 19:24 / C01TECH01 / WM1HR6E1G ok, puppet ran, nginx restarted e04ada / 2026-01-07 19:06 / C0919MFSA4X / U025R2RLLM8 (thread) Have been back and forth with cloud a bit on camel support ... and 6 more
Use Cases:
- Scan unread messages
- Filter by type (threads only, DMs only, etc.)
- Find messages from specific period
Command: slack-chat inbox view <id>
slack-chat inbox view <id>Purpose: Display full content of a message.
Command:
slack-chat inbox view <id>
Supports:
- Partial IDs:
b89c7a - Full IDs:
b89c7a14755df6dca57ece8e14f38652e727cbd8 - Event ID format:
C01TECH01:1767815267.099869
Output: Complete Markdown file with YAML frontmatter and rendered body.
Use Cases:
- Read full message content
- Extract data for analysis
- Check message metadata (reactions, attachments, etc.)
Example:
# View by short ID slack-chat inbox view b89c7a # View by event ID slack-chat inbox view C01TECH01:1767815267.099869
How to interpet messsages
When I ask you to view a message, the output will have ID numbers in place of channel and user names, for example:
events: - id: D04R3C0G1JT:1766426423.335079 type: mention channel: '#USLACKBOT' from: slackbot text: <@WNHDFCXTJ> archived the channel <#C08TR8S0QJ0> timestamp: '1766426423.335079' - id: D0849DD71UP:1765928154.858059 type: reaction channel: '#WNHDFCXTJ' text: From here not much needed apart from those future meetings y timestamp: '1765928154.858059' thread_ts: '1765321208.614079' url: https://bigco-producta.slack.com/archives/D0849DD71UP/p1765928154858059 - id: G01GROUP01:1765909149.353759@1765321208.614079 type: reaction (thread reply) channel: '#sre-nexus' text: <@WM1HR6E1G|teddy> I want you to be the coordinator timestamp: '1765909149.353759' thread_ts: '1765321208.614079' url: https://bigco-producta.slack.com/archives/G01GROUP01/p1765909149353759
where:
is an example of a user_id@WNHDFCXTJ- indicated by the
(may not always appear) as well as the@
prefix (part of the identifier)W
- indicated by the
is an example of a channel_id#C08TR8S0QJ0- indicated by the
(may not always appear) as well as the#
prefix (part of the identifier)C
- indicated by the
indicates the message is part of a thread (value is the parent message timestamp)thread_ts- Event IDs for threaded messages use the format:
CHANNEL_ID:TIMESTAMP@THREAD_TS
Use the
slack-chat channel resolve <id> and slack-chat user resolve <id> commands to find out what the human-readable version of these are, and only cite these when replying back to me (I don't want to see IDs, unless names are not available.)
Command: slack-chat inbox read <id>
slack-chat inbox read <id>Purpose: Mark a message as read.
Command:
slack-chat inbox read <id> [--offline-only]
Behavior:
- Updates
in local fileoffline.read: true - By default, also marks as read on Slack server
- Use
to skip server-side marking--offline-only
Output:
ok: true marked_read_locally: b89c7a14... marked_read_on_slack: true
Use Cases:
- Mark messages as processed
- Track which messages have been reviewed
Command: slack-chat inbox mark-thread <id>
slack-chat inbox mark-thread <id>Purpose: Mark all messages in a thread as read.
Command:
slack-chat inbox mark-thread <id> [--offline-only]
Behavior:
- Finds all stored messages with the same thread_ts
- Marks them all as read locally
- By default, also marks thread as read on Slack server
- Use
to skip server-side marking--offline-only
Output:
ok: true thread_ts: '1767773973.649239' channel_id: C0919MFSA4X marked_count: 5 marked_ids: - e04ada37 - 8e206898 - a1b2c3d4 marked_read_on_slack: true
Use Cases:
- Done reviewing a thread, mark all at once
- Clean up multiple thread replies efficiently
Command: slack-chat inbox mark-channel <channel_id>
slack-chat inbox mark-channel <channel_id>Purpose: Mark all messages in a channel as read.
Command:
slack-chat inbox mark-channel <channel_id> [--offline-only]
Behavior:
- Finds all stored messages in the channel
- Marks them all as read locally
- By default, also marks channel as read on Slack (up to latest message)
- Use
to skip server-side marking--offline-only
Output:
ok: true channel_id: C01TECH01 marked_count: 12 marked_ids: - b89c7a14 - 4aab08f1 - 7d8e9bce marked_read_on_slack: true
Use Cases:
- Done with a channel's backlog, mark all at once
- Clear noisy channels efficiently
Command: slack-chat inbox unread <id>
slack-chat inbox unread <id>Purpose: Mark a message as unread (local only).
Command:
slack-chat inbox unread <id>
Effect:
- Sets
in local fileoffline.read: false - Does NOT sync to Slack (Slack API doesn't support marking unread)
Output:
ok: true marked_unread_locally: b89c7a14...
Use Cases:
- Recover from accidental marks
- Re-queue messages for processing
ID Resolution (Online, Cached)
Command: slack-chat channel resolve <id>
slack-chat channel resolve <id>Purpose: Convert channel ID to human-readable info.
slack-chat channel resolve C01TECH01
Output:
name: engineering is_archived: false is_private: false created: 1563498384 creator: U0A4DBTGDPZ topic: Technical discussions purpose: Engineering team collaboration members: - WNARLG5HB - WMCH36A6Q
Caching: Result is saved to
storage/_cache/channels.yml. Subsequent calls return cached data.
Command: slack-chat user resolve <id>
slack-chat user resolve <id>Purpose: Convert user ID to human-readable info.
slack-chat user resolve WNARLG5HB
Output:
name: Alice Johnson is_bot: false is_admin: false email: alice@bigco.com display_name: alice title: Software Engineer tz: America/Los_Angeles
Caching: Result is saved to
storage/_cache/users.yml. Subsequent calls return cached data.
When to use: Whenever you see a raw ID (like
WNARLG5HB or C01TECH01) and need the human-readable name.
Lookup Commands (Offline)
These commands search the offline cache without making API calls.
Command: slack-chat channel list
slack-chat channel listPurpose: List all cached channels.
slack-chat channel list
Output (tab-separated columns):
id | name | description
C01TECH01 prod-tech-internal-ProductA Production tech discussion C098Q7ALDNU engineering-general General engineering chat C6M7U8DFF ProductA-server-team ProductA server team coordination
Use Cases:
- See all channels you've resolved/cached
- Find channel IDs for posting
Command: slack-chat channel find <keyword>
slack-chat channel find <keyword>Purpose: Find cached channels by name keyword.
slack-chat channel find prod slack-chat channel find ProductA
Output (tab-separated columns):
id | name | description
Matches channels whose name contains the keyword (case-insensitive). For example,
hal matches thal, fhaly, etc.
Use Cases:
- Find a channel when you only remember part of the name
- Look up channel ID before posting with
slack-chat reply
Command: slack-chat user list
slack-chat user listPurpose: List all cached users.
slack-chat user list
Output (tab-separated columns):
id | name | title | project
WNARLG5HB Alice Johnson Associate Lead Software Engineer ProductA IV WMCH36A6Q Charlie Brown Senior Software Engineer ProductA U04MYEUTJLU Dana Evans Engineering Manager IT Infrastructure
Use Cases:
- See all users you've resolved/cached
- Find user IDs for @ mentions
Command: slack-chat user find <keyword>
slack-chat user find <keyword>Purpose: Find cached users by keyword (searches all fields).
slack-chat user find john slack-chat user find ProductA slack-chat user find infrastructure
Output (tab-separated columns):
id | name | title | project
Searches all fields in the user object (case-insensitive), including:
- Name, real_name, display_name
- Title, email
- Team/project custom fields
- Any other string value
Examples:
# Find by name slack-chat user find shelly # Find by project/team slack-chat user find ProductA slack-chat user find "producta" # Find by title slack-chat user find "software engineer"
Use Cases:
- Find a user when you only remember part of the name
- Find all users on a specific team/project
- Look up user ID for mentions
Context Commands (Online)
Often, viewing one message in isolation does not provide enough information; To truly understand a given message, often its necessary to look at messages in the surrounding (channel/thread) context (before and after), similar to
grep -B and -A flags.
Command: slack-chat message around <event_id>
slack-chat message around <event_id>Purpose: View messages before/after a target message for context.
slack-chat message around C6M7U8DFF:1766558024.931179 -B 3 -A 3
Options:
: Number of messages before (default: 3)-B <n>
: Number of messages after (default: 3)-A <n>
Use Cases:
- Understand conversation context
- See what led to a message
- Review thread context
Command: slack-chat inbox context <event_id>
slack-chat inbox context <event_id>Purpose: View surrounding context (thread or channel messages).
slack-chat inbox context C6M7U8DFF:1766558024.931179 --limit 5
Write Commands (Online)
Command: slack-chat reply <target> <message>
slack-chat reply <target> <message>Purpose: Reply to a channel or thread with smart targeting.
Command:
slack-chat reply <target> "<message>"
Smart Targeting - accepts multiple ID formats:
- Channel ID:
→ posts to channelC01TECH01 - Channel name:
→ posts to channel (looks up from cache)#prod-tech-internal-ProductA - Storage ID:
→ replies to that message's threadb89c7a - Event ID:
→ replies to threadC01TECH01:1767815267.099869 - Event ID with thread:
C01TECH01:1767815267.099869@1767773973.649239
Channel Name Resolution: When using a channel name (with
# prefix), the system:
- Looks up the name in the offline cache (
)storage/_cache/channels.yml - If found, uses the cached channel ID
- If not found, returns an error with suggestion to use
slack-chat channel find
To cache a channel, use
slack-chat channel resolve <id> first.
Output:
ok: true channel: C01TECH01 message_ts: '1767820123.456789' thread_ts: '1767815267.099869' permalink: https://bigco-producta.slack.com/archives/...
Examples:
# Post to channel by ID slack-chat reply C01TECH01 "Hello everyone!" # Post to channel by name slack-chat reply "#prod-ProductA" "Hello world!" # Reply to a thread (by storage ID) slack-chat reply b89c7a "Thanks for the update!" # Reply to a thread (by event ID) slack-chat reply C01TECH01:1767815267.099869 "Got it, will look into this."
Use Cases:
- Quick replies to messages you just viewed
- Respond to threads without looking up thread_ts manually
- Post updates to channels by name
Command: slack-chat react <target> <emoji>
slack-chat react <target> <emoji>Purpose: Add an emoji reaction to a message.
Command:
slack-chat react <target> <emoji>
Smart Targeting - accepts:
- Storage ID:
→ reacts to that messageb89c7a - Event ID:
→ reacts to messageC01TECH01:1767815267.099869 - Event ID with thread:
C01TECH01:1767815267.099869@1767773973.649239
Emoji formats (with or without colons):
,thumbsup
,+1
,eyeswhite_check_mark
,:thumbsup:
,:+1::eyes:
Output:
ok: true channel: C01TECH01 timestamp: '1767815267.099869' emoji: thumbsup
Examples:
# React by storage ID slack-chat react b89c7a thumbsup # React by event ID slack-chat react C01TECH01:1767815267.099869 eyes # Acknowledge with checkmark slack-chat react b89c7a white_check_mark
Use Cases:
- Acknowledge messages quickly
- React to messages you just viewed
- Signal agreement/approval without writing a reply
Command: slack-chat mute <channel_id>
slack-chat mute <channel_id>Purpose: Mute a channel to stop receiving notifications.
Command:
slack-chat mute <channel_id>
Output:
ok: true channel: C01TECH01 muted: true
Examples:
# Mute a noisy channel slack-chat mute C01TECH01 # Mute after resolving channel name slack-chat channel resolve C6M7U8DFF # Check it's the right channel slack-chat mute C6M7U8DFF
Use Cases:
- Silence noisy channels
- Stop notifications from low-priority channels
- Reduce distractions during focus time
Workflow Scenarios
Scenario 1: Daily Slack Processing
Goal: Pull messages daily, review, mark processed.
# 1. Start server slack-chat server start # 2. Pull recent messages slack-chat pull --since "1 day ago" --limit 20 # 3. Check statistics slack-chat inbox summary # Output: unread: 15, read: 0, total: 15 # 4. List messages for review slack-chat inbox list --limit 20 # 5. View specific message slack-chat inbox view b89c7a # 6. Resolve user ID to name slack-chat user resolve WNARLG5HB # 7. Mark as processed slack-chat inbox read b89c7a # 8. Verify slack-chat inbox summary # Output: unread: 14, read: 1, total: 15
Scenario 2: Thread-focused Processing
Goal: Focus on thread replies only.
# 1. Pull only threads slack-chat pull --since "3 days ago" --type threads # 2. List thread messages slack-chat inbox list --type threads # 3. View thread reply slack-chat inbox view e04ada # 4. Get full thread context (online) slack-chat message around C0919MFSA4X:1767819961.835769@1767773973.649239 -B 5 -A 5 # 5. Mark as read slack-chat inbox read e04ada
Scenario 3: Incremental Processing
Goal: Process in small batches.
# Pull small batch slack-chat pull --since yesterday --limit 5 # Process each for id in b89c7a 4aab08 7d8e9b; do echo "=== Message: $id ===" slack-chat inbox view $id # ... analyze ... slack-chat inbox read $id done # Check remaining slack-chat inbox summary
Agent Workflow: Processing Unread Activity
When the user asks to "check Slack" or "process my unreads":
Step 1: Pull Fresh Data
slack-chat pull --since "1 day ago" --limit 20
Step 2: Get Overview
slack-chat inbox summary
If all counts are 0, report "No unread activity" and stop.
Step 3: List Messages
slack-chat inbox list --limit 20
Step 4: Present Summary
Parse the output. Present to user:
- Count by type (channels, DMs, threads)
- Preview of important messages
Example:
You have 11 unread messages: 6 in channels, 5 thread replies. Notable: Thread reply from U025R2RLLM8 about "camel support"
Step 5: Drill Down (on request)
slack-chat inbox view e04ada # View message slack-chat user resolve U025R2RLLM8 # Get user name slack-chat channel resolve C0919MFSA4X # Get channel name
Step 6: Mark as Read (on request)
slack-chat inbox read e04ada
File Organization
slack-chat/ ├── src/ │ ├── cli.py # Main CLI │ ├── server.py # Browser server (FastAPI) │ ├── storage.py # Storage operations │ └── pull.py # Pull command ├── storage/ # Local message cache │ ├── _cache/ │ │ ├── users.yml │ │ └── channels.yml │ ├── b89c7a14...md │ ├── 4aab08f1...md │ └── ... └── doc/ └── SPEC1.md # Architecture spec
Tips for AI Agents
- Pull first: Always
before reading messages to get fresh dataslack-chat pull - Use partial IDs:
instead of fullb89c7ab89c7a14755df6dca... - Check summary:
to understand data volumeslack-chat inbox summary - Resolve IDs: Use
andslack-chat user resolve
to convert IDs to namesslack-chat channel resolve - Test with limits: Use
when prototyping workflows--limit 5 - Mark processed: Always
after processing to track stateinbox read - Use relative dates:
,yesterday
are clearer than exact dates"7 days ago" - Cache is your friend: ID resolution is cached, so feel free to resolve repeatedly
Architecture Notes
- Storage: All files in
are Markdown with YAML frontmatter (Git-friendly)storage/ - No database: Direct filesystem access
- Offline-first: Inbox commands work without server running
- Deduplication: SHA1 hashing ensures same message = same storage file
- ID cache: User/channel info cached to reduce API calls
- Server required: For
, resolve commands, and write operationspull
Troubleshooting
- if a command returns
,HTTP 500slack-chat server status # check if server is healthy slack-chat server stop # stop it slack-chat server start # re-start it