HERMES_WECHAT_ARCHITECTURE.md 23.9 KB

Hermes WeChat 本地闭环架构方案

版本: 3.0 (Node.js Plugin + SQLCipher + Frida) 日期: 2026-05-23 目标设备: Pixel 10 Fold (Android) 运行环境: Termux + Ubuntu proot-distro 微信版本: 8.0.72


1. 目标

在 Pixel 手机本地实现微信全自动闭环:

收到消息 → 读取内容 → HTTP 调用 hermes-agent → 生成回复 → 发送回复

不依赖 Mac 远程 adb,所有组件运行在 Android 本地。

核心设计原则:

  • auto-reply.js (Node.js plugin) 是常驻后台进程,负责消息检测、AI 调用、回复发送
  • hermes-agent (lemonPCRM wrapper) 是独立的 OpenAI-compatible AI 服务,负责 LLM 推理
  • 两者通过 HTTP API (POST /v1/chat/completions) 通信
  • SQLCipher DB 轮询 替代 LSPosed 日志 tail,更稳定可靠
  • Frida Daemon 替代 am broadcast,绕过 Android 10+ 后台限制

2. 架构总览

┌─────────────────────────────────────────────────────────────────────────────┐
│                           Pixel 手机本地运行环境                               │
│                                                                             │
│  ┌───────────────────────────────────────────────────────────────────────┐  │
│  │                    Ubuntu proot-distro 容器                             │  │
│  │  ┌─────────────────────────────────────────────────────────────────┐  │  │
│  │  │                        hermes-agent (:8642)                        │  │  │
│  │  │  ┌──────────────┐  ┌──────────┐  ┌──────────────────────────┐  │  │  │
│  │  │  │ Node.js      │  │ OpenAI   │  │ Claude CLI / Agents      │  │  │  │
│  │  │  │ Express      │  │ compat   │  │ (wrapped via lemonPCRM)  │  │  │  │
│  │  │  └──────────────┘  └──────────┘  └──────────────────────────┘  │  │  │
│  │  │         ↑                                                        │  │  │
│  │  │         │ POST /v1/chat/completions                               │  │  │
│  │  │         │ {model, messages, stream}                               │  │  │
│  │  └─────────┼────────────────────────────────────────────────────────┘  │  │
│  │            │                                                             │  │
│  │  ┌─────────┴─────────────────────────────────────────────────────────┐  │  │
│  │  │                    auto-reply.js (Node.js)                          │  │  │
│  │  │  ┌──────────────┐  ┌──────────┐  ┌──────────┐  ┌──────────────┐  │  │  │
│  │  │  │ SQLCipher    │→ │ 新消息   │→ │ HTTP     │→ │ Frida Queue  │  │  │  │
│  │  │  │ DB 轮询      │  │ 检测     │  │ hermes-  │  │ /tmp/frida_  │  │  │  │
│  │  │  │              │  │          │  │ agent    │  │ daemon/      │  │  │  │
│  │  │  └──────────────┘  └──────────┘  └──────────┘  └──────────────┘  │  │  │
│  │  │         ↑                                              │          │  │  │
│  │  │         │                                              │          │  │  │
│  │  │  ┌──────────────┐                          ┌──────────┴─────┐    │  │  │
│  │  │  │ sqlcipher    │                          │ Frida Daemon   │    │  │  │
│  │  │  │ 直接查询     │                          │ (注入微信进程) │    │  │  │
│  │  │  └──────────────┘                          └────────────────┘    │  │  │
│  │  └──────────────────────────────────────────────────────────────────┘  │  │
│  │         ↑                                                              │  │
│  │         │                                                              │  │
│  │  ┌──────────────┐                                          ┌──────────┴──┐│
│  │  │ EnMicroMsg.db│                                          │ com.tencent ││
│  │  │ (SQLCipher)  │                                          │ .mm 主进程  ││
│  │  └──────────────┘                                          └─────────────┘│
│  └───────────────────────────────────────────────────────────────────────────┘  │
│         ↑                                                              │        │
│         │                                                              ▼        │
│  ┌───────────────────────────────────────────────────────────────────────┐      │
│  │                    Termux 环境 (与 proot 共享 home)                      │      │
│  │  ┌─────────────────────────────────────────────────────────────────┐  │      │
│  │  │ 通知监听线程(息屏兜底)                                          │  │      │
│  │  │  termux-notification-list 每 3 秒轮询                            │  │      │
│  │  │  发现微信通知 → 点亮屏幕 → 解锁 → 启动微信 → tracker 恢复工作   │  │      │
│  │  └─────────────────────────────────────────────────────────────────┘  │      │
│  │  ┌─────────────────────────────────────────────────────────────────┐  │      │
│  │  │ Termux:Boot 开机自启                                            │  │      │
│  │  │  ~/.termux/boot/start-hermes.sh                                 │  │      │
│  │  └─────────────────────────────────────────────────────────────────┘  │      │
│  │  ┌─────────────────────────────────────────────────────────────────┐  │      │
│  │  │ Frida Server (可选,用于注入 daemon)                             │  │      │
│  │  │  /data/local/tmp/frida-server                                   │  │      │
│  │  └─────────────────────────────────────────────────────────────────┘  │      │
│  └───────────────────────────────────────────────────────────────────────┘      │
│         ↑                                                              │        │
│         │                                                              ▼        │
│  ┌───────────────────────────────────────────────────────────────────────┐      │
│  │                         Android 系统层                                  │      │
│  │  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐                │      │
│  │  │ 微信 APK     │  │ SQLCipher DB │  │ 通知栏       │                │      │
│  │  │ (已 root)    │  │ EnMicroMsg   │  │ (微信通知)   │                │      │
│  │  └──────────────┘  └──────────────┘  └──────────────┘                │      │
│  └───────────────────────────────────────────────────────────────────────┘      │
└─────────────────────────────────────────────────────────────────────────────────┘

