28 lines
4.1 KiB
Markdown
28 lines
4.1 KiB
Markdown
# 项目长期记忆 — 企业微信 RPA 自动化
|
||
|
||
## 项目背景
|
||
- 企业微信(WeCom)消息自动回复,核心:红点检测 → 会话定位 → 提取文本 → AI 回复 → GUI 发送。
|
||
- 企微用自定义 GPU 渲染(UIA 节点=0),**无法**用 UIAutomation/win32gui 内部控件查询,只能截图 + 坐标。
|
||
- 本地库(message.db 等)为 wxSQLite3 加密(文件头 `4fa4c7db855d54ad`),需内存提密钥 + 解密,普通 sqlite3 打不开。
|
||
- 主 GUI:`wechat_gui_qt.py`(PySide6),后台运行时:`gui_runtime.py`(BotThread),核心:`wechat_bot.py`(13664 行,WeChatBot 类)。
|
||
- AI 统一入口:`ai_chat.get_ai_reply(chat_text, image_bytes, history, *, force_vision, media_types)`,Dify 提供商(gpt-5.6-sol),`ai_settings.json` 配置。
|
||
|
||
## 双引擎架构(2026-08-21 落地)
|
||
- **引擎 A**(截图 RPA):红点识别 → 打开会话 → 视觉提取 → `_generate_ai_reply` → `send_reply`。发送收敛点。
|
||
- **引擎 B**(数据直读,`engine_b.py`):**两路并行双跑、互为兜底**——① DB 直读(升级数据源)② `conversations.json`(引擎 A 视觉回写档案)每轮都独立检测;任一数据源有盲区另一路补漏,同一条消息靠 dedup_key 去重(fp_hex:时间戳,300s 防抖+队列级去重)只投一次 → `bot.enqueue_detected()` 投共享队列 → 由引擎 A 的 `_resume_orphaned_pending_reply` 统一处理。B 不碰窗口。两路游标独立:`_seen`(JSON)/`_seen_db`(DB),DB 失败仅停 DB 路(db_active=False)。
|
||
- **DB 直读**(`wxwork_db.py`,Phase 2 主线,密钥已验证):密钥在 `wxwork_keys.json`(2 账号:`1688856770803435`→`db7288a302bfbe66563d81f025bde977`、`1688855555743233`→`d18e7f9a222665389989066f929ece19`,其余 9 账号无密钥/未登录)。解密缓存 `wxwork_decrypted/`,WAL 感知(帧同算法加密,可合并拿 checkpoint 前最新消息)。`get_new_messages(since_ts)` 秒级 send_time 增量查询,`is_personal_chat` 只留 M:/S: 单聊。fp_hex = `session_fp_from_name`(md5+blake2b 40 字节,与引擎 A identity_by_name 模式一致)。
|
||
- **共享队列** `pending_replies.json`:字段白名单读写(`_load_pending_replies`/`_persist_pending_replies_unlocked`)。新字段必须两处透传!现有 44 字段含:dedup_key(去重)、detected_by(engine_a/engine_b)、detection_ts、sending_owner、send_lock_ts。
|
||
- **发送互斥** `send_lock.py`:Windows 命名互斥量 `Global\WeChatBotSendLock` + 线程持有者跟踪。`send_reply()` 入口抢占,拿不到即让出。
|
||
- 引擎开关(`app_settings.json`,GUI「检测引擎」卡片可改):`engine_a_enabled`(默认 true,注意键名不是 enable_engine_a!)、`enable_engine_b`(默认 true)、`engine_b_poll_interval`(2.0)、`engine_b_data_source`(parallel/db/json,非法回落 parallel)。运行时在 BotThread 启动时读取,GUI 改后本轮结束重启生效。
|
||
- 引擎 A 关闭(`engine_a_enabled=false`)≠ 不回复:`_poll_once(scan_unread=False)` 跳过红点截图扫描,但队列恢复照常,B 投递的消息仍被定位发送。
|
||
|
||
## 关键约定
|
||
- 队列任务 stage 状态机:queued→opening→reading→collecting→generating→ready_to_send→sending→sent,另有 manual_review/retry_wait/call_paused/uncertain。
|
||
- 发送频率限制:`MAX_SENDS_PER_MINUTE=4`、`MAX_SENDS_PER_HOUR=60`(`_send_gate`)。
|
||
- 测试注意:wechat_bot.py 依赖 win32gui/mss/numpy/pyautogui,**只能用系统 Python 3.11 跑**(`C:\Users\pc\AppData\Local\Programs\Python\Python311\python.exe`),managed python 3.13 无这些包。
|
||
- 构造最小 bot 对象用 `WeChatBot.__new__(WeChatBot)` + 手工补 `_pending_lock/_pending_reply_sessions/_pending_reply_path/_cancelled_reply_sessions`。
|
||
|
||
## 待办/未来方向
|
||
- Phase 2 DB 直读主线已打通(密钥就位 + WAL 合并 + 指纹对齐 + 引擎 B 集成),回归 31 项通过。剩余:长稳联跑验证(企微运行中轮询 WAL 增量 → 引擎 A 回复闭环)。
|
||
- 机器人对接口子:ai_chat(已用)/ MCP 增强(AI_MCP_ENABLED + mcp_bridge)/ 外部 Agent(mcp_server.py)。
|