Files
strukto-ai--mirage/docs/python/resource/slack.mdx
T
wehub-resource-sync bcbd1bdb22
Integ / changes (push) Has been skipped
Pre-commit / pre-commit (push) Failing after 1s
CLI exit codes / changes (push) Has been skipped
Test (Install) / changes (push) Has been skipped
Test (Python) / changes (push) Has been skipped
Test (TypeScript) / changes (push) Has been skipped
CLI exit codes / cli-gate (push) Has been cancelled
Test (Install) / test-install-gate (push) Has been cancelled
Integ / integ-gate (push) Has been cancelled
Test (Python) / test-python-gate (push) Has been cancelled
Test (TypeScript) / test-typescript-gate (push) Has been cancelled
Test (Install) / python-minimal (3.12) (push) Has been cancelled
Test (Install) / python-minimal (3.11) (push) Has been cancelled
Test (Install) / python-extra (agno, mirage.agents.agno) (push) Has been cancelled
Test (Install) / python-extra (chroma, mirage.resource.chroma) (push) Has been cancelled
Test (Install) / python-extra (pdf, mirage.core.filetype.pdf) (push) Has been cancelled
Integ / integ (push) Has been cancelled
Integ / integ-database (push) Has been cancelled
Integ / integ-database-ts (push) Has been cancelled
Integ / integ-data (push) Has been cancelled
Integ / integ-ssh (push) Has been cancelled
Integ / integ-ssh-ts (push) Has been cancelled
Test (Python) / audit (push) Has been cancelled
Test (TypeScript) / test (push) Has been cancelled
Test (TypeScript) / python-fs-shim (push) Has been cancelled
CLI exit codes / Python CLI (push) Has been cancelled
CLI exit codes / TypeScript CLI (push) Has been cancelled
CLI exit codes / Cross-language snapshot interop (push) Has been cancelled
Test (Python) / test (push) Has been cancelled
Test (Python) / import-isolation (deepagents, openai, mirage.agents.openai_agents) (push) Has been cancelled
Test (Python) / import-isolation (deepagents, pydantic-ai, mirage.agents.pydantic_ai) (push) Has been cancelled
Integ / integ-ts (push) Has been cancelled
Integ / integ-fuse (push) Has been cancelled
Test (Install) / python-extra (databricks, mirage.resource.databricks_volume) (push) Has been cancelled
Test (Install) / python-extra (deepagents, mirage.agents.langchain) (push) Has been cancelled
Test (Install) / python-extra (email, mirage.resource.email) (push) Has been cancelled
Test (Install) / python-extra (fuse, mirage.fuse.mount) (push) Has been cancelled
Test (Install) / python-extra (hdf5, mirage.core.filetype.hdf5) (push) Has been cancelled
Test (Install) / python-extra (hf, mirage.resource.hf_buckets) (push) Has been cancelled
Test (Install) / python-extra (lancedb, mirage.resource.lancedb) (push) Has been cancelled
Test (Install) / python-extra (langfuse, mirage.resource.langfuse) (push) Has been cancelled
Test (Install) / python-extra (mongodb, mirage.resource.mongodb) (push) Has been cancelled
Test (Install) / python-extra (nextcloud, mirage.resource.nextcloud) (push) Has been cancelled
Test (Install) / python-extra (openai, mirage.agents.openai_agents) (push) Has been cancelled
Test (Install) / python-extra (openhands, mirage.agents.openhands, 3.12) (push) Has been cancelled
Test (Install) / python-extra (parquet, mirage.core.filetype.parquet) (push) Has been cancelled
Test (Install) / python-extra (postgres, mirage.resource.postgres) (push) Has been cancelled
Test (Install) / python-extra (pydantic-ai, mirage.agents.pydantic_ai) (push) Has been cancelled
Test (Install) / python-extra (qdrant, mirage.resource.qdrant) (push) Has been cancelled
Test (Install) / python-extra (redis, mirage.resource.redis) (push) Has been cancelled
Test (Install) / python-extra (s3, mirage.resource.s3) (push) Has been cancelled
Test (Install) / python-extra (ssh, mirage.resource.ssh) (push) Has been cancelled
Test (Install) / ts-minimal (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:30:44 +08:00

332 lines
8.9 KiB
Plaintext

---
title: Slack
description: Mount Slack channels, DMs, messages, users, and shared files as a Mirage virtual filesystem for Python agents.
icon: slack
---
The Slack resource exposes a Slack workspace as a virtual filesystem
mounted at some prefix such as `/slack/`.
For token setup, see [Slack Setup](/python/setup/slack).
## Config
```python
import os
from mirage import MountMode, Workspace
from mirage.resource.slack import SlackConfig, SlackResource
config = SlackConfig(token=os.environ["SLACK_BOT_TOKEN"])
resource = SlackResource(config=config)
ws = Workspace({"/slack": resource}, mode=MountMode.READ)
```
## Filesystem Layout
```text
/slack/
channels/
<channel-name>__<channel-id>/
<yyyy-mm-dd>/
chat.jsonl
files/
<name>__<F-id>.<ext>
dms/
<user-name>__<dm-id>/
<yyyy-mm-dd>/
chat.jsonl
files/
<name>__<F-id>.<ext>
users/
<username>__<user-id>.json
...
```
Example:
```text
/slack/
channels/
general__C04KEPWF6V7/
2026-04-04/
chat.jsonl
files/
2026-04-05/
chat.jsonl
files/
random__C04JVGZM7UN/
2026-04-11/
chat.jsonl
files/
dms/
alice__D0AQDJ5FP9V/
2026-04-04/
chat.jsonl
files/
slackbot__D0ARPA1QSPJ/
2026-04-04/
chat.jsonl
files/
users/
alice__U12345678.json
bob__U87654321.json
```
Directory names embed the Slack ID so that write commands
(`slack-post-message --channel_id`, etc.) can reference the correct
resource without extra lookups.
### Channels
`/slack/channels/` lists public and private channels the bot has
access to. The channel ID is appended after `__`. Each channel
directory contains day-partitioned directories for the last 90 days
(or since channel creation, whichever is shorter). Each date directory
contains `chat.jsonl` plus a `files/` directory for attachments shared
that day.
The date range is derived from the channel's `created` timestamp.
### DMs
`/slack/dms/` lists direct message conversations. The DM ID is
appended after `__`. Like channels, DM directories contain daily
directories with `chat.jsonl` and `files/`.
### Users
`/slack/users/` lists one `.json` file per non-deleted, non-bot user.
Reading a user file calls `get_user_profile()` and returns the full
profile JSON from the Slack API.
## Cache
The Slack resource uses `IndexCacheStore` (same as Discord and other
resources). Index entries store channel IDs, DM IDs, user IDs, and
channel creation timestamps for date range computation. There is no
separate content cache - file content caching is handled by the
workspace `IOResult` mechanism.
## Example
```python
import asyncio
import os
from dotenv import load_dotenv
from mirage import MountMode, Workspace
from mirage.resource.slack import SlackConfig, SlackResource
load_dotenv(".env.development")
config = SlackConfig(token=os.environ["SLACK_BOT_TOKEN"])
resource = SlackResource(config=config)
async def main():
ws = Workspace({"/slack": resource}, mode=MountMode.READ)
# List structure
r = await ws.execute("ls /slack/")
print(await r.stdout_str())
# List channels
r = await ws.execute("ls /slack/channels/")
print(await r.stdout_str())
ch = r.stdout_str().strip().splitlines()[0].strip()
base = f"/slack/channels/{ch}"
# Read messages from a specific date
r = await ws.execute(f'cat "{base}/2026-04-04/chat.jsonl" | head -n 3')
print(await r.stdout_str())
# Read user profile
r = await ws.execute("cat /slack/users/alice__U12345678.json")
print(await r.stdout_str())
# Extract message text with jq
r = await ws.execute(
f'cat "{base}/2026-04-04/chat.jsonl"'
' | jq -r ".[] | .text" | head -n 5')
print(await r.stdout_str())
# Search across channel (scans all date files)
r = await ws.execute(f'rg message "{base}/"')
print(await r.stdout_str())
# Tree view
r = await ws.execute("tree -L 1 /slack/")
print(await r.stdout_str())
# Navigate with cd/pwd
await ws.execute(f'cd "{base}"')
r = await ws.execute("pwd")
print(await r.stdout_str())
if __name__ == "__main__":
asyncio.run(main())
```
See `examples/python/slack/slack.py` for the full working example.
## Finding IDs
Resource-specific commands require Slack IDs (`channel_id`, `user_id`,
`ts`). These can be extracted from the filesystem:
```bash
# Channel ID - embedded in directory name after "__"
ls /slack/channels/
# → general__C04KEPWF6V7 ← channel_id = C04KEPWF6V7
# User ID - embedded in filename after "__"
ls /slack/users/
# → alice__U04K21SEVR9.json ← user_id = U04K21SEVR9
# Message timestamp (ts) - inside JSONL messages
jq -r '.[] | "\(.ts) [\(.user)] \(.text)"' \
"/slack/channels/general__C04KEPWF6V7/2026-04-04/chat.jsonl"
# → 1712345678.123456 [U04K21SEVR9] hello world
# Find a specific message then reply
jq -r '.[] | select(.text | test("hello")) | .ts' \
"/slack/channels/general__C04KEPWF6V7/2026-04-04/chat.jsonl"
# → 1712345678.123456
slack-reply-to-thread --channel_id C04KEPWF6V7 \
--ts 1712345678.123456 --text "Reply to hello"
```
## Working with Large Channels
Channels with many messages produce large `chat.jsonl` files per day.
Tips for efficient access:
```bash
# Check message count per day
wc -l "/slack/channels/general__C04KEPWF6V7/2026-04-04/chat.jsonl"
# Read only recent messages
tail -n 10 "/slack/channels/general__C04KEPWF6V7/2026-04-04/chat.jsonl"
# Search across all dates (scans each file)
rg "keyword" "/slack/channels/general__C04KEPWF6V7/"
# Extract specific fields to reduce output
jq -r '.[] | "\(.ts) [\(.user)] \(.text)"' \
"/slack/channels/general__C04KEPWF6V7/2026-04-04/chat.jsonl" | head -n 20
# Count messages per user
cat "/slack/channels/general__C04KEPWF6V7/2026-04-04/chat.jsonl" \
| jq -r '.[] | .user' | sort | uniq -c
```
## Shell Commands
Standard commands available on the mounted Slack tree:
| Command | Notes |
| --------------- | ------------------------------------------ |
| `ls` | List channels, DMs, users, dates |
| `cat` | Read `chat.jsonl`, user `.json`, or files |
| `head` / `tail` | First/last N lines |
| `grep` / `rg` | Pattern search (file or directory level) |
| `jq` | Query JSON; use `.[]` prefix for JSONL |
| `wc` | Line/word/byte counts |
| `stat` | File metadata (name, size, type) |
| `find` | Recursive search with `-name`, `-maxdepth` |
| `tree` | Directory tree view |
Resource-specific commands:
### `slack-post-message`
Post a message to a channel.
```bash
slack-post-message --channel_id C04KEPWF6V7 --text "Hello from MIRAGE"
```
| Option | Required | Description |
| -------------- | -------- | -------------------- |
| `--channel_id` | yes | Slack channel ID |
| `--text` | yes | Message text to send |
Returns the posted message JSON.
### `slack-reply-to-thread`
Reply to a specific thread.
```bash
slack-reply-to-thread --channel_id C04KEPWF6V7 --ts 1712345678.123456 --text "Thread reply"
```
| Option | Required | Description |
| -------------- | -------- | ----------------------- |
| `--channel_id` | yes | Slack channel ID |
| `--ts` | yes | Thread parent timestamp |
| `--text` | yes | Reply text |
The `--ts` value is the message timestamp (e.g., from a `.jsonl`
entry's `ts` field). Returns the posted reply JSON.
### `slack-add-reaction`
Add an emoji reaction to a message.
```bash
slack-add-reaction --channel_id C04KEPWF6V7 --ts 1712345678.123456 --reaction thumbsup
```
| Option | Required | Description |
| -------------- | -------- | ----------------------------- |
| `--channel_id` | yes | Slack channel ID |
| `--ts` | yes | Message timestamp to react to |
| `--reaction` | yes | Emoji name (without colons) |
### `slack-get-users`
Search for users by name, real name, or email.
```bash
slack-get-users --query "alice"
```
| Option | Required | Description |
| --------- | -------- | ------------ |
| `--query` | yes | Search query |
Returns matching users as JSON array.
### `slack-get-user-profile`
Get a single user's full profile.
```bash
slack-get-user-profile --user_id U04K21SEVR9
```
| Option | Required | Description |
| ----------- | -------- | ------------- |
| `--user_id` | yes | Slack user ID |
Returns the user profile JSON. The user ID can be found in
filenames under `/slack/users/` (e.g., `alice__U04K21SEVR9.json`).
### `slack-search`
Search messages across the workspace.
```bash
slack-search --query "incident report"
```
| Option | Required | Description |
| --------- | -------- | ------------ |
| `--query` | yes | Search query |
Returns search results as JSON.