Skip to content

feat(channel): render post attachment zone in normalize - #20

Merged
mazhe-nerd merged 2 commits into
larksuite:mainfrom
yjhcjykwbk-jlsec:feat/post-attachment-zone
Aug 31, 2026
Merged

feat(channel): render post attachment zone in normalize#20
mazhe-nerd merged 2 commits into
larksuite:mainfrom
yjhcjykwbk-jlsec:feat/post-attachment-zone

Conversation

@yjhcjykwbk-jlsec

Copy link
Copy Markdown

Summary

The rich-text attachment zone (top-level files array on a post message) was ignored by the post converter: only the locale document (title/content/content_v2) was flattened and scanned for resources, so attachments attached to a rich-text message were invisible to channel consumers.

This PR makes the attachment zone visible and downloadable (node-aligned with larksuite/channel-sdk-node):

  • lark_channel/channel/normalize/converters/post.py
    • _attachment_files(): extract the top-level files: [{file_key, file_name, is_folder}] array
    • render attachment-zone entries as <file key="..." name="..."/> / <folder key="..." name="..."/> lines after the body, matching the standalone file/folder converters
    • surface attachment-zone files as ResourceDescriptor(type="file") so they are downloadable; folders stay tag-only (mirrors the standalone folder converter's resources=[])
    • the attachment zone is also included in convert_body (i.e. InboundMessage.body_text)
  • lark_channel/channel/tests/test_flatten.py: three new tests — rendering + resource extraction, empty files array tolerance, and body_text propagation

Wire shape

{
  "zh_cn": { "title": "报告", "content": [[{"tag": "text", "text": "正文"}]] },
  "files": [
    { "file_key": "file_a", "file_name": "report.pdf" },
    { "file_key": "dir_1", "file_name": "assets", "is_folder": true }
  ]
}

renders as:

# 报告
正文
<file key="file_a" name="report.pdf"/>
<folder key="dir_1" name="assets"/>

with resources: [ResourceDescriptor(type="file", file_key="file_a", file_name="report.pdf")].

Test

python3 -m pytest lark_channel/channel/tests/ -q
# 893 passed (incl. 3 new)

The rich-text attachment zone (top-level files array) was ignored by the
post converter: only the locale document (title/content/content_v2) was
flattened and scanned for resources, so attachments attached to a rich-text
message were invisible to channel consumers.

- render attachment-zone files as <file key=... name=.../> lines and
  is_folder entries as <folder .../> lines, matching the standalone
  file/folder converters
- surface attachment-zone files as ResourceDescriptor(type=file) so they
  are downloadable; folders remain tag-only like the folder converter
- include the attachment zone in convert_body (InboundMessage.body_text)
- cover with tests: rendering + resource extraction, empty files array,
  body_text propagation
@yjhcjykwbk-jlsec
yjhcjykwbk-jlsec force-pushed the feat/post-attachment-zone branch from 7ca71ba to ca713f1 Compare August 31, 2026 09:30
Maintainer follow-up on the attachment-zone support in this branch.

- Read the attachment zone before the no-locale-document guard. A post
  carrying only attachments previously returned empty text while still
  surfacing downloadable resources, so the two paths disagreed on the
  same input.
- Narrow every attachment field at extraction time. A non-string
  file_name would otherwise reach attr() and raise out of the normalize
  pipeline, which has no converter-level trap; a stringly is_folder
  ("false") would hide a real, downloadable file behind a <folder/> tag.
- Escape the key as well as the name, so neither field can close the
  attribute and forge a sibling tag.
- Pick the first dict-valued entry as the locale document in
  _flatten_post_text. The wire may place `files` before the locale key,
  which emptied PostContent.text and with it the pipeline's @ALL probe
  and <at>-tag parsing.
- Collapse the file/folder render matrix into _render_attachment.

Covered by seven new tests. Bump to 1.4.0.
@mazhe-nerd
mazhe-nerd merged commit 52ba796 into larksuite:main Aug 31, 2026
7 checks passed
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.

3 participants