3. 数据流详解

3.1 完整消息处理流程

1. 息屏状态:通知监听线程发现微信通知
   │
   ▼
2. 点亮屏幕 → 解除锁屏 → 启动微信到前台(约 3-5 秒)
   │
   ▼
3. auto-reply.js 的 SQLCipher tracker 轮询 EnMicroMsg.db
   │
   ▼
4. 查询 message 表:SELECT ... WHERE msgId > last_msg_id AND isSend = 0
   │
   ▼
5. 提取消息内容(单聊 / 群聊@ / 群聊引用)
   │
   ▼
6. 构造 OpenAI messages 数组,HTTP POST 到 hermes-agent /v1/chat/completions
   │   {
   │     "model": "hermes-agent",
   │     "messages": [{"role": "system", ...}, {"role": "user", ...}],
   │     "stream": false
   │   }
   │
   ▼
7. hermes-agent (lemonPCRM) 调用 Claude CLI 处理消息,返回 JSON
   │   {"choices": [{"message": {"content": "回复内容"}}]}
   │
   ▼
8. auto-reply.js 提取 content 作为回复文本
   │
   ▼
9. 写入 /data/local/tmp/frida_daemon/queue.jsonl
   │
   ▼
10. Frida Daemon(注入微信进程)读取队列,调用微信内部 API 发送消息

3.2 Session 管理

每个微信联系人 (talker) 对应一个独立的 hermes-agent session:

talker sessionId(X-Hermes-Session-Id) 作用
filehelper wx-filehelper 文件传输助手
wxid_abc123 wx-wxid_abc123 个人联系人
123456789@chatroom wx-123456789@chatroom 群聊

好处:

  • hermes-agent 自动维护每个对话的上下文记忆
  • 不同联系人的对话互不干扰

4. 消息监听双通道

4.1 通道 A: SQLCipher DB 轮询(主推)

原理: sqlcipher CLI 直接查询微信加密 DB 的 message 表,检测 msgId 变化。

流程:

// AndroidWechatTrackerSQLCipher
await tracker.init();        // SELECT MAX(msgId) 初始化 lastMsgId
tracker.startPolling(3000);  // 每 3 秒轮询

