Files
codex-oauth-plus-onboarding…/skill/codex-oauth-plus-onboarding/references/2925-mail-provider-original-extension-rules-2026-05-11.md
T

5.7 KiB

2925 mail provider rules from original extension — 2026-05-11

Source inspected: original extension repo codex-oauth-automation-extension (mail2925-utils.js, managed-alias-utils.js, background/generated-email-helpers.js, background/mail-2925-session.js, background/verification-flow.js, content/mail-2925.js, related tests).

Provider modes

mailProvider=2925 has two distinct modes:

  • mail2925Mode=provide (default): 2925 provides the registration email via a managed alias.
  • mail2925Mode=receive: registration email comes from another generator/manual path; 2925 is only the mailbox used to receive/poll mail.

For replacing ClawEmail in OpenAI/Codex signup, prefer provide first.

Alias generation

2925 does not use Gmail-style plus tags.

base:  yourname@2925.com
alias: yourname + randomSuffix(6) + @2925.com

Examples:

abc@2925.com -> abcxk39qz@2925.com

Provider ownership check:

domain == 2925.com
candidate local == base local OR candidate local startsWith(base local)

Account pool

Import format:

邮箱----密码
user1@2925.com----[REDACTED_PASSWORD_1]
user2@2925.com----[REDACTED_PASSWORD_2]

Normalized account fields:

{
  "id": "...",
  "email": "xxx@2925.com",
  "password": "...",
  "enabled": true,
  "lastUsedAt": 0,
  "lastLoginAt": 0,
  "lastLimitAt": 0,
  "disabledUntil": 0,
  "lastError": ""
}

Available account gate:

email present
password present
enabled != false
not cooling down

Selection policy: choose the available account with the oldest lastUsedAt; tie-break by email.

Login/session gates

URLs/domains:

mail list: https://2925.com/#/mailList
login:     https://2925.com/login/
cookie domains: 2925.com, www.2925.com, mail2.xiyouji.com
cookie origins: https://2925.com, https://www.2925.com, https://mail2.xiyouji.com

Force relogin flow:

  1. Clear 2925 cookies on the domains/origins above.
  2. Wait ~3 seconds.
  3. Open login URL.
  4. Wait ~3 seconds before checking fields.
  5. Ensure agreement/remember checkboxes if present.
  6. Fill email, wait ~150ms.
  7. Fill password, wait ~200ms + 1000ms.
  8. Click login.
  9. Wait up to 40 seconds for mailbox view.

Critical gate: the displayed mailbox email at the top of the 2925 page must match the selected account. If mismatched and account pool is enabled, clear/relogin to the target account. If pool is disabled, stop rather than polling the wrong mailbox.

Limit/cooldown handling

Detect page/error text matching:

子邮箱已达上限
已达上限邮箱
子邮箱上限
邮箱已达上限

When detected:

  • Prefix/internal class: MAIL2925_LIMIT_REACHED::...
  • If account pool disabled: stop the flow.
  • If current account is known: set lastLimitAt=now, disabledUntil=now+24h, lastError=reason.
  • Pick the next available account excluding the current id.
  • Force relogin to the next account.
  • End the current attempt/thread; next retry should start fresh.

Cooldown constant: 24 * 60 * 60 * 1000.

Verification polling

For 2925, both signup and login verification use:

maxAttempts = 15
intervalMs = 15000

Total mailbox wait window is about 225 seconds per poll round.

Signup filters:

sender:  openai, noreply, verify, auth, duckduckgo, forward
subject: verify, verification, code, 验证码, confirm

Login filters:

sender:  openai, noreply, verify, auth, chatgpt, duckduckgo, forward
subject: verify, verification, code, 验证码, confirm, login

receive mode enables weak target-email matching: if the preview/body contains an explicit target email, it must match the current registration/login email. provide mode does not require this because the generated registration email belongs to the current 2925 mailbox.

Anti-stale-code rules

Prefer this sequence over ClawEmail-style newest-list polling:

  1. Before sending/requesting a fresh OpenAI code, pre-clear the 2925 inbox when no reliable filterAfterTimestamp is available.
  2. Request/resend the OpenAI code.
  3. Poll inbox with refresh cycles.
  4. For each candidate mail: open it, read preview/body, extract 6-digit code, delete the mail, return to inbox.
  5. Maintain seenCodes and rejectedCodes to avoid resubmitting old/invalid codes.
  6. If OpenAI marks a code invalid, add it to rejectedCodes, request a new code if allowed, and continue polling.
  7. After a successful verification step, trigger best-effort delete-all cleanup for 2925.

Important: 2925 page list ordering should not be trusted as the only freshness signal. The original extension relies heavily on pre-clear + delete-after-read + seen/rejected-code sets.

For a 2925-backed Codex OAuth runner, add env/config like:

MAIL_PROVIDER=2925
MAIL2925_MODE=provide
MAIL2925_ACCOUNTS_FILE=/path/to/2925-accounts.jsonl-or-txt
MAIL2925_USE_ACCOUNT_POOL=true

Then implement gates:

select available 2925 account
login/ensure session
verify displayed mailbox email == selected account email
pre-clear inbox
generate alias: baseLocal + 6 random lowercase/digits + @2925.com
submit alias to OpenAI
poll 2925, delete after read, strict 6-digit extraction
submit code
on invalid code: rejectedCodes + resend + repoll
on limit text: disable account 24h and switch account; do not continue current OpenAI attempt

Why this is better than ClawEmail for this class

  • No sub-mailbox creation step.
  • No external receive permission/Dashboard API gate.
  • No mail-cli profile ambiguity.
  • Delete-after-read and pre-clear reduce old-code pollution.
  • Account pool/cooldown explicitly handles 2925 per-account limits.

Risk: single 2925 account can hit sub-mailbox limits, so account pool support is not optional for high-volume runs.