From 51988b4f8d3c8d486f1f1aafbc095b00277d901d Mon Sep 17 00:00:00 2001 From: EmptyDust <1422492074@qq.com> Date: Tue, 28 Apr 2026 14:26:17 +0800 Subject: [PATCH] fix: read hotmail codes from full imap body --- scripts/hotmail_helper.py | 50 +++++++++++++ tests/hotmail_helper_logging_test.py | 104 ++++++++++++++++++++++++++- 2 files changed, 153 insertions(+), 1 deletion(-) diff --git a/scripts/hotmail_helper.py b/scripts/hotmail_helper.py index 806ecad..768b480 100644 --- a/scripts/hotmail_helper.py +++ b/scripts/hotmail_helper.py @@ -123,6 +123,48 @@ def log_info(message): print(f"[HotmailHelper] {message}", flush=True) +def is_openai_sender(address): + sender = str(address or "").strip().lower() + return "openai" in sender + + +def get_message_body_content(message): + body = message.get("body") or {} + if not isinstance(body, dict): + return "" + return str(body.get("content") or "").strip() + + +def log_openai_messages(messages, transport=""): + for message in messages or []: + sender_info = message.get("from", {}).get("emailAddress", {}) or {} + sender = str(sender_info.get("address") or "").strip() + if not is_openai_sender(sender): + continue + + sender_name = str(sender_info.get("name") or "").strip() + mailbox = str(message.get("mailbox") or "").strip() or "INBOX" + subject = str(message.get("subject") or "").strip() + transport_label = str(transport or "").strip() or "unknown" + base = ( + f"transport={transport_label} mailbox={mailbox} sender={sender} " + f"senderName={sender_name or '-'} subject={subject}" + ) + + log_info(f"openai mail received {base}") + + body_content = get_message_body_content(message) + if body_content: + log_info(f"openai mail full body start {base}") + print(body_content, flush=True) + log_info("openai mail full body end") + continue + + preview = str(message.get("bodyPreview") or "").strip() + if preview: + log_info(f"openai mail preview {base} preview={compact_text(preview, 1000)}") + + def get_proxy_debug_context(): names = ["all_proxy", "http_proxy", "https_proxy", "ALL_PROXY", "HTTP_PROXY", "HTTPS_PROXY"] parts = [] @@ -481,6 +523,9 @@ def normalize_message(message_id, raw_bytes, mailbox): } }, "bodyPreview": body[:500], + "body": { + "content": body, + }, "receivedDateTime": to_iso_string(timestamp_ms), "receivedTimestamp": timestamp_ms, } @@ -680,6 +725,7 @@ def collect_messages(email_addr, client_id, refresh_token, mailboxes, top): try: log_info(f"message collection start transport={transport_name}") result = collector(email_addr, client_id, refresh_token, mailboxes, top) + log_openai_messages(result.get("messages") or [], transport=transport_name) log_info( f"message collection success transport={transport_name} " f"tokenEndpoint={result['token_payload'].get('token_endpoint', '')}" @@ -722,6 +768,10 @@ def select_latest_code(messages, sender_filters, subject_filters, exclude_codes, preview = str(message.get("bodyPreview", "")) combined = " ".join([sender, subject.lower(), preview.lower()]) code = extract_code(" ".join([subject, preview, sender])) + if not code: + body_content = get_message_body_content(message) + if body_content: + code = extract_code(" ".join([subject, body_content, sender])) if not code or code in excluded: return None diff --git a/tests/hotmail_helper_logging_test.py b/tests/hotmail_helper_logging_test.py index dade9e4..bc926fc 100644 --- a/tests/hotmail_helper_logging_test.py +++ b/tests/hotmail_helper_logging_test.py @@ -18,6 +18,107 @@ hotmail_helper = load_hotmail_helper() class HotmailHelperLoggingTest(unittest.TestCase): + def test_select_latest_code_can_use_full_body_when_preview_is_truncated(self): + css_prefix = ( + 'Your temporary ChatGPT verification code ' + '@font-face { font-family: "Söhne"; src: url(https://cdn.openai.com/common/fonts/soehne/soehne-buch.woff2) format("woff2"); } ' + '.ExternalClass { width: 100%; } ' + '#bodyTable { width: 560px; } ' + 'body { min-width: 100% !important; } ' + ) * 8 + full_body = ( + css_prefix + + 'Enter this temporary verification code to continue: 272964 ' + + 'Please ignore this email if this was not you.' + ) + message = { + "id": "imap-1", + "mailbox": "INBOX", + "subject": "Your temporary ChatGPT verification code", + "from": { + "emailAddress": { + "address": "otp@tm1.openai.com", + "name": "OpenAI", + } + }, + "bodyPreview": full_body[:500], + "body": { + "content": full_body, + }, + "receivedTimestamp": 200, + } + + result = hotmail_helper.select_latest_code( + [message], + ['openai', 'noreply', 'verify', 'auth', 'chatgpt', 'duckduckgo', 'forward'], + ['verify', 'verification', 'code', '验证码', 'confirm', 'login'], + [], + 0, + ) + + self.assertEqual(result["code"], "272964") + self.assertEqual(result["message"]["id"], "imap-1") + + def test_log_openai_messages_logs_full_body_when_available(self): + messages = [{ + "mailbox": "INBOX", + "subject": "Your verification code", + "from": { + "emailAddress": { + "address": "account-security@openai.com", + "name": "OpenAI", + } + }, + "bodyPreview": "Use 123456 to continue.", + "body": { + "content": "Hello there\nUse 123456 to continue.", + }, + }] + + output = io.StringIO() + with redirect_stdout(output): + hotmail_helper.log_openai_messages(messages, transport="imap") + + rendered = output.getvalue() + self.assertIn( + "[HotmailHelper] openai mail received transport=imap mailbox=INBOX sender=account-security@openai.com senderName=OpenAI subject=Your verification code", + rendered, + ) + self.assertIn( + "[HotmailHelper] openai mail full body start transport=imap mailbox=INBOX sender=account-security@openai.com senderName=OpenAI subject=Your verification code", + rendered, + ) + self.assertIn("Hello there\nUse 123456 to continue.", rendered) + self.assertIn("[HotmailHelper] openai mail full body end", rendered) + + def test_log_openai_messages_falls_back_to_preview_without_full_body(self): + messages = [{ + "mailbox": "Junk", + "subject": "Verify your sign in", + "from": { + "emailAddress": { + "address": "noreply@tm.openai.com", + "name": "ChatGPT", + } + }, + "bodyPreview": "Use 654321 to continue.", + }] + + output = io.StringIO() + with redirect_stdout(output): + hotmail_helper.log_openai_messages(messages, transport="graph") + + rendered = output.getvalue() + self.assertIn( + "[HotmailHelper] openai mail received transport=graph mailbox=Junk sender=noreply@tm.openai.com senderName=ChatGPT subject=Verify your sign in", + rendered, + ) + self.assertIn( + "[HotmailHelper] openai mail preview transport=graph mailbox=Junk sender=noreply@tm.openai.com senderName=ChatGPT subject=Verify your sign in preview=Use 654321 to continue.", + rendered, + ) + self.assertNotIn("openai mail full body start", rendered) + def test_refresh_access_token_logs_invalid_grant_and_direct_connection_refused_separately(self): failures = [ { @@ -38,7 +139,8 @@ class HotmailHelperLoggingTest(unittest.TestCase): }, ] - with mock.patch.object(hotmail_helper, "try_refresh_access_token", side_effect=failures): + with mock.patch.object(hotmail_helper, "try_refresh_access_token", side_effect=failures), \ + mock.patch.object(hotmail_helper, "get_proxy_debug_context", return_value="direct"): output = io.StringIO() with redirect_stdout(output): with self.assertRaises(RuntimeError):