fix(feishu): support reading WebSocket rendered card content
Feishu cards arriving via WebSocket have a different structure than expected: elements are nested lists with tag:text/text fields instead of flat lists with tag:markdown/content. Also extract user_dsl for richer card data and support body.elements (schema 2.0).
This commit is contained in:
@@ -108,6 +108,18 @@ def _extract_interactive_content(content: dict) -> list[str]:
|
||||
if not isinstance(content, dict):
|
||||
return parts
|
||||
|
||||
# user_dsl: original card definition (richest source for rendered cards)
|
||||
user_dsl = content.get("user_dsl")
|
||||
if isinstance(user_dsl, str) and user_dsl.strip():
|
||||
try:
|
||||
dsl = json.loads(user_dsl)
|
||||
if isinstance(dsl, dict):
|
||||
parts.extend(_extract_interactive_content(dsl))
|
||||
if parts:
|
||||
return parts
|
||||
except (json.JSONDecodeError, TypeError):
|
||||
pass
|
||||
|
||||
if "title" in content:
|
||||
title = content["title"]
|
||||
if isinstance(title, dict):
|
||||
@@ -117,11 +129,27 @@ def _extract_interactive_content(content: dict) -> list[str]:
|
||||
elif isinstance(title, str):
|
||||
parts.append(f"title: {title}")
|
||||
|
||||
for elements in (
|
||||
content.get("elements", []) if isinstance(content.get("elements"), list) else []
|
||||
):
|
||||
for element in elements:
|
||||
parts.extend(_extract_element_content(element))
|
||||
# Top-level elements: flat list or nested list format
|
||||
elements = content.get("elements")
|
||||
if isinstance(elements, list):
|
||||
if elements and isinstance(elements[0], list):
|
||||
# Nested list: [[{tag:"text",text:"..."}], ...]
|
||||
for row in elements:
|
||||
if isinstance(row, list):
|
||||
for element in row:
|
||||
parts.extend(_extract_element_content(element))
|
||||
else:
|
||||
# Flat list: [{tag:"markdown",content:"..."}, ...]
|
||||
for element in elements:
|
||||
parts.extend(_extract_element_content(element))
|
||||
|
||||
# Body elements (schema 2.0)
|
||||
body = content.get("body", {})
|
||||
if isinstance(body, dict):
|
||||
body_elements = body.get("elements")
|
||||
if isinstance(body_elements, list):
|
||||
for element in body_elements:
|
||||
parts.extend(_extract_element_content(element))
|
||||
|
||||
card = content.get("card", {})
|
||||
if card:
|
||||
@@ -152,6 +180,11 @@ def _extract_element_content(element: dict) -> list[str]:
|
||||
if content:
|
||||
parts.append(content)
|
||||
|
||||
elif tag == "text":
|
||||
text = element.get("text", "")
|
||||
if isinstance(text, str) and text.strip():
|
||||
parts.append(text)
|
||||
|
||||
elif tag == "div":
|
||||
text = element.get("text", {})
|
||||
if isinstance(text, dict):
|
||||
|
||||
Reference in New Issue
Block a user