fix(feishu): tolerate null multi_url and list fields in card extract
This commit is contained in:
@@ -269,7 +269,7 @@ def _extract_element_content(element: dict) -> list[str]:
|
||||
parts.append(text_content)
|
||||
elif isinstance(text, str):
|
||||
parts.append(text)
|
||||
for field in element.get("fields", []):
|
||||
for field in element.get("fields") or []:
|
||||
if isinstance(field, dict):
|
||||
field_text = field.get("text", {})
|
||||
if isinstance(field_text, dict):
|
||||
@@ -291,7 +291,10 @@ def _extract_element_content(element: dict) -> list[str]:
|
||||
c = text.get("content", "")
|
||||
if c:
|
||||
parts.append(c)
|
||||
url = element.get("url", "") or element.get("multi_url", {}).get("url", "")
|
||||
multi_url = element.get("multi_url") or {}
|
||||
url = element.get("url", "") or (
|
||||
multi_url.get("url", "") if isinstance(multi_url, dict) else ""
|
||||
)
|
||||
if url:
|
||||
parts.append(f"link: {url}")
|
||||
|
||||
@@ -300,12 +303,14 @@ def _extract_element_content(element: dict) -> list[str]:
|
||||
parts.append(alt.get("content", "[image]") if isinstance(alt, dict) else "[image]")
|
||||
|
||||
elif tag == "note":
|
||||
for ne in element.get("elements", []):
|
||||
for ne in element.get("elements") or []:
|
||||
parts.extend(_extract_element_content(ne))
|
||||
|
||||
elif tag == "column_set":
|
||||
for col in element.get("columns", []):
|
||||
for ce in col.get("elements", []):
|
||||
for col in element.get("columns") or []:
|
||||
if not isinstance(col, dict):
|
||||
continue
|
||||
for ce in col.get("elements") or []:
|
||||
parts.extend(_extract_element_content(ce))
|
||||
|
||||
elif tag == "plain_text":
|
||||
@@ -319,7 +324,7 @@ def _extract_element_content(element: dict) -> list[str]:
|
||||
for column in (element.get("columns") or [])
|
||||
if isinstance(column, dict) and column.get("name")
|
||||
]
|
||||
rows = element.get("rows", [])
|
||||
rows = element.get("rows") or []
|
||||
if columns:
|
||||
parts.append(" | ".join(header for _, header in columns))
|
||||
if isinstance(rows, list):
|
||||
@@ -337,7 +342,7 @@ def _extract_element_content(element: dict) -> list[str]:
|
||||
parts.append(row_text)
|
||||
|
||||
else:
|
||||
for ne in element.get("elements", []):
|
||||
for ne in element.get("elements") or []:
|
||||
parts.extend(_extract_element_content(ne))
|
||||
|
||||
return parts
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import json
|
||||
|
||||
from nanobot.channels.feishu.runtime import (
|
||||
_extract_element_content,
|
||||
_extract_post_content,
|
||||
_extract_share_card_content,
|
||||
)
|
||||
@@ -60,3 +61,28 @@ def test_extract_post_content_tolerates_null_fields() -> None:
|
||||
assert "@user" in text
|
||||
assert "ok" in text
|
||||
assert images == []
|
||||
|
||||
|
||||
def test_extract_button_tolerates_null_multi_url() -> None:
|
||||
element = {"tag": "button", "text": {"content": "Go"}, "multi_url": None}
|
||||
assert _extract_element_content(element) == ["Go"]
|
||||
|
||||
|
||||
def test_extract_column_set_tolerates_null_columns_and_elements() -> None:
|
||||
assert _extract_element_content({"tag": "column_set", "columns": None}) == []
|
||||
assert _extract_element_content(
|
||||
{"tag": "column_set", "columns": [{"elements": None}]}
|
||||
) == []
|
||||
|
||||
|
||||
def test_extract_div_tolerates_null_fields() -> None:
|
||||
assert _extract_element_content(
|
||||
{"tag": "div", "text": {"content": "hi"}, "fields": None}
|
||||
) == ["hi"]
|
||||
|
||||
|
||||
def test_interactive_card_button_null_multi_url() -> None:
|
||||
content = {
|
||||
"elements": [{"tag": "button", "text": {"content": "Go"}, "multi_url": None}]
|
||||
}
|
||||
assert _extract_share_card_content(content, "interactive") == "Go"
|
||||
|
||||
Reference in New Issue
Block a user