Skip to content

feat: export file attachments and repair Moments video loading - #345

Closed
fan26a wants to merge 2 commits into
ILoveBingLu:mainfrom
fan26a:codex/export-attachments-moments-video
Closed

feat: export file attachments and repair Moments video loading#345
fan26a wants to merge 2 commits into
ILoveBingLu:mainfrom
fan26a:codex/export-attachments-moments-video

Conversation

@fan26a

@fan26a fan26a commented Aug 12, 2026

Copy link
Copy Markdown

Summary

  • add an export option for local file attachments and include exported paths in message content
  • make Moments video downloads support HTTP/HTTPS CDN redirects, timeouts, and completeness checks
  • reject invalid decrypted video data and automatically recover from corrupted cache files

Testing

  • node --experimental-strip-types scripts/test-sns-video.ts
  • vite build

@ILoveBingLu ILoveBingLu left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

目前不建议直接合并,请先处理以下问题:

阻塞:206 Partial Content 可能被当成完整视频永久缓存

downloadSnsVideoToFile 接受所有 206 响应,但完整性检查只比较 Content-Length 与本次响应实际接收长度,没有解析 Content-Range 判断响应是否覆盖整个视频。

我用下面的响应做了复现:

HTTP/1.1 206 Partial Content
Content-Length: 24
Content-Range: bytes 0-23/1000000

下载器会返回 { success: true },保存的 24 字节由于包含合法 ftyp 文件头,也会被 isPlayableVideoBuffer 判定为有效。之后 snsService 会将其写入正式缓存;缓存命中时又只验证前 12 字节,因此这个截断文件会持续被当作可播放视频。

这与本 PR 的“下载完整性检查”和“损坏缓存自动恢复”目标直接冲突。建议:

  • 未主动发送 Range 请求时只接受 200;或
  • 严格解析 206 的 Content-Range,确认范围从 0 开始且结束位置覆盖总长度;
  • 增加测试:仅返回合法视频头的 206 分段响应必须失败且不得保留文件。

相关位置:electron/services/snsVideoUtils.ts 112-143 行、electron/services/snsService.ts 1553-1559 和 1592-1632 行。

次要:AI 导出入口没有接入 exportFiles

页面导出已经新增 exportFiles,但 AI 导出相关的 AiExportMediaOptions、校验、runner 映射及工具 Schema 仍只有头像、图片、视频、表情、语音五项。因此新功能只能从导出页面使用,AI 的聊天导出工具无法导出附件。

涉及:

  • electron/services/agent/aiExportTypes.ts
  • electron/services/agent/aiExportValidation.ts
  • electron/services/agent/aiExportRunner.ts
  • electron/services/agent/tools/exportChat.ts

如果产品范围明确只支持页面导出,请在 PR 中说明;否则建议一并补齐契约和测试。

补充验证:PR 自带的 node --experimental-strip-types scripts/test-sns-video.ts 可以通过,git diff --check 也通过;当前 PR 没有 CI checks。

@ILoveBingLu

Copy link
Copy Markdown
Owner

跟进一下:自上次评审(08-13)以来 PR 没有新提交,两条意见仍然有效。我在当前分支上重新复现了阻塞问题:本地起一个返回 206 / Content-Length: 24 / Content-Range: bytes 0-23/1000000 的 server,downloadSnsVideoToFile 仍返回 success: true,24 字节被写进正式缓存,之后每次命中只校验前 12 字节,永远被当作可播放视频(snsVideoUtils.ts:112 / :139 原样未动)。此外无 Content-Length 的 200 响应完全不做长度校验。

补充几点新发现,供修改时一并考虑:

  • 除了 AI 导出四个文件,MCP 导出入口(mcp/types.tsmcp/readService.tsmcp/tools.ts)同样没有接入 exportFiles
  • HTML 导出对新的 [文件] <原名> files/<日期>/<导出名> 不生成链接,且 safeFileName 不替换空格,"原名 路径"之间用空格分隔下游无法可靠拆分(例如 1700000000_12_my doc.pdf)。
  • 附件定位按 XML title 在几个候选目录里找文件名,同月同名文件微信会改名为 name(1).ext 而 title 不变,会静默拿错;videoService 已有基于 hardlink.db 的查找逻辑,建议复用。

也确认了 main 自 PR 基线以来没有另行修改朋友圈视频加载,这部分不冗余。建议把"朋友圈视频修复"和"导出附件"拆成两个 PR,先把修好 206 的视频部分单独推进,更容易合。

@ILoveBingLu

Copy link
Copy Markdown
Owner

自 08-13 评审以来没有新提交,阻塞问题(206 分段响应被当作完整视频永久缓存)仍未处理,先关闭以保持 PR 列表整洁。

这两部分改动本身都有价值,欢迎拆成两个 PR 重新提交:

  1. 朋友圈视频修复 —— 修好 206 / 无 Content-Length 的完整性校验并补测试后可以很快合;
  2. 导出附件 —— 接入 AI 导出与 MCP 导出入口、处理 HTML 链接与文件名空格、附件定位改用 hardlink.db。

具体点位见上面两条评论。感谢贡献!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants