feat(feishu): render markdown headings, tables, and horizontal rules …#32455
Open
lzcopyer wants to merge 1 commit into
Open
feat(feishu): render markdown headings, tables, and horizontal rules …#32455lzcopyer wants to merge 1 commit into
lzcopyer wants to merge 1 commit into
Conversation
…as interactive cards
Feishu post-type 'md' elements do not support headings (##),
pipe tables (|...|), or horizontal rules (---). Previously, these
were either stripped to plain text or rendered incorrectly.
This change routes messages containing headings, tables, or HRs to
Feishu interactive cards, which support native components:
- ## Heading → div element with lark_md bold text
- | table | → native table element ({name: value} row objects)
- --- → hr element
- Other markdown → markdown element (preserves code blocks, lists, etc.)
Fenced code blocks are tracked so | and --- inside them are preserved
as literal text rather than being split into separate elements.
Also adds detailed API error logging when interactive cards are
rejected, showing the error code and message for easier debugging.
Tests: 210 feishu adapter tests pass (added 7 new card rendering tests)
Author
|
Fixes Feishu message rendering for Markdown headings, pipe tables, and horizontal rules. Previously, these Markdown elements were either stripped to plain text or rendered incorrectly because Feishu's |
Collaborator
|
Duplicate of #12114 (canonical Feishu markdown table → card rendering PR), tracked by consolidation issue #27469. This is part of a 70+ PR cluster all implementing Feishu interactive card rendering for markdown tables/headings. See #27469 for the full list of competing PRs (#25453, #29630, #31056, #30928, #31038, #31804, #32488, etc.). |
This was referenced May 27, 2026
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.
…as interactive cards
Feishu post-type 'md' elements do not support headings (##), pipe tables (|...|), or horizontal rules (---). Previously, these were either stripped to plain text or rendered incorrectly.
This change routes messages containing headings, tables, or HRs to Feishu interactive cards, which support native components:
Heading → div element with lark_md bold text
Fenced code blocks are tracked so | and --- inside them are preserved as literal text rather than being split into separate elements.
Also adds detailed API error logging when interactive cards are rejected, showing the error code and message for easier debugging.
Tests: 210 feishu adapter tests pass (added 7 new card rendering tests)
What does this PR do?
Fixes Feishu message rendering for Markdown headings, pipe tables, and horizontal rules. Previously, these Markdown elements were either stripped to plain text or rendered incorrectly because Feishu's
postmessage type does not support them.This PR routes messages containing headings (
##), pipe tables (|...|), or horizontal rules (---) to Feishu interactive cards, where they are rendered using native card components:## Headingdiv+lark_mdbold| table |table{column_name: value}row objects per Feishu spec---hrmarkdownFenced code blocks are tracked so
---and|inside them are preserved as literal text — they are not falsely split into separate card elements.Related Issue
N/A (no existing issue)
Type of Change
Changes Made
gateway/platforms/feishu.py(+183 lines)_MARKDOWN_HEADING_RE,_MARKDOWN_HR_RE) — detect headings and horizontal rules for routing to card format_build_outbound_payload()— routes headings/tables/HRs tointeractivecard instead oftextorpost_build_card_payload()— builds the card JSON with header + parsed elements_build_card_elements()(new static method) — parses markdown content intodiv/table/hr/markdownelements with code block tracking_build_card_table_element()(new static method) — converts pipe-table lines to Feishu's{name: value}row object formattests/gateway/test_feishu.py(+66 lines)Added 7 new tests and updated 2 existing tests:
test_build_card_elements_converts_horizontal_rules_to_hr— verifies HR → hr elementtest_build_card_elements_preserves_hr_inside_code_blocks— verifies---in fenced blocks stays literaltest_send_uses_card_for_markdown_heading— verifies##routes to interactive card with div elementtest_send_uses_card_for_markdown_table— verifies table routing to cardtest_build_card_payload_custom_header— verifies custom card headertest_build_card_payload_exception_fallback— verifies fallback on card rejectiontest_edit_message_card_fallback_to_plain_text— verifies edit fallbackHow to Test
## Heading, pipe tables, and---:Test Heading
##)---or|are not splitRun tests:
python -m pytest tests/gateway/test_feishu.py -q(210 passed)Checklist
Code
pytest tests/gateway/test_feishu.pyand all 210 tests passDocumentation & Housekeeping
cli-config.yaml.example— N/ACONTRIBUTING.mdorAGENTS.md— N/AScreenshots / Logs
Gateway logs showing successful interactive card delivery (no rejection/fallback):
2026-05-26 14:28:09 INFO [Feishu] Connected in websocket mode
...no "Interactive card rejected" errors in logs...