Files
autoreg-skills-max/skills/email-infrastructure/references/html-otp-parsing.md

2.2 KiB

HTML OTP Parsing Notes

Use this when IMAP fetch succeeds but naive regex extraction returns the wrong verification code.

Problem pattern

Some transactional emails contain multiple \d{6} candidates in one message because the HTML includes:

  • the visible OTP block,
  • responsive/mobile duplicate markup,
  • unrelated build/tracking numbers embedded in template fragments.

If you do re.findall(r'\\b\\d{6}\\b', body)[0], you may grab a stale or irrelevant number.

Preferred extraction order

  1. Subject line first if it explicitly contains the OTP.
  2. OTP-specific markup next:
    • <strong>123456</strong>
    • .otp-code
    • monospace / headline blocks near words like verification code, 验证码, OTP, code
  3. Generic body regex only as fallback.
  4. If multiple distinct codes remain, prefer the one from the latest message that appears in OTP-specific markup, not the first raw body match.

Minimal robust pattern

from email.header import decode_header
import email as em
import re


def decode_subject(msg):
    parts = []
    for value, enc in decode_header(msg.get('Subject', '')):
        if isinstance(value, bytes):
            parts.append(value.decode(enc or 'utf-8', errors='replace'))
        else:
            parts.append(value)
    return ''.join(parts)


def extract_code(subject, body):
    # 1) explicit subject code
    m = re.search(r'\b(\d{4,8})\b', subject)
    if m:
        return m.group(1)

    # 2) OTP-specific HTML / text blocks
    patterns = [
        r'otp-code[^>]*>\s*(\d{4,8})\s*<',
        r'<strong[^>]*>\s*(\d{4,8})\s*</strong>',
        r'(?:verification code|验证码|OTP|code)[^\d]{0,40}(\d{4,8})',
    ]
    for pat in patterns:
        m = re.search(pat, body, re.I | re.S)
        if m:
            return m.group(1)

    # 3) generic fallback
    codes = re.findall(r'\b(\d{4,8})\b', body)
    codes = [c for c in codes if not (2020 <= int(c) <= 2035)]
    return codes[0] if codes else None

Session-derived example shape

Observed shape: one provider email produced several six-digit matches from a single HTML message. The visible OTP and the first regex hit did not reliably align. The safe fix was to stop trusting codes[0] and rank candidates by subject / OTP markup / latest message.