1414import hashlib
1515import os
1616import json
17+ import re
1718import random
1819import logging
20+ import asyncio
1921import httpx
2022from pathlib import Path
2123from typing import Optional , List , Dict , Any
@@ -203,7 +205,56 @@ def get_db_key_workflow():
203205
204206# 远程 API 配置
205207REMOTE_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
209260def get_wechat_internal_global_config (wx_dir : Path , file_name1 ) -> bytes :
@@ -221,41 +272,20 @@ def get_wechat_internal_global_config(wx_dir: Path, file_name1) -> bytes:
221272 return Path (target_path ).read_bytes ()
222273
223274
224- # def get_local_config_sha3_224() -> bytes:
225- # """
226- # 不要在意,抽象的实现 哈哈哈
227- # """
228- # content = json.dumps({
229- # "wxfile_dir": "C:\\Users\\17078\\xwechat_files",
230- # "weixin_id_folder": "wxid_lnyf4hdo9csb12_f1c4",
231- # "cache_dir": "C:\\Users\\17078\\Desktop\\wxDBHook\\test\\wx-dat\\wx-dat\\.cache",
232- # "db_key": "",
233- # "port": 8001
234- # }, indent=4).encode("utf-8")
235- #
236- # # 计算 SHA3-224
237- # digest = hashlib.sha3_224(content).digest()
238- # return digest
239-
240- # async def log_request(request):
241- # print(f"--- Request Raw ---")
242- # print(f"{request.method} {request.url} {request.extensions.get('http_version', b'HTTP/1.1').decode()}")
243- # for name, value in request.headers.items():
244- # print(f"{name}: {value}")
245- #
246- # print()
247- #
248- # body = request.read()
249- # if body:
250- # print(body.decode(errors='replace'))
251- # print(f"-------------------\n")
252-
253275
254276async def fetch_and_save_remote_keys (account : Optional [str ] = None ) -> Dict [str , Any ]:
255277 account_dir = _resolve_account_dir (account )
256278 wx_id_dir = _resolve_account_wxid_dir (account_dir )
257279 wxid = wx_id_dir .name
258280
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+
259289 logger .info (f"正在为账号 { wxid } 获取密钥..." )
260290
261291 try :
@@ -274,7 +304,7 @@ async def fetch_and_save_remote_keys(account: Optional[str] = None) -> Dict[str,
274304
275305 headers = {
276306 "Accept" : "text/x-component" ,
277- "Next-Action" : NEXT_ACTION_ID ,
307+ "Next-Action" : next_action_id ,
278308 "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" ,
279309 "Origin" : "https://view.free.c3o.re" ,
280310 "Referer" : "https://view.free.c3o.re/dashboard" ,
0 commit comments