196 lines
5.7 KiB
Markdown
196 lines
5.7 KiB
Markdown
# 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.
|
|
|
|
```text
|
|
base: yourname@2925.com
|
|
alias: yourname + randomSuffix(6) + @2925.com
|
|
```
|
|
|
|
Examples:
|
|
|
|
```text
|
|
abc@2925.com -> abcxk39qz@2925.com
|
|
```
|
|
|
|
Provider ownership check:
|
|
|
|
```text
|
|
domain == 2925.com
|
|
candidate local == base local OR candidate local startsWith(base local)
|
|
```
|
|
|
|
## Account pool
|
|
|
|
Import format:
|
|
|
|
```text
|
|
邮箱----密码
|
|
user1@2925.com----[REDACTED_PASSWORD_1]
|
|
user2@2925.com----[REDACTED_PASSWORD_2]
|
|
```
|
|
|
|
Normalized account fields:
|
|
|
|
```json
|
|
{
|
|
"id": "...",
|
|
"email": "xxx@2925.com",
|
|
"password": "...",
|
|
"enabled": true,
|
|
"lastUsedAt": 0,
|
|
"lastLoginAt": 0,
|
|
"lastLimitAt": 0,
|
|
"disabledUntil": 0,
|
|
"lastError": ""
|
|
}
|
|
```
|
|
|
|
Available account gate:
|
|
|
|
```text
|
|
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:
|
|
|
|
```text
|
|
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:
|
|
|
|
```text
|
|
子邮箱已达上限
|
|
已达上限邮箱
|
|
子邮箱上限
|
|
邮箱已达上限
|
|
```
|
|
|
|
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:
|
|
|
|
```text
|
|
maxAttempts = 15
|
|
intervalMs = 15000
|
|
```
|
|
|
|
Total mailbox wait window is about 225 seconds per poll round.
|
|
|
|
Signup filters:
|
|
|
|
```text
|
|
sender: openai, noreply, verify, auth, duckduckgo, forward
|
|
subject: verify, verification, code, 验证码, confirm
|
|
```
|
|
|
|
Login filters:
|
|
|
|
```text
|
|
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.
|
|
|
|
## Recommended Hermes runner design
|
|
|
|
For a 2925-backed Codex OAuth runner, add env/config like:
|
|
|
|
```text
|
|
MAIL_PROVIDER=2925
|
|
MAIL2925_MODE=provide
|
|
MAIL2925_ACCOUNTS_FILE=/path/to/2925-accounts.jsonl-or-txt
|
|
MAIL2925_USE_ACCOUNT_POOL=true
|
|
```
|
|
|
|
Then implement gates:
|
|
|
|
```text
|
|
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.
|