Repository navigation
feat: richText resource extraction and streaming downloadFileToFile - #4
Merged
haofeng0705 merged 3 commits intoSep 20, 2026
Conversation
- normalize: richText picture/file segments now extract into IncomingMessage.resources with strict typeof narrowing, dirty-segment skip, and per-message download-code dedup. - DingTalkChannel.downloadFileToFile: streaming media download to a local path (Readable.fromWeb + pipeline, no whole-file buffering), SSRF-guarded like downloadFile, same-dir temp file + atomic rename, parent dir must exist, no partial file left behind. Returns bytes written. - wire test/download-to-file.test.js into the npm test script. - Tests: resource extraction/dedup/dirty-data; streaming download success, non-200 status, and missing-parent-dir regressions.
…ark channel-sdk - normalize: richText picture/file segments now extract into IncomingMessage.resources (analog of lark's post attachment zone) with strict typeof narrowing and per-message download-code dedup. - DingTalkChannel.downloadFileToFile: streaming media download to a local path (Readable.fromWeb + pipeline, no whole-file buffering), SSRF-guarded like downloadFile, same-dir temp file + atomic rename, parent dir must exist, no partial file left behind. Returns bytes written. - Tests: resource extraction/dedup/dirty-data; streaming download success, non-200 status, and missing-parent-dir regressions.
haofeng0705
requested changes
Sep 20, 2026
haofeng0705
left a comment
Contributor
There was a problem hiding this comment.
复查结论:请求修改,当前不建议合入。
- 阻塞
src/normalize/message.js:52从part.picture读取 richText 图片下载码;真实回调使用downloadCode/pictureDownloadCode,当前测试数据掩盖了该问题。 - 阻塞
src/channel.js:144-155只校验初始 URL,fetch默认自动跟随重定向,重定向目标没有重新做 SSRF/DNS 校验。 src/channel.js:154临时文件名只由 PID 和毫秒时间戳组成,且未独占创建;同进程同毫秒并发写同一目标时会碰撞。已复现一个调用成功、另一个ENOENT。
npm test 本地 43/43 通过,但未覆盖真实 richText 字段、重定向及并发写入。请补齐修复和回归测试后再合入。
…eToFile - Support downloadCode and pictureDownloadCode with fallback to picture for richText images - Use POST with JSON body for messageFiles/download in reply - Prevent SSRF redirect bypass with manual redirect verification - Prevent temp file collision on concurrent downloads to same destination - Add GitHub Actions CI workflow Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
haofeng0705
approved these changes
Sep 20, 2026
haofeng0705
left a comment
Contributor
There was a problem hiding this comment.
复查通过。
- richText 图片字段已兼容
downloadCode/pictureDownloadCode/picture(src/normalize/message.js:50-63)。 - SSRF 重定向绕过已修复:
fetchWithSsrfGuard手动处理重定向并逐跳校验(src/channel.js:25-43),测试覆盖。 - 临时文件名加入
crypto.randomBytes(8)(src/channel.js:173-174),并发写同一目标不再碰撞,测试覆盖。 - 新增 CI workflow(Node 18/20/22)。
npm test本地 45/45 通过。
可合入。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
为钉钉 richText 消息补齐两项媒体能力:
1. richText 附件资源提取
richText 消息中的 picture/file 段此前被解析器直接丢弃,现在提取进
IncomingMessage.resources:{ type: 'image', downloadCode }{ type: 'file', ... }2. DingTalkChannel.downloadFileToFile(流式落盘)
流式下载文件到本地路径,不整块载入内存(
Readable.fromWeb+pipeline,背压感知):downloadFile完全一致rename,失败不落半截文件验证
npm test:43 个测试全部通过(含新增:资源提取/去重/脏数据、流式落盘成功/非 200/父目录缺失;新增的test/download-to-file.test.js已挂入 npm test 脚本)。与 #2 互不冲突,可任意顺序合并。@haofeng0705 请复查。