mcpField
W
wa — safe WhatsApp automation

wa — safe WhatsApp automation

本地服务
github.com通信协作02 天前更新

关于 wa — safe WhatsApp automation

wa 是个人 WhatsApp 自动化工具,包含常驻守护进程、命令行客户端和 MCP 服务,面向脚本与 AI Agent 使用。发送默认进入人工审核草稿队列,并由守护进程强制执行允许列表、速率限制和追加式审计日志。

主要功能

  1. 01常驻守护进程管理 WhatsApp 会话
  2. 02发送消息与媒体并支持定时发送
  3. 03草稿审核后发送
  4. 04允许列表与强制速率限制
  5. 05搜索消息并查看聊天信息

适用场景

  1. 01通过脚本或 cron 发送消息
  2. 02让 AI Agent 起草待审核消息
  3. 03搜索已同步消息并查看会话
  4. 04分别管理工作和个人配置

MCP 相关

`wa mcp serve` 通过 stdio 向 MCP 客户端提供消息、聊天、联系人等工具,以及资源和提示词。所有调用均经过守护进程中的安全管道;发送默认为草稿,须人工批准后才会发出。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

暂未收录安装方式

我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。

代码仓库
安装包
mcpbwa_2.3.0_darwin_arm64.mcpb
mcpbwa_2.3.0_linux_amd64.mcpb
mcpbwa_2.3.0_linux_arm64.mcpb

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

wa:供 Claude Code 使用的持久化 WhatsApp 守护进程

wa

个人 WhatsApp 自动化命令行工具 + 守护进程,以 Go 编写。

一个采用六边形架构的 Go 守护进程,负责持有 WhatsApp Multi-Device 会话;另有一个轻量 JSON-RPC 客户端与之通信。它足够安全,可以让大模型代你发送消息;足够可靠,即使迁移过程中断电也能恢复;也足够谨慎,会拒绝所有你可能预期会有的破坏性标志。

CI Release Go License Conventional Commits Nix flake OpenSSF Scorecard SLSA L2 Verified by Sigstore

快速入门 · 安装 · 手册 · 架构 · 安全 · 贡献 · 葡萄牙语(巴西)


功能

模式。 通过 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"

演示

wa CLI 演示

每一帧都是真实输出,来自本仓库中的二进制文件,并在私有临时目录中对未配对的临时守护进程录制。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 — 所有构件的 SHA256
  • checksums.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

配置文件选择优先级(从高到低):

  1. --profile <name> 标志
  2. WA_PROFILE 环境变量(为空 = 未设置)
  3. $XDG_CONFIG_HOME/wa/active-profile 指针
  4. 单例(恰好存在一个配置文件时)
  5. 字面值 default

参见 docs/manual.md §4。

安全性

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|unassignWhatsApp 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|powershellShell 补全脚本
守护进程(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.dbSignal 会话(切勿复制正在使用的文件)
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.xAgent 体验三级发布 — 嵌入向量 sidecar、定时草稿、基于 FTS5 trigram 的联系人搜索、可观测性环形缓冲区。
v1.0.x – v1.1.x首批生产版本 — 供应链证明、OSV-Scanner V2、OpenSSF Scorecard、Cosign 签名、双份 SBOM。
v0.x1.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 频道插件的先例,并明确授予专利许可。

致谢

另请参阅(yolo-labz 生态系统)


服务

面向受监管工作负载的合规级 AI 架构——异步优先、以美元计价、立足拉美/精通英语。请参阅 blog.home301server.com.br/services。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。