diff --git a/gateway/platforms/feishu.py b/gateway/platforms/feishu.py index 718f01e995..2c5398bb83 100644 --- a/gateway/platforms/feishu.py +++ b/gateway/platforms/feishu.py @@ -156,6 +156,7 @@ _MARKDOWN_LINK_RE = re.compile(r"\[([^\]]+)\]\(([^)]+)\)") _MARKDOWN_FENCE_OPEN_RE = re.compile(r"^```([^\n`]*)\s*$") _MARKDOWN_FENCE_CLOSE_RE = re.compile(r"^```\s*$") _MENTION_RE = re.compile(r"@_user_\d+") +_OUTBOUND_MENTION_RE = re.compile(r"@ou_[a-zA-Z0-9]+") _MULTISPACE_RE = re.compile(r"[ \t]{2,}") _POST_CONTENT_INVALID_RE = re.compile(r"content format of the post type is incorrect", re.IGNORECASE) # --------------------------------------------------------------------------- @@ -506,11 +507,24 @@ def _coerce_required_int(value: Any, default: int, min_value: int = 0) -> int: def _build_markdown_post_payload(content: str) -> str: - rows = _build_markdown_post_rows(content) + # Split content by @ou_xxx mentions, then interleave at elements with plain text + parts: List[Any] = [] + last_end = 0 + for match in _OUTBOUND_MENTION_RE.finditer(content): + before = content[last_end : match.start()] + if before: + parts.append([{"tag": "md", "text": before}]) + user_id = match.group(0)[1:] # strip leading @ + parts.append([{"tag": "at", "user_id": user_id}]) + last_end = match.end() + if last_end < len(content): + parts.append([{"tag": "md", "text": content[last_end:]}]) + if not parts: + parts.append([{"tag": "md", "text": content}]) return json.dumps( { "zh_cn": { - "content": rows, + "content": parts, } }, ensure_ascii=False, @@ -3829,7 +3843,7 @@ class FeishuAdapter(BasePlatformAdapter): # ========================================================================= def _build_outbound_payload(self, content: str) -> tuple[str, str]: - if _MARKDOWN_HINT_RE.search(content): + if _MARKDOWN_HINT_RE.search(content) or _OUTBOUND_MENTION_RE.search(content): return "post", _build_markdown_post_payload(content) text_payload = {"text": content} return "text", json.dumps(text_payload, ensure_ascii=False)