"""浏览器 / IM 伪装设备头(User-Agent)预设。 a_bogus 签名、Playwright 浏览器上下文、IM HTTP 请求头、Protobuf body 必须使用同一 UA, 否则抖音会返回 7911 安全校验失败。 """ from rpa_engine.douyin_im.dy_util import DEFAULT_USER_AGENT # id 用于前端下拉;user_agent 为完整字符串 DEVICE_PROFILES: list[dict[str, str]] = [ { "id": "chrome_win120", "label": "Chrome 120 · Windows(默认,推荐)", "platform": "Windows", "user_agent": DEFAULT_USER_AGENT, }, { "id": "chrome_win131", "label": "Chrome 131 · Windows", "platform": "Windows", "user_agent": ( "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " "(KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36" ), }, { "id": "edge_win125", "label": "Edge 125 · Windows", "platform": "Windows", "user_agent": ( "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 " "(KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0" ), }, { "id": "firefox_win117", "label": "Firefox 117 · Windows", "platform": "Windows", "user_agent": ( "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) " "Gecko/20100101 Firefox/117.0" ), }, { "id": "chrome_mac120", "label": "Chrome 120 · macOS", "platform": "macOS", "user_agent": ( "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 " "(KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" ), }, { "id": "safari_mac17", "label": "Safari 17 · macOS", "platform": "macOS", "user_agent": ( "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 " "(KHTML, like Gecko) Version/17.0 Safari/605.1.15" ), }, ] _PROFILE_BY_UA = {p["user_agent"]: p for p in DEVICE_PROFILES} def list_device_profiles() -> list[dict[str, str]]: return [ {"id": p["id"], "label": p["label"], "platform": p["platform"], "user_agent": p["user_agent"]} for p in DEVICE_PROFILES ] def resolve_user_agent(stored: str | None) -> str: """账号保存的 UA;空则使用默认 Chrome 120。""" text = (stored or "").strip() return text or DEFAULT_USER_AGENT def profile_label_for_ua(ua: str | None) -> str: text = (ua or "").strip() if not text: return "Chrome 120 · Windows(默认)" hit = _PROFILE_BY_UA.get(text) if hit: return hit["label"] if len(text) > 48: return text[:48] + "…" return text