// 每次轮询执行:
SELECT msgId, type, isSend, talker, content, createTime
FROM message
WHERE msgId > ${lastMsgId} AND isSend = 0 AND type IN (1, 10002)
ORDER BY msgId ASC

关键参数: | 参数 | 值 | 说明 | |------|-----|------| | SQLCipher key | e03ce81 | 7 字符字符串密码 | | cipher_compatibility | 1 | WCDB 兼容模式 | | cipher_page_size | 1024 | 页大小 | | 轮询间隔 | 3000ms | 可配置 | | 查询条件 | isSend = 0 | 只查收到的消息 | | 消息类型 | type IN (1, 10002) | 文本消息 + 撤回通知 |

优势:

  • 不依赖 LSPosed hook(WeChat 8.0.72 上 Xposed 不稳定)
  • 数据完整(含群聊名称、发送者等)
  • 不需要复制 WAL 文件

4.2 通道 B: 通知监听(息屏兜底)

原理: 通过 Termux:API 的 termux-notification-list 读取系统通知栏,发现微信通知后执行屏幕唤醒流程。

唤醒流程:

检测到微信通知
    │
    ▼
屏幕关闭? → input keyevent 224 (KEYCODE_WAKEUP)
    │
    ▼
锁屏状态? → wm dismiss-keyguard (无密码设备)
    │
    ▼
微信不在前台? → am start -n com.tencent.mm/.ui.LauncherUI
    │
    ▼
轮询确认 screen on + unlocked + WeChat foreground(最多 20 秒)
    │
    ▼
tracker 恢复 DB 轮询,捕获新消息

权限要求:

  1. 安装 Termux:API 应用
  2. 设置 → 应用 → Termux:API → 通知访问权限 → 允许
  3. 关闭 Termux 和 Termux:API 的电池优化

4.3 双通道协同

正常状态: SQLCipher tracker 每 3 秒轮询 DB

息屏后微信被冻结:
  微信消息到来 → 系统通知栏产生通知
                        │
                        ▼
              termux-notification-list 在 3 秒内发现
                        │
                        ▼
              执行 wakeWechat() 唤醒流程(约 3-5 秒)
                        │
                        ▼
              微信前台运行 → SQLCipher tracker 恢复轮询
                        │
                        ▼
              获取完整消息内容 → HTTP POST hermes-agent → 发送回复

5. Hermes-Agent HTTP API 调用

5.1 API 端点

端点 方法 说明
POST /v1/chat/completions HTTP OpenAI-compatible,发送消息,返回 JSON
GET /api/health HTTP 健康检查

5.2 请求格式

POST /v1/chat/completions
Content-Type: application/json
X-Hermes-Session-Id: wx-filehelper

{
  "model": "hermes-agent",
  "messages": [
    {"role": "system", "content": "你是 lemonAI 助手..."},
    {"role": "user", "content": "收到微信私聊消息(来自 filehelper):你好\n请给出自然、简短、得体的中文回复。只输出回复内容,不要加任何解释。"}
  ],
  "stream": false
}

5.3 响应格式

{
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": "你好!很高兴收到你的消息。"
      }
    }
  ]
}

auto-reply.js 提取 choices[0].message.content 作为最终回复。


6. 消息发送

6.1 发送机制(Frida Daemon — 主推)

Frida Daemon 注入微信主进程,通过 Java.perform 调用微信内部 API:

auto-reply.js
    │
    ├── 写入队列文件 /data/local/tmp/frida_daemon/queue.jsonl
    │   {"talker": "filehelper", "content": "回复内容", "id": "msg_xxx"}
    │
    ▼
Frida Daemon(注入微信进程)
    │
    ├── 读取 queue.jsonl
    │
    ▼
Java.perform → 调用微信内部发送 API
    │
    ▼
微信服务器

前置条件:

  1. frida-server 运行中
  2. frida_daemon.js 已注入微信进程

6.2 发送机制(LSPosed Broadcast — 备用)

当 Frida Daemon 不可用时,回退到 am broadcast:

