plan.md 4.03 KB

WeChat Daemon 开发计划

当前状态(2026-05-22)

完整自动回复闭环已验证成功:

  1. Termux API 检测微信通知
  2. 复制 EnMicroMsg.db + WAL + SHM 到工作目录
  3. SQLCipher 解密(key=e03ce81, compat=1, page_size=1024)
  4. 查询最新消息(ORDER BY msgId DESC)
  5. 调用 hermes api_server OpenAI-compatible API(SSE 流式)
  6. 通过 am broadcast 发送回复到微信

已知问题

P1 — last_msg_id 无持久化

  • --once 模式每次从 0 开始,会重复处理历史消息
  • run_daemon() 前台运行时 last_msg_id 仅在内存中,进程重启后丢失
  • 影响:重复回复、API 浪费、用户体验差

P2 — 后台 daemon 未充分验证

  • 通知驱动 + wake_wechat() + 3s 延迟 + DB 轮询的实时流程未完整测试
  • 长时间运行稳定性未知(内存泄漏、句柄泄漏)
  • 影响:无法部署为 7x24 服务

P3 — WAL 复制偶发不稳定

  • copy_db 使用 su -c cp 复制 WAL,在 root/Termux 权限边界上偶尔行为不一致
  • 已观察到:不带 WAL 时 sqlcipher 解密成功,带 WAL 时某些环境下失败
  • 影响:最新消息丢失(WAL 中未 checkpoint 的数据)

P4 — 通知内容无法直接用于回复

  • Termux termux-notification-list 只能拿到通知标题/摘要
  • 微信通知内容通常被截断,拿不到完整消息文本
  • 影响:必须依赖 DB 轮询,通知只能作为"触发器"

P5 — 微信唤醒延迟硬编码

  • poll_notifications() 中 time.sleep(3) 固定等待微信同步 DB
  • 网络差时 3 秒不够,网络好时浪费
  • 影响:回复延迟不稳定或过度延迟

P6 — 群聊消息处理不完善

  • 当前仅通过 contacts 白名单过滤 talker
  • 群聊消息 talker 是 @chatroom,没有解析群成员昵称和 @ 信息
  • 影响:群聊中被 @ 时无法正确识别和回复

下一步开发目标

1. 状态持久化(高优先级)

  • 将 last_msg_id 和 last_reply_time 持久化到 /data/data/com.termux/files/home/.hermes_daemon_state.json
  • poll_cycle() 启动时读取,结束时写入
  • 支持 last_msg_id 初始化为当前最大 msgId(首次运行不处理历史消息)

2. 后台 daemon 稳定运行(高优先级)

  • 测试 run_daemon() 前台模式 30 分钟以上
  • 验证通知 → 唤醒微信 → DB 同步 → 自动回复的完整实时流
  • 添加进程守护(崩溃自动重启)或 systemd/termux-services 集成

3. 通知内容直接提取(中优先级)

  • 研究 Termux API 或 Android AccessibilityService 能否拿到完整通知内容
  • 如果能拿到,实现"通知内容直接回复"分支,跳过 DB 轮询
  • 作为 DB 轮询的补充/降级方案

4. 配置热重载(中优先级)

  • 监听 config.json 修改时间戳,变化时重新加载
  • 支持运行时修改 contacts、system_hint、cooldown_sec 等

5. 日志系统修复(中优先级)

  • su 环境下 /sdcard/ 的 FUSE 限制导致 FileHandler 可能失败
  • 将日志写入 Termux home 目录,或完全依赖 print(..., flush=True)
  • 添加日志轮转,避免单文件过大

6. 群聊消息支持(低优先级)

  • 解析 @chatroom 消息中的 fromusername 字段
  • 识别被 @ 的场景(检查消息内容是否包含当前用户昵称)
  • 群聊回复时引用原消息上下文

7. 消息类型扩展(低优先级)

  • 图片(type=3)、语音(type=34)、链接(type=49)的识别
  • 对非文本消息回复固定提示(如"收到图片/语音,暂不支持查看")
  • 链接类型消息提取标题和 URL 传给 hermes API

技术债务

  • [ ] decrypt_db 中的 .quit 命令在 sqlcipher stdin 模式下是否必要?
  • [ ] copy_db 使用 su -c cp 在 su 环境下嵌套调用,考虑直接用 shutil.copy
  • [ ] poll_interval_sec 和 cooldown_sec 的默认值需要调优
  • [ ] 缺少单元测试框架

已验证环境

  • Pixel 10 Fold
  • Android 15
  • Termux + Termux:API
  • WeChat 8.0.72
  • sqlcipher 3.x
  • hermes-agent api_server @ localhost:8642