"""只读诊断:逐个检查自动回复链路上的每个闸门,不点击、不发送、不滚动列表。""" import os import sys import time sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import win32gui import wechat_bot as bot_module def show(label, value): print(f"{label:<34}: {value}") def main(): bot = bot_module.WeChatBot() bot.safe_window_mode = True # 不抢前台,纯读。 bot.auto_activate_window = False print("=" * 70) print("1) 配置") print("=" * 70) from ai_config import ( AI_ENABLED, AI_USE_VISION, AI_PROVIDER_TYPE, AI_API_BASE, AI_MODEL, ) show("AI_ENABLED", AI_ENABLED) show("AI_USE_VISION", AI_USE_VISION) show("AI_PROVIDER_TYPE", AI_PROVIDER_TYPE) show("AI_API_BASE", AI_API_BASE) show("AI_MODEL", AI_MODEL) show("mouse_idle_enabled", bot.mouse_idle_enabled) show("mouse_idle_seconds", bot.mouse_idle_seconds) show("message_batch_window_seconds", bot.message_batch_window_seconds) print() print("=" * 70) print("2) 窗口") print("=" * 70) ok = bot.connect(activate=False, wait_if_missing=False) show("connect()", ok) if not ok: print("[结论] 找不到企业微信主窗口,后面全部无法执行。") return show("hwnd", hex(bot.hwnd)) show("窗口矩形", (bot.L, bot.T, bot.R, bot.B)) fg = win32gui.GetForegroundWindow() show("当前前台窗口", f"{hex(fg)} / {win32gui.GetWindowText(fg)!r}") show("企业微信是否在前台", fg == bot.hwnd) show("_ensure_visible()", bot._ensure_visible()) show("_window_ready", bot._window_ready) show("安全验证页锁死", bot.security_verification_required) show("_security_gate_visible()", bot._security_gate_visible()) print() print("=" * 70) print("3) 页面与几何标定") print("=" * 70) full = bot._capture_full_window() show("全窗口截图", None if full is None else full.shape) nav_ok = bot._message_nav_selected(full) show("_message_nav_selected", nav_ok) show("_refresh_message_geometry", bot._refresh_message_geometry(full)) show("_session_geometry_valid", getattr(bot, "_session_geometry_valid", None)) show("_input_geometry_valid", getattr(bot, "_input_geometry_valid", None)) show("_composer_geometry_valid", getattr(bot, "_composer_geometry_valid", None)) show("_chat_geometry_valid", getattr(bot, "_chat_geometry_valid", None)) identity = bot._chat_identity_signature() surface = bot._chat_surface_signature() show("聊天标题指纹", identity.hex() or "<空>") show("消息布局指纹", surface.hex() or "<空>") time.sleep(1.0) show("消息布局指纹(1秒后)", bot._chat_surface_signature().hex() or "<空>") try: raw_sel = bot._raw_selected_session_fingerprint() except Exception as exc: raw_sel = f"异常 {exc}" show("选中行指纹(raw)", raw_sel.hex() if isinstance(raw_sel, bytes) else raw_sel) print() print("=" * 70) print("4) 发送与人机共存闸门") print("=" * 70) show("_send_gate_open()", bot._send_gate_open()) show("剩余限流秒数", f"{bot._send_gate_remaining():.1f}") show("_mouse_is_idle_now()", bot._mouse_is_idle_now()) print() print("=" * 70) print("5) 待回复任务") print("=" * 70) pending = bot._pending_reply_sessions show("任务数", len(pending)) now = time.time() for key, state in pending.items(): print("-" * 70) show("会话键", key) show("键长度(字节)", len(bytes.fromhex(key))) show("batch_ready", state.get("batch_ready")) show("confirmed_unread", state.get("confirmed_unread")) show("requires_visual_proof", state.get("requires_visual_proof")) show("send_state", repr(state.get("send_state"))) show("视觉否决次数", state.get("visual_rejection_count")) show("创建于(秒前)", f"{now - float(state.get('created_at') or 0):.0f}") show("更新于(秒前)", f"{now - float(state.get('updated_at') or 0):.0f}") deadline = float(state.get("batch_deadline_at") or 0.0) show( "合并窗口截止", "未开始" if not deadline else f"{deadline - now:+.0f} 秒", ) stored_identity = state.get("identity_signature") or b"" show( "任务标题指纹", bytes(stored_identity).hex() if stored_identity else "<空>", ) show("与当前标题一致", bytes(stored_identity) == identity) try: matched = bot._chat_target_matches( bytes.fromhex(key), bytes(stored_identity or identity), current_identity=identity, ) except Exception as exc: matched = f"异常 {exc}" show("_chat_target_matches", matched) show("render_identities", state.get("render_identities")) show("被拉黑(纯色头像否决)", key in getattr(bot, "_flat_rejected_session_fps", set())) chat_text = str(state.get("chat_text") or "") show("已缓存待回复文本长度", len(chat_text)) if chat_text: print(" 最后 120 字: " + repr(chat_text[-120:])) print() print("=" * 70) print("6) 未读红点扫描(只读,不点击)") print("=" * 70) preview = bot.capture_session_list() show("会话列表截图", None if preview is None else preview.shape) try: found = bot._find_next_unread_session(set(), set(), full=bot._capture_full_window()) except Exception as exc: found = f"异常 {exc}" if isinstance(found, tuple): _img, rel_y, target_fp = found show("发现未读", f"rel_y={rel_y} fp={target_fp.hex()}") else: show("发现未读", found) if __name__ == "__main__": main()