Skip to content

Commit 1df1b76

Browse files
committed
fix: fix the request error when next_action_id changed
1 parent b6cd2d7 commit 1df1b76

1 file changed

Lines changed: 61 additions & 2 deletions

File tree

src/wechat_decrypt_tool/key_service.py

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@
1414
import hashlib
1515
import os
1616
import json
17+
import re
1718
import random
1819
import logging
20+
import asyncio
1921
import httpx
2022
from pathlib import Path
2123
from typing import Optional, List, Dict, Any
@@ -203,7 +205,56 @@ def get_db_key_workflow():
203205

204206
# 远程 API 配置
205207
REMOTE_URL = "https://view.free.c3o.re/dashboard"
206-
NEXT_ACTION_ID = "7c8f99280c70626ccf5960cc4a68f368197e15f8e9"
208+
BASE_URL = "https://view.free.c3o.re" # 用于拼接js
209+
210+
# NEXT_ACTION_ID = "7c8f99280c70626ccf5960cc4a68f368197e15f8e9" # 不可以硬编码
211+
212+
213+
async def fetch_js_and_scan(client: httpx.AsyncClient, js_path: str) -> Optional[str]:
214+
"""
215+
异步下载单个 JS 文件并匹配 Action ID
216+
"""
217+
full_url = f"{BASE_URL}{js_path}" if js_path.startswith("/") else js_path
218+
try:
219+
response = await client.get(full_url)
220+
if response.status_code != 200:
221+
return None
222+
223+
content = response.text
224+
225+
action_id_pattern = re.compile(r'createServerReference.*?["\']([a-f0-9]{42})["\'].*?["\']getUserConfigFromBytes["\']')
226+
227+
match = action_id_pattern.search(content)
228+
if match:
229+
found_id = match.group(1)
230+
return found_id
231+
232+
except Exception as e:
233+
logger.error(f"Error fetching {js_path}: {e}")
234+
return None
235+
236+
237+
async def _get_next_action_id_async() -> str:
238+
async with httpx.AsyncClient(timeout=10.0) as client:
239+
240+
resp = await client.get(REMOTE_URL)
241+
html = resp.text
242+
243+
js_file_pattern = re.compile(r'src="(/_next/static/chunks/[^"]+\.js)"')
244+
js_files = set(js_file_pattern.findall(html))
245+
246+
if not js_files:
247+
raise Exception("未找到任何 Next.js chunk 文件,可能页面结构已变动。")
248+
249+
tasks = [fetch_js_and_scan(client, js_path) for js_path in js_files]
250+
251+
results = await asyncio.gather(*tasks)
252+
253+
for res in results:
254+
if res:
255+
return res
256+
257+
raise Exception("遍历了所有 JS 文件,但未找到匹配的 createServerReference ID。")
207258

208259

209260
def get_wechat_internal_global_config(wx_dir: Path, file_name1) -> bytes:
@@ -227,6 +278,14 @@ async def fetch_and_save_remote_keys(account: Optional[str] = None) -> Dict[str,
227278
wx_id_dir = _resolve_account_wxid_dir(account_dir)
228279
wxid = wx_id_dir.name
229280

281+
logger.info("尝试获取next_action_id")
282+
try:
283+
next_action_id = await _get_next_action_id_async()
284+
logger.info(f"获取next_action_id成功: {next_action_id}")
285+
except Exception as e:
286+
raise RuntimeError(f"获取next_action_id失败:{e}")
287+
288+
230289
logger.info(f"正在为账号 {wxid} 获取密钥...")
231290

232291
try:
@@ -245,7 +304,7 @@ async def fetch_and_save_remote_keys(account: Optional[str] = None) -> Dict[str,
245304

246305
headers = {
247306
"Accept": "text/x-component",
248-
"Next-Action": NEXT_ACTION_ID,
307+
"Next-Action": next_action_id,
249308
"Next-Router-State-Tree": "%5B%22%22%2C%7B%22children%22%3A%5B%22dashboard%22%2C%7B%22children%22%3A%5B%22__PAGE__%22%2C%7B%7D%2Cnull%2Cnull%5D%7D%2Cnull%2Cnull%5D%7D%2Cnull%2Cnull%2Ctrue%5D",
250309
"Origin": "https://view.free.c3o.re",
251310
"Referer": "https://view.free.c3o.re/dashboard",

0 commit comments

Comments
 (0)