/system/bin/am broadcast \
  -a com.hermes.wechat.SEND_MSG \
  --es toUser "filehelper" \
  --es content "回复内容"

6.3 发送限制

限制 说明
仅文本消息 当前只支持文本
Frida 依赖 需要 frida-server + 注入的 daemon
微信主进程 发送必须在微信主进程存活时

7. 开机自启(Termux:Boot)

7.1 启动脚本

文件: ~/.termux/boot/start-hermes.sh

#!/bin/bash

# 启动 frida-server
if [ -f "/data/local/tmp/frida-server" ]; then
    su -c "/data/local/tmp/frida-server &"
fi

# 启动微信(如果未运行)
if ! su -c "pgrep -x com.tencent.mm" > /dev/null 2>&1; then
    su -c "am start -n com.tencent.mm/.ui.LauncherUI"
    sleep 5
fi

# 启动 hermes-agent (lemonPCRM) — 在 proot 内
export PATH=/data/data/com.termux/files/usr/bin:$PATH
proot-distro login --shared-home ubuntu --user ubuntu -- bash -c \
    "cd /data/data/com.termux/files/home/hermes-wechat && . .env && node server/index.js &"

sleep 5

# 启动 auto-reply plugin
proot-distro login --shared-home ubuntu --user ubuntu -- bash -c \
    "cd /data/data/com.termux/files/home/hermes-wechat/server/services/wechat && MY_WXID=xxx MY_NICKNAME=xxx node auto-reply.js &"

# 发送启动通知
termux-notification \
    --title "Hermes WeChat" \
    --content "自动回复已启动" \
    --priority low

7.2 安装步骤

mkdir -p ~/.termux/boot
cp setup_termux_boot.sh ~/.termux/boot/start-hermes.sh
chmod +x ~/.termux/boot/start-hermes.sh

8. 目录结构

~/hermes-wechat/server/services/wechat/   # 主 plugin
├── auto-reply.js                         # 主入口
├── android-wechat-tracker-sqlcipher.js   # **主推** 消息跟踪
├── android-wechat-sender-frida.js        # **主推** 消息发送
├── android-wechat-tracker.js             # 备用消息跟踪
├── android-wechat-sender.js              # 备用消息发送
├── index.js                              # 统一入口
└── README.md                             # plugin 文档

~/local-testkit/                          # 备用 daemon / 工具
├── hermes_wechat_daemon.py              # 备用 Python 守护进程
├── 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

/sdcard/hermes/                           # 运行时数据
├── dbs/                                  # DB 副本(备用方案用)
├── wechat_msgs.jsonl                    # 消息日志(备用方案用)
└── auto-reply.log                        # auto-reply plugin 日志

9. 配置说明

auto-reply.js 环境变量

变量 默认值 说明
MY_WXID — 你的微信 wxid(必填)
MY_NICKNAME — 你的微信昵称(必填,用于判断群聊@)
HERMES_HOST 127.0.0.1 hermes-agent API 地址
HERMES_PORT 8642 hermes-agent API 端口
NOTIFICATION_ENABLED true 是否启用通知监听兜底

config.json(Python daemon 备用)

{
  "db_src_path": "",
  "db_copy_dir": "/sdcard/hermes/dbs",
  "sqlcipher_key": "e03ce81",
  "cipher_compatibility": 1,
  "cipher_page_size": 1024,
  "poll_interval_sec": 10,
  "max_msgs_per_poll": 50,
  "hermes": {
    "api_url": "http://localhost:3010/api/master/chat",
    "timeout_sec": 120
  },
  "auto_reply": {
    "enabled": false,
    "contacts": ["filehelper"],
    "exclude_types": [10000],
    "cooldown_sec": 5
  },
  "send": {
    "method": "am_broadcast",
    "broadcast_action": "com.hermes.wechat.SEND_MSG",
    "am_path": "/system/bin/am"
  },
  "logging": {
    "level": "INFO",
    "file": "/sdcard/hermes/daemon.log"
  }
}

