openclaw/slacrawl
GitHub: openclaw/slacrawl
slacrawl 是一个基于 Go 的 CLI 工具,用于将 Slack 工作区的消息和元数据同步到本地 SQLite,实现离线全文搜索、SQL 查询与自定义数据归档。
Stars: 189 | Forks: 17
💾 slacrawl
一个基于 Go 的 CLI,用于将 Slack 工作区数据镜像到本地 SQLite
以便进行搜索、查询和离线检查。
## 为什么使用 slacrawl?
当你需要自定义工作流、自定义保留策略或自定义查询时,Slack 自带的搜索功能就显得不够用了。`slacrawl` 是一个基于 Go 的 CLI,它将 Slack 工作区元数据和消息历史记录拉取到 SQLite 中,让你无需依赖 Slack UI 即可进行检查。
数据始终保留在你的本地机器上。你可以在 API 模式、MCP connector 模式、desktop 模式或混合工作流下运行它。这涵盖了单向同步、基于 Socket Mode 的实时 tail、由 connector 支持的抓取,以及本地 desktop 恢复或对你机器上已有 Slack Desktop artifacts 进行的“wiretap”式检查。
## 包含功能
- 本地 SQLite 存储,具备基于 SQLite FTS5 的全文搜索
- 工作区、频道、用户和消息同步
- 通过 Codex 的 HTTP Slack connector 或参考 Slack MCP server 进行 MCP connector 同步
- 当 user token 可用时,补全 thread 回复
- 当 user token 可用时,同步 DM 和 MPIM
- 默认提供增量 API 历史同步,`--full` 专用于刻意的全量补全
- 提供 `sync --latest-only`,用于对已抓取的频道进行轻量级增量刷新
- 提及内容提取,便于结构化查询
- 提供只读 SQL 访问,用于 ad hoc 分析
- 提供用于 config、database、token 和 desktop-source 检查的 `doctor` 诊断
- 支持 desktop 本地摄取工作区元数据、频道、用户、已缓存的 channel/DM 消息、草稿、已读标记、最近频道提示及自定义状态元数据
- 可选基于 app token 的 Socket Mode 实时 tail
- 使用 `watch` 进行周期性 desktop 刷新
- 支持保留预览及基于绝对或相对截止时间的事务性消息清理
- 支持 git-backed 归档发布、订阅及读取时自动刷新
## 当前覆盖范围
- 多工作区存储和过滤
- 配置了 `[[workspaces]]` 时的多工作区 API 同步
- 配置了各工作区 app token 时的多工作区实时 tail
- 公开频道
- 私有频道
- 顶级消息
- 频道 thread
- 本地 FTS 搜索
- 只读 SQL 访问
- macOS 和 Linux 上的 Slack Desktop 自动发现
- 可选的 Slack 文件媒体缓存
## 尚未包含
- write-back 操作
- 公共 Marketplace 式的发布强化
- 超出已文档化 bootstrap 范围的 desktop 本地消息提取
如果这些缺失的某项影响了你的工作流,请提交一个 issue 以便明确追踪。
## 环境要求
- Go `1.26.4+`
- 如果需要更丰富的 desktop 本地 IndexedDB blob 解码,则需要 `node`
- 标准 API 同步所需的 Slack bot token
- 如果需要 MCP 支持的同步,则需配置 Slack MCP connector
- 如果想使用 `tail`,则需要 app token
- 可选的 user token,用于获取更完整的历史 thread 覆盖
- 仅当需要 desktop 本地发现时,才需在 macOS 或 Linux 上安装 Slack Desktop
## 安装
Homebrew (macOS)
```
brew tap openclaw/tap
brew install slacrawl
```
从 GitHub Releases 获取 Linux 安装包
从 [最新发布版本](https://github.com/openclaw/slacrawl/releases/latest) 下载与你的平台相匹配的安装包。
Debian/Ubuntu:
```
curl -LO https://github.com/openclaw/slacrawl/releases/latest/download/slacrawl_0.7.2_amd64.deb
sudo dpkg -i slacrawl_0.7.2_amd64.deb
```
RHEL/Fedora:
```
curl -LO https://github.com/openclaw/slacrawl/releases/latest/download/slacrawl-0.7.2-1.x86_64.rpm
sudo rpm -i slacrawl-0.7.2-1.x86_64.rpm
```
从源码构建
```
git clone https://github.com/openclaw/slacrawl.git
cd slacrawl
go build -o bin/slacrawl ./cmd/slacrawl
./bin/slacrawl --help
```
Docker
```
docker build -t slacrawl .
docker run --rm -e SLACK_BOT_TOKEN -v "$PWD/.slacrawl:/data" slacrawl doctor
docker run --rm -e SLACK_BOT_TOKEN -e SLACK_APP_TOKEN -v "$PWD/.slacrawl:/data" slacrawl tail
```
该镜像将 config、SQLite 数据、cache 和 Git 快照状态存储在 `/data` 目录下。Desktop/wiretap 模式需要显式地将宿主机挂载到 Slack Desktop 数据目录。
免编译直接运行
```
git clone https://github.com/openclaw/slacrawl.git
cd slacrawl
go run ./cmd/slacrawl --help
```
## 快速开始
```
export SLACK_BOT_TOKEN="xoxb-..."
export SLACK_APP_TOKEN="xapp-..."
export SLACK_USER_TOKEN="xoxp-..."
go run ./cmd/slacrawl init
go run ./cmd/slacrawl doctor
go run ./cmd/slacrawl sync --source bot
go run ./cmd/slacrawl sync --source mcp --workspace T01234567
go run ./cmd/slacrawl search --workspace T01234567 "incident"
go run ./cmd/slacrawl purge --older-than 90d
go run ./cmd/slacrawl analytics trends --weeks 4
go run ./cmd/slacrawl tail --repair-every 30m
go run ./cmd/slacrawl watch --desktop-every 5m
```
如果你已自行编译了二进制文件,请将 `go run ./cmd/slacrawl` 替换为 `./bin/slacrawl`。
`tail` 是工具的实时 API 侧功能。`watch` 是周期性的 desktop 侧刷新循环。
## 可见性模型
请将一个 `slacrawl` 的 config/database 视为一个 Slack 可见性边界。该归档应代表“此 bot/account/profile 能看到的内容”,而不是将不相关的个人备份与公司备份混为一谈。
- `--source bot` 是 `--source api` 的别名;它通过配置的 bot/user token 抓取 Slack
- `--source mcp` 通过 Codex 的 HTTP Slack connector 或基于 stdio 的参考 Slack MCP server 获取数据,并且需要一个 workspace ID 来声明归档所有权
- `--source wiretap` 是 `--source desktop` 的别名;它读取本地 Slack Desktop 缓存
- `--source all` 先运行 API 抓取,随后进行 desktop 补全
- `[share]` 用于当前 DB 的备份/恢复,而非第二个 Slack 数据源
如果需要分离公司和个人归档,请使用独立的 config,并设置不同的 `db_path` 和 `[share].remote` 值。
请选择与你设置相匹配的路径:
- 对于普通的基于 token 的增量同步,使用 `sync --source bot`
- 仅在你想要进行刻意的全量补全时,使用 `sync --source bot --full`
- 当你只想为已存在本地历史的频道获取最新增量时,使用 `sync --source bot --latest-only`
- 当已配置的 HTTP 或 stdio MCP connector 能够读取该工作区时,使用 `sync --source mcp --workspace T01234567`
- 当你只想进行本地 desktop 恢复时,使用 `sync --source wiretap`
- 当你希望 desktop 本地状态持续刷新到 SQLite 时,使用 `watch`
## 命令
- `init` 创建一个入门 config 文件
- `doctor` 检查 config、DB 访问权限、token 存在状态、FTS 以及 desktop 源的可用性
- `report` 在不编写 SQL 的情况下总结归档活动和 git-share 新鲜度
- `publish` 将本地 SQLite 归档导出为压缩的 JSONL 分片和清单,并存入 git 仓库
- `subscribe` 配置一个支持在没有 Slack 凭据的情况下运行的 git-backed 读取器
- `update` 拉取并导入最新的 git 快照
- `sync` 执行从 bot/API、MCP connector、wiretap/desktop 或两者结合的单次抓取
- `import` 导入 Slack 导出的 ZIP 文件或解压后的导出目录
- `purge` 预览或删除早于截止时间的消息及其拥有的记录
- `tail` 通过 Socket Mode 监听实时事件,包括为每个配置的工作区各开启一个 tail
- `watch` 按计划刷新 desktop 本地状态
- `search` 执行安全的本地文本搜索,带有 FTS 和子字符串回退机制,可选择按工作区过滤
- `messages` 列出已存储的消息(带过滤器)
- `mentions` 列出结构化的提及记录
- `sql` 对本地数据库执行只读 SQL 查询
- `users` 列出已同步的用户
- `channels` 列出已同步的频道
- `status` 打印工作区和同步状态
- `metadata --json`、`status --json` 和 `doctor --json` 暴露 crawlkit
的控制/状态 payload,供 launchers、自动化工具和 CI 使用
- `check-update` 检查 GitHub Releases 中是否有更新的 OpenClaw 构建;交互式
终端运行时也会打印缓存的每日 stderr 提醒,除非
设置了 `SLACRAWL_NO_UPDATE_CHECK=1` 或 `CRAWLKIT_NO_UPDATE_CHECK=1`
- `digest` 打印指定时间窗口内各频道的活动摘要
- `analytics` 将分析子命令分组 (`digest`, `quiet`, `trends`)
- `completion` 输出适用于 `bash` 或 `zsh` 的 shell 补全脚本
## 保留期清理
`purge` 可移除早于排他性截止时间的归档消息。请选择
绝对 UTC 日期/时间戳或相对年龄。thread 将作为整体被保留或移除,
判定依据是父消息的时间戳:
```
# 预览超过 90 天的消息。
slacrawl purge --older-than 90d
# 预览 2026 年 1 月 1 日 UTC 之前的一个 workspace。
slacrawl purge --workspace T01234567 --before 2026-01-01
# 删除匹配的行和未引用的缓存媒体。
slacrawl purge --older-than 90d --force
# 删除后同时压缩 SQLite 文件。
slacrawl purge --older-than 90d --force --vacuum
```
预览是默认操作。`--force` 将在单个 SQLite 事务中删除匹配的消息及其
事件历史、文件元数据、提及、embedding jobs 和 FTS 条目。工作区/频道/用户元数据和同步游标将会保留,以便随后的
API 和 MCP 同步可以继续增量进行,而不会越过保留的
截止时间。在数据库提交后,不再被其他消息引用的已缓存媒体将被移除;
传递 `--keep-media` 可将其保留。显式的全量同步、
更早的 `--since` 值、desktop 摄取和导入操作可能会恢复旧数据。
SQLite 通常会重用释放的页面,而不会缩小数据库文件。当你
需要立即回收文件系统空间时,请添加 `--vacuum`。如果启用了 git-backed
共享,请在清理后发布新的快照;导入较旧的
快照可能会恢复本地已删除的记录。
## 导入 Slack 导出文件
```
slacrawl import ./my-export.zip --workspace T01234567
slacrawl import ./extracted-export/ --workspace T01234567 --dry-run
```
设置包含 `im:history`、`mpim:history`、`im:read` 和 `mpim:read` scope 的 `SLACK_USER_TOKEN`,以便在 API 同步中包含 DM 和 MPIM。
## 分析
- `analytics digest [--since 7d] [--workspace X] [--channel C]`
- `analytics quiet [--since 30d] [--workspace X]`
- `analytics trends [--weeks 8] [--workspace X] [--channel C]`
计划中的后续功能:`health`, `response-times`, `threads-stale`, `activity`。
## 输出模式
此 CLI 支持三种输出模式:
- `--format text` 用于默认的带有样式的终端视图
- `--format json` 或 `--json` 用于机器可读输出
- `--format log` 用于面向行的、适合自动化的输出
当 stdout 不是 TTY 时,颜色将自动禁用。你也可以使用 `--no-color` 或设置 `NO_COLOR=1` 来强制使用纯文本。
## Make 目标
```
make build
make test
make run ARGS="status"
make generate-sqlc
make completion
```
补全文件将生成到 `dist/completions/` 目录中。
## Shell 补全
使用以下命令生成补全脚本:
```
go run ./cmd/slacrawl completion bash
go run ./cmd/slacrawl completion zsh
```
或者使用 Makefile:
```
make completion
```
典型的安装位置:
```
# bash
go run ./cmd/slacrawl completion bash > /usr/local/etc/bash_completion.d/slacrawl
# zsh
mkdir -p "${HOME}/.zsh/completions"
go run ./cmd/slacrawl completion zsh > "${HOME}/.zsh/completions/_slacrawl"
```
## 默认路径
- config: `~/.slacrawl/config.toml`
- database: `~/.slacrawl/slacrawl.db`
- cache: `~/.slacrawl/cache`
- logs: `~/.slacrawl/logs`
## 配置
对于单一工作区,可继续使用顶层的 `[slack.bot]`、`[slack.app]` 和 `[slack.user]` token 配置。
对于多 API 工作区或多个实时 wiretap/tail 会话,请添加 `[[workspaces]]` 条目并配置各工作区的 token 环境变量:
```
workspace_id = "T01234567"
[[workspaces]]
id = "T01234567"
default = true
[[workspaces]]
id = "T08976543"
bot_token_env = "SLACK_CLIENT_BOT_TOKEN"
app_token_env = "SLACK_CLIENT_APP_TOKEN"
user_token_env = "SLACK_CLIENT_USER_TOKEN"
```
默认情况下,每个工作区条目会自动寻找 `SLACK_
_BOT_TOKEN`、`SLACK__APP_TOKEN` 和 `SLACK__USER_TOKEN`,因此在常见场景下你只需提供 `id`。顶层的 `enabled` 标志依然全局生效,这避免了为每个工作区重复写 `enabled = true`。
如果不指定 `--workspace`,`sync --source bot` 和 `tail` 将分发到所有已配置的工作区条目中。像 `search`、`messages`、`mentions`、`users` 和 `channels` 这样的读取命令接受 `--workspace` 参数,以便在需要时对共享的本地数据库进行范围限定。
文件媒体下载是可选的。SQLite 存储文件元数据和缓存指针;字节流存储在 `cache_dir/media` 下。
```
[sync]
file_media = false
max_file_bytes = 104857600
```
当你想要填充本地缓存时,请使用 `sync --with-media` 或 `files fetch`。
```
go run ./cmd/slacrawl files --filename runbook
go run ./cmd/slacrawl files fetch --missing --max-bytes 104857600
go run ./cmd/slacrawl sync --source bot --latest-only --with-media
```
## Git 归档共享
当一台机器拥有 Slack 凭据并应发布快照,而其他机器只需要本地只读归档时,请使用 git-share 模式。
典型的职责划分:
- 发布者机器:运行 `sync`,随后运行 `publish --push`
- 订阅者机器:运行 `subscribe`,随后可选择在读取时自动刷新,从本地 SQLite 读取数据
Git-backed 归档共享在 `[share]` 下进行配置:
```
[share]
remote = "git@github.com:your-org/private-slacrawl-archive.git"
repo_path = "~/.slacrawl/share"
branch = "main"
auto_update = true
stale_after = "15m"
```
行为说明:
- `publish` 将 压缩的 JSONL 分片和 `manifest.json` 写入 `repo_path`
- 默认包含已缓存的非 DM/非私有文件媒体;使用 `--no-media` 可将其忽略
- `subscribe` 会写入一个 git-reader 配置,禁用该配置的 Slack API 和 desktop 源,克隆仓库,并导入快照
- 当你希望读取器归档存放在非默认的 SQLite 路径时,向 `subscribe` 传递 `--db` 参数
- `update` 仅在 manifest 更改时拉取并重新导入
- 当 `auto_update = true` 时,`status`、`search`、`messages`、`mentions`、`sql`、`users`、`channels` 和 `report` 会在读取前自动刷新过期的 git 快照
- 当配置了共享 remote 时,`sync --source bot` 和 `sync --source all` 会在请求 Slack 之前先从 git 快照中预热数据
- `status` 和 `doctor` 会显示当前的 git-share 仓库、最后导入时间以及本地快照是否过期
### `publish`
`publish` 是写入端的命令。它将当前的 SQLite 归档导出到 git 共享仓库中,并能在一步内完成提交/推送。
```
go run ./cmd/slacrawl publish --remote /path/to/private/slacrawl-archive.git --push
go run ./cmd/slacrawl publish --repo ~/.slacrawl/share --branch main --message "archive: daily refresh" --push
```
相关标志:
- `--repo` 选择本地 git 工作仓库路径
- `--remote` 设置或覆盖用于发布的 git remote
- `--branch` 选择目标分支
- `--message` 设置 git 提交信息
- `--no-commit` 仅导出文件,而不创建 git commit
- `--push` 将新 commit 推送到 `origin`
- `--no-media` 从快照中排除缓存的媒体文件
### `subscribe`
`subscribe` 是读取端的设置命令。它克隆 git 归档,写入 share-reader 配置,禁用该配置的实时 Slack 源,并将快照导入 SQLite。
```
go run ./cmd/slacrawl subscribe --repo ~/.slacrawl/share --db ~/.slacrawl/slacrawl.db /path/to/private/slacrawl-archive.git
go run ./cmd/slacrawl subscribe --remote git@github.com:your-org/private-slacrawl-archive.git --stale-after 30m
go run ./cmd/slacrawl subscribe --repo ~/.slacrawl/share --no-import --no-auto-update /path/to/private/slacrawl-archive.git
```
相关标志:
- `--repo` 选择本地克隆路径
- `--db` 选择读取器使用的 SQLite 文件
- `--branch` 选择要追踪的分支
- `--remote` 将 remote 存入配置,而无需将其作为位置参数提供
- `--stale-after` 控制读取时刷新在何时认为本地快照已过期
- `--no-auto-update` 为 search/status/report 类命令禁用读取时刷新
- `--no-import` 跳过初始的快照导入
- `--no-media` 跳过对已缓存媒体文件的恢复
### `update`
`update` 是显式的读取端刷新命令。当你希望按需拉取并导入,而不是等待自动过期检查时,请使用它。
```
go run ./cmd/slacrawl update
go run ./cmd/slacrawl update --repo ~/.slacrawl/share --branch main
```
### `report`
`report` 是最快捷的、人类可读的归档摘要,在 git-share 模式下尤为实用,因为它能显示当前的归档足迹以及共享数据的新鲜度。
```
go run ./cmd/slacrawl report
```
典型的发布/订阅流程:
```
# publisher
go run ./cmd/slacrawl sync --source bot --latest-only
go run ./cmd/slacrawl publish --remote /path/to/private/slacrawl-archive.git --push
# subscriber
go run ./cmd/slacrawl subscribe --repo ~/.slacrawl/share --db ~/.slacrawl/slacrawl.db /path/to/private/slacrawl-archive.git
go run ./cmd/slacrawl search incident
```
初始配置位于 [`config.example.toml`](./config.example.toml)。默认情况下,它指向以下环境变量:
- `SLACK_BOT_TOKEN`
- `SLACK_APP_TOKEN`
- `SLACK_USER_TOKEN`
desktop 发现功能默认启用,并会检查你所支持平台上的 Slack Desktop
位置:
```
# macOS
~/Library/Containers/com.tinyspeck.slackmacgap/Data/Library/Application Support/Slack
# Linux
${XDG_CONFIG_HOME}/Slack
~/.config/Slack
```
desktop 配置说明:
- 设置 `[slack.desktop].enabled = false` 可禁用 desktop 摄取
- 留空 `[slack.desktop].path = ""` 可自动检测 macOS 或 Linux 的 Slack 路径
- 如果 Slack Desktop 数据存放在其他位置,请设置自定义的绝对路径
- 设置 `[slack.bot]`、`[slack.app]` 或 `[slack.user]` 的 `enabled = false` 可完全忽略该 token 源
独立的可见性配置应使用独立的配置文件:
```
# ~/.slacrawl/company.toml
db_path = "~/.slacrawl/company.db"
[share]
remote = "git@github.com:your-org/company-slacrawl-archive.git"
repo_path = "~/.slacrawl/company-share"
```
```
# ~/.slacrawl/personal.toml
db_path = "~/.slacrawl/personal.db"
[share]
remote = "git@github.com:your-user/personal-slacrawl-archive.git"
repo_path = "~/.slacrawl/personal-share"
```
## 典型工作流
```
go run ./cmd/slacrawl init
go run ./cmd/slacrawl sync --source bot
go run ./cmd/slacrawl status
go run ./cmd/slacrawl report
go run ./cmd/slacrawl digest --since 7d
go run ./cmd/slacrawl channels
go run ./cmd/slacrawl messages --channel C12345678 --limit 20
go run ./cmd/slacrawl mentions --limit 20
go run ./cmd/slacrawl sql 'select channel_id, count(*) as messages from messages group by channel_id order by messages desc limit 10;'
```
## 覆盖范围说明
- 在公开和私有频道中获取完整的历史 thread 回复覆盖,取决于是否提供了 user token。
- `tail` 需要 app token,因为它使用了 Socket Mode。
- SQLite FTS5 是内置的全文索引,无需外部搜索服务器即可实现快速本地文本搜索。
- 到达 FTS 之前的索引文本会经过净化处理,因此格式错误的 UTF-8、零宽垃圾字符和异常空白不会污染搜索。
- desktop 本地支持比简单的发现更广泛,但仍不是完整的 write-back 或 export-import 路径。
## 开发
```
go test ./...
go build ./cmd/slacrawl
```
有关贡献工作流,请参阅 [`CONTRIBUTING.md`](./CONTRIBUTING.md);有关实现契约,请参阅 [`SPEC.md`](./SPEC.md)。
深度文档:
- [`docs/configuration.md`](./docs/configuration.md)
- [`docs/desktop-mode.md`](./docs/desktop-mode.md)
- [`docs/retention.md`](./docs/retention.md)
由 Vincent Koc 构建 · MIT标签:EVTX分析, Slack, SQLite, 全文搜索, 数据同步, 数据提取, 日志审计, 请求拦截