opt(channel): lark channel parse_post_content opt

This commit is contained in:
FISHers6 2026-02-17 09:30:17 +08:00 committed by Chummy
parent b322960899
commit 0e498f2702

View file

@ -417,9 +417,15 @@ impl LarkChannel {
Ok(v) => v, Ok(v) => v,
Err(_) => continue, Err(_) => continue,
}; };
v.get("text").and_then(|t| t.as_str()).unwrap_or("").to_string() match v.get("text").and_then(|t| t.as_str()).filter(|s| !s.is_empty()) {
Some(t) => t.to_string(),
None => continue,
} }
"post" => parse_post_content(&lark_msg.content), }
"post" => match parse_post_content(&lark_msg.content) {
Some(t) => t,
None => continue,
},
_ => { tracing::debug!("Lark WS: skipping unsupported type '{}'", lark_msg.message_type); continue; } _ => { tracing::debug!("Lark WS: skipping unsupported type '{}'", lark_msg.message_type); continue; }
}; };
@ -542,31 +548,41 @@ impl LarkChannel {
return messages; return messages;
} }
// Extract message content (text only) // Extract message content (text and post supported)
let msg_type = event let msg_type = event
.pointer("/message/message_type") .pointer("/message/message_type")
.and_then(|t| t.as_str()) .and_then(|t| t.as_str())
.unwrap_or(""); .unwrap_or("");
if msg_type != "text" {
tracing::debug!("Lark: skipping non-text message type: {msg_type}");
return messages;
}
let content_str = event let content_str = event
.pointer("/message/content") .pointer("/message/content")
.and_then(|c| c.as_str()) .and_then(|c| c.as_str())
.unwrap_or(""); .unwrap_or("");
// content is a JSON string like "{\"text\":\"hello\"}" let text: String = match msg_type {
let text = serde_json::from_str::<serde_json::Value>(content_str) "text" => {
let extracted = serde_json::from_str::<serde_json::Value>(content_str)
.ok() .ok()
.and_then(|v| v.get("text").and_then(|t| t.as_str()).map(String::from)) .and_then(|v| {
.unwrap_or_default(); v.get("text")
.and_then(|t| t.as_str())
if text.is_empty() { .filter(|s| !s.is_empty())
.map(String::from)
});
match extracted {
Some(t) => t,
None => return messages,
}
}
"post" => match parse_post_content(content_str) {
Some(t) => t,
None => return messages,
},
_ => {
tracing::debug!("Lark: skipping unsupported message type: {msg_type}");
return messages; return messages;
} }
};
let timestamp = event let timestamp = event
.pointer("/message/create_time") .pointer("/message/create_time")
@ -751,10 +767,12 @@ impl LarkChannel {
// ───────────────────────────────────────────────────────────────────────────── // ─────────────────────────────────────────────────────────────────────────────
/// Flatten a Feishu `post` rich-text message to plain text. /// Flatten a Feishu `post` rich-text message to plain text.
fn parse_post_content(content: &str) -> String { ///
let Ok(parsed) = serde_json::from_str::<serde_json::Value>(content) else { /// Returns `None` when the content cannot be parsed or yields no usable text,
return "[富文本消息]".to_string(); /// so callers can simply `continue` rather than forwarding a meaningless
}; /// placeholder string to the agent.
fn parse_post_content(content: &str) -> Option<String> {
let parsed = serde_json::from_str::<serde_json::Value>(content).ok()?;
let locale = parsed let locale = parsed
.get("zh_cn") .get("zh_cn")
.or_else(|| parsed.get("en_us")) .or_else(|| parsed.get("en_us"))
@ -762,11 +780,19 @@ fn parse_post_content(content: &str) -> String {
parsed parsed
.as_object() .as_object()
.and_then(|m| m.values().find(|v| v.is_object())) .and_then(|m| m.values().find(|v| v.is_object()))
}); })?;
let Some(locale) = locale else {
return "[富文本消息]".to_string();
};
let mut text = String::new(); let mut text = String::new();
if let Some(title) = locale
.get("title")
.and_then(|t| t.as_str())
.filter(|s| !s.is_empty())
{
text.push_str(title);
text.push_str("\n\n");
}
if let Some(paragraphs) = locale.get("content").and_then(|c| c.as_array()) { if let Some(paragraphs) = locale.get("content").and_then(|c| c.as_array()) {
for para in paragraphs { for para in paragraphs {
if let Some(elements) = para.as_array() { if let Some(elements) = para.as_array() {
@ -795,9 +821,6 @@ fn parse_post_content(content: &str) -> String {
text.push('@'); text.push('@');
text.push_str(n); text.push_str(n);
} }
"img" => {
text.push_str("[图片]");
}
_ => {} _ => {}
} }
} }
@ -805,11 +828,12 @@ fn parse_post_content(content: &str) -> String {
} }
} }
} }
let result = text.trim().to_string(); let result = text.trim().to_string();
if result.is_empty() { if result.is_empty() {
"[富文本消息]".to_string() None
} else { } else {
result Some(result)
} }
} }