Skip to content

fix(dingtalk-platform): extract ASR recognition and file message text from incoming messages - #50014

Closed
rayjerrywoo wants to merge 2 commits into
NousResearch:mainfrom
rayjerrywoo:fix/dingtalk-audio-file-robot
Closed

fix(dingtalk-platform): extract ASR recognition and file message text from incoming messages#50014
rayjerrywoo wants to merge 2 commits into
NousResearch:mainfrom
rayjerrywoo:fix/dingtalk-audio-file-robot

Conversation

@rayjerrywoo

@rayjerrywoo rayjerrywoo commented Jun 21, 2026

Copy link
Copy Markdown

Summary

3 fixes for the dingtalk-platform plugin (plugins/platforms/dingtalk/adapter.py) enabling:

  • ASR recognition text extraction from voice messages
  • File message filename fallback and download code resolution
  • Proper MIME mapping for file/image attachments

All of which were missing after the refactor from gateway/platforms/dingtalk.py to the plugin architecture.

Changes

_extract_text — Voice ASR and file filename

  • Parse ASR recognition text from audio messages via extensions['content']['recognition']
  • Fall back to extensions['content']['fileName'] for file messages (rendered as [文件] filename)

_extract_media — Audio/file/image type detection

  • Handle msgtype='audio': set VOICE type but skip passing media URLs (preserves DingTalk's built-in ASR result, avoids failed whisper re-transcription)
  • Handle msgtype='file'/'image': parse downloadCode, map common file extensions to MIME types

_resolve_media_codes — Download code for file/image

  • Parse downloadCode from extensions['content'] for file and image message types

Notes

  • This targets the new plugin (plugins/platforms/dingtalk/adapter.py) — the old gateway/platforms/dingtalk.py has been deleted upstream. Before applying, ensure your Hermes is up to date (post-refactor, commit ≥560010547) and the dingtalk-platform plugin is enabled.
  • Supersedes the now-stale fix(dingtalk): extract ASR recognition from 1:1 voice messages #49546 (zh-xl-kang, targets the deleted old file)
  • Sending (file/image/voice via OpenAPI) is not included — pending further DingTalk API verification
  • All changes tested with live DingTalk group chat: voice → recognition text, PDF/Markdown file → filename + download

@alt-glitch alt-glitch added type/feature New feature or request comp/plugins Plugin system and bundled plugins platform/dingtalk DingTalk adapter P2 Medium — degraded but workaround exists labels Jun 21, 2026
@rayjerrywoo
rayjerrywoo force-pushed the fix/dingtalk-audio-file-robot branch 2 times, most recently from 0f589ce to b1af1a3 Compare June 21, 2026 11:31
@rayjerrywoo rayjerrywoo changed the title feat(dingtalk-platform): audio ASR, file messages, and Robot OpenAPI send fix(dingtalk-platform): extract ASR recognition and file message text from incoming messages Jun 21, 2026
… from incoming messages

3 fixes for the dingtalk-platform plugin (plugins/platforms/dingtalk/adapter.py):

1. _extract_text: parse ASR recognition text from voice messages via
   extensions['content']['recognition'], fall back to fileName for
   file messages ("[文件] xxx")
2. _extract_media: handle audio/file/image msgtype_str with correct
   MIME mapping; exclude audio from media_urls to preserve DingTalk's
   built-in ASR result (avoids failed whisper re-transcription)
3. _resolve_media_codes: parse downloadCode from extensions['content']
   for file/image message types

All tested with live DingTalk group chat: voice → recognition text,
PDF/Markdown file → filename + download.

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for targeting the post-plugin-refactor inbound-media gap. The current adapter still lacks handling for extensions.content audio/file/image payloads (plugins/platforms/dingtalk/adapter.py:765-824,1301-1338), so the premise remains valid.

Problems

  • The new msgtype='image' path is grouped with files and unconditionally sets MessageType.DOCUMENT at plugins/platforms/dingtalk/adapter.py:879. Image MIME values map to PHOTO in the normalized adapter contract (plugins/platforms/google_chat/adapter.py:302-316), and PHOTO has distinct busy-session handling (gateway/platforms/base.py:4763-4769).
  • Please add regression tests. Existing DingTalk coverage tests rich-text media but not these new extensions.content payload shapes (tests/gateway/test_dingtalk.py:574-623).

Suggested changes

  • Split image classification from generic files: retain DOCUMENT for files, but emit PHOTO for image/* attachments.
  • Cover ASR text, file name/code resolution, and direct-image MIME/type extraction with fixture-like message objects.

Automated hermes-sweeper review.

Comment thread plugins/platforms/dingtalk/adapter.py Outdated
mime = EXT_MAP.get(ext, mime)
media_types.append(mime)
if msg_type == MessageType.TEXT:
msg_type = MessageType.DOCUMENT

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This branch also handles msgtype='image', but it always emits DOCUMENT. Please classify image MIME values as PHOTO; PHOTO has separate busy-session album/queue behavior in gateway/platforms/base.py, while the existing MIME-based adapter mappings also treat image/* as PHOTO.

@teknium1 teknium1 added sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 14, 2026
… card/interactiveCard message handling

- Promote EXT_MAP to a module-level constant for reuse
- Classify DingTalk image messages and image file attachments as PHOTO
- Extract DingTalk card/interactiveCard document link content with defensive parsing
- Handle None, empty, JSON, and plain-string card content fields
- Add coverage: 8 card + 4 interactiveCard + 5 _extract_media = 17 test cases
- Remove a shadowed duplicate TestExtractText class (pytest collected only the later one)
@rayjerrywoo
rayjerrywoo force-pushed the fix/dingtalk-audio-file-robot branch from b1af1a3 to d8f667b Compare July 15, 2026 14:22
@rayjerrywoo

Copy link
Copy Markdown
Author

@teknium1 Thanks for the review — the feedback has been addressed in the second commit (d8f667b).

Summary of the follow-up changes:

  • PHOTO classification: Image messages (msgtype='image') and file attachments with image MIME types (e.g., .png sent as a file message) are now classified as MessageType.PHOTO instead of DOCUMENT. The logic checks msgtype_str == "image" first, then falls back to MIME-based detection (mime.startswith("image/")).
  • EXT_MAP: Promoted to a module-level constant so it can be reused across _extract_text and _extract_media.
  • Card/interactiveCard: Added fallback extraction for DingTalk document-share card and interactiveCard message types.

17 new test cases covering all the above scenarios are included in the second commit. Please take another look when you get a chance.

@teknium1

Copy link
Copy Markdown
Contributor

Merged into main via consolidated salvage PR #73515 (merge c911a5f10f). Your DingTalk ASR extraction/routing fix (recognition text from extensions["content"], voice→VOICE routing, EXT_MAP, card handling) was cherry-picked with your authorship.

Your contribution is credited to you in git history. Thank you! Closing this PR as merged-via-salvage.

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

Labels

comp/plugins Plugin system and bundled plugins P2 Medium — degraded but workaround exists platform/dingtalk DingTalk adapter sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants