README.md
10.3 KB
Pixel WeChat Auto-Reply — Plugin for Hermes
在 Pixel 手机本地实现微信全自动闭环,通过 hermes API 生成回复,息屏时通过通知监听兜底。
运行环境:Pixel 10 Fold / Android 15 / WeChat 8.0.72
架构(双轨制)
主流程:Node.js Plugin(推荐)
LSPosed 模块 hook WCDB insert
│
▼
┌─────────────────────────┐
│ XposedBridge.log() │────→ /data/adb/lspd/log/verbose_*.log
│ writeMsgToFile() │────→ /sdcard/hermes/wechat_msgs.jsonl
└─────────────────────────┘
│
▼
┌─────────────────────────┐ ┌─────────────────────────┐
│ AndroidWechatTracker │────→│ tail -f 日志 │
│ (Node.js EventEmitter) │ │ 实时事件驱动 │
└─────────────────────────┘ └─────────────────────────┘
│
▼
┌─────────────────────────┐
│ auto-reply.js │
│ handleMessage() │
│ - 判断单聊/群聊@/引用 │
│ - 检查 cooldown │
└─────────────────────────┘
│
▼
┌─────────────────────────┐ ┌─────────────────────────┐
│ callHermesApi() │────→│ POST localhost:3010 │
│ buildHermesPrompt() │ │ /api/master/chat │
│ 构造 prompt + session │ │ SSE 流式响应 │
└─────────────────────────┘ └─────────────────────────┘
│ │
│ ▼
│ ┌─────────────────────────┐
│ │ hermes (lemonPCRM) │
│ │ MasterSession │
│ │ → Claude CLI / Agents │
│ └─────────────────────────┘
│ │
▼ ▼
┌─────────────────────────┐ ┌─────────────────────────┐
│ parseSSE() 提取 output │────→│ 回复文本 │
└─────────────────────────┘ └─────────────────────────┘
│
▼
┌─────────────────────────┐ ┌─────────────────────────┐
│ 微信在前台? │ No →│ am start 唤醒微信 │
└─────────────────────────┘ │ 等待 2s │
│Yes └─────────────────────────┘
▼
┌─────────────────────────┐
│ sendTextMessageBroadcast │────→ am broadcast
│ (android-wechat-sender) │ action: com.hermes.wechat.SEND_MSG
└─────────────────────────┘
│
▼
┌─────────────────────────┐
│ LSPosed 模块 │────→ u01.r1.a() → builder → m1.a()
│ HermesWeChatModule │ setIntField f=0, i=4
└─────────────────────────┘
优势:
- 事件驱动(tail -f),比 DB 轮询实时性高
- 不需要 sqlcipher 解密,不需要复制 WAL
- 通过 hermes API 享受完整的 Agent 编排、工具调用、记忆能力
- hermes 不可用时自动 fallback 到直接 LLM API
备用流程: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 API → sender | proot Ubuntu |
../../server/services/wechat/android-wechat-tracker.js |
手机端消息跟踪(tail -f LSPosed 日志) | proot Ubuntu |
../../server/services/wechat/android-wechat-sender.js |
手机端消息发送(am broadcast) | 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 server(如果还没运行)
cd ~/hermes-wechat
node server/index.js
4. 启动 auto-reply plugin(推荐主流程)
cd ~/hermes-wechat/server/services/wechat
export MY_WXID=wxid_xxxxxx
export MY_NICKNAME=你的昵称
export HERMES_HOST=localhost
export HERMES_PORT=3010
nohup node auto-reply.js > auto-reply.log 2>&1 &
5. 启动保活脚本(推荐)
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 &
6. 备用:启动 Python daemon
cd ~/local-testkit
python3 hermes_wechat_daemon.py --daemon
配置说明
auto-reply.js 环境变量
| 变量 | 默认值 | 说明 |
|---|---|---|
MY_WXID |
— | 你的微信 wxid(必填) |
MY_NICKNAME |
— | 你的微信昵称(必填,用于判断群聊@) |
HERMES_HOST |
localhost |
hermes server 地址 |
HERMES_PORT |
3010 |
hermes server 端口 |
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 收不到消息 | 检查 LSPosed 模块日志:`su -c "cat /data/adb/lspd/log/verbose_*.log \ |
| hermes API 返回空 | 检查 hermes server 是否运行:curl http://localhost:3010/api/health |
| 息屏后完全失效 | 确认电池优化已关闭;检查 keepalive.sh 是否运行 |
| 发送失败 | 检查微信是否在前台;检查 LSPosed 模块是否启用 |
| Python daemon 查询不到新消息 | 检查微信是否在前台;检查 sqlcipher_key;确认 WAL 已复制 |
目录结构
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 → sender
├── android-wechat-tracker.js # 消息跟踪
├── android-wechat-sender.js # 消息发送
├── index.js # 统一入口
└── README.md # plugin 文档