From: 小龙 Date: Thu, 16 Jul 2026 03:59:42 +0000 (+0800) Subject: 第6封链接邮件+检测重发+窗口检测 v3.2 X-Git-Url: https://szjxzxh.cn/gitweb/index.html?a=commitdiff_plain;h=ec9b9428aa876ed0e223aade6080a42d044b25c3;p=%E5%BE%AE%E4%BF%A1%E7%9B%91%E6%8E%A7 第6封链接邮件+检测重发+窗口检测 v3.2 --- diff --git a/wechat_auto_login.py b/wechat_auto_login.py index fb59326..92c00a5 100644 --- a/wechat_auto_login.py +++ b/wechat_auto_login.py @@ -201,6 +201,37 @@ try: log.error("邮件发送失败: %s", e) + def send_resend_link_email(): + """发送重发链接邮件(不含二维码,仅文字+链接)""" + if not EMAIL_ENABLED or not EMAIL_ACCOUNT: + log.warning("邮件未启用或账号未配置,跳过重发邮件") + return + try: + from email.mime.text import MIMEText + msg = MIMEText( + "微信登录二维码提醒已全部发送完毕,如仍需登录请点击以下链接申请重新发送:\n\n" + "https://szjxzxh.cn/wechat-resend.html\n\n" + "(点击后监控程序将重新开始发送二维码通知)", + "plain", "utf-8" + ) + from email.utils import formataddr + msg["From"] = formataddr(("微信助手", EMAIL_ACCOUNT)) + msg["To"] = EMAIL_TO + msg["Subject"] = "微信登录二维码已过期 - 申请重发" + + if USE_SSL: + s = smtplib.SMTP_SSL(SMTP_SERVER, SMTP_PORT, timeout=10) + else: + s = smtplib.SMTP(SMTP_SERVER, SMTP_PORT, timeout=10) + s.starttls() + s.login(EMAIL_ACCOUNT, EMAIL_PASSWORD) + s.send_message(msg) + s.quit() + log.info("重发链接邮件已发送至 %s", EMAIL_TO) + except Exception as e: + log.error("重发链接邮件发送失败: %s", e) + + def _find_wechat_windows(): """找到标题严格等于'微信'的可见窗口列表(排除包含'微信'的其他窗口)""" return [w for w in gw.getAllWindows() if w.title == "微信"] @@ -341,6 +372,7 @@ try: self.qr_sent_count = 0 self._last_login_hash = None self._user_resized = False + self._resend_link_sent = False self._setup_ui() @@ -481,6 +513,7 @@ try: self.last_md5 = None self.qr_sent_count = 0 self._last_login_hash = None + self._resend_link_sent = False log.info("监控已停用") # ── status ── @@ -672,11 +705,15 @@ try: self._set_status("微信未运行,启动中...") return # _do_detect 会在下一轮自动启动微信 - # ② 检查邮件是否已发满(含重发次数) + # ② 检查邮件已发满后的处理 if self.hash_mode_emails_sent >= MAX_EMAILS: - # 已发满,进入等待重发模式 - self._check_resend_flag() - return + if not self._resend_link_sent: + # 还没发第6封链接邮件,继续监测窗口 + pass # 不走下面,会继续执行到窗口尺寸检查 + else: + # 第6封已发,进入等待重发模式 + self._check_resend_flag() + return # ③ 查窗口尺寸 wechat_windows = _find_wechat_windows() @@ -728,37 +765,69 @@ try: # 仍然是登录窗口→发通知 time.sleep(2) img2 = _capture_center() - qr_path = os.path.join(tempfile.gettempdir(), f"wechat_qr_{int(time.time())}.png") - img2.save(qr_path, "PNG") - self.hash_mode_emails_sent += 1 + if self.hash_mode_emails_sent >= MAX_EMAILS: + if not self._resend_link_sent: + # 第5封已发完,现在二维码过期了,发第6封链接邮件 + send_resend_link_email() + self._resend_link_sent = True + self._set_status("二维码已过期,等待重发") + log.info("二维码已过期,第6封链接邮件已发送") + self.root.after(PAUSE * 1000, self._check_resend_flag) + return + else: + # 正常发邮件(第1-5封) + qr_path = os.path.join(tempfile.gettempdir(), f"wechat_qr_{int(time.time())}.png") + img2.save(qr_path, "PNG") + + self.hash_mode_emails_sent += 1 - # 发邮件 - send_qr_email(qr_path) + # 发邮件 + send_qr_email(qr_path) - # 短信:只在第1次发(无论多少轮,只发一次) - if self.hash_mode_emails_sent == 1: - if SMS_PHONE: - send_sms("888888", SMS_PHONE) + # 短信:只在第1次发(无论多少轮,只发一次) + if self.hash_mode_emails_sent == 1: + if SMS_PHONE: + send_sms("888888", SMS_PHONE) - # 第5封邮件末尾带重发链接 - if self.hash_mode_emails_sent == MAX_EMAILS: - # TODO: 发第5封邮件时包含重发链接 - log.info("邮件已发满 %d 次,进入等待重发模式", MAX_EMAILS) + # 第5封邮件已发完,继续监测,等二维码过期再发第6封 + if self.hash_mode_emails_sent >= MAX_EMAILS and not self._resend_link_sent: + log.info("第5封邮件已发送,等待二维码过期...") + self._set_status("第5封已发送,等待二维码过期") - self.last_md5 = _md5_of_image(img2) - self._set_status(f"请扫码登录 ({self.hash_mode_emails_sent}/{MAX_EMAILS})") - self.root.after(PAUSE * 1000, self._hash_loop_tick) + self.last_md5 = _md5_of_image(img2) + self._set_status(f"请扫码登录 ({self.hash_mode_emails_sent}/{MAX_EMAILS})") + self.root.after(PAUSE * 1000, self._hash_loop_tick) def _check_resend_flag(self): """检查服务器上是否有重发标记""" - url = "https://szjxzxh.cn/wechat_resend.flag" + + # ① 先查窗口尺寸 + wechat_windows = _find_wechat_windows() + visible = [w for w in wechat_windows if w.visible] + login_window = None + for w in visible: + if w.width < 700 and w.height < 850: + login_window = w + break + + if not login_window: + # 窗口变大了 → 已登录 + self.hash_mode = False + self._last_login_hash = None + self.qr_sent_count = 0 + self._resend_link_sent = False + self._set_status("微信运行中") + log.info("微信已登录,退出等待重发模式") + return + + # ② 查flag import requests + url = "https://szjxzxh.cn/wechat_resend.flag" try: resp = requests.get(url, timeout=5) if resp.status_code == 200: # 用户申请了重发,删除flag文件 - # 先删服务器上的flag delete_url = "https://szjxzxh.cn/cgi/wechat_resend.py?action=delete" try: requests.get(delete_url, timeout=5) @@ -767,6 +836,7 @@ try: # 重置计数,开始新一轮 self.hash_mode_emails_sent = 0 self.last_md5 = None + self._resend_link_sent = False self._set_status("准备重新发送通知...") log.info("检测到重发请求,开始新一轮通知") self.root.after(PAUSE * 1000, self._hash_loop_tick)