From 8e18d10318f9fb69f0b748db11e37de44b71da85 Mon Sep 17 00:00:00 2001 From: WuTianyi Date: Wed, 22 Apr 2026 08:09:20 +0800 Subject: [PATCH] fix(feishu): force text mode for markdown tables Feishu post-type 'md' elements do not render markdown tables. When table content is sent as post (triggered by **bold** matching _MARKDOWN_HINT_RE), the message appears blank on the client. Add _MARKDOWN_TABLE_RE to detect markdown table syntax and force text mode for table content, ensuring it is visible as plain text. --- gateway/platforms/feishu.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/gateway/platforms/feishu.py b/gateway/platforms/feishu.py index 0a28491240..40711d9680 100644 --- a/gateway/platforms/feishu.py +++ b/gateway/platforms/feishu.py @@ -153,6 +153,9 @@ _MARKDOWN_HINT_RE = re.compile( r"(^#{1,6}\s)|(^\s*[-*]\s)|(^\s*\d+\.\s)|(^\s*---+\s*$)|(```)|(`[^`\n]+`)|(\*\*[^*\n].+?\*\*)|(~~[^~\n].+?~~)|(.+?)|(\*[^*\n]+\*)|(\[[^\]]+\]\([^)]+\))|(^>\s)", re.MULTILINE, ) +# Detect markdown tables: a line starting with | followed by a separator line. +# Feishu post-type 'md' elements do not render tables, so we force text mode. +_MARKDOWN_TABLE_RE = re.compile(r"^\|.*\|\n\|[-|: ]+\|", re.MULTILINE) _MARKDOWN_LINK_RE = re.compile(r"\[([^\]]+)\]\(([^)]+)\)") _MARKDOWN_FENCE_OPEN_RE = re.compile(r"^```([^\n`]*)\s*$") _MARKDOWN_FENCE_CLOSE_RE = re.compile(r"^```\s*$") @@ -3995,6 +3998,12 @@ class FeishuAdapter(BasePlatformAdapter): # ========================================================================= def _build_outbound_payload(self, content: str) -> tuple[str, str]: + # Feishu post-type 'md' elements do not render markdown tables; sending + # table content as post causes the message to appear blank on the client. + # Force plain text for anything that looks like a markdown table. + if _MARKDOWN_TABLE_RE.search(content): + text_payload = {"text": content} + return "text", json.dumps(text_payload, ensure_ascii=False) if _MARKDOWN_HINT_RE.search(content): return "post", _build_markdown_post_payload(content) text_payload = {"text": content}