wacli 评测:把 WhatsApp 变成可脚本化的本地数据库
WhatsApp CLI:同步、搜索、发送。从源代码构建 wacli 需要 Go 1.26.5 或更高版本并使用 go-sqlite3,因此需要 cgo + C 编译器。
秒懂
- 它是什么?
- wacli 是一个用 Go 写的 WhatsApp 命令行客户端,通过 whatsmeow 协议将消息镜像到本地 SQLite,支持搜索、发送和聊天管理。本文基于仓库文档与发布信息,分析它的工作机制、安装方式、适用场景与边界。
- 适合谁用?
- wacli 适合需要把 WhatsApp 消息纳入本地自动化流程的工程师,比如日志归档、关键词告警、只读审计。它不适合追求零维护或不愿处理 cgo 构建的人,因为从源码编译需要 Go 1.27.0、C 编译器以及 CGO_ENABLED=1。
- 能商用吗?
- 可以。MIT 是宽松许可证:你可以使用、修改并销售基于它的软件,只需保留版权和许可证声明。
- 还在维护吗?
- 在维护。仓库最近一次提交在 1 天前。
- 用什么语言写的?
- 主要是 Go(依据 GitHub 的语言统计)。
以上回答依据项目的 GitHub 数据(最近同步于 2026年9月15日)和我们的分析,不构成法律意见。
开源项目深度解析
它解决什么问题
wacli 面向的是那些在终端里工作和写脚本的人。它把 WhatsApp 变成一个可编程的接口,而不是一个只能手动点击的 App。核心能力是三条:同步、搜索、发送。同步指的是把 WhatsApp 的消息镜像到本地 SQLite 数据库。搜索是在本地索引上执行,不依赖实时连接。发送则通过命令行直接给指定号码或群组发消息。这个工具适合谁?适合需要把 WhatsApp 消息纳入自动化流程的工程师,比如把聊天记录归档、用脚本监控特定关键词、或者做只读审计。它不适合普通用户,因为安装和配置的门槛明显高于官方客户端。
底层机制:whatsmeow 与双数据库设计
wacli 使用 whatsmeow 库来实现 WhatsApp Web 协议。它不是官方 API,而是逆向工程的协议实现,因此不受 WhatsApp 或 Meta 的附属或认可。这一点在 README 中有明确声明。wacli 把 WhatsApp 会话和消息索引分开存储,放在两个独立的 SQLite 数据库中。会话数据库保存登录状态,索引数据库保存可搜索的消息记录。这种分离的收益是:搜索可以在没有网络连接时进行,因为索引是本地副本。另一个细节是写操作使用 per-store 锁。当 sync --follow 持续运行时,它持有锁,此时发送命令会被委托给正在运行的同步进程。这意味着你可以一边持续同步,一边通过命令行发送消息,而不会产生锁冲突。这个设计对长时间运行的集成场景很关键。
安装与构建:Go 版本与 cgo 是硬门槛
安装方式有三种:Homebrew、预编译归档、源码构建。Homebrew 适用于 macOS 和 Linux,命令是 brew install openclaw/tap/wacli。预编译归档覆盖 macOS、Linux 和 Windows。源码构建的要求比较苛刻:需要 Go 1.27.0 或更新版本,以及 C 编译器,因为依赖 go-sqlite3,它需要 cgo。README 给出的构建命令是:CGO_ENABLED=1 CGO_CFLAGS="-Wno-error=missing-braces" go install -tags sqlite_fts5 github.com/openclaw/wacli/cmd/wacli@latest。注意那个 CGO_CFLAGS 是必需的,否则可能因为编译错误而失败。如果你没有 C 编译器,或者不想处理 cgo 的交叉编译问题,那么源码构建这条路基本走不通。预编译归档是更省事的选择,但你需要确认你的平台在发布列表中。
快速上手:配对、搜索、发送
基本流程三步走。首先运行 wacli auth,终端会显示一个 QR 码,用 WhatsApp 的 Linked devices 屏幕扫码配对。配对后 auth 会执行第一次同步。然后就可以搜索了,比如 wacli messages search "meeting"。发送消息用 wacli send text --to +15551234567 --message "hello"。接收方可以是电话号码、WhatsApp JID,或者已同步的联系人、群组和聊天名称。注意发送要求接收方是你被允许联系的人,也就是说不能随便给陌生人发。搜索命令支持过滤,比如 wacli messages search "invoice" --has-media 只搜索带媒体的消息。默认输出是表格,适合人看;脚本可以用 --json 获取结构化输出。还有一个 --read-only 参数,或者环境变量 WACLI_READONLY=1,可以保证集成脚本不会修改 WhatsApp 或本地存储。
同步与历史消息的边界
wacli 的同步命令是 wacli sync --follow,它会持续运行,把新事件镜像到本地。但历史消息的可用性是个问题。README 明确说 WhatsApp Web 提供历史消息是 best-effort 的,也就是说可能不完整。为此 wacli 提供了 history coverage 命令,用来检查本地已经有哪些历史,再决定是否向主手机请求更早的消息。这个功能很务实,它承认了协议的限制,而不是假装能拿到全部历史。如果你需要完整的聊天记录,这个工具可能让你失望。但如果你只需要从配对时刻开始的新消息,那 sync --follow 就够用了。存储限制和媒体下载行为在 docs/sync.md 中有说明,具体细节需要查阅文档。
配置与多账户隔离
默认存储位置在 Linux 上是 ~/.local/state/wacli,其他平台是 ~/.wacli。可以用 --store DIR 或环境变量 WACLI_STORE_DIR 覆盖。如果你有多个 WhatsApp 身份,可以用命名账户来隔离。每个账户有自己的会话、数据库和锁。例如 wacli accounts add work 创建一个名为 work 的账户,然后 wacli --account work sync --follow 启动该账户的同步。这个设计对同时管理个人和工作 WhatsApp 的人很有用,也方便在测试环境里隔离数据。配置方面没有复杂的 config 文件,主要靠命令行参数和环境变量,符合 CLI 工具的习惯。
局限性与错误使用场景
最大的局限是依赖非官方协议。whatsmeow 是逆向工程的结果,WhatsApp 随时可能更改协议导致工具失效。这不是 wacli 独有的问题,但采用者必须接受这种风险。另一个局限是 cgo 依赖。go-sqlite3 需要 C 编译器,这限制了纯 Go 的静态编译能力,也增加了交叉编译的复杂度。如果你需要部署到没有 C 工具链的容器或服务器,预编译归档是唯一可行的方式。还有一个场景是 wacli 不适合:如果你只需要发送消息而不需要本地搜索,那么它的同步机制和数据库设计就是多余的复杂度。此外,历史消息的 best-effort 特性意味着它不能作为官方备份工具。最后,写锁机制虽然解决了并发问题,但如果你有多个进程同时写同一个 store,必须依赖委托机制,这增加了调试的复杂度。
替代方案与对比
README 提到 wacli 深受 whatsapp-cli 的启发,作者是 Vicente Reig。whatsapp-cli 也是一个 WhatsApp 命令行工具,但它的实现方式不同。whatsapp-cli 更轻量,它不维护本地 SQLite 搜索索引,而是直接通过协议操作。wacli 的差异化在于本地存储和搜索能力,这使得它更适合需要离线查询和复杂过滤的场景。另一个替代方案是直接用 whatsmeow 库自己写脚本,但那样你需要自己处理会话管理、消息存储和 CLI 接口。wacli 把这些都封装好了,代价是学习它的命令体系和配置方式。如果你只需要简单的发送功能,whatsapp-cli 可能更简单;如果你需要本地搜索和自动化,wacli 的设计更贴近需求。
编辑结论
wacli 适合需要把 WhatsApp 消息纳入本地自动化流程的工程师,比如日志归档、关键词告警、只读审计。它不适合追求零维护或不愿处理 cgo 构建的人,因为从源码编译需要 Go 1.27.0、C 编译器以及 CGO_ENABLED=1。采用前应先验证三件事:你的 Go 版本是否满足要求,目标平台是否有可用的 C 编译器,以及你的使用场景是否能接受 WhatsApp Web 历史消息的 best-effort 特性。如果你只需要收发消息而不需要本地搜索,更轻量的方案可能更合适。wacli 的核心价值在于把 WhatsApp 数据变成可查询的本地资产,这个定位在同类工具中并不常见。
社区笔记