155 lines
3.6 KiB
Markdown
155 lines
3.6 KiB
Markdown
# 2925 account pool integration notes — 2026-05-11
|
|
|
|
Decision: abandon POP3/SMTP/IMAP forwarding to ClawEmail. Use the original extension's 2925 webmail/account-pool model directly.
|
|
|
|
## Account pool
|
|
|
|
Secret file:
|
|
|
|
```text
|
|
~/.hermes/secrets/mail2925_accounts.txt
|
|
```
|
|
|
|
Format:
|
|
|
|
```text
|
|
邮箱----密码
|
|
user@2925.com----password
|
|
```
|
|
|
|
BOSS provided 20 accounts (`chickliu2021@2925.com` through `chickliu2040@2925.com`). Passwords are stored only in the local secret file with mode `0600`; never print or commit raw passwords.
|
|
|
|
State file:
|
|
|
|
```text
|
|
~/.hermes/state/mail2925_accounts_state.json
|
|
```
|
|
|
|
State fields per account:
|
|
|
|
```json
|
|
{
|
|
"lastUsedAt": 0,
|
|
"lastLoginAt": 0,
|
|
"lastLimitAt": 0,
|
|
"disabledUntil": 0,
|
|
"lastError": ""
|
|
}
|
|
```
|
|
|
|
## Hard invariant: alias/account binding
|
|
|
|
A generated 2925 registration address must be derived from the same 2925 account used to read mail.
|
|
|
|
Example:
|
|
|
|
```text
|
|
selected account: chickliu2021@2925.com
|
|
allowed alias: chickliu2021rl9sxh@2925.com
|
|
mail reader: logged in as chickliu2021@2925.com
|
|
```
|
|
|
|
Forbidden:
|
|
|
|
```text
|
|
alias from chickliu2021*, but mailbox logged in as chickliu2022@2925.com
|
|
```
|
|
|
|
Gate before reading any code:
|
|
|
|
```text
|
|
displayedMailboxEmail == selectedAccount.email
|
|
alias.localPart startsWith selectedAccount.localPart
|
|
```
|
|
|
|
If the displayed mailbox email differs, clear 2925 cookies and force-login the selected account before continuing.
|
|
|
|
## Alias generation
|
|
|
|
Use original extension rule, not Gmail-style plus tags:
|
|
|
|
```text
|
|
baseLocal + randomSuffix(6) + @2925.com
|
|
```
|
|
|
|
Example:
|
|
|
|
```text
|
|
chickliu2021@2925.com -> chickliu2021a8k2mz@2925.com
|
|
```
|
|
|
|
Do not generate `chickliu2021+tag@2925.com`.
|
|
|
|
## Account selection
|
|
|
|
Pick among accounts that are:
|
|
|
|
```text
|
|
enabled != false
|
|
have password
|
|
disabledUntil <= now
|
|
```
|
|
|
|
Sort by:
|
|
|
|
```text
|
|
lastUsedAt ascending, then email ascending
|
|
```
|
|
|
|
This rotates accounts and avoids overusing one mailbox.
|
|
|
|
## Limit handling
|
|
|
|
Detect 2925 limit messages:
|
|
|
|
```text
|
|
子邮箱已达上限
|
|
已达上限邮箱
|
|
子邮箱上限
|
|
邮箱已达上限
|
|
```
|
|
|
|
On hit:
|
|
|
|
```text
|
|
currentAccount.disabledUntil = now + 24h
|
|
currentAccount.lastLimitAt = now
|
|
currentAccount.lastError = reason
|
|
switch to next available account
|
|
terminate current OpenAI attempt and restart next round with a fresh alias
|
|
```
|
|
|
|
Do not continue the same OpenAI page after switching 2925 account; it risks mixing alias/account state.
|
|
|
|
## Local helper
|
|
|
|
```bash
|
|
python3 scripts/mail2925_pool.py selftest
|
|
python3 scripts/mail2925_pool.py list
|
|
python3 scripts/mail2925_pool.py pick --dry-run # preview without changing rotation state
|
|
python3 scripts/mail2925_pool.py pick # allocate and update lastUsedAt
|
|
python3 scripts/mail2925_pool.py mark-limit chickliu2021@2925.com --reason '子邮箱已达上限邮箱'
|
|
python3 scripts/mail2925_pool.py mark-login chickliu2021@2925.com
|
|
```
|
|
|
|
`pick` prints only email + generated alias; never prints passwords.
|
|
|
|
Verified locally on 2026-05-11:
|
|
|
|
```json
|
|
{"accounts":20,"aliasFailures":[],"secretMode":"0o600","ok":true}
|
|
```
|
|
|
|
## Webmail flow to implement/use
|
|
|
|
1. Pick account and generate alias in one operation.
|
|
2. Open/login `https://2925.com/login/` or `https://2925.com/#/mailList`.
|
|
3. Verify displayed mailbox email equals picked account email.
|
|
4. Clear inbox before triggering OpenAI code.
|
|
5. Submit generated alias to OpenAI.
|
|
6. Poll 2925 inbox: 15 attempts, 15s interval.
|
|
7. Match OpenAI/auth/verify/code/login sender/subject/body; extract 6-digit code.
|
|
8. Open matching mail, extract body code, delete mail, return inbox.
|
|
9. Submit code; if invalid, add to rejectedCodes, resend, and continue polling.
|
|
10. On 2925 limit, mark current account cooldown and restart with next account.
|