README.md
Pixel WeChat Auto-Reply — Plugin for Hermes
在 Pixel 手机本地实现微信全自动闭环,通过 hermes API 生成回复,息屏时通过通知监听兜底。
运行环境:Pixel 10 Fold / Android 15 / WeChat 8.0.72
架构(双轨制)
主流程:Node.js Plugin(推荐)
sqlcipher 直接查询 EnMicroMsg.db
│
▼
┌─────────────────────────────────┐
│ AndroidWechatTrackerSQLCipher │────→ 轮询 message 表 (msgId > last)
│ (Node.js EventEmitter) │ PRAGMA key="e03ce81"
└─────────────────────────────────┘
│
▼
┌─────────────────────────┐
│ auto-reply.js │
│ handleMessage() │
│ - 判断单聊/群聊@/引用 │
│ - 检查 cooldown │
│ - 息屏唤醒微信 │
└─────────────────────────┘
│
▼
┌─────────────────────────┐ ┌─────────────────────────┐
│ callHermesApi() │────→│ POST 127.0.0.1:8642 │
│ buildHermesMessages() │ │ /v1/chat/completions │
│ OpenAI messages 格式 │ │ (OpenAI-compatible) │
└─────────────────────────┘ └─────────────────────────┘
│ │
│ ▼
│ ┌─────────────────────────┐
│ │ hermes-agent │
│ │ (lemonPCRM wrapper) │
│ └─────────────────────────┘
│ │
▼ ▼
┌─────────────────────────┐ ┌─────────────────────────┐
│ JSON 提取 content │────→│ 回复文本 │
└─────────────────────────┘ └─────────────────────────┘
│
▼
┌─────────────────────────┐ ┌─────────────────────────┐
│ 微信在前台? │ No →│ wakeWechat() 点亮+解锁 │
└─────────────────────────┘ │ + am start 启动微信 │
│Yes └─────────────────────────┘
▼
┌─────────────────────────┐
│ sendTextMessageFrida │────→ 写入 /data/local/tmp/frida_daemon/queue.jsonl
│ (android-wechat-sender-frida) │
└─────────────────────────┘
│
▼
┌─────────────────────────┐
│ Frida Daemon (注入微信) │────→ Java.perform → 调用微信内部发送 API
└─────────────────────────┘
优势:
- 不依赖 LSPosed hook(WeChat 8.0.72 上 Xposed hook 不稳定)
- sqlcipher 直接查询,数据完整(含群聊名称、发送者等)
- Frida 发送比 am broadcast 更可靠(绕过 Android 10+ 后台限制)
- 通过 hermes-agent API 享受完整的 Agent 编排、工具调用、记忆能力
备用流程:Python Daemon
hermes_wechat_daemon.py 作为备用通道,当 Node.js plugin 不可用时运行:
- DB 轮询检测
- 优先调用 hermes API,fallback 到直接 LLM API
- 同样支持通知监听兜底
息屏兜底:通知监听 + Termux 保活
息屏后微信/Termux 被冻结
│
▼
微信消息到来 → 系统通知栏产生通知
│
▼
┌─────────────────────────┐
│ termux-notification-list │────→ 每 3 秒轮询(独立线程)
│ (Node.js plugin 内) │
└─────────────────────────┘
│
▼
检测到微信通知
│
▼
isWechatForeground()? No → wakeWechat() → sleep 3s
│
▼
微信唤醒 → LSPosed 恢复写日志 → tail -f 捕获 → 正常处理
保活措施:
termux-wake-lock— 防止息屏后 CPU 被冻结- 关闭电池优化(Termux / Termux:API / 微信)
keepalive.sh进程守护 — hermes / auto-reply 死了自动重启
文件清单
| 文件 | 用途 | 环境 |
|---|---|---|
../../server/services/wechat/auto-reply.js |
主 plugin:tracker → hermes-agent API → sender | proot Ubuntu |
../../server/services/wechat/android-wechat-tracker-sqlcipher.js |
主推 消息跟踪(sqlcipher 轮询 DB) | proot Ubuntu |
../../server/services/wechat/android-wechat-sender-frida.js |
主推 消息发送(Frida daemon 队列) | proot Ubuntu |
../../server/services/wechat/android-wechat-tracker.js |
备用消息跟踪(tail -f LSPosed 日志) | proot Ubuntu |
../../server/services/wechat/android-wechat-sender.js |
备用消息发送(am broadcast / content insert) | proot Ubuntu |
hermes_wechat_daemon.py |
备用 daemon:DB 轮询 → hermes/LLM API → sender | Termux / proot |
config.json |
运行时配置 | Termux / proot |
keepalive.sh |
保活脚本:wake-lock + 进程守护 | Termux |
test_env.py |
环境预检 | Termux / proot |
test_send_msg.py |
发送消息测试 | Termux / proot |
run_all_tests.sh |
一键运行全部测试 | Termux / proot |
快速开始
1. 前置设置(必须手动)
Android 设置中关闭电池优化:
- 设置 → 应用 → Termux → 电池优化 → 不优化
- 设置 → 应用 → Termux:API → 电池优化 → 不优化
- 设置 → 应用 → 微信 → 电池优化 → 不优化
- 设置 → 应用 → Termux → 允许自启动 / 后台运行
Termux:API 权限:
- 安装 Termux:API 应用
- 设置 → 应用 → Termux:API → 通知访问权限 → 允许
2. 部署
# Mac 上推送
adb push server/services/wechat /data/data/com.termux/files/home/hermes-wechat
adb push wechat_plain/scripts/local-testkit /data/data/com.termux/files/home/local-testkit
# Pixel 上
cp -r /sdcard/hermes/local-testkit ~/local-testkit
cd ~/local-testkit
3. 启动 hermes-agent(如果还没运行)
hermes-agent 是 lemonPCRM 的 OpenAI-compatible wrapper,默认监听 127.0.0.1:8642:
proot-distro login ubuntu --user ubuntu -- bash -c \
"cd /data/data/com.termux/files/home/hermes-wechat && . .env && node server/index.js"
或后台运行:
nohup proot-distro login ubuntu --user ubuntu -- bash -c \
"cd /data/data/com.termux/files/home/hermes-wechat && . .env && node server/index.js" \
> hermes-server.log 2>&1 &
确认 agent 就绪:
curl http://127.0.0.1:8642/v1/chat/completions -X POST \
-H "Content-Type: application/json" \
-d '{"model":"hermes-agent","messages":[{"role":"user","content":"hi"}]}'
4. 启动 Frida Daemon(发送端依赖)
# 确保 frida-server 在运行
su -c "/data/local/tmp/frida-server &"
# 注入 daemon 到微信进程(从 Mac 端执行)
frida -U -n com.tencent.mm -l frida_daemon.js
5. 启动 auto-reply plugin(推荐主流程)
cd ~/hermes-wechat/server/services/wechat
export MY_WXID=wxid_xxxxxx
export MY_NICKNAME=你的昵称
export HERMES_HOST=127.0.0.1
export HERMES_PORT=8642
nohup node auto-reply.js > auto-reply.log 2>&1 &
6. 启动保活脚本(推荐)
cd ~/local-testkit
export MY_WXID=wxid_xxxxxx
export MY_NICKNAME=你的昵称
export HERMES_DIR=/data/data/com.termux/files/home/hermes-wechat
chmod +x keepalive.sh
nohup ./keepalive.sh > keepalive.log 2>&1 &
7. 备用:启动 Python daemon
cd ~/local-testkit
python3 hermes_wechat_daemon.py --daemon
配置说明
auto-reply.js 环境变量
| 变量 | 默认值 | 说明 |
|---|---|---|
MY_WXID |
— | 你的微信 wxid(必填) |
MY_NICKNAME |
— | 你的微信昵称(必填,用于判断群聊@) |
HERMES_HOST |
127.0.0.1 |
hermes-agent API 地址 |
HERMES_PORT |
8642 |
hermes-agent API 端口(OpenAI-compatible) |
NOTIFICATION_ENABLED |
true |
是否启用通知监听兜底(息屏唤醒) |
Python daemon config.json
{
"hermes": {
"host": "localhost",
"port": 3010,
"timeout_sec": 120,
"default_session_prefix": "wx-",
"system_hint": "你是一个微信智能助手...",
"api_url": "",
"api_key": "",
"provider": "anthropic",
"model": ""
}
}
host/port:本地 hermes API 地址api_url/api_key/provider/model:hermes 不可用时 fallback 到直接 LLM API 的配置
故障排查
| 问题 | 排查步骤 |
|---|---|
| auto-reply 收不到消息 | 检查 sqlcipher 能否查询:su -c "sqlcipher /data/.../EnMicroMsg.db 'PRAGMA key=\\\"e03ce81\\\"; SELECT COUNT(*) FROM message;'" |
| hermes-agent API 返回空 | 检查 hermes-agent 是否运行:curl http://127.0.0.1:8642/v1/chat/completions ... |
| 息屏后完全失效 | 确认电池优化已关闭;检查 keepalive.sh 是否运行;检查通知权限 |
| 发送失败(Frida) | 确认 frida-server 运行中;确认 frida_daemon.js 已注入微信进程;检查队列文件 /data/local/tmp/frida_daemon/queue.jsonl |
| 发送失败(broadcast 备用) | 检查微信是否在前台;检查 LSPosed 模块是否启用 |
| Python daemon 查询不到新消息 | 检查微信是否在前台;检查 sqlcipher_key;确认 WAL 已复制 |
Claude CLI 报错 root/sudo privileges |
hermes 必须以 proot 内 ubuntu 用户 运行,不能是 root |
目录结构
local-testkit/
├── hermes_wechat_daemon.py # 备用守护进程(DB 轮询)
├── config.json # 运行时配置
├── keepalive.sh # 保活脚本
├── test_env.py # 环境预检
├── test_send_msg.py # 发送消息测试
├── run_all_tests.sh # 一键测试
└── docs/
├── README.md # 本文档
├── HERMES_WECHAT_ARCHITECTURE.md
├── REVERSE_ENGINEERING_LOG.md
├── NOTIFICATION_STRATEGY.md
└── plan.md
server/services/wechat/ # 主 plugin(Node.js)
├── auto-reply.js # 主入口:tracker → hermes-agent → sender
├── android-wechat-tracker-sqlcipher.js # **主推** 消息跟踪(sqlcipher 轮询 DB)
├── android-wechat-sender-frida.js # **主推** 消息发送(Frida daemon 队列)
├── android-wechat-tracker.js # 备用消息跟踪(tail -f LSPosed 日志)
├── android-wechat-sender.js # 备用消息发送(am broadcast / content insert)
├── index.js # 统一入口
└── README.md # plugin 文档