wechat_msg_clicker/CLAUDE.md

79 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# WeChat 消息自动点击器
自动点击微信桌面端未读消息中的图片和文件,触发原始文件下载到本地目录。
## 项目背景
配合另一个信息收集项目使用:信息收集脚本负责将微信消息入库,但图片和文件需要被点击预览后微信才会下载原始文件到本地。本工具自动完成这个"点击"操作。
## 技术架构
- **语言**: Python 3.11+
- **核心技术**: macOS Accessibility API (AXUIElement) via pyobjc
- **目标应用**: 微信桌面端 v4.1.9+ (bundle ID: com.tencent.xinWeChat)
- **运行平台**: macOS Sonoma 14+
### 模块结构
```
wechat_clicker/
├── ax_bridge.py # AXUIElement 底层封装(属性读取、鼠标点击、键盘事件、滚动)
├── wechat_ui.py # 微信 UI 导航(聊天列表、消息列表、预览界面元素查找)
├── state_machine.py # UI 状态机窗口状态检测、恢复、Preview.app 管理)
├── automator.py # 主自动化逻辑(扫描→进入聊天→锚点+箭头导航点击图片→点击文件→循环)
├── human_like.py # 拟人行为(高斯分布延迟、长休息、工作时间)
├── config.py # YAML 配置加载
└── logger_setup.py # 日志配置
```
### 关键设计决策
- 聊天列表项为 AXStaticText无 AXPress使用 **CGEvent 鼠标坐标点击**
- AXValue 位置/尺寸需用 AXValueGetValue 解包 CGPoint/CGSize
- 消息类型通过 title 内容判断:`"图片"` → 图片,`"文件\n..."` → 文件
- **图片/文件气泡偏移点击**AXStaticText 覆盖整行575px宽实际气泡仅在左侧 ~80-170px 区域,使用 `click_at_element_offset(x=120, y=height/2)` 命中
- **图片处理(锚点+箭头导航)**:滚到底部 → 找最底部可见图片(锚点)→ 点击锚点进入预览 → 按 i 次左箭头到达第 i 张 → 点"..."→"使用预览打开"→ 关闭 Preview.app → 回到微信 → 再次点击锚点 → 左箭头 i+1 次 → ... 循环直到覆盖 `unread_count + overlap` 张。彻底绕过滚动覆盖、元素可见性、去重等问题
- **锚点稳定性**:连续 3 次失败自动重锚(重新滚到底部 + 重找锚点 + i 归零),最多重锚 2 次;每聊天最多处理 30 张图片(`MAX_IMAGES_PER_CHAT`),防止单聊天垄断处理时间
- 文件处理:直接点击触发下载(不走箭头导航)
- **滚动方向**macOS CGEvent ScrollWheel **负值=向下滚**(看新消息),**正值=向上滚**(看旧消息)
- 进入聊天后滚到底部(负值),图片通过箭头导航覆盖历史
- 滚动使用 **kCGEventMouseMoved + ScrollWheel**(不触发点击),避免误点 UI 元素
- "..."按钮搜索限制在预览区域(独立窗口或主窗口 x>200排除侧边栏
- 可见性检查基于元素**中心点**是否在消息列表可见区域内30px margin
- 状态检测基于窗口计数 + **AXMinimized 属性**:区分窗口存在但最小化 vs 真正可见
- **窗口恢复策略**NSRunningApplication.unhide隐藏→ AX API 设置 AXMinimized=False最小化→ activate前台AppleScript 不可靠(微信不支持 miniaturized 属性)
## 使用方法
```bash
# 前置条件
pip install -r requirements.txt
# 系统设置 > 隐私与安全 > 辅助功能 → 添加终端/Python
# 复制配置
cp config.example.yaml config.yaml
# 运行
python main.py # 持续运行
python main.py --once # 单次扫描
python main.py --dry-run # 只扫描不点击
python main.py --dump-ui # 输出 UI 元素树
python main.py --dump-ui --chat "聊天名" # 进入指定聊天 dump 消息元素树(诊断用)
python main.py --debug # 详细日志
```
## 配置重点
- `config.yaml` 中可设置扫描间隔、延迟范围、白/黑名单、工作时间、媒体类型开关
- `max_chats_per_scan: 0` 表示不限制,处理全部未读聊天(适合大量群聊场景)
- 默认只点击图片(`media.click_files: false`, `media.click_videos: false`
- 默认黑名单包含微信系统账号
- 处理完有未读的聊天后立即重扫,不等待 scan interval只有无未读时才 sleep
- 忙时(未读 > 5自动跳过随机休息
## 注意事项
- 微信窗口最小化或隐藏时工具会自动恢复(通过 AX API 设置 AXMinimized=False + NSRunningApplication activate
- 运行时会占用微信前台操作
- 建议在专用电脑上运行