feat: implement M5 moments and rich messages

This commit is contained in:
2026-09-04 23:48:28 +08:00
parent 77e1e9dc2b
commit 1bd0344e8b
7 changed files with 806 additions and 0 deletions
+54
View File
@@ -0,0 +1,54 @@
# M5 功能清单
依据 `docs/WxAgent-CSharp-开发计划.md` 与 wxautox4 当前官方公开文档,M5 共包含以下能力。
## 1. 多聊天子窗口
- 双击会话弹出独立聊天窗口。
- 按聊天名称查找已存在的子窗口。
- 枚举全部已打开子窗口。
- 关闭子窗口。
- 所有窗口的 UI 写操作仍进入同一命令队列,不并行操作微信 UI。
## 2. 朋友圈
- 打开朋友圈窗口 `Moments`。
- 读取当前页朋友圈 `GetMoments`,返回短生命周期快照。
- 刷新朋友圈 `Refresh`。
- 发布文字、图片/视频朋友圈 `PublishMoment` / `Publish`。
- 发布范围:公开、标签白名单、标签黑名单。
- 点赞/取消赞 `Like`。
- 评论 `Comment`。
朋友圈条目没有稳定公开 ID;读取后应立即操作,刷新后旧指纹不得盲目复用。发布、点赞和评论均要求 `CONFIRM`,且禁止自动重试。
## 3. 特殊发送
- 发送 URL 卡片 `SendUrlCard`,支持多个目标和可选附带消息。
- 发送本地音频为微信语音条 `SendAudio`;按官方文档标记为 Beta,单次执行且不盲目重试。
## 4. 消息动作与内容读取
- 对消息发送者“拍一拍” `tickle`。
- 获取链接卡片 URL `get_url`。
- 读取微信笔记内容 `NoteMessage.get_content`。
- 将微信笔记保存为 Markdown `NoteMessage.to_markdown`。
- 通用消息内容/Markdown 视图,供 C# 调用方处理普通消息。
当前官方文档只为 `NoteMessage` 定义 `get_content()` / `to_markdown()`。合并转发消息在 v3.9 曾有 `get_messages()`,当前 v4 无公开展开合同,因此不伪装成 Note API;现阶段仅保留消息类型识别。
## 5. M5 验收项
- Core:URL 提取、内容模型、Markdown、朋友圈指纹、特殊消息分类、发布参数校验。
- Linux:Core 测试、全量 Release 构建、Windows x64 self-contained 发布。
- Windows:`doctor`、`inspect-ui`、`smoke`、`m5-smoke`。
- 真机写操作只允许文件传输助手或专用测试对象;朋友圈发布、点赞、评论不得在真实联系人内容上试验。
## 官方行为基线
- <https://docs.wxauto.org/docs/class/WeChat.html>
- <https://docs.wxauto.org/docs/class/Chat.html>
- <https://docs.wxauto.org/docs/class/Message.html>
- <https://docs.wxauto.org/docs/class/Moment.html>
- <https://docs.wxauto.org/docs/cli/automation.html>
- <https://docs.wxauto.org/update/wxautox4.html>
@@ -0,0 +1,73 @@
# M5 朋友圈、特殊发送与富消息验证记录(2026-09-04)
## 功能范围
完整清单见 `docs/M5-功能清单.md`。本阶段实现:
- 多聊天子窗口:弹出、查找、枚举和关闭(复用并补齐 M4 基础能力)。
- 朋友圈:打开、当前页/下一页读取、刷新、发布文字和媒体、公开/标签白名单/标签黑名单、点赞/取消赞、评论。
- 特殊发送:URL 卡片、PCM WAV 音频录制为语音条。
- 消息:拍一拍、链接 URL、特殊消息分类、微信笔记内容、笔记 Markdown 文件。
- 当前 v4 官方文档没有合并转发内容展开合同,因此只识别 `merge` 类型,不把 Note API 错套到合并消息。
## 安全设计
- 发布朋友圈、点赞、评论、URL 卡片、语音和拍一拍均要求精确确认令牌 `CONFIRM`。
- 所有微信 UI 写操作继续使用统一命令队列;发送失败或结果未确认时不自动重试。
- 朋友圈指纹只用于同一可见页面内的短生命周期定位;刷新/翻页后重新读取。
- CLI 和验证产物不输出朋友圈作者、正文、联系人名称或消息正文。
## Linux 验证
```text
~/.dotnet/dotnet test tests/WxAgent.Core.Tests -c Release --no-restore
Passed: 30, Failed: 0
~/.dotnet/dotnet build WxAgent.sln -c Release -p:EnableWindowsTargeting=true --no-restore
Build succeeded. 0 Warning(s), 0 Error(s)
~/.dotnet/dotnet publish src/WxAgent.Host -c Release -r win-x64 --self-contained true \
-p:EnableWindowsTargeting=true -p:PublishSingleFile=true -p:PublishTrimmed=false --no-restore
Publish succeeded.
```
新增测试覆盖 URL 提取、链接/引用 Markdown、Note Markdown、特殊消息分类、朋友圈稳定指纹和朋友圈可见范围参数校验。
## Windows 真机验证
主机:`DESKTOP-EGI7QCK`,微信登录用户会话。
```text
WxAgent.Host doctor --timeout 30 exit 0
WxAgent.Host inspect-ui --output m5-ui-tree.json --timeout 30 exit 0
WxAgent.Host smoke --output m5-smoke-ui.json --timeout 30 exit 0
WxAgent.Host m5-smoke --timeout 60 exit 0
```
`m5-smoke` 脱敏结果:
```json
{
"scope": "M5",
"momentsWindow": "moments",
"momentCount": 2,
"urlParsed": true,
"markdownRendered": true,
"confirmationGuarded": true,
"privacy": "moment authors and content omitted"
}
```
验证覆盖朋友圈打开、刷新、只读快照、关闭并返回聊天页。URL 卡片在“文件传输助手”单次发送后读回为链接消息;后续一次结果确认超时按规则返回 `ResultUnconfirmed`,未自动重试。
语音能力已实现为按住微信“发语音”控件并播放 PCM WAV,且失败后不重试。当前 Windows 主机没有可用麦克风输入,用户明确要求跳过语音真机发送验收;保留 Beta 能力和明确诊断,不以文件消息冒充语音消息。
朋友圈发布、点赞、评论和拍一拍未对真实联系人内容执行;只验证输入、确认门禁、编译和只读页面定位,符合项目安全规则。
脱敏证据位于 `artifacts/m5-2026-09-04/`。
## 官方行为差异
- `NoteMessage.get_content()` / `to_markdown()` 仅适用于 Note;合并消息当前无公开展开 API。
- `SendAudio` 官方标为 Beta 且要求额外配置,本项目只支持单个 PCM WAV,不复制官方默认自动重试。
- 朋友圈发布公开文档没有稳定返回合同;本项目不因无异常而盲目重试。