from __future__ import annotations import asyncio import hashlib import json from urllib.parse import quote from ...providers.response import JsonMixin from ...requests import Tab API_PATH = "/v4/api/chat/msg" class CallbackResults(JsonMixin): def __init__(self): self.token: str = None self.path_and_query: str = None self.timestamp: int = None def hash_function(base_string: str) -> str: """ Mimics the hashFunction using MD5. """ return hashlib.md5(base_string.encode()).hexdigest() def generate_yy_header(has_search_params_path: str, body_to_yy: dict, time: int) -> str: """ Python equivalent of the generateYYHeader function. """ # print("Encoded Path:", quote(has_search_params_path, "")) # print("Stringified Body:", s) # print("Hashed Time:", hash_function(str(time))) encoded_path = quote(has_search_params_path, "") time_hash = hash_function(str(time)) combined_string = f"{encoded_path}_{body_to_yy}{time_hash}ooui" # print("Combined String:", combined_string) # print("Hashed Combined String:", hash_function(combined_string)) return hash_function(combined_string) def get_body_to_yy(l): L = l["msgContent"].replace("\r\n", "").replace("\n", "").replace("\r", "") M = hash_function(l["characterID"]) + hash_function(L) + hash_function(l["chatID"]) M += hash_function("") # Mimics hashFunction(undefined) in JS # print("bodyToYY:", M) return M def get_body_json(s): return json.dumps(s, ensure_ascii=True, sort_keys=True) async def get_browser_callback(auth_result: CallbackResults): async def callback(page: Tab): while not auth_result.token: auth_result.token = await page.evaluate("localStorage.getItem('_token')") if not auth_result.token: await asyncio.sleep(1) (auth_result.path_and_query, auth_result.timestamp) = await page.evaluate(""" const device_id = localStorage.getItem("USER_HARD_WARE_INFO"); const uuid = localStorage.getItem("UNIQUE_USER_ID"); const os_name = navigator.userAgentData?.platform || navigator.platform || "Unknown"; const browser_name = (() => { const userAgent = navigator.userAgent.toLowerCase(); if (userAgent.includes("chrome") && !userAgent.includes("edg")) return "chrome"; if (userAgent.includes("edg")) return "edge"; if (userAgent.includes("firefox")) return "firefox"; if (userAgent.includes("safari") && !userAgent.includes("chrome")) return "safari"; return "unknown"; })(); const cpu_core_num = navigator.hardwareConcurrency || 8; const browser_language = navigator.language || "unknown"; const browser_platform = `${navigator.platform || "unknown"}`; const screen_width = window.screen.width || "unknown"; const screen_height = window.screen.height || "unknown"; const unix = Date.now(); // Current Unix timestamp in milliseconds const params = { device_platform: "web", biz_id: 2, app_id: 3001, version_code: 22201, lang: "en", uuid, device_id, os_name, browser_name, cpu_core_num, browser_language, browser_platform, screen_width, screen_height, unix }; [new URLSearchParams(params).toString(), unix] """) auth_result.path_and_query = f"{API_PATH}?{auth_result.path_and_query}" return callback