注意:主流程(auto-reply.js)不读取 config.json,所有配置通过环境变量传入。


10. 部署步骤

Step 1: 环境准备

# Pixel Termux 中
pkg update
pkg install python sqlcipher termux-api

# 安装 Termux:Boot 和 Termux:API 应用(F-Droid 或 GitHub)
# 关闭电池优化(Termux / Termux:API / 微信)

Step 2: 部署 hermes-agent (lemonPCRM)

# 在 proot Ubuntu 中
cd ~/hermes-wechat
npm install
# 配置 .env 中的 Claude API key
npm start  # 或 npm run dev(热重载)

确认 hermes-agent 监听 127.0.0.1:8642:

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"}]}'

Step 3: 部署 Frida Daemon

# 1. 确保 frida-server 运行
su -c "/data/local/tmp/frida-server &"

# 2. 注入 daemon 到微信进程(从 Mac 或手机端)
frida -U -n com.tencent.mm -l frida_daemon.js

Step 4: 部署 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 &

Step 5: 启动保活脚本

cd ~/local-testkit
chmod +x keepalive.sh
nohup ./keepalive.sh > keepalive.log 2>&1 &

Step 6: 设置开机自启

cp setup_termux_boot.sh ~/.termux/boot/start-hermes.sh
chmod +x ~/.termux/boot/start-hermes.sh

11. 故障排查

Q: DB 轮询报错 "database is locked"

A: 微信正在写入 DB 时 sqlcipher 尝试打开。tracker 已对此静默处理,会在下次轮询重试。如频繁出现,可增大轮询间隔。

Q: sqlcipher 解密失败

A:

  1. 确认 key 正确:e03ce81
  2. 确认 cipher_compatibility=1 和 cipher_page_size=1024
  3. 直接测试:sqlcipher /path/to/EnMicroMsg.db "PRAGMA key='e03ce81'; PRAGMA cipher_compatibility=1; SELECT COUNT(*) FROM message;"

Q: hermes-agent API 调用超时

A:

  1. 确认 hermes-agent 已启动:curl http://127.0.0.1:8642/api/health
  2. 检查 hermes-agent 日志是否有 Claude CLI 调用错误
  3. 增加 HERMES_TIMEOUT(Claude 推理可能需要 30-60 秒)

Q: Frida 发送失败

A:

  1. 确认 frida-server 运行中:ps aux | grep frida-server
  2. 确认 frida_daemon.js 已注入微信进程
  3. 检查队列文件权限:ls -la /data/local/tmp/frida_daemon/queue.jsonl
  4. 备用方案:回退到 sendTextMessageBroadcast()

Q: 息屏后完全失效

A:

  1. 确认电池优化已关闭(Termux / Termux:API / 微信)
  2. 检查 keepalive.sh 是否运行
  3. 检查通知权限:Termux:API 是否有通知访问权限
  4. 检查日志:tail -f auto-reply.log 看是否有 [NOTIF] 或 [WAKE] 日志

Q: termux-notification-list 返回空

A:

  1. 确认 Termux:API 应用已安装
  2. 确认已授予通知访问权限
  3. 发送一条测试消息,等待通知出现

12. 版本演进

版本 日期 主要变更
1.0 2026-05-20 初始方案:Mac adb + Python daemon
2.0 2026-05-22 Pixel 本地方案:LSPosed 日志 tail + am broadcast + SSE API
3.0 2026-05-23 SQLCipher DB 轮询 + Frida 发送 + OpenAI-compatible API

13. 安全与风险提示

  1. 微信封号风险: 自动化操作存在被检测风险,建议使用测试小号
  2. Root 权限: 需要 Magisk root
  3. Frida 注入: 需要 frida-server 常驻运行
  4. API Key: Claude API key 仅在 hermes-agent 中配置,plugin 不持有

14. 扩展方向

  • [ ] 支持群聊 @识别和回复
  • [ ] 支持图片/语音消息处理
  • [ ] 本地 LLM 部署(减少 API 延迟)
  • [ ] Web UI 管理界面
  • [ ] 多账号支持