Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 26 additions & 35 deletions bot/vikingbot/channels/feishu.py
Original file line number Diff line number Diff line change
Expand Up @@ -535,52 +535,44 @@ async def send(self, msg: OutboundMessage) -> None:

content_with_mentions = cleaned_content

# Check if we need to reply to a specific message
# Get reply message ID from metadata (original incoming message ID)
# --- Build interactive card with markdown rendering ---
reply_to_message_id = None
original_sender_id = None
chat_type = "group"
if msg.metadata:
reply_to_message_id = msg.metadata.get("reply_to_message_id") or msg.metadata.get(
"message_id"
)

# Build post message content
content_elements = []

# Add @mention for the original sender when replying
original_sender_id = None
chat_type = "group"
if reply_to_message_id and msg.metadata:
original_sender_id = msg.metadata.get("sender_id")
chat_type = msg.metadata.get("chat_type", "group")

# Build content line: [@mention, text content]
content_line = []
# Build card elements using markdown for proper formatting
card_elements: list[dict] = []

# Add @mention element for original sender when replying (only in group chats)
if original_sender_id and chat_type == "group":
content_line.append({"tag": "at", "user_id": original_sender_id})
# @mention prefix only when replying in group chats
mention_prefix = ""
if reply_to_message_id and original_sender_id and chat_type == "group":
mention_prefix = f"<at id={original_sender_id}></at>"

# Add text content
if content_with_mentions.strip():
content_line.append({"tag": "text", "text": content_with_mentions})

# Add content line if not empty
if content_line:
content_elements.append(content_line)
md_content = (
f"{mention_prefix}\n{content_with_mentions}"
if mention_prefix
else content_with_mentions
)
card_elements.extend(self._build_card_elements(md_content))
elif mention_prefix:
card_elements.append({"tag": "markdown", "content": mention_prefix})

# Add images
for img in images:
content_elements.append([{"tag": "img", "image_key": img["image_key"]}])

# Ensure we have content
if not content_elements:
content_elements.append([{"tag": "text", "text": " "}])

post_content = {"zh_cn": {"title": "", "content": content_elements}}
card_elements.append({"tag": "img", "img_key": img["image_key"]})

import json
if not card_elements:
card_elements.append({"tag": "markdown", "content": " "})

content = json.dumps(post_content, ensure_ascii=False)
# Build interactive card message (no extra {"card": ...} wrapper)
card_content = json.dumps({"elements": card_elements}, ensure_ascii=False)

if reply_to_message_id:
# Reply to existing message (quotes the original)
Expand All @@ -598,9 +590,8 @@ async def send(self, msg: OutboundMessage) -> None:
.message_id(reply_to_message_id)
.request_body(
ReplyMessageRequestBody.builder()
.content(content)
.msg_type("post")
# Only reply in topic thread if it's actually a topic thread (not regular group)
.content(card_content)
.msg_type("interactive")
.reply_in_thread(should_reply_in_thread)
.build()
)
Expand All @@ -615,8 +606,8 @@ async def send(self, msg: OutboundMessage) -> None:
.request_body(
CreateMessageRequestBody.builder()
.receive_id(reply_to)
.msg_type("post")
.content(content)
.msg_type("interactive")
.content(card_content)
.build()
)
.build()
Expand Down
Loading