关于 wa — safe WhatsApp automation
wa 是个人 WhatsApp 自动化工具,包含常驻守护进程、命令行客户端和 MCP 服务,面向脚本与 AI Agent 使用。发送默认进入人工审核草稿队列,并由守护进程强制执行允许列表、速率限制和追加式审计日志。
主要功能
- 01常驻守护进程管理 WhatsApp 会话
- 02发送消息与媒体并支持定时发送
- 03草稿审核后发送
- 04允许列表与强制速率限制
- 05搜索消息并查看聊天信息
适用场景
- 01通过脚本或 cron 发送消息
- 02让 AI Agent 起草待审核消息
- 03搜索已同步消息并查看会话
- 04分别管理工作和个人配置
MCP 相关
`wa mcp serve` 通过 stdio 向 MCP 客户端提供消息、聊天、联系人等工具,以及资源和提示词。所有调用均经过守护进程中的安全管道;发送默认为草稿,须人工批准后才会发出。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
wa
个人 WhatsApp 自动化命令行工具 + 守护进程,以 Go 编写。
一个采用六边形架构的 Go 守护进程,负责持有 WhatsApp Multi-Device 会话;另有一个轻量 JSON-RPC 客户端与之通信。它足够安全,可以让大模型代你发送消息;足够可靠,即使迁移过程中断电也能恢复;也足够谨慎,会拒绝所有你可能预期会有的破坏性标志。
功能
模式。 通过 Unix 套接字运行的持久化 WhatsApp 守护进程——一个 wad 进程持有 Multi-Device 会话、ratchet 存储和 websocket;轻量的 wa JSON-RPC 客户端负责调用它。
权衡。 每个配置文件约占用 30 MB RSS,冷启动连接需要 5–8 秒,换来后续每次 wa send 调用都能在亚秒级完成。完全避免了每次调用时重新附加会话。
适用场景。 Shell 管道、cron 任务或 Claude Code 插件需要发送 WhatsApp 消息,并要求延迟可预测;同时,每条 RPC 路径下方都有不可覆盖的安全流水线(默认拒绝的允许列表 + 速率限制器 + 预热渐增 + 仅追加审计日志)。
brew install yolo-labz/tap/wa
wad & # daemon, single instance per profile
wa pair # QR-code pairing on first run
wa allow add [email protected] --actions send
wa send --to [email protected] --body "hello"
演示

