From 61d20c1d0a46aa504815ebe29610f426f2fce8f9 Mon Sep 17 00:00:00 2001 From: Kyrie Date: Thu, 14 May 2026 13:44:55 +0800 Subject: [PATCH] feat: extract URL from link messages and favorites Add extract_appmsg_url to parse url and link tags from XML. Link messages now include url field when available. Article favorites now include url field from favitem XML. --- src/daemon/query.rs | 57 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/src/daemon/query.rs b/src/daemon/query.rs index 18cf28e..1e8f333 100644 --- a/src/daemon/query.rs +++ b/src/daemon/query.rs @@ -520,15 +520,22 @@ fn query_messages( let content = decompress_message(&content_bytes, ct); let sender = sender_label(real_sender_id, &content, is_group, chat_username, &id2u, names_map); let text = fmt_content(local_id, local_type, &content, is_group); - - result.push(json!({ + let mut msg = json!({ "timestamp": ts, "time": fmt_time(ts, "%Y-%m-%d %H:%M"), "sender": sender, "content": text, "type": fmt_type(local_type), "local_id": local_id, - })); + }); + // 对链接消息提取 URL + let base_type = (local_type as u64 & 0xFFFFFFFF) as i64; + if base_type == 49 && content.contains(" Option { } } +/// 从 appmsg XML 或 favitem XML 中提取链接 URL。 +/// 适用于聊天消息中的链接(appmsg type=5)和收藏文章(favitem type=5)。 +fn extract_appmsg_url(text: &str) -> Option { + // 优先提取 标签(聊天消息中的 appmsg) + if let Some(url) = extract_xml_text(text, "url") { + if !url.is_empty() { + return Some(url); + } + } + // 收藏文章使用 标签(favitem XML) + if let Some(link) = extract_xml_text(text, "link") { + if !link.is_empty() { + return Some(link); + } + } + None +} + fn extract_xml_text(xml: &str, tag: &str) -> Option { let open = format!("<{}>", tag); let close = format!("", tag); @@ -1330,7 +1363,13 @@ pub async fn q_favorites( }; // WeChat 部分版本的 update_time 为毫秒,10位以上判定为毫秒后转秒 let ts_secs = if ts > 9_999_999_999 { ts / 1000 } else { ts }; - json!({ + // 对文章类型收藏提取 URL(favitem XML 使用 标签) + let fav_url = if ftype == 5 { + extract_appmsg_url(&content) + } else { + None + }; + let mut item = json!({ "id": local_id, "type": type_str, "type_num": ftype, @@ -1339,7 +1378,11 @@ pub async fn q_favorites( "preview": preview, "from": fromusr, "chat": chatname, - }) + }); + if let Some(url) = fav_url { + item["url"] = json!(url); + } + item }) .collect();