docs: record 1085 clawemail permission and phone results
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
import json, pathlib, urllib.request, urllib.parse, re, subprocess, time, sys
|
||||
ENV=pathlib.Path('/Users/chick/.hermes/env/codex_oauth_onboarding.env')
|
||||
text=ENV.read_text()
|
||||
def get(k,default=''):
|
||||
m=re.search(r'^'+re.escape(k)+r'=(.*)$', text, re.M)
|
||||
return (m.group(1).strip().strip('"\'') if m else default)
|
||||
TOKEN=get('FIVE_SIM_API_KEY') or get('FIVESIM_API_KEY')
|
||||
ORDER=[x.strip() for x in get('FIVE_SIM_COUNTRY_ORDER','').split(',') if x.strip()] or ([get('FIVE_SIM_COUNTRY_ID')] if get('FIVE_SIM_COUNTRY_ID') else ['vietnam'])
|
||||
LIMIT=int(get('PHONE_VERIFICATION_REPLACEMENT_LIMIT','3') or '3')
|
||||
PRODUCT=get('FIVE_SIM_PRODUCT','openai') or 'openai'
|
||||
OP=get('FIVE_SIM_OPERATOR','any') or 'any'
|
||||
META={'argentina':('阿根廷','54'),'netherlands':('荷兰','31'),'indonesia':('印度尼西亚','62'),'vietnam':('越南','84')}
|
||||
HEAD={'Authorization':'Bearer '+TOKEN,'Accept':'application/json'}
|
||||
|
||||
def emit(**kw): print(json.dumps(kw,ensure_ascii=False),flush=True)
|
||||
def req(method,url,data=None,timeout=30):
|
||||
body=None
|
||||
if data is not None: body=json.dumps(data).encode()
|
||||
r=urllib.request.Request(url,data=body,headers=HEAD,method=method)
|
||||
if body: r.add_header('Content-Type','application/json')
|
||||
with urllib.request.urlopen(r,timeout=timeout) as resp: return json.loads(resp.read().decode())
|
||||
def cdp(js,match='auth.openai.com',timeout=40):
|
||||
p=subprocess.run(['bash','-lc',f"CDP_MATCH='{match}' python3 /tmp/cdp_async_eval.py"],input=js,text=True,capture_output=True,timeout=timeout)
|
||||
return (p.stdout or '')+(p.stderr or '')
|
||||
def page_state():
|
||||
return cdp("""return {url:location.href,title:document.title,text:document.body.innerText.slice(0,1600),country:[...document.querySelectorAll('button')].map(b=>b.innerText).find(t=>/\\(\\+\\d+\\)/.test(t)),tel:document.querySelector('input[type=tel]')?.value};""",timeout=25)
|
||||
def select_country(country):
|
||||
label,prefix=META[country]
|
||||
iso={"argentina":"AR","netherlands":"NL","indonesia":"ID","vietnam":"VN"}[country]
|
||||
js=f"""
|
||||
const iso={json.dumps(iso)};
|
||||
const sel=document.querySelector('select');
|
||||
sel.focus();
|
||||
sel.value=iso;
|
||||
sel.dispatchEvent(new Event('input',{{bubbles:true}}));
|
||||
sel.dispatchEvent(new Event('change',{{bubbles:true}}));
|
||||
await new Promise(r=>setTimeout(r,800));
|
||||
return {{selectValue:sel.value,country:[...document.querySelectorAll('button')].map(b=>b.innerText).find(t=>/\\(\\+\\d+\\)/.test(t)),text:document.body.innerText.slice(0,700)}};
|
||||
"""
|
||||
return cdp(js,timeout=25)
|
||||
def buy(country):
|
||||
url=f'https://5sim.net/v1/user/buy/activation/{urllib.parse.quote(country)}/{urllib.parse.quote(OP)}/{urllib.parse.quote(PRODUCT)}'
|
||||
return req('GET',url,timeout=40)
|
||||
def cancel(aid):
|
||||
try: return req('GET',f'https://5sim.net/v1/user/cancel/{aid}',timeout=20)
|
||||
except Exception as e: return {'error':str(e)}
|
||||
def check(aid):
|
||||
return req('GET',f'https://5sim.net/v1/user/check/{aid}',timeout=20)
|
||||
def submit_phone(country,phone):
|
||||
label,prefix=META[country]
|
||||
digits=re.sub(r'\D+','',phone)
|
||||
local=digits[len(prefix):] if digits.startswith(prefix) else digits
|
||||
js=f"""
|
||||
const local={json.dumps(local)};
|
||||
const input=document.querySelector('input[type=tel]');
|
||||
const setter=Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype,'value').set;
|
||||
input.focus(); setter.call(input,''); input.dispatchEvent(new InputEvent('input',{{bubbles:true,inputType:'deleteContentBackward'}}));
|
||||
setter.call(input,local); input.dispatchEvent(new InputEvent('input',{{bubbles:true,inputType:'insertText',data:local}})); input.dispatchEvent(new Event('change',{{bubbles:true}}));
|
||||
await new Promise(r=>setTimeout(r,500));
|
||||
let btn=[...document.querySelectorAll('button')].find(b=>(b.innerText||'').trim()==='继续'); btn?.click();
|
||||
await new Promise(r=>setTimeout(r,12000));
|
||||
return {{url:location.href,title:document.title,text:document.body.innerText.slice(0,1200),country:[...document.querySelectorAll('button')].map(b=>b.innerText).find(t=>/\\(\\+\\d+\\)/.test(t)),tel:document.querySelector('input[type=tel]')?.value}};
|
||||
"""
|
||||
return cdp(js,timeout=45)
|
||||
def resend_phone():
|
||||
js="""const btn=[...document.querySelectorAll('button')].find(b=>/重新发送/.test(b.innerText||'')); btn?.click(); await new Promise(r=>setTimeout(r,3000)); return {clicked:!!btn,text:document.body.innerText.slice(0,800),url:location.href};"""
|
||||
return cdp(js,timeout=20)
|
||||
|
||||
def poll_sms(aid,rounds=8):
|
||||
for i in range(rounds):
|
||||
time.sleep(12)
|
||||
st=check(aid)
|
||||
sms=st.get('sms') or []
|
||||
emit(phase='sms_poll',activation_id=aid,round=i+1,status=st.get('status'),sms_count=len(sms))
|
||||
if sms:
|
||||
txt=json.dumps(sms,ensure_ascii=False)
|
||||
m=re.search(r'(?<!\d)(\d{4,8})(?!\d)',txt)
|
||||
if m: return m.group(1),st
|
||||
return None,None
|
||||
|
||||
emit(phase='phone_start',countries=ORDER,limit=LIMIT)
|
||||
for country in ORDER:
|
||||
if country not in META:
|
||||
emit(phase='country_skip',country=country,reason='missing_meta'); continue
|
||||
for attempt in range(1,LIMIT+1):
|
||||
sel=select_country(country)
|
||||
if META[country][0] not in sel or META[country][1] not in sel:
|
||||
emit(phase='country_select_failed',country=country,attempt=attempt,out=sel[-500:])
|
||||
continue
|
||||
act=buy(country)
|
||||
aid=act.get('id'); phone=act.get('phone')
|
||||
pathlib.Path('/tmp/fivesim_activation.json').write_text(json.dumps(act,ensure_ascii=False,indent=2))
|
||||
emit(phase='buy',country=country,attempt=attempt,activation_id=aid,masked=re.sub(r'(\+?\d{4})\d+(\d{3})',r'\1***\2',str(phone)),status=act.get('status'))
|
||||
out=submit_phone(country,phone)
|
||||
if '电话号码无效' in out or '美国 (+1)' in out and country!='usa':
|
||||
emit(phase='submit_invalid_or_country_revert',country=country,activation_id=aid)
|
||||
emit(phase='cancel',activation_id=aid,result=cancel(aid).get('status'))
|
||||
continue
|
||||
if '无法向此电话号码发送验证码' in out:
|
||||
emit(phase='direct_reject',country=country,activation_id=aid)
|
||||
emit(phase='cancel',activation_id=aid,result=cancel(aid).get('status'))
|
||||
continue
|
||||
emit(phase='accepted_or_waiting',country=country,activation_id=aid,state=out[-300:])
|
||||
code,st=poll_sms(aid,rounds=5)
|
||||
if not code:
|
||||
emit(phase='resend_phone',activation_id=aid,out=resend_phone()[-300:])
|
||||
code,st=poll_sms(aid,rounds=5)
|
||||
if code:
|
||||
emit(phase='sms_code_received',activation_id=aid,code='[REDACTED]')
|
||||
js=f"""
|
||||
const code={json.dumps(code)};
|
||||
let inputs=[...document.querySelectorAll('input')].filter(i=>i.type==='text'||i.type==='tel'||i.inputMode==='numeric');
|
||||
let input=inputs.find(i=>i!==document.querySelector('input[type=tel]'))||inputs[0];
|
||||
const setter=Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype,'value').set;
|
||||
input.focus(); setter.call(input,code); input.dispatchEvent(new InputEvent('input',{{bubbles:true,inputType:'insertText',data:code}})); input.dispatchEvent(new Event('change',{{bubbles:true}}));
|
||||
await new Promise(r=>setTimeout(r,500));
|
||||
[...document.querySelectorAll('button')].find(b=>/继续|Continue|验证/.test(b.innerText||''))?.click();
|
||||
await new Promise(r=>setTimeout(r,15000));
|
||||
return {{url:location.href,title:document.title,text:document.body.innerText.slice(0,1600)}};
|
||||
"""
|
||||
final=cdp(js,timeout=45)
|
||||
emit(phase='phone_code_submitted',activation_id=aid,state=final[-500:])
|
||||
sys.exit(0)
|
||||
emit(phase='no_sms_after_resend',country=country,activation_id=aid)
|
||||
emit(phase='cancel',activation_id=aid,result=cancel(aid).get('status'))
|
||||
emit(phase='phone_failed_all')
|
||||
sys.exit(3)
|
||||
@@ -45,9 +45,9 @@ These are confirmed operating rules for BOSS's environment:
|
||||
- Do **not** set a default target platform. If `PANEL_MODE` is empty or not one of `cpa|sub2api|codex2api`, stop before launching the run.
|
||||
- Proxies are supplied as unauthenticated `socks5://host:port` or `http://host:port`; do not expect proxy username/password.
|
||||
- The new account password is unified through `CUSTOM_PASSWORD`. If it is empty, stop and ask BOSS to fill it, unless BOSS explicitly allows auto-generation for that run.
|
||||
- ClawEmail creates a fresh mailbox for every run (`CLAWEMAIL_CREATE_PER_RUN=true`). Record every created mailbox locally with outcome classification: pending, success, failed.
|
||||
- ClawEmail creates a fresh mailbox for every run (`CLAWEMAIL_CREATE_PER_RUN=true`). Record every created mailbox locally with outcome classification: pending, success, failed. **Immediately after creation, actively set/verify the mailbox's communication settings before submitting it to OpenAI:** new sub-mailboxes can default to internal-only (`commLevel=1`, `extReceiveType=0`), which blocks OpenAI verification mail. The gate must pass with external receive enabled (`commLevel=2`, `extReceiveType=1`). Do not merely tell BOSS to do this manually: first try the logged-in ClawEmail Dashboard API `POST /api/v1/mailboxes/comm-settings?id=<mailboxId>` with `{commLevel:2, extReceiveType:1, extSendType:0}`. If the Dashboard is not logged in, open/login to it and ask BOSS only for the QQ master-mailbox 6-digit login code if the agent cannot read QQ mail. See `clawemail-operations` reference `references/clawemail-dashboard-comm-settings-openai-signup-2026-05-10.md` and this skill's `references/clawemail-external-receive-gate-openai-2026-05-10.md`.
|
||||
- Phone/SMS platform has no default. Keep `PHONE_VERIFICATION_ENABLED=false` and `PHONE_SMS_PROVIDER` empty unless BOSS configures one or approves enabling it after a phone verification appears.
|
||||
- If phone verification appears and BOSS has configured 5sim, use **SMS activation for `openai`**, not WhatsApp receive channels. The original extension's 5sim provider buys `/v1/user/buy/activation/{country}/{operator}/openai`, polls `/v1/user/check/{activationId}`, and finishes/cancels the activation. **Country selection priority is `FIVE_SIM_COUNTRY_ORDER` first** (comma-separated list such as `argentina,netherlands,indonesia`), then `FIVE_SIM_COUNTRY_ID`, then the original extension default `vietnam` only if both are empty. For each configured country, rotate numbers up to `PHONE_VERIFICATION_REPLACEMENT_LIMIT`; do **not** silently switch outside the configured order unless BOSS approves. Before buying/submitting a non-USA number, verify the OpenAI visible country selector is already the expected country (for example `阿根廷 (+54)`, `荷兰 (+31)`, `印度尼西亚 (+62)`, or `越南 (+84)`); if it reverted to `美国 (+1)`, fix the selector first or the number will be parsed as invalid. Use visible UI paste/click on `add-phone` when possible because CDP-only input mutation can desync React state and revert the country on submit. If a number is **not immediately rejected**, do not cancel it after one polling timeout: poll 5sim, click OpenAI `重新发送`, poll again, and retry resend at least once before canceling/rotating. If changing proxy (for example `1085` → `1083` or back), expect OpenAI auth session invalidation and restart from a fresh target OAuth URL. Codex2API env URLs may point at `/admin/accounts`; derive the API origin before calling `/api/admin/oauth/generate-auth-url`. If OpenAI returns `account_deactivated` after email verification, stop the current account and start with a new ClawEmail sub-mailbox instead of burning 5sim numbers. See `references/openai-add-phone-5sim-sms-activation-2026-05-10.md`, `references/openai-phone-verification-5sim-sms-2026-05-10.md`, `references/openai-phone-verification-proxy1083-resend-2026-05-10.md`, and `references/codex-oauth-token-lite-automation-flow-2026-05-10.md` for observed behavior, resend strategy, proxy-switch recovery, and pitfalls.
|
||||
- If phone verification appears and BOSS has configured 5sim, use **SMS activation for `openai`**, not WhatsApp receive channels. The original extension's 5sim provider buys `/v1/user/buy/activation/{country}/{operator}/openai`, polls `/v1/user/check/{activationId}`, and finishes/cancels the activation. **Before buying any 5sim number, pass the identity gate:** the browser must already be confirmed on `auth.openai.com/add-phone` for a usable OpenAI account. If OpenAI returns `account_deactivated`, if ClawEmail cannot create a new sub-mailbox due to quota, or if reused sub-mailboxes only show password mismatch, stop and ask BOSS to free mailbox quota/provide the correct password/approve another mailbox provider. **Country selection priority is `FIVE_SIM_COUNTRY_ORDER` first** (comma-separated list such as `argentina,netherlands,indonesia`), then `FIVE_SIM_COUNTRY_ID`, then the original extension default `vietnam` only if both are empty. For each configured country, rotate numbers up to `PHONE_VERIFICATION_REPLACEMENT_LIMIT`; do **not** silently switch outside the configured order unless BOSS approves. Before buying/submitting a non-USA number, verify the OpenAI visible country selector is already the expected country (for example `阿根廷 (+54)`, `荷兰 (+31)`, `印度尼西亚 (+62)`, or `越南 (+84)`); if it reverted to `美国 (+1)`, fix the selector first or the number will be parsed as invalid. Use visible UI paste/click on `add-phone` when possible because CDP-only input mutation can desync React state and revert the country on submit. If a number is **not immediately rejected**, do not cancel it after one polling timeout: poll 5sim, click OpenAI `重新发送`, poll again, and retry resend at least once before canceling/rotating. If changing proxy (for example `1085` → `1083` or back), expect OpenAI auth session invalidation and restart from a fresh target OAuth URL. Codex2API env URLs may point at `/admin/accounts`; derive the API origin before calling `/api/admin/oauth/generate-auth-url`. If OpenAI returns `account_deactivated` after email verification, stop the current account and start with a new ClawEmail sub-mailbox instead of burning 5sim numbers. See `references/openai-add-phone-5sim-sms-activation-2026-05-10.md`, `references/openai-phone-verification-5sim-sms-2026-05-10.md`, `references/openai-phone-verification-proxy1083-resend-2026-05-10.md`, `references/codex-oauth-token-lite-automation-flow-2026-05-10.md`, and `references/clawemail-quota-identity-gate-before-phone-verify-2026-05-10.md` for observed behavior, resend strategy, proxy-switch recovery, identity-gate checks, and pitfalls.
|
||||
- Plus mode uses `PLUS_PAYMENT_METHOD=gopay`. Any paid GoPay action still requires explicit confirmation immediately before payment/approval.
|
||||
- GoPay WhatsApp OTP uses **方案 A / manual checkpoint**: set `GOPAY_OTP_SOURCE=manual`. The extension detects OTP input and opens a side-panel prompt (`requestGoPayOtpInput` / “输入 GoPay 验证码”); BOSS pastes the WhatsApp code, then the extension fills OTP, fills `GOPAY_PIN`, and continues.
|
||||
- `GOPAY_OTP` should normally stay empty before the run. It is only a temporary prefill/cache for the current OTP dialog, not a durable secret.
|
||||
@@ -463,13 +463,24 @@ If `chrome://extensions` is empty and `extensions.settings` is empty, stop befor
|
||||
|
||||
A 2026-05-09 ordinary-registration test reached OpenAI's normal `email-verification` page with two fresh ClawEmail sub-mailboxes, but no OpenAI code arrived in inbox or spam even after resend. Both sub-mailboxes passed a self-send receive test, so the block was classified as OpenAI/ClawEmail deliverability rather than browser, proxy, extension, CAPTCHA, or phone-verification failure. See `references/openai-clawemail-verification-nondelivery-2026-05-09.md`.
|
||||
|
||||
When this happens:
|
||||
### OpenAI email verification does not arrive
|
||||
|
||||
1. Confirm the exact email in the OpenAI page body via DOM, not OCR only.
|
||||
2. Poll the **sub-mailbox profile**, not just the default primary mailbox profile.
|
||||
3. Check inbox and spam.
|
||||
4. Send a self-test email to the sub-mailbox and verify it arrives.
|
||||
5. If self-test works but OpenAI mail still does not arrive after resend, stop and record `openai_email_verification` failure; try a primary ClawEmail mailbox or another provider next.
|
||||
1. Confirm ClawEmail external receive is enabled on the **exact sub-mailbox** used for the run. Newly-created sub-mailboxes default to internal-only communication (`commLevel=1`, `extReceiveType=0`) and will silently miss OpenAI mail.
|
||||
2. For BOSS's setup, keep ClawEmail Dashboard master-login state in a **dedicated persistent Chrome profile**, not in the disposable Codex OAuth browser profile:
|
||||
- profile: `/Users/chick/.Hermes/workspace/browser-profiles/clawemail-dashboard-persistent`
|
||||
- CDP port: `9224`
|
||||
- URL: `https://claw.163.com/projects/dashboard/#/`
|
||||
The Codex OAuth Chrome profile/port 9223 may be killed or recreated frequently; do not store Dashboard master login there.
|
||||
3. After creating a run sub-mailbox, immediately update its communication settings before submitting it to OpenAI:
|
||||
- call Dashboard API base `https://claw.163.com/mailserv-claw-dashboard` (observed via `performance.getEntriesByType('resource')`, not bare `/api/v1/...`)
|
||||
- `GET /api/v1/workspaces` to obtain `workspaceId`
|
||||
- `GET /api/v1/mailboxes?workspaceId=<workspaceId>` to find the sub-mailbox `id`
|
||||
- `POST /api/v1/mailboxes/comm-settings?id=<mailboxId>` with JSON body `{"commLevel":2,"extReceiveType":1,"extSendType":0}`
|
||||
- verify with `mail-cli clawemail info --uid <submailbox> --json` that `commLevel=2` and `extReceiveType=1`
|
||||
4. Poll the **sub-mailbox profile**, not just the default primary mailbox profile. If the profile was deleted/recreated, fix `~/.config/mail-cli/config.json` or call `mail-cli` with a valid profile/user.
|
||||
5. Check inbox and spam.
|
||||
6. Send a self-test email to the sub-mailbox and verify it arrives.
|
||||
7. If self-test works but OpenAI mail still does not arrive after resend, stop and record `openai_email_verification` failure; try a primary ClawEmail mailbox or another provider next.
|
||||
|
||||
### Proxy not applied
|
||||
|
||||
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
# ClawEmail external-receive gate for OpenAI verification (2026-05-10)
|
||||
|
||||
Context: during a fresh Codex2API/OpenAI OAuth registration run with `socks5://192.168.2.8:1085`, a new ClawEmail sub-mailbox was created successfully:
|
||||
|
||||
```text
|
||||
chickliu.<8letters>@claw.163.com
|
||||
```
|
||||
|
||||
The OpenAI flow reached `https://auth.openai.com/email-verification` after password creation, but no OpenAI verification email arrived. `mail-cli clawemail info --uid ... --json` showed the newly-created sub-mailbox defaults to:
|
||||
|
||||
```json
|
||||
{
|
||||
"commLevel": 1,
|
||||
"extReceiveType": 0,
|
||||
"extSendType": 0
|
||||
}
|
||||
```
|
||||
|
||||
Meaning: internal communication only. External OpenAI mail is blocked unless communication settings are changed.
|
||||
|
||||
## Required gate before submitting a new sub-mailbox to OpenAI
|
||||
|
||||
After creating a per-run ClawEmail sub-mailbox and before using it in OpenAI registration:
|
||||
|
||||
1. Verify mailbox info:
|
||||
|
||||
```bash
|
||||
mail-cli clawemail info --uid "$NEW_UID" --json
|
||||
```
|
||||
|
||||
2. If it is not already external-receive enabled, stop and set it in ClawEmail Dashboard:
|
||||
|
||||
```text
|
||||
通讯规则 -> 开放外部通信 -> 收信范围:所有人
|
||||
```
|
||||
|
||||
Target state:
|
||||
|
||||
```json
|
||||
{
|
||||
"commLevel": 2,
|
||||
"extReceiveType": 1
|
||||
}
|
||||
```
|
||||
|
||||
3. Only after the gate passes, submit the mailbox to OpenAI / click resend verification.
|
||||
|
||||
## Why this matters
|
||||
|
||||
If the sub-mailbox remains `commLevel=1`, OpenAI verification mail may never arrive. Repeated resend attempts can also destabilize the OpenAI email-verification page (observed page class: HTTP 500 / `chrome-error://chromewebdata/`) and wastes a registration session.
|
||||
|
||||
## mail-cli profile pitfall after cleanup
|
||||
|
||||
If old test sub-mailboxes were deleted, named profiles such as `codex-current`, `codex-retry`, or `codex-zlajiqjc` can still point to deleted mailboxes. Polling with a stale profile can return errors like:
|
||||
|
||||
```text
|
||||
JWT_FETCH_FAILED / 资源不存在
|
||||
```
|
||||
|
||||
For new runs, either:
|
||||
|
||||
- update/create a profile for the new mailbox before polling, or
|
||||
- poll through the verified default/master profile only if the API actually exposes the new sub-mailbox's mail there.
|
||||
|
||||
Do not treat `JWT_FETCH_FAILED` from a stale profile as an OpenAI non-delivery signal.
|
||||
|
||||
## Recommended automation behavior
|
||||
|
||||
The low-token runner should include a `clawemail_external_receive_gate` phase:
|
||||
|
||||
```json
|
||||
{"phase":"clawemail_external_receive_gate","uid":"chickliu.<prefix>@claw.163.com","commLevel":1,"extReceiveType":0,"result":"blocked_requires_dashboard"}
|
||||
```
|
||||
|
||||
When blocked, emit a screenshot/instruction and stop before burning the OpenAI auth session or proceeding to 5sim.
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
# ClawEmail quota and reusable-account gate before phone verification (2026-05-10)
|
||||
|
||||
Context: after the OpenAI/Codex OAuth flow was mostly proven, BOSS asked to continue using `socks5://192.168.2.8:1085` and run the phone-verification part again. The current OpenAI account `chickliu.hykolnqk@claw.163.com` was already returning `account_deactivated`, so the expected path was to create a fresh ClawEmail sub-mailbox and reach `add-phone` again.
|
||||
|
||||
## What happened
|
||||
|
||||
Creating a fresh 8-letter ClawEmail sub-mailbox failed:
|
||||
|
||||
```text
|
||||
OPEN_API_1004
|
||||
邮箱数量已达上限
|
||||
```
|
||||
|
||||
The existing sub-mailboxes listed under `chickliu@claw.163.com` were:
|
||||
|
||||
```text
|
||||
chickliu.ktqcxzux@claw.163.com
|
||||
chickliu.zlajiqjc@claw.163.com
|
||||
chickliu.gmmpioju@claw.163.com
|
||||
chickliu.hykolnqk@claw.163.com
|
||||
```
|
||||
|
||||
Known state:
|
||||
|
||||
- `chickliu.hykolnqk@claw.163.com`: OpenAI returned `account_deactivated` after email-code submit.
|
||||
- `chickliu.gmmpioju@claw.163.com`: OpenAI recognized it as an existing account and showed password login; configured `CUSTOM_PASSWORD` returned `Incorrect email address or password`.
|
||||
- `chickliu.zlajiqjc@claw.163.com`: same password mismatch.
|
||||
- `chickliu.ktqcxzux@claw.163.com`: same password mismatch.
|
||||
|
||||
Result: no usable account reached `add-phone`, so no 5sim numbers were purchased. This avoided wasting SMS activations.
|
||||
|
||||
## Operational lesson
|
||||
|
||||
Before running the phone-verification phase, add an **identity gate**:
|
||||
|
||||
1. Check ClawEmail mailbox quota/list first.
|
||||
2. If the current account is `account_deactivated`, do not continue it.
|
||||
3. If a fresh sub-mailbox cannot be created because of quota, do not start 5sim.
|
||||
4. Existing sub-mailboxes are not automatically reusable. First verify either:
|
||||
- OpenAI login works with the configured password, or
|
||||
- the account is genuinely unregistered and can enter signup.
|
||||
5. If all existing sub-mailboxes are either deactivated or password-mismatch accounts, stop and ask BOSS to free quota/delete old sub-mailboxes, provide the correct password, or approve another mailbox provider.
|
||||
|
||||
## Low-token event examples
|
||||
|
||||
```json
|
||||
{"phase":"identity_gate","result":"clawemail_quota_full","code":"OPEN_API_1004"}
|
||||
{"phase":"identity_gate","email":"chickliu.gmmpioju@claw.163.com","result":"password_mismatch"}
|
||||
{"phase":"identity_gate","result":"no_usable_mailbox","next":"free_clawemail_quota_or_provide_password"}
|
||||
```
|
||||
|
||||
## Runner impact
|
||||
|
||||
The token-lite runner should implement this gate before `phone_verify`:
|
||||
|
||||
- `clawemail list` and parse `data.mailbox.subMailboxes`.
|
||||
- Attempt new sub-mailbox creation only if quota allows.
|
||||
- Maintain a local status file for each sub-mailbox with outcomes: `deactivated`, `password_mismatch`, `usable`, `unknown`.
|
||||
- Never buy a 5sim activation until the browser is confirmed to be on `auth.openai.com/add-phone`.
|
||||
+8
-1
@@ -22,7 +22,14 @@ Recommended phases:
|
||||
- Redact secrets in all printed output.
|
||||
- Validate selected target mode, Codex2API origin/admin key, ClawEmail profile, browser proxy, and 5sim settings.
|
||||
- Verify proxy TCP + exit IP with short timeouts.
|
||||
2. `browser_start`
|
||||
- If creating a fresh ClawEmail sub-mailbox, immediately open external receive before OpenAI submission: set/verify `commLevel=2` and `extReceiveType=1` via the logged-in ClawEmail Dashboard API `POST /api/v1/mailboxes/comm-settings?id=<mailboxId>` with `{commLevel:2, extReceiveType:1, extSendType:0}`. If Dashboard login requires QQ master-mailbox OTP and the agent cannot read QQ mail, pause only for that 6-digit code.
|
||||
2. `identity_gate`
|
||||
- Before any 5sim purchase, confirm there is a usable OpenAI identity path.
|
||||
- If creating a fresh ClawEmail sub-mailbox returns `OPEN_API_1004` / quota full, parse `data.mailbox.subMailboxes` and only reuse a mailbox after proving OpenAI login or signup can proceed.
|
||||
- After creating a fresh ClawEmail sub-mailbox, verify its communication rules before submitting it to OpenAI: target state is `commLevel=2` and `extReceiveType=1`. New sub-mailboxes can default to internal-only (`commLevel=1`, `extReceiveType=0`), which blocks OpenAI verification mail. If internal-only, stop with `blocked_requires_dashboard` and ask BOSS to enable `通讯规则 -> 开放外部通信 -> 收信范围:所有人` in the ClawEmail Dashboard.
|
||||
- Mark sub-mailbox outcomes locally (`deactivated`, `password_mismatch`, `usable`, `external_receive_blocked`, `unknown`).
|
||||
- If all candidates are deactivated/password-mismatch and quota is full, stop with `no_usable_mailbox` instead of buying SMS activations.
|
||||
3. `browser_start`
|
||||
- Kill only the dedicated CDP Chrome process for port 9223.
|
||||
- Start visible Chrome with a dedicated profile and `--proxy-server`.
|
||||
- Verify CDP `/json/version` and browser target.
|
||||
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
# Codex OAuth 1085 full run notes: ClawEmail permission + add-phone SMS/WhatsApp behavior (2026-05-10)
|
||||
|
||||
## Summary
|
||||
|
||||
This run used proxy `socks5://192.168.2.8:1085`, a fresh ClawEmail sub-mailbox, and a fresh Codex2API OAuth session. The email-registration part is now reproducible. The run reached OpenAI `https://auth.openai.com/add-phone` successfully.
|
||||
|
||||
Phone verification did not complete because OpenAI accepted the submitted phone numbers but 5sim SMS activation did not receive any SMS after resend. During some non-US country selections, the OpenAI page text changed to a WhatsApp-specific message, suggesting OpenAI may be trying WhatsApp delivery for those regions rather than SMS.
|
||||
|
||||
No full phone numbers or secrets are stored here.
|
||||
|
||||
## Working pieces confirmed
|
||||
|
||||
1. ClawEmail sub-mailbox can be created after cleaning old sub-mailboxes.
|
||||
2. Newly-created ClawEmail sub-mailboxes default to internal-only communication:
|
||||
- `commLevel=1`
|
||||
- `extReceiveType=0`
|
||||
- `extSendType=0`
|
||||
3. External OpenAI mail will not arrive until the sub-mailbox communication setting is changed.
|
||||
4. A dedicated persistent Dashboard browser should be used for master mailbox login:
|
||||
- profile: `/Users/chick/.Hermes/workspace/browser-profiles/clawemail-dashboard-persistent`
|
||||
- CDP port: `9224`
|
||||
- URL: `https://claw.163.com/projects/dashboard/#/`
|
||||
5. The ClawEmail Dashboard API base is not bare `/api/v1`; it is:
|
||||
- `https://claw.163.com/mailserv-claw-dashboard`
|
||||
6. After Dashboard login, the sub-mailbox permission can be updated through:
|
||||
- `GET /api/v1/workspaces`
|
||||
- `GET /api/v1/mailboxes?workspaceId=<workspaceId>`
|
||||
- `POST /api/v1/mailboxes/comm-settings?id=<mailboxId>`
|
||||
- body: `{"commLevel":2,"extReceiveType":1,"extSendType":0}`
|
||||
7. Verification command:
|
||||
- `mail-cli clawemail info --uid <submailbox> --json`
|
||||
- expected: `commLevel=2`, `extReceiveType=1`
|
||||
8. Once external receive is enabled, OpenAI email codes arrive at the sub-mailbox. In this run, OpenAI sent both temporary login-code style messages and email-verification codes; reading the full body is more reliable than scanning list previews.
|
||||
|
||||
## OpenAI add-phone page country selection
|
||||
|
||||
The country selector is backed by a real hidden/native `select` element with ISO country codes. React Aria click events were unreliable in CDP. The reliable approach was setting the native select directly and dispatching input/change:
|
||||
|
||||
```js
|
||||
const sel = document.querySelector('select');
|
||||
sel.focus();
|
||||
sel.value = 'AR'; // AR, NL, ID, VN, etc.
|
||||
sel.dispatchEvent(new Event('input', {bubbles: true}));
|
||||
sel.dispatchEvent(new Event('change', {bubbles: true}));
|
||||
await new Promise(r => setTimeout(r, 800));
|
||||
```
|
||||
|
||||
Then verify the visible button text, e.g.:
|
||||
|
||||
```js
|
||||
[...document.querySelectorAll('button')]
|
||||
.map(b => b.innerText)
|
||||
.find(t => /\(\+\d+\)/.test(t))
|
||||
```
|
||||
|
||||
Expected values observed:
|
||||
|
||||
- Argentina: `阿根廷 (+54)`
|
||||
- Netherlands: `荷兰 (+31)`
|
||||
- Indonesia: `印度尼西亚 (+62)`
|
||||
|
||||
## 5sim country-order run results
|
||||
|
||||
Configured order:
|
||||
|
||||
```text
|
||||
argentina -> netherlands -> indonesia
|
||||
```
|
||||
|
||||
The run used 5sim SMS activation (`product=openai`, operator `any`), not WhatsApp channels.
|
||||
|
||||
Results:
|
||||
|
||||
- Argentina: activation `1006713742`, OpenAI did not direct-reject; 5sim status stayed `RECEIVED`, no SMS after initial polling + resend; order canceled.
|
||||
- Netherlands: activation `1006714867`, OpenAI did not direct-reject; 5sim status stayed `RECEIVED`, no SMS after initial polling + resend; order canceled.
|
||||
- Indonesia: activation `1006715764`, OpenAI did not direct-reject; 5sim status stayed `RECEIVED`, no SMS after initial polling + resend; order canceled.
|
||||
|
||||
## Important behavior observed
|
||||
|
||||
For Argentina, after selecting the country, OpenAI page text changed from generic SMS wording:
|
||||
|
||||
```text
|
||||
我们将向该号码发送一次性验证码以进行验证。
|
||||
```
|
||||
|
||||
to WhatsApp wording:
|
||||
|
||||
```text
|
||||
我们会通过 WhatsApp 向该号码发送一次性验证码进行验证。
|
||||
```
|
||||
|
||||
This likely explains why 5sim SMS activation did not receive codes even though OpenAI did not direct-reject the numbers. Future phone tests should detect page wording before buying SMS numbers:
|
||||
|
||||
- If page says generic SMS/one-time code, continue 5sim SMS.
|
||||
- If page explicitly says WhatsApp, either stop before buying SMS or switch to a WhatsApp-capable provider only if BOSS explicitly approves. BOSS previously said OpenAI/Codex接码必须用 SMS, not WhatsApp.
|
||||
|
||||
## Automation improvements for next runner
|
||||
|
||||
1. After creating ClawEmail sub-mailbox, immediately update Dashboard communication settings.
|
||||
2. Persist Dashboard master login in profile 9224; never put it in disposable OAuth profile 9223.
|
||||
3. Read full OpenAI email body to extract code, not only message list preview.
|
||||
4. Use native select `.value = ISO` for country selection.
|
||||
5. Before buying 5sim, inspect page text for WhatsApp wording. If WhatsApp wording appears and policy is SMS-only, emit blocker and do not buy.
|
||||
6. If OpenAI accepted number and navigates to phone-verification but no SMS arrives, resend once, poll again, cancel order, and log compact JSONL.
|
||||
7. Some OpenAI phone-verification transitions produce `chrome-error://chromewebdata/` HTTP 500 after waiting/resend. Recover by generating a fresh Codex2API OAuth session and logging in with the same email/password; the account returns to add-phone.
|
||||
Reference in New Issue
Block a user