Skip to content

Commit b80b176

Browse files
committed
fix(chat): 补充视频号消息 objectId 和 objectNonceId 字段透传
补充 Finder/视频号类型 app message 的 objectId、objectNonceId 解析 在聊天消息接口、搜索结果和导出链路中透传上述字段 前端消息归一化增加 objectId、objectNonceId 字段 新增对应测试,覆盖 type=51 场景
1 parent acd895b commit b80b176

5 files changed

Lines changed: 74 additions & 0 deletions

File tree

frontend/lib/chat/message-normalizer.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,8 @@ export const createMessageNormalizer = ({ apiBase, getSelectedAccount, getSelect
227227
_quoteThumbError: false,
228228
amount: msg.amount || '',
229229
coverUrl: msg.coverUrl || '',
230+
objectId: String(msg.objectId || '').trim(),
231+
objectNonceId: String(msg.objectNonceId || '').trim(),
230232
fileSize: msg.fileSize || '',
231233
fileMd5: msg.fileMd5 || '',
232234
paySubType: msg.paySubType || '',

src/wechat_decrypt_tool/chat_export_service.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3435,6 +3435,8 @@ def _parse_message_for_export(
34353435
quote_voice_length = ""
34363436
quote_title = ""
34373437
quote_content = ""
3438+
object_id = ""
3439+
object_nonce_id = ""
34383440
amount = ""
34393441
cover_url = ""
34403442
file_size = ""
@@ -3472,6 +3474,8 @@ def system_display_name_resolver(username: str, fallback_display_name: str) -> s
34723474
from_username = str(parsed.get("fromUsername") or "")
34733475
link_type = str(parsed.get("linkType") or "")
34743476
link_style = str(parsed.get("linkStyle") or "")
3477+
object_id = str(parsed.get("objectId") or "")
3478+
object_nonce_id = str(parsed.get("objectNonceId") or "")
34753479
record_item = str(parsed.get("recordItem") or "")
34763480
quote_username = str(parsed.get("quoteUsername") or "")
34773481
quote_server_id = str(parsed.get("quoteServerId") or "")
@@ -3699,6 +3703,8 @@ def add_url_or_id(v: Any) -> None:
36993703
from_username = str(parsed.get("fromUsername") or from_username)
37003704
link_type = str(parsed.get("linkType") or link_type)
37013705
link_style = str(parsed.get("linkStyle") or link_style)
3706+
object_id = str(parsed.get("objectId") or object_id)
3707+
object_nonce_id = str(parsed.get("objectNonceId") or object_nonce_id)
37023708
record_item = str(parsed.get("recordItem") or record_item)
37033709
quote_username = str(parsed.get("quoteUsername") or quote_username)
37043710
quote_server_id = str(parsed.get("quoteServerId") or quote_server_id)
@@ -3765,6 +3771,8 @@ def add_url_or_id(v: Any) -> None:
37653771
"fromUsername": from_username,
37663772
"linkType": link_type,
37673773
"linkStyle": link_style,
3774+
"objectId": object_id,
3775+
"objectNonceId": object_nonce_id,
37683776
"recordItem": record_item,
37693777
"thumbUrl": thumb_url,
37703778
"imageMd5": image_md5,

src/wechat_decrypt_tool/chat_helpers.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,6 +1238,14 @@ def _extract_appmsg_type(xml_text: str) -> int:
12381238
or (_extract_xml_tag_text(finder_feed, "username") if finder_feed else "")
12391239
or (_extract_xml_tag_text(finder_feed, "finderusername") if finder_feed else "")
12401240
)
1241+
object_id = (
1242+
(_extract_xml_tag_or_attr(finder_feed, "objectid") if finder_feed else "")
1243+
or _extract_xml_tag_or_attr(text, "objectid")
1244+
)
1245+
object_nonce_id = (
1246+
(_extract_xml_tag_or_attr(finder_feed, "objectnonceid") if finder_feed else "")
1247+
or _extract_xml_tag_or_attr(text, "objectnonceid")
1248+
)
12411249

12421250
thumb_url = _normalize_xml_url(
12431251
_extract_xml_tag_or_attr(text, "thumburl")
@@ -1277,6 +1285,8 @@ def _extract_appmsg_type(xml_text: str) -> int:
12771285
"fromUsername": from_u,
12781286
"linkType": "finder",
12791287
"linkStyle": "finder",
1288+
"objectId": str(object_id or "").strip(),
1289+
"objectNonceId": str(object_nonce_id or "").strip(),
12801290
}
12811291

12821292
if app_type in (33, 36):
@@ -2418,6 +2428,8 @@ def _row_to_search_hit(
24182428
quote_thumb_url = ""
24192429
link_type = ""
24202430
link_style = ""
2431+
object_id = ""
2432+
object_nonce_id = ""
24212433
amount = ""
24222434
pay_sub_type = ""
24232435
transfer_status = ""
@@ -2441,6 +2453,8 @@ def _row_to_search_hit(
24412453
quote_thumb_url = str(parsed.get("quoteThumbUrl") or "")
24422454
link_type = str(parsed.get("linkType") or "")
24432455
link_style = str(parsed.get("linkStyle") or "")
2456+
object_id = str(parsed.get("objectId") or "")
2457+
object_nonce_id = str(parsed.get("objectNonceId") or "")
24442458
quote_username = str(parsed.get("quoteUsername") or "")
24452459
amount = str(parsed.get("amount") or "")
24462460
pay_sub_type = str(parsed.get("paySubType") or "")
@@ -2526,6 +2540,8 @@ def _row_to_search_hit(
25262540
quote_thumb_url = str(parsed.get("quoteThumbUrl") or quote_thumb_url)
25272541
link_type = str(parsed.get("linkType") or link_type)
25282542
link_style = str(parsed.get("linkStyle") or link_style)
2543+
object_id = str(parsed.get("objectId") or object_id)
2544+
object_nonce_id = str(parsed.get("objectNonceId") or object_nonce_id)
25292545
amount = str(parsed.get("amount") or amount)
25302546
pay_sub_type = str(parsed.get("paySubType") or pay_sub_type)
25312547
quote_username = str(parsed.get("quoteUsername") or quote_username)
@@ -2567,6 +2583,8 @@ def _row_to_search_hit(
25672583
"url": url,
25682584
"linkType": link_type,
25692585
"linkStyle": link_style,
2586+
"objectId": object_id,
2587+
"objectNonceId": object_nonce_id,
25702588
"quoteUsername": quote_username,
25712589
"quoteTitle": quote_title,
25722590
"quoteContent": quote_content,

src/wechat_decrypt_tool/routers/chat.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3049,6 +3049,8 @@ def _append_full_messages_from_rows(
30493049
quote_thumb_url = ""
30503050
link_type = ""
30513051
link_style = ""
3052+
object_id = ""
3053+
object_nonce_id = ""
30523054
quote_server_id = ""
30533055
quote_type = ""
30543056
quote_voice_length = ""
@@ -3082,6 +3084,8 @@ def _append_full_messages_from_rows(
30823084
quote_thumb_url = str(parsed.get("quoteThumbUrl") or "")
30833085
link_type = str(parsed.get("linkType") or "")
30843086
link_style = str(parsed.get("linkStyle") or "")
3087+
object_id = str(parsed.get("objectId") or "")
3088+
object_nonce_id = str(parsed.get("objectNonceId") or "")
30853089
quote_username = str(parsed.get("quoteUsername") or "")
30863090
quote_server_id = str(parsed.get("quoteServerId") or "")
30873091
quote_type = str(parsed.get("quoteType") or "")
@@ -3324,6 +3328,8 @@ def _append_full_messages_from_rows(
33243328
quote_thumb_url = str(parsed.get("quoteThumbUrl") or quote_thumb_url)
33253329
link_type = str(parsed.get("linkType") or link_type)
33263330
link_style = str(parsed.get("linkStyle") or link_style)
3331+
object_id = str(parsed.get("objectId") or object_id)
3332+
object_nonce_id = str(parsed.get("objectNonceId") or object_nonce_id)
33273333
amount = str(parsed.get("amount") or amount)
33283334
cover_url = str(parsed.get("coverUrl") or cover_url)
33293335
thumb_url = str(parsed.get("thumbUrl") or thumb_url)
@@ -3382,6 +3388,8 @@ def _append_full_messages_from_rows(
33823388
"url": url,
33833389
"linkType": link_type,
33843390
"linkStyle": link_style,
3391+
"objectId": object_id,
3392+
"objectNonceId": object_nonce_id,
33853393
"from": from_name,
33863394
"fromUsername": from_username,
33873395
"recordItem": record_item,
@@ -4584,6 +4592,8 @@ def _collect_chat_messages(
45844592
quote_thumb_url = ""
45854593
link_type = ""
45864594
link_style = ""
4595+
object_id = ""
4596+
object_nonce_id = ""
45874597
quote_server_id = ""
45884598
quote_type = ""
45894599
quote_voice_length = ""
@@ -4617,6 +4627,8 @@ def _collect_chat_messages(
46174627
quote_thumb_url = str(parsed.get("quoteThumbUrl") or "")
46184628
link_type = str(parsed.get("linkType") or "")
46194629
link_style = str(parsed.get("linkStyle") or "")
4630+
object_id = str(parsed.get("objectId") or "")
4631+
object_nonce_id = str(parsed.get("objectNonceId") or "")
46204632
quote_username = str(parsed.get("quoteUsername") or "")
46214633
quote_server_id = str(parsed.get("quoteServerId") or "")
46224634
quote_type = str(parsed.get("quoteType") or "")
@@ -4838,6 +4850,8 @@ def _collect_chat_messages(
48384850
quote_thumb_url = str(parsed.get("quoteThumbUrl") or quote_thumb_url)
48394851
link_type = str(parsed.get("linkType") or link_type)
48404852
link_style = str(parsed.get("linkStyle") or link_style)
4853+
object_id = str(parsed.get("objectId") or object_id)
4854+
object_nonce_id = str(parsed.get("objectNonceId") or object_nonce_id)
48414855
amount = str(parsed.get("amount") or amount)
48424856
cover_url = str(parsed.get("coverUrl") or cover_url)
48434857
thumb_url = str(parsed.get("thumbUrl") or thumb_url)
@@ -4901,6 +4915,8 @@ def _collect_chat_messages(
49014915
"url": url,
49024916
"linkType": link_type,
49034917
"linkStyle": link_style,
4918+
"objectId": object_id,
4919+
"objectNonceId": object_nonce_id,
49044920
"from": from_name,
49054921
"fromUsername": from_username,
49064922
"recordItem": record_item,
@@ -5502,6 +5518,8 @@ def pick(*keys: str) -> Any:
55025518
quote_thumb_url = ""
55035519
link_type = ""
55045520
link_style = ""
5521+
object_id = ""
5522+
object_nonce_id = ""
55055523
quote_server_id = ""
55065524
quote_type = ""
55075525
quote_voice_length = ""
@@ -5531,6 +5549,8 @@ def pick(*keys: str) -> Any:
55315549
quote_thumb_url = str(parsed.get("quoteThumbUrl") or "")
55325550
link_type = str(parsed.get("linkType") or "")
55335551
link_style = str(parsed.get("linkStyle") or "")
5552+
object_id = str(parsed.get("objectId") or "")
5553+
object_nonce_id = str(parsed.get("objectNonceId") or "")
55345554
quote_username = str(parsed.get("quoteUsername") or "")
55355555
quote_server_id = str(parsed.get("quoteServerId") or "")
55365556
quote_type = str(parsed.get("quoteType") or "")
@@ -5736,6 +5756,8 @@ def pick(*keys: str) -> Any:
57365756
quote_thumb_url = str(parsed.get("quoteThumbUrl") or quote_thumb_url)
57375757
link_type = str(parsed.get("linkType") or link_type)
57385758
link_style = str(parsed.get("linkStyle") or link_style)
5759+
object_id = str(parsed.get("objectId") or object_id)
5760+
object_nonce_id = str(parsed.get("objectNonceId") or object_nonce_id)
57395761
amount = str(parsed.get("amount") or amount)
57405762
cover_url = str(parsed.get("coverUrl") or cover_url)
57415763
thumb_url = str(parsed.get("thumbUrl") or thumb_url)
@@ -5788,6 +5810,8 @@ def pick(*keys: str) -> Any:
57885810
"url": url,
57895811
"linkType": link_type,
57905812
"linkStyle": link_style,
5813+
"objectId": object_id,
5814+
"objectNonceId": object_nonce_id,
57915815
"from": from_name,
57925816
"fromUsername": from_username,
57935817
"recordItem": record_item,
@@ -7796,6 +7820,8 @@ async def resolve_app_message(
77967820
"fromUsername": str(parsed.get("fromUsername") or "").strip(),
77977821
"linkType": str(parsed.get("linkType") or "").strip(),
77987822
"linkStyle": str(parsed.get("linkStyle") or "").strip(),
7823+
"objectId": str(parsed.get("objectId") or "").strip(),
7824+
"objectNonceId": str(parsed.get("objectNonceId") or "").strip(),
77997825
"size": str(parsed.get("size") or "").strip(),
78007826
"baseUrl": base_url,
78017827
}

tests/test_parse_app_message.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,26 @@ def test_finder_type_51_uses_nested_desc_and_cover(self):
148148
self.assertEqual(parsed.get("thumbUrl"), "https://finder.video.qq.com/cover.jpg")
149149
self.assertEqual(parsed.get("url"), "https://channels.weixin.qq.com/web/pages/feed?feedid=abc")
150150

151+
def test_finder_type_51_exposes_object_fields(self):
152+
raw_text = (
153+
'<msg><appmsg appid="" sdkver="0">'
154+
'<title>当前版本不支持展示该内容,请升级至最新版本。</title>'
155+
'<des></des>'
156+
'<type>51</type>'
157+
'<finderFeed>'
158+
'<nickname><![CDATA[央视新闻]]></nickname>'
159+
'<objectId><![CDATA[1234567890]]></objectId>'
160+
'<objectNonceId><![CDATA[nonce-abc]]></objectNonceId>'
161+
'</finderFeed>'
162+
'</appmsg></msg>'
163+
)
164+
165+
parsed = _parse_app_message(raw_text)
166+
167+
self.assertEqual(parsed.get("linkType"), "finder")
168+
self.assertEqual(parsed.get("objectId"), "1234567890")
169+
self.assertEqual(parsed.get("objectNonceId"), "nonce-abc")
170+
151171
def test_quote_type_5_nested_xml_refermsg_uses_inner_title(self):
152172
raw_text = (
153173
'<msg><appmsg appid="" sdkver="0">'

0 commit comments

Comments
 (0)