每一帧都是真实输出,来自本仓库中的二进制文件,并在私有临时目录中对未配对的临时守护进程录制。doctor 会如实警告设备尚未配对(并可能提示新建沙盒中缺少备份)。
未使用任何真实账户数据。撤销命令仅展示帮助信息,不会执行任何更改。
录制内容由程序生成,从不手动编辑。真实来源是纯文本 docs/assets/wa-demo.tape;只需一条命令,即可重新生成 GIF、MP4、WebM、静态 PNG 和捕获的文本:
nix develop -c ./scripts/record-demo.sh
想使用播放控件或减少动态效果?请使用 MP4、 WebM、静态帧 或文本版本。 录制说明介绍了隔离方式、安全控制、字节预算和检查项。播放速度为 1×,无声音;演示中不会实时发送消息。
wa 的比较
反向工程 WhatsApp 生态中的最接近方案:
| 功能 | wa(本仓库) | whatsmeow 直连 | whatsapp-web-cli |
|---|---|---|---|
| 持久守护进程(预热调用低于 1 秒) | 是 | 否(每次调用都要附加会话) | 否(由浏览器驱动) |
| 通过 Unix 套接字进行 JSON-RPC | 是 | 不适用(库,不是守护进程) | 否(Chrome 桥接) |
| 默认拒绝的允许列表(按操作配置) | 是 | 需手动实现 | 否 |
| 不可覆盖的限流器(2 次/秒 + 30 次/分钟) | 是 | 需手动实现 | 否 |
| 新会话的预热渐增机制 | 是 | 需手动实现 | 否 |
| 仅追加的 JSON-Lines 审计日志 | 是 | 需手动实现 | 否 |
| SLSA L2 + Sigstore 签名发布 | 是 | 不适用 | 否 |
| 双 SBOM(CycloneDX 1.6 + SPDX 2.3) | 是 | 不适用 | 否 |
CGO_ENABLED=0 静态二进制文件 | 是 | 取决于使用方 | 否(由浏览器驱动) |
| 入站提示注入防火墙 | 是 | 不适用 | 否 |
对于多租户 REST 网关,请参阅 EvolutionAPI 或 WAHA——这类问题的形态不同,详见本项目不是什么。
本项目是什么
两个二进制文件,一个仓库:
wad——长期运行的守护进程,负责管理 WhatsApp 会话、SQLite ratchet 存储,以及连接到web.whatsapp.com的 websocket。在 Linux 上由systemd运行,在 macOS 上由launchd运行,也可使用 NixOS 模块。每个配置文件仅运行一个实例,绝不以 root 身份运行。wa——轻量级 JSON-RPC 客户端,通过 Unix 套接字与wad通信。shell 脚本、cron 任务和 Claude Code 插件实际调用的就是它。
它基于 go.mau.fi/whatsmeow 构建——这是在生产环境中为 mautrix-whatsapp 提供支持的库,也是 2026 年唯一仍在积极维护的反向工程 WhatsApp 库。它还提供一个安全优先的 MCP 服务(wa mcp serve),让 AI Agent 通过同一套不可绕过的安全流程操作 WhatsApp,默认需经草稿审核。详见 MCP 服务。
本项目不是什么
- 不是群发消息工具。限流器不可覆盖,任何地方都没有
--force标志。 - 不是多租户 SaaS。每个
wa安装都对应一个人;也可选择隔离多个配置文件,以区分工作和个人用途。 - 不是 Matrix 桥接。若这是你想要的,请使用
mautrix-whatsapp。 - 不是 REST 网关。若这是你想要的,请使用
EvolutionAPI或WAHA。 - 不是官方 WhatsApp Cloud API。本项目通过
whatsmeow使用反向工程的 Multi-Device 协议。
快速开始
# Install (Homebrew — macOS + Linuxbrew)
brew install yolo-labz/tap/wa
# Or via Nix (recommended for NixOS/nix-darwin users)
nix profile install github:yolo-labz/wa
# Or the checksum-verified installer (80 lines — inspect first if you like)
curl -fsSL https://raw.githubusercontent.com/yolo-labz/wa/main/install.sh | bash
# Or Docker — single distroless container (~12 MB); /data holds the session
docker compose up -d # see docker-compose.yaml; pair via `docker compose exec`
# Start the daemon (default profile)
wad &
# Pair your phone — QR code in terminal
wa pair
# Allowlist yourself (default-deny policy)
wa allow add [email protected] --actions send
# Send a message
wa send --to [email protected] --body "hello from wa"
# Install as a persistent system service
wad install-service --profile default
# Hand it to an AI agent — MCP over stdio, draft-gated sends by default:
# the agent PROPOSES messages into a human-review queue; nothing leaves
# until you run `wa draft approve`. Add to Claude Desktop/Code, Cursor:
# {"mcpServers": {"wa": {"command": "wa", "args": ["mcp", "serve"]}}}
wa mcp serve --help
根据命令不同,收件人标志可以写作 --to、--jid 或 --group;所有命令都接受 --chat <jid> 作为通用别名(原有标志仍可使用)。
如需了解完整用法,包括多配置文件设置、shell 补全、迁移和审计日志,请参阅 docs/manual.md。
MCP 服务
wa mcp serve 通过 模型上下文协议(stdio 传输)向 AI Agent 开放守护进程。每次工具调用都会经过与 CLI 相同且不可绕过的安全管道——默认拒绝的允许列表、强制执行的短时间窗口限制(每秒 2 次,突发上限为 2;每分钟 30 次,突发上限为 30;普通发送没有每日上限),并包含预热机制和只追加的审计日志。发送默认采用草稿模式:模型将消息提交到人工审核队列,在你运行 wa draft approve 前,不会有任何内容发出。这个草稿门槛至关重要——正是它让将 WhatsApp 交给自主 Agent 变得安全。
现已上线官方 MCP 注册表,名称为 io.github.yolo-labz/wa;可通过每个版本发布页中的签名 .mcpb 包一键安装,也可以手动配置到 Claude Desktop/Code 或 Cursor 中:
{ "mcpServers": { "wa": { "command": "wa", "args": ["mcp", "serve"] } } }
工具(12 个):
| 工具 | 用途 |
|---|---|
wa_send_message | 通过安全管道发送(或保存为草稿)消息 |
wa_send_media | 发送(或保存为草稿)媒体文件 |
wa_schedule_message | 安排稍后发送(遵循草稿设置) |
wa_draft_review | 列出等待人工批准的待处理草稿 |
wa_search_messages | 在已同步消息中进行全文搜索 |
wa_get_thread | 获取一个聊天中的近期消息 |
wa_list_chats | 列出近期有活动的聊天 |
wa_resolve_contact | 将姓名/电话号码解析为 JID |
wa_group_info | 获取群组元数据和参与者 |
wa_wait_for_reply | 阻塞等待符合条件的入站事件 |
wa_transcribe_voice | 转录语音消息 |
wa_status | 查看守护进程连接和会话状态 |
它还会按照 MCP 规范提供资源(只读上下文界面)和提示词(预先构建的工作流)。使用 --toolsets 限定可用界面;发送模式可以是 draft(默认)、direct 或 deny,而 read-only 集合会隐藏所有可变更状态的工具。
有关注册表发布流程和包内部结构,请参阅 docs/mcp-registry.md。
安装
Homebrew(macOS + Linux)
brew install yolo-labz/tap/wa
Nix flake
# One-shot
nix run github:yolo-labz/wa -- profile list
# Install to profile
nix profile install github:yolo-labz/wa
# Dev shell (go + gopls + golangci-lint + goreleaser + sqlite + jq)
nix develop github:yolo-labz/wa
NixOS 模块 — 导入系统模块并启用:
{
inputs.wa.url = "github:yolo-labz/wa";
outputs = { self, nixpkgs, wa, ... }: {
nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
modules = [
wa.nixosModules.default
{ services.wa.enable = true; services.wa.profile = "default"; }
];
};
};
}
home-manager 模块 — 导入以进行单用户安装:
{
imports = [ wa.homeManagerModules.default ];
services.wa = {
enable = true;
profile = "default";
autoStart = true;
};
}
GoReleaser 压缩包 + 供应链验证
VERSION=v2.0.5 # pin to a known tag
ARCH=linux_amd64 # or darwin_arm64 / linux_arm64
BASE="https://github.com/yolo-labz/wa/releases/download/$VERSION"
# 1. Download the tarball + checksums
curl -LO "$BASE/wa_${VERSION#v}_${ARCH}.tar.gz"
curl -LO "$BASE/checksums.txt"
# 2. Verify the SHA256 (defends against accidental corruption)
sha256sum -c checksums.txt --ignore-missing
# 3. Verify the SLSA-L2 attestation against THIS tarball (not just the
# manifest) via GitHub's native attestation store. From v2.0.5 onward
# every artifact (.tar.gz / .deb / .rpm / .apk) is registered as its
# own attestation subject — earlier releases (≤ v2.0.4) only attested
# `checksums.txt` and would 404 on per-artifact verify. Requires
# `gh` CLI ≥ 2.50 (Sigstore bundle v0.3.1 support). The verify step
# transparently checks Rekor v2 transparency-log inclusion proof on
# the Sigstore bundle — no separate `rekor-cli` invocation needed.
gh attestation verify "wa_${VERSION#v}_${ARCH}.tar.gz" --repo yolo-labz/wa
# 4. Install
tar xzf "wa_${VERSION#v}_${ARCH}.tar.gz"
install -m 0755 wa wad ~/.local/bin/
gh attestation verify 步骤可证明,这个压缩包确实由 yolo-labz/wa GoReleaser 作业基于标签指向的确切提交 SHA 生成。每个版本都会发布:
wa_<version>_<os>_<arch>.tar.gz— 平台压缩包checksums.txt— 所有构件的 SHA256checksums.txt.sigstore.json— 为checksums.txt提供的 Cosign 签名 Sigstore 捆绑包(旧版/可选验证方式;使用gh attestation verify验证上述构件时不需要)sbom.cdx.json— CycloneDX 1.6 SBOM(完整仓库,syft)sbom.spdx.json— SPDX 2.3 SBOM(完整仓库,syft)sbom.gomod.{wa,wad}.cdx.json— Go 原生 CycloneDX SBOM(cyclonedx-gomod,按二进制文件生成,包含标准库和许可证信息)openvex.json— OpenVEX 0.2 声明文件。支持 VEX 的扫描器(Trivy、Grype)会使用此文件筛选“这个 CVE 是否确实能在wa中被利用?”——大多数传递性 CVE 都是not_affected,因为由depguard强制执行的端口边界会阻止它们进入运行时路径。随着发现问题,声明会不断增加;目前基线为空,等待逐个 CVE 分类。CHANGELOG.md— 由 git-cliff 生成的变更日志
darwin 用户 — 未签名版本:未使用 Apple Developer 账户构建的版本所附带的 darwin-arm64 二进制文件未签名且未经公证。Gatekeeper 会在首次启动时将其隔离。运行前请移除隔离标记:
xattr -cr ~/.local/bin/wa ~/.local/bin/wad或通过 Homebrew tap 安装(
brew install yolo-labz/tap/wa)——brew 会在本地从源代码重新构建,并完全绕过隔离。填入APPLE_DEVELOPER_ID_APPLICATION_{CERT,KEY}密钥后,下一个 GA 标签版本将恢复提供已签名且经过公证的 darwin 二进制文件。
go install
根据 Go 的 v2+ 版本语义导入版本控制规则,模块路径包含 /v2 后缀。
# Pin to a tag (recommended — reproducible builds need a known revision):
go install github.com/yolo-labz/wa/v2/cmd/[email protected]
go install github.com/yolo-labz/wa/v2/cmd/[email protected]
# Or follow main:
go install github.com/yolo-labz/wa/v2/cmd/wa@latest
go install github.com/yolo-labz/wa/v2/cmd/wad@latest
在标签上运行 go install 不会继承 GoReleaser 的构建标志(-trimpath、-buildvcs=true、通过 ldflag 写入的版本)。生成的二进制文件可以运行,但 wa --version 会报告 (devel)。如果你需要带版本标记且可复现的二进制文件,请使用 GoReleaser 压缩包或 Homebrew tap。
多配置文件
并行运行两个 WhatsApp 账户——个人和工作账户,或每个客户端使用一个账户——且进程完全隔离。每个配置文件都有独立的 session.db、allowlist.toml、audit.log、速率限制器、Unix 套接字和预热时间戳。
wa profile create work
wad --profile work &
wa --profile work pair
wa --profile work status
wa profile list
# PROFILE ACTIVE STATUS JID LAST_SEEN
# default * connected [email protected] 2026-04-11T17:00:00Z
# work connected [email protected] 2026-04-11T17:00:00Z
配置文件选择优先级(从高到低):
--profile <name>标志WA_PROFILE环境变量(为空 = 未设置)$XDG_CONFIG_HOME/wa/active-profile指针- 单例(恰好存在一个配置文件时)
- 字面值
default
安全性
wa 足够安全,可以让大模型代你调用。安全流程不可绕过,位于守护进程内部,处于所有 RPC 路径之下:
- 允许列表,默认拒绝。按操作(
read/send/group.add/group.create)设置。收到 SIGHUP 时热重载。通过wa allow add/remove修改。 - 速率限制器。普通发送上限为 2 次/秒(突发上限 2 次)和 30 次/分钟(突发上限 30 次),没有普通发送的每日上限。没有
--force标志。永远不会有。 - 预热递增。新会话在运行时间 <7 天时,按上限的 25 % 运行;运行时间为 7 至 <14 天时,按上限的 50 % 运行;运行时间达到 14 天及以上时,按上限的 100 % 运行。时间戳取自会话存储,因此重启守护进程不会重置计时。
- 审计日志。以仅追加的 JSON Lines 格式写入
$XDG_STATE_HOME/wa/<profile>/audit.log。每次发送、每项允许列表判定和每次迁移都会记录。绝不会自动轮换——请自行备份。 - 入站提示词注入防火墙。入站消息正文会在送达 Claude Code 前包裹在
<channel source="wa" ...>…</channel>标签中,让模型能够从结构上区分“用户在终端中输入的内容”和“未知联系人发送的内容”。 - 崩溃安全迁移。007→008 迁移使用预写标记、单次
os.Rename切换和 fsync 屏障。通过子进程SIGKILL注入测试验证:测试会在每个步骤之间终止进程,并断言恢复时没有任何数据丢失。 - 套接字加固。Unix 套接字及同级锁文件使用
O_NOFOLLOW打开(CVE-2025-68146);验证父目录的权限模式为0700且归 euid 所有;每次接受连接时检查SO_PEERCRED;绑定时收窄 umask。
完整威胁模型:SECURITY.md。
架构
┌──────────────────────────┐
│ cmd/wa │ thin JSON-RPC client
│ (cobra, no business │ (stateless, re-invokable,
│ logic, no state) │ what scripts actually call)
└─────────────┬────────────┘
│ JSON-RPC 2.0 over
│ $XDG_RUNTIME_DIR/wa/<profile>.sock
▼
┌──────────────────────────────────────────────────────────────┐
│ cmd/wad │ composition root
│ │ (one process per profile)
│ ┌─────────────────────────┐ ┌────────────────────────┐ │
│ │ internal/app/dispatcher │◄──►│ Safety pipeline: │ │
│ │ (use cases, port-only) │ │ allowlist + rate lim │ │
│ │ │ │ + warmup + audit │ │
│ └───────────┬─────────────┘ └────────────────────────┘ │
│ │ │
│ ▼ 9 port interfaces │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ internal/adapters/secondary │ │
│ │ whatsmeow | sqlitestore | sqlitehistory | memory │ │
│ │ slogaudit | … │ │
│ └───────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
│
│ Signal Protocol ratchets +
│ WhatsApp Multi-Device websocket
▼
web.whatsapp.com
- 六边形核心(
internal/domain/、internal/app/)仅依赖internal/app/ports.go中的 9 个端口接口。适配器之外没有任何go.mau.fi/whatsmeow导入;这一规则由golangci-lint depguard强制执行,并会阻止 CI 通过。 - 端口边界伪实现:每个次级适配器都附带一个用于测试的内存孪生实现。契约测试套件(
internal/app/porttest/)可针对任何适配器运行。没有测试会访问真实 WebSocket。 - 每个配置文件运行一个守护进程。功能 008 限制了影响范围:一个配置文件的守护进程崩溃绝不会影响其他配置文件。代价:每个配置文件约占用 30 MB RSS。
- 不使用 CGO。永远不使用。
modernc.org/sqlite是唯一的 SQLite 路径。此规则在 Nix flake(env.CGO_ENABLED = "0")、GoReleaser 和go.mod工具链标志中强制执行。
完整设计和可靠性原则请参阅 docs/manual.md。
命令参考(概览)
客户端(wa):
| 命令 | 用途 |
|---|---|
wa pair | 扫描二维码,或使用 --phone 通过手机验证码配对 |
wa status | 非阻塞式连接状态 |
wa send --to <jid> --body <text> | 发送文本消息(应用允许列表和速率限制器) |
wa sendMedia --to <jid> --path <file> | 发送图片/视频/音频/文档(通过 --remote 时,客户端本地文件会自动上传,然后按 sha256 发送) |
wa reply --to <jid> --quoted-id <id> --body <text> | 发送引用回复,使其串在某条消息下方 |
wa markRead --chat <jid> --messageId <id> | 将消息标记为已读 |
wa react --chat <jid> --messageId <id> --emoji 👍 | 添加/移除回应 |
wa msg revoke|edit|forward|star|disappearing | 管理已发送的消息 |
wa poll create --chat <jid> --question <text> --option <text> --option <text> | 发送投票(2-12 个选项;多选请使用 --selectable) |
wa poll vote --chat <jid> --poll-id <id> --option <n> | 参与投票(多选时可重复使用 --option) |
wa presence composing|recording start|stop --chat <jid> | 发送正在输入/录音指示 |
wa groups | 列出已加入的群组 |
wa group create|leave|add|remove|promote|demote|edit|invite | 管理群组(管理员操作) |
wa chat list / wa chat last-active | 列出聊天,按最近活跃时间从近到远排列(只读) |
wa chat archive|pin|mute|mark-unread --chat <jid> | 更改聊天级状态 |
wa history --chat <jid> [--before <id>] | 显示单个聊天的历史记录(分页) |
wa messages list --chat <jid> --media-type audio | 按聊天、媒体类型、方向和时间范围筛选消息 |
wa search --query <fts5> | 对所有消息进行全文搜索(FTS5) |
wa thread get --chat <jid> [--cursor <c>] | 获取按游标分页的消息窗口 |
wa export --chat <jid> [--since <ts>] | 按时间从早到晚将聊天导出为 NDJSON |
wa contacts list / wa contacts search --query <q> | 列出本地联系人目录,或通过三元组搜索联系人 |
wa contact block|unblock|blocklist|lid|pn | 服务端屏蔽列表及 PN↔LID 解析 |
wa privacy get [--key <k>] | 读取当前账号的隐私设置 |
wa privacy set --key <k> --value <v> | 更改一项隐私设置(例如,lastSeen → contacts) |
wa media list --chat <jid> [--sender <jid>] [--caption <text>] [--since/--until <rfc3339>] | 列出媒体及缓存状态(sha256、大小、时长),在获取前缩小范围 |
wa media resolve|download|fetch | 解析/按需获取内容寻址的媒体 |
wa media gc --dry-run | 以 NDJSON 和可回收字节数摘要预览 GC 候选项 |
wa --remote <url> push <file> | 将客户端本地文件上传到远程守护进程的媒体存储;打印其 sha256,供 sendMedia --sha256 复用 |
wa schedule send|list|cancel|update | 安排未来发送(pending → fired|cancelled|failed) |
wa draft list|get|approve|reject | 供人工审核的草稿队列 |
wa labels list|create|delete|assign|unassign | WhatsApp Business 标签(需启用 labels 标志) |
wa session logout-all | 取消账号与所有设备的关联 |
wa allow add <jid> --actions send,read | 授予操作权限 |
wa allow remove <jid> | 撤销所有操作权限 |
wa allow list | 输出允许列表 |
wa wait --events message --timeout 30s | 阻塞等待事件到达 |
wa subscribe --events <types> [--since <seq>] | 将筛选后的事件流式输出为 NDJSON(可通过游标恢复) |
wa stream [--chat <jid>] | 实时追踪并以 NDJSON 输出收到的消息(封装 wa subscribe --events message) |
wa sync force [--chat <jid>] [--count N] | 当数据库落后于手机时,强制立即拉取历史记录 |
wa sync status | 显示按需同步引擎状态(正在进行的拉取、队列深度) |
wa embeddings status / wa embeddings purge --yes | 检查/清除向量索引(需启用 embeddings 标志) |
wa health | 非阻塞式存活探测(已配对/已连接/上次事件) |
wa doctor | 对本地安装运行 11 项自诊断检查 |
wa debug pprof [cpu|heap|goroutine|block|mutex] | 从 wad 捕获运行时性能分析数据 |
wa audit verify [--path <log>] [--key <keyfile>] | 验证审计日志的 HMAC 链 |
wa config features | 显示解析后的功能标志(embeddings、scheduled_sends、labels) |
wa profile list/use/create/rm/show | 多配置文件生命周期管理 |
wa migrate [--dry-run|--rollback] | 显式执行 007→008 迁移 |
wa panic | 取消设备关联并清除本地会话 |
wa version | 版本、提交、构建日期 |
wa upgrade | 输出适用于当前安装方式的升级命令 |
wa completion bash|zsh|fish|powershell | Shell 补全脚本 |
守护进程(wad): |
| 命令 | 用途 |
|---|---|
wad [--profile <name>] [--log-level <lvl>] | 在前台运行守护进程 |
wad install-service --profile <name> | 为指定配置文件安装 systemd/launchd 单元 |
wad uninstall-service --profile <name> | 仅移除指定配置文件的单元 |
wad migrate [--dry-run|--rollback] | wa migrate 的内部目标 |
完整标志参考:docs/manual.md §6。
检查守护进程(当 CLI“说谎”时)
守护进程掌握 SQLite 中的真实数据;CLI 只是它的轻量客户端。如果某条命令的输出看起来不对——比如你预期的聊天记录缺失,或消息数量似乎过时——请按以下步骤逐一排查。第一步就能解决几乎所有问题,无需触碰数据库。
1. 首选发现命令(受支持的方式)
这些命令直接从守护进程读取数据,无需 SQL。它们取代了旧的 docker cp messages.db + 手动编写 SELECT 查询的变通方法:
| 问题 | 命令 |
|---|---|
| 有哪些聊天,按最近时间优先排列? | wa chat list(或 wa chat last-active) |
| 某个聊天中有哪些内容,经过筛选后? | wa messages list --chat <jid> --media-type audio --since 2026-01-01T00:00:00Z |
| 联系人目录中有哪些人? | wa contacts list / wa contacts search --query <name> |
| 磁盘上缓存了哪些媒体? | wa media list --chat <jid>(SIZE / CACHED / SHA256 列) |
| 哪些附件才是我真正需要的? | wa media list --chat <jid> --sender <jid> --caption <text> — 先缩小范围;按时间戳接近程度批量获取会下载其他人的私人文件 |
| 垃圾回收会回收哪些内容? | wa media gc --dry-run(NDJSON 候选项 + stderr 上的可回收字节数) |
| 手机上有但这里缺失的消息? | wa sync force(全局)或 wa sync force --chat <jid>(阻塞,直到该聊天的拉取完成),然后重新运行查询 |
| 当前是否有同步正在进行? | wa sync status(syncing、正在进行的强制拉取、工作线程队列深度) |
| 实时查看新消息到达? | wa stream(或 wa stream --chat <jid>) |
为任意命令添加 --json,即可获得可通过管道传给 jq 的 NDJSON。在 Dokku 部署中,可在容器内运行相同命令——
dokku enter <app> -- /usr/local/bin/wa chat list——或通过 SSH 转发的套接字运行 scripts/wa-remote chat list。
2. wa doctor
如果发现命令本身看起来不可能成功(例如,已配对的账户中聊天数为零),请运行 wa doctor。它会执行 11 项检查——套接字权限、配对状态、磁盘布局版本、审计日志大小——并为每个 WARN/FAIL 打印一行 hint:。schema_version 警告表示磁盘布局与 domain.LayoutSchemaVersion 不一致;运行 wa migrate 以升级迁移。
3. 原始 SQLite(最后手段)
生产镜像为 gcr.io/distroless/static-debian12:nonroot——没有 shell、sqlite3,也没有 ls/find。因此你无法运行 dokku enter <app> -- sqlite3 …,并且我们有意不提供 wa-debug sidecar 镜像(它会扩大 distroless 基础镜像旨在缩小的攻击面)。请改为从 Dokku 主机查询 WAL 安全快照,该主机自带 sqlite3:
# messages.db lives under XDG_DATA_HOME → on the host storage mount:
DB=/var/lib/dokku/data/storage/<app>/data/wa/<profile>/messages.db # <profile> defaults to "default"
# Snapshot via the online-backup API (WAL-safe; never `cp` a live WAL DB):
ssh dokku.example.com sudo -u dokku-65532 \
sqlite3 "$DB" ".backup '/tmp/messages-snapshot.db'"
# Inspect the snapshot, not the live file:
ssh dokku.example.com sqlite3 /tmp/messages-snapshot.db \
"SELECT chat_jid, push_name, COUNT(*) AS msgs, MAX(ts) AS last
FROM messages
WHERE chat_jid LIKE '%@s.whatsapp.net'
GROUP BY chat_jid ORDER BY last DESC LIMIT 20;"
磁盘布局(容器路径 → /var/lib/dokku/data/storage/<app> 下的 Dokku 主机路径):
| 文件 | 容器路径 | 用途 |
|---|---|---|
messages.db | /data/data/wa/<profile>/messages.db | 历史记录 + FTS5 |
session.db | /data/data/wa/<profile>/session.db | Signal 会话(切勿复制正在使用的文件) |
contacts.db | /data/data/wa/<profile>/contacts.db | 联系人镜像 |
| 媒体 blob | /data/cache/wa/media/sha256/ | 内容寻址缓存 |
.schema-version | /data/config/wa/.schema-version | 磁盘布局版本 |
使用 cp 复制实时运行的 WAL 模式数据库可能会生成损坏的文件——请始终通过 .backup 操作。参见docs/deploy/dokku.md中的“备份”部分。
开发
# Clone
git clone [email protected]:yolo-labz/wa.git
cd wa
# Devshell (Nix users)
nix develop
# Or use your own Go toolchain (1.26+, matching go.mod)
go version
# Build
go build ./cmd/wa ./cmd/wad
# Test (race detector on by default; ~20s wall clock)
go test -race ./...
# Lint
golangci-lint run
# Format
gofumpt -w .
# Nix build + smoke test
nix build .#default && ./result/bin/wa version
# Snapshot release (local only, no publish)
goreleaser release --snapshot --clean --skip=publish
工作流:所有更改都通过 PR 合入 main,提交主题遵循 Conventional Commits。详见 CONTRIBUTING.md。
CI/CD 在自托管的 GitHub Actions 运行器池上运行(标签集 [self-hosted, dokku],其中一个运行器 — wa-sonar-runner — 另加 sonar 标签)。必需的检查任务:detect、lint(golangci-lint)、test(竞态 + 随机顺序 + 覆盖率)、sonar(SonarQube 扫描,使用 cover.out 构建产物)、nix(nix flake check + nix build .#default + 冒烟测试)、commitlint(PR 标题)、Reproducibility(两次构建的字节级一致性)、OSV-Scanner(漏洞数据库 + 通过内部 govulncheck 进行 Go 调用图可达性分析)、gitleaks(密钥扫描)、CodeQL(Go + actions)。托管运行器专供 OpenSSF Scorecard 使用(需要保证使用全新镜像)。发布工作流在 v* 标签触发,并将 GoReleaser 压缩包 + 双份 SBOM(CycloneDX 1.6 + SPDX 2.3 + 每个二进制文件各自的 Go 原生 SBOM)+ Cosign Sigstore bundles + GitHub 原生证明发布到 GitHub Releases。若未提供相应密钥,Apple 公证和 Homebrew tap 发布会优雅降级。
项目状态
| 版本 | 亮点 |
|---|---|
| v2.0.2 | 紧急修复 system.hello 握手回归问题(issue #41),确保所有 CLI 命令都能与 v2 守护进程正常配合。 |
| v2.0.1 | 发布流水线紧急修复:cyclonedx-gomod 路径、syft CycloneDX 1.6 上限、关闭 gomod 代理、Apple GA 门控在 rc7 后的修订。存在问题:CLI 握手 — 已由 v2.0.2 取代。 |
| v2.0.0 | 一致性强化 — 新增 7 个端口 + 20 个 P0 方法 + 幂等性 + 聊天状态 + 阻止功能 + 隐私 + 个人资料编辑器 + 群组管理 + 投票管理器。OTel 运行时指标、模糊测试、诊断。JSON-RPC 的 protoVersion: 2 已冻结。 |
| v1.2.x | Agent 体验三级发布 — 嵌入向量 sidecar、定时草稿、基于 FTS5 trigram 的联系人搜索、可观测性环形缓冲区。 |
| v1.0.x – v1.1.x | 首批生产版本 — 供应链证明、OSV-Scanner V2、OpenSSF Scorecard、Cosign 签名、双份 SBOM。 |
| v0.x | 1.0 之前 — 多个人资料、崩溃安全迁移、强化版 systemd + launchd,所有经过基准测试的 SC 均通过,性能余量为 7.6×–870×。 |
待办事项(推迟至固定某个个人资料或存在外部操作时再处理):homebrew_casks: 迁移(取代 brews:,但 Linuxbrew 在仅适用于 darwin 的 cask 上会丢失 formula 路径 — 需先通过 nFPM 提供 apt/rpm 作为 Linux 替代方案)、在 domain.JID 中使用 LID/BSUID 双键(Meta 将于 2026 年 6 月推出用户名)、default.pgo PGO 配置文件(采集流水线 + 提交)、从 attest-build-provenance@v4 封装器迁移 actions/attest。
适用对象
仅面向一个人 — 维护者。多租户、托管 SaaS 和群组批量消息等使用场景明确不在范围内。整个安全设计基于单用户威胁模型,其中 FileVault / LUKS 是加密边界,wa panic 是恢复按钮。如果这不符合你的需求,请使用《本项目不是什么》中列出的替代方案。
许可证
Apache-2.0。上游项目 go.mau.fi/whatsmeow 使用 MPL-2.0,该许可证是文件级 copyleft,不会传递给使用者(Mozilla MPL FAQ Q9–Q11)。选择 Apache 是沿用 Anthropic 官方 Telegram 频道插件的先例,并明确授予专利许可。
致谢
tulir/whatsmeow— 感谢 Tulir Asokan 和 mautrix 项目,提供了 2026 年唯一值得使用的 WhatsApp 库。AsamK/signal-cli— 证明了端到端加密通信应用可以通过单个二进制文件实现守护进程加精简 CLI 的架构。aldinokemal/go-whatsapp-web-multidevice— 最接近的先例,但解决的是不同的问题(REST 网关,而非 CLI 守护进程)。spf13/cobra+creachadair/jrpc2+modernc.org/sqlite— 这三个关键的 Go 库让本项目无需 CGO、易于测试且易于维护。rogpeppe/go-internal— 感谢提供lockedfile和testscript,项目大量依赖这两者。
另请参阅(yolo-labz 生态系统)
- yolo-labz/claude-mac-chrome — 用于跨应用工作流的 Chrome 自动化(例如,通过此守护进程将 LinkedIn 私信 → 分类处理 → WhatsApp 跟进)。
- yolo-labz/linkedin-chrome-copilot — LinkedIn 工作流插件,可与
wa组合使用,实现跨渠道自动化。 - yolo-labz/kokoro-speakd — TTS 守护进程,可在长时间运行的批量发送过程中提供语音状态反馈。
- 架构深入解析和 WhatsApp 守护进程设计原理:blog.home301server.com.br。
- 作者作品集:portfolio.home301server.com.br。
服务
面向受监管工作负载的合规级 AI 架构——异步优先、以美元计价、立足拉美/精通英语。请参阅 blog.home301server.com.br/services。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。