# 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 → am start LauncherUI └─────────────────────────┘ + (息屏时) wakeWechat() │Yes ▼ ┌──────────────────────────────────────────────────────────┐ │ am broadcast -a com.hermes.wechat.SEND_MSG │ │ --es toUser │ │ --es toUserDisplayName ← 必传! │ │ --es content │ └──────────────────────────────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────┐ │ HermesAccessibilityService (lsposed-wechat-sendmsg 模块) │ │ 1. startActivity(LauncherUI, CLEAR_TASK) │ │ 2. 点搜索按钮 (id=jha) │ │ 3. ACTION_SET_TEXT 输入 nickname → 点搜索结果 │ │ 4. 进入聊天后 ACTION_SET_TEXT 写入 content │ │ 5. 点发送按钮 (id=bql) │ └──────────────────────────────────────────────────────────┘ │ ▼ 微信走自己正常的发送流程 → 服务器 → message 表 isSend=1 ``` **优势**: - 不依赖反射 hook 微信内部 NetSceneSendMsg(在 WeChat 8.0.72 上主线程提交持续 NPE 失败) - 不依赖 Frida 注入(Frida 17 + 微信 8.0.72 注入会触发反调试 / 进程崩溃) - sqlcipher 直接查询,数据完整(含群聊名称、发送者等) - 走 UI 是慢一点(~8s/条)但**唯一稳定可用** - 通过 hermes-agent API 享受完整的 Agent 编排、工具调用、记忆能力 > ⚠️ **历史遗留命名警告**:`android-wechat-sender-frida.js` 中的 `sendTextMessageFrida` 写入 `.frida_queue/queue.jsonl` 的设计**已废弃**。同样地,README 早期版本把 Frida daemon 描述为主路径——那是错的。所有发送最终都走 `am broadcast` → A11y service。 ### 备用流程: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 捕获 → 正常处理 ``` **保活措施**: 1. `termux-wake-lock` — 防止息屏后 CPU 被冻结 2. 关闭电池优化(Termux / Termux:API / 微信) 3. `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. 部署 ```bash # 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`: ```bash proot-distro login ubuntu --user ubuntu -- bash -c \ "cd /data/data/com.termux/files/home/hermes-wechat && . .env && node server/index.js" ``` 或后台运行: ```bash 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 就绪: ```bash 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. 启用 HermesAccessibilityService(发送端依赖) A11y service 是消息真正能发出去的唯一路径——务必确认启用: ```bash # 启用 adb shell "su -c 'settings put secure enabled_accessibility_services com.hermes.wechat.xposed/com.hermes.wechat.xposed.accessibility.HermesAccessibilityService; settings put secure accessibility_enabled 1'" # 验证 adb shell "settings get secure enabled_accessibility_services" adb shell "dumpsys accessibility | grep -A3 Hermes" # 应看到: Bound services / Enabled services 都包含 HermesAccessibilityService ``` `enabled_accessibility_services` 在系统重启 / 微信或模块更新 / 用户在设置里关闭后会变成 `null`,发送会静默失败——把这个检查写进保活脚本里。 ### 5. 启动 auto-reply plugin(推荐主流程) ```bash 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. 启动保活脚本(推荐) ```bash 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 ```bash 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 ```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 的配置 --- ## 故障排查 | 问题 | 排查步骤 | |------|---------| | 发送接口返回 ok 但 yibooo 没收到 / `message` 表没新行 | **最常见**:A11y service 未启用。`adb shell "settings get secure enabled_accessibility_services"` 若为 `null` 即是。重新启用见上文 | | A11y 日志 `Root package=com.termux` 后退出 | 广播触发时微信不在前台。先 `am start -n com.tencent.mm/.ui.LauncherUI` 再发 broadcast | | A11y 日志 `Search button not found` | 当前页面不是主界面 / nickname 错。检查 `toUserDisplayName` 必须是好友的 WeChat 昵称(如"火星人"),不是 wxid | | `[HermesWX] Send result: true` 但 DB 没新消息 | LSPosed 反射路径的**误报**,是已知 bug。看 `HermesA11y:*` 日志才反映真实状态 | | 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` 是否运行;检查通知权限 | | 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 ├── PIXEL_CLAUDE_CODE_OAUTH_SETUP.md # Pixel 上 claude-run 复用 Mac OAuth ├── HERMES_AGENT_PIXEL_SETUP.md # 在 Pixel 编译装 NousResearch hermes-agent + 配 Kimi Coding Plan └── 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 文档 ```