Files
codex-oauth-plus-onboarding…/SKILL.md
T

24 KiB
Raw Blame History

name, description, version, author, license, metadata
name description version author license metadata
codex-oauth-plus-onboarding Low-token, stable workflow for BOSS's Codex/OpenAI OAuth onboarding: ClawEmail signup, optional 5sim SMS phone verification, and callback import into CPA/Codex2API/SUB2API. 2.0.0 Hermes Agent MIT
hermes
tags related_skills
codex
oauth
clawemail
5sim
cpa
codex2api
sub2api
browser-automation
clawemail-operations
browser-extension-storage-audit

Codex OAuth + CPA/Codex2API Onboarding — low-token runbook

Use when BOSS asks to register/login an OpenAI/Codex OAuth account, verify it via ClawEmail and possibly 5sim SMS, then import the OAuth callback into CPA / CLI Proxy API, Codex2API, or SUB2API.

Safety: BOSS-owned infra/accounts only. Stop for CAPTCHA/security challenge/payment confirmation unless BOSS explicitly approves the next step. Never reveal API keys, passwords, proxy URLs, full phone numbers, OAuth code=, SMS/email codes, admin keys, or tokens; report [REDACTED].

0. Required companion skill

Before ClawEmail work, load:

clawemail-operations

1. Low-token operating mode

Prefer script-driven runs that emit compact JSONL. Only send screenshots or long logs when a gate fails.

Tool/reporting rules

  • Read secrets only from ~/.hermes/env/codex_oauth_onboarding.env; do not paste them into chat.
  • Do not blindly source this env file in shell: values such as CHROME_BIN=/Applications/Google Chrome.app/... may contain spaces and break source if unquoted. For probes/runners, parse KEY=VALUE safely in Python or require quoted values before shell sourcing.
  • Reports should contain: phase, account email, country slug, activation id, high-level status, HTTP status, and redacted error class.
  • Avoid dumping HTML, callback URLs, headers, full 5sim responses, or full phone numbers.
  • Save detailed evidence to references/ or local logs; final response stays concise.

2. Environment constants for BOSS

env: ~/.hermes/env/codex_oauth_onboarding.env
workspace: /Users/chick/.Hermes/workspace
OAuth Chrome CDP default: 9223
ClawEmail Dashboard CDP default: 9224
OAuth profile root: /Users/chick/.Hermes/workspace/browser-profiles/codex-oauth
Dashboard profile: /Users/chick/.Hermes/workspace/browser-profiles/clawemail-dashboard-persistent
Preferred browser proxy when unspecified: socks5://192.168.2.8:1085
Chrome: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

Use visible Google Chrome for OpenAI/Auth pages. Do not use BOSS's personal browser profile.

3. Hard gates — do not skip

  1. Target gate: exactly one target mode: cpa, codex2api, or sub2api. No default if env is empty.
  2. Password gate: CUSTOM_PASSWORD must be set unless BOSS approves generating one.
  3. Proxy gate: verify proxy TCP and OpenAI reachability before browser flow.
  4. Mailbox gate: new ClawEmail sub-mailbox must have external receive enabled before OpenAI signup.
  5. OpenAI identity gate before phone: only buy 5sim if active page is a usable https://auth.openai.com/add-phone for a non-deactivated account.
  6. Country gate before phone buy/submit: OpenAI select value and visible dial code must match target country before buying and again before clicking Continue.
  7. SMS-only gate: if OpenAI resend channel probes as WhatsApp, do not click it; cancel/rotate under SMS-only policy.
  8. Callback state gate: callback state must match generated OAuth state when known.
  9. Payment gate: any Plus/GoPay paid action needs explicit BOSS confirmation.
Need OAuth import?
  ├─ Target CPA available? → prefer CPA (most reliable after 2026-05-10 success)
  ├─ Codex2API requested? → try Codex2API; if token exchange returns unsupported_country_region_territory, switch/fix backend proxy or use CPA
  └─ SUB2API requested? → use original extension/content-script path

Need new OpenAI account?
  ├─ Create ClawEmail sub-mailbox with 8 lowercase letters
  ├─ Enable external receive via Dashboard API
  ├─ Submit email/password, poll ClawEmail code
  └─ If phone page appears → 5sim SMS flow

Already phone-verified account?
  └─ Generate fresh target OAuth URL, login/consent, submit callback to target

5. ClawEmail sub-mailbox gate

BOSS preference: per-run ClawEmail prefix is exactly 8 lowercase letters with no codex prefix, e.g. chickliu.ktqcxzux@claw.163.com.

After creation, enable external receive. Observed Dashboard API base:

https://claw.163.com/mailserv-claw-dashboard/api/v1

Do not use relative /api/v1/... if it returns public ClawEmail HTML. Working sequence: GET <base>/workspaces -> GET <base>/mailboxes?workspaceId=<workspaceId> -> find the target sub-mailbox id -> POST <base>/mailboxes/comm-settings?id=<mailboxId> with the payload above. If controlling the persistent Dashboard Chrome on CDP 9224 fails with Handshake status 403 Forbidden ... remote-allow-origins, use websocket.create_connection(ws_url, suppress_origin=True) or restart Chrome with --remote-allow-origins=*.

Required final values:

{"commLevel":2,"extReceiveType":1,"extSendType":0}

Use Dashboard persistent Chrome/profile for master login, not the disposable OAuth profile. If Dashboard login needs a master QQ mailbox code and the agent cannot retrieve it, ask BOSS. If automating through CDP, Chrome may reject WebSocket Origin unless launched with --remote-allow-origins=*; Python websocket-client can connect with suppress_origin=True. If relative /api/v1/workspaces returns raw/empty data, inspect Dashboard resource URLs and try the full https://claw.163.com/mailserv-claw-dashboard/api/v1/... base before diagnosing mailbox absence; see clawemail-operations reference references/clawemail-dashboard-cdp-origin-and-api-base-pitfalls-2026-05-10.md.

Key references:

  • references/clawemail-external-receive-gate-openai-2026-05-10.md
  • references/clawemail-random-suffix-policy-2026-05.md

6. OpenAI email/profile flow

Minimal flow:

fresh OAuth URL / signup page
submit ClawEmail sub-mailbox using real CDP input events, not only `input.value=`
submit CUSTOM_PASSWORD using real CDP input events
poll ClawEmail inbox/spam for OpenAI code using a mail-cli config/profile that points to the exact sub-mailbox
submit code using real CDP input events
fill profile/about-you if shown
continue to phone or OAuth consent

OpenAI Auth can route a fresh sub-mailbox first to log-in/password; if the password attempt returns Incorrect email address or password, click visible 注册 / Sign up and continue on create-account. Navigation after code/password submit can close the inspected CDP target; reattach and inspect before retrying.

mail-cli default profile may still point to chickliu@claw.163.com; it will not show mail delivered to chickliu.<suffix>@claw.163.com. For sub-mailbox code polling, create a temp config/profile for that UID before mail list/read body; see clawemail-operations reference references/submailbox-profile-polling-openai-code-2026-05-10.md.

Expected fields observed in 2026-05-11 run:

input[name=name] type=text required
input[name=age] type=number required
input[name=birthday] type=hidden

Set name and a valid numeric age explicitly with the native input value setter and dispatch input/change; optionally set hidden birthday consistently. Do not fill every input with the same generic text.

If OpenAI returns account_deactivated, stop that account immediately and do not buy 5sim numbers.

If login recovery hits Incorrect email address or password, invalid_state, stale email verification, or tab ambiguity, stop before buying phone numbers; recover account/page first. For existing accounts with password failure, the login-page 使用一次性验证码登录 path may send an email code, but mail-cli output is not guaranteed newest-first: parse/sort the date field and submit the newest OpenAI login mail. Do not use passwordless signup (使用一次性验证码注册) for an existing account; it can return passwordless_signup_disabled. If a fresh email-code submission returns account_deactivated, stop the account immediately even if phone verification previously succeeded.

7. 5sim SMS phone flow

If login recovery hits Incorrect email address or password, invalid_state, stale email verification, or tab ambiguity, stop before buying phone numbers; recover account/page first. For existing accounts with password failure, the login-page 使用一次性验证码登录 path may send an email code, but mail-cli output is not guaranteed newest-first: parse/sort the date field and submit the newest OpenAI login mail. Do not use passwordless signup (使用一次性验证码注册) for an existing account; it can return passwordless_signup_disabled. If a fresh email-code submission returns account_deactivated, stop the account immediately even if phone verification previously succeeded.

7. 5sim SMS phone flow

Use SMS activation provider selected by PHONE_SMS_PROVIDER:

5sim (default): PHONE_SMS_PROVIDER=5sim
Luban SMS:      PHONE_SMS_PROVIDER=luban

Luban SMS provider

Docs: https://lubansms.com/api_docs/. All endpoints are GET under:

https://lubansms.com/v2/api

Env:

LUBAN_SMS_API_KEY=[REDACTED]
LUBAN_SMS_API_BASE=https://lubansms.com/v2/api
LUBAN_SMS_SERVICE_QUERY=OpenAI
LUBAN_SMS_LANGUAGE=en

Important API quirk: requests without a browser-like User-Agent may return HTTP 403. Use a Chrome UA.

Core endpoints:

BALANCE:  /getBalance?apikey=...
SERVICES: /List?apikey=...&country=<countryName>&service=OpenAI&language=en&page=1
BUY:      /getNumber?apikey=...&service_id=<service_id>
CHECK:    /getSms?apikey=...&request_id=<request_id>
CANCEL:   /setStatus?apikey=...&request_id=<request_id>&status=reject
HISTORY:  /smsHistory?apikey=...&language=en&page=1

Observed OpenAI service lookup returns entries such as OpenAI / ChatGpt and OpenAI; cheapest current match can be resolved with:

/Users/chick/homebrew/opt/python@3.11/bin/python3.11 \
  /Users/chick/.hermes/skills/software-development/codex-oauth-plus-onboarding/scripts/luban_sms.py \
  resolve --service OpenAI --language en --pages 5

Verified 2026-05-11 with BOSS key: balance API OK, balance 2.000; service list OK. Do not print the key. The helper script is at scripts/luban_sms.py.

If using the long-running runner:

PHONE_SMS_PROVIDER=luban START_USED_NUMBERS=<prior> MAX_NEW_NUMBERS=<cap> CDP_PORT=<port> \
  /Users/chick/homebrew/opt/python@3.11/bin/python3.11 \
  /Users/chick/.hermes/skills/software-development/codex-oauth-plus-onboarding/scripts/phone_verify_until_success.py

5sim legacy API:

PHONE_SMS_PROVIDER=5sim
FIVE_SIM_OPERATOR=any
FIVE_SIM_PRODUCT=openai
FIVE_SIM_SERVICE=openai
BUY:    /v1/user/buy/activation/{country}/any/openai
CHECK:  /v1/user/check/{activation_id}
FINISH: /v1/user/finish/{activation_id}
CANCEL: /v1/user/cancel/{activation_id}

Country precedence for configured runs:

FIVE_SIM_COUNTRY_ORDER > FIVE_SIM_COUNTRY_ID > vietnam fallback only if both empty

For free-country exploration, ignore stale configured order if BOSS explicitly says unrestricted. Count only real activations with ids toward the budget. no free phones, pre-buy country-gate errors, CDP errors, or OAuth recovery failures are not attempts.

Known mappings:

vietnam -> VN -> 越南 (+84) -> 84
argentina -> AR -> 阿根廷 (+54) -> 54
netherlands -> NL -> 荷兰 (+31) -> 31
indonesia -> ID -> 印度尼西亚 (+62) -> 62
italy -> IT -> 意大利 (+39) -> 39
poland -> PL -> 波兰 (+48) -> 48
spain -> ES -> 西班牙 (+34) -> 34
england -> GB -> 英国 (+44) -> 44
chile -> CL -> 智利 (+56) -> 56
portugal -> PT -> 葡萄牙 (+351) -> 351
germany -> DE -> 德国 (+49) -> 49
romania -> RO -> 罗马尼亚 (+40) -> 40

Phone handling:

OpenAI immediate reject (`无法向此电话号码发送验证码`) or invalid-phone (`电话号码无效`) → cancel activation, rotate
No immediate reject → poll 5sim
Before resend → probe channel text/value/aria/title
  ├─ WhatsApp → cancel/rotate (SMS-only)
  └─ SMS/unknown → click resend, poll again
SMS received → prefer a 6-digit code candidate for OpenAI phone verification; submit code, verify page leaves phone-verification, then finish activation
Interrupted runner → inspect/cancel active RECEIVED activations immediately

If a broad SMS regex finds 4-8 digit candidates, prefer (?<!\d)(\d{6})(?!\d) first for OpenAI phone verification. A 2026-05-11 run mistakenly selected a 4-digit candidate from the 5sim SMS blob while the page required 6 characters; the activation was already FINISHED, but re-checking the finished activation and extracting a 6-digit candidate allowed successful submission. Do not call 5sim finish until the browser leaves phone-verification unless you have separately verified the SMS code was accepted.

When replacing a rejected/invalid number on the same OpenAI add-phone page, clear the visible input[type=tel] using real keyboard select-all/backspace before inserting the next number; JS-only .value='' can leave the hidden phoneNumber/React state stale. Vietnam-only test on 2026-05-10 had 7 immediate rejects/invalids despite correct VN / 越南 (+84) gate; see references/openai-add-phone-vietnam-only-rejects-2026-05-10.md. Later the same verified account was relaunched with the same Chrome user-data-dir but proxy changed from 1085 to 1083 (--proxy-server=socks5://192.168.2.8:1083, new CDP port 9226); the page stayed on add-phone but country reset to US, so rerun the country gate before buying. 1083 + Vietnam still produced 5 immediate rejects/invalids; see references/openai-vietnam-phone-rejects-proxy1085-1083-2026-05-10.md.

A later unrestricted continuation succeeded on the 335th actual activation (Indonesia, 5sim FINISHED); see references/openai-phone-335-success-cpa-oauth-login-session-pitfalls-2026-05-11.md. That run exposed post-phone pitfalls: fill about-you fields explicitly (name, age, hidden birthday), avoid Chrome /json/new?<oauth_url> for CPA OAuth because it can produce OpenAI unknown_error, and use same-tab Page.navigate instead. If phone is already verified but CPA OAuth still fails with Workspaces not found in client auth session, unknown_error, Incorrect email address or password, invalid_state, or passwordless_signup_disabled, treat it as an Auth/session/credential problem, not an SMS/proxy problem; do not keep buying phone numbers for the same account.

Multi-country / free-country runner stability:

  • Count only real 5sim activations with ids toward requested totals. no free phones, country-gate failures, page recovery failures, and CDP errors do not count.
  • Log compact JSONL phases: activation_bought, phone_submitted, activation_cancel_rejected, sms_timeout_cancel, sms_received, and final summary. This makes it possible to top up to an exact activation count after page interruptions.
  • If OpenAI reaches phone-verification but page text says the code was sent by WhatsApp, treat it as SMS-only failure: poll 5sim briefly if already purchased, cancel on zero SMS, then explicitly navigate back to https://auth.openai.com/add-phone before continuing; otherwise later country gates fail because the page remains on phone-verification.
  • For OpenAI SMS/email verification code extraction, prefer strict 6-digit extraction ((?<!\d)(\d{6})(?!\d)) over broad 48 digit matching; broad matching can capture unrelated numbers and leave the page on “code incorrect”.
  • If OpenAI shows 糟糕,出错了! Bad request after many attempts/cancellations, click retry/reload or navigate directly to https://auth.openai.com/add-phone, then verify phone-country controls before buying another number.?!\d)`) over broad 48 digit matching; broad matching can capture unrelated numbers and leave the page on “code incorrect”.
  • If OpenAI shows 糟糕,出错了! Bad request after many attempts/cancellations, click retry/reload or navigate directly to https://auth.openai.com/add-phone, then verify phone-country controls before buying another number.
  • OpenAI phone/SMS codes are normally 6 digits. Do not extract a generic 48 digit token from serialized 5sim objects before checking page requirements; prefer (?<!\d)(\d{6})(?!\d) from the SMS message text, and only finish the 5sim activation after the page has left phone-verification.
  • If a country repeatedly enters WhatsApp-only verification (e.g. Germany in the 2026-05-11 run), skip/reorder it for top-up attempts unless BOSS explicitly wants to keep testing that country.

See references/free-country-openai-phone-20-activation-failure-2026-05-11.md for the session details: 1083 free-country 20 actual activations, WhatsApp-only Germany/Argentina cases, Bad Request recovery, top-up accounting, and cancellation verification.

When BOSS asks to keep running “until it works” and report how many numbers were used, use the bundled long-running script instead of manual 20-number chunks:

START_USED_NUMBERS=<prior-real-activations> MAX_NEW_NUMBERS=300 CDP_PORT=<port> \
  /Users/chick/homebrew/opt/python@3.11/bin/python3.11 \
  /Users/chick/.hermes/skills/software-development/codex-oauth-plus-onboarding/scripts/phone_verify_until_success.py \
  | tee /tmp/phone_verify_until_success.log

The script emits new_numbers and total_numbers, persists /tmp/phone_verify_until_success_state.json, and keeps /tmp/current_fivesim_activation_id.txt updated for interruption cleanup. MAX_NEW_NUMBERS=0 means unlimited; otherwise keep a safety cap unless BOSS explicitly approves unlimited spend. See references/until-success-phone-runner-cumulative-accounting-2026-05-11.md.

Known result: free-country run succeeded with Vietnam SMS, activation 1006871765, status FINISHED; OpenAI phone verification passed. See references/openai-phone-free-country-vietnam-sms-success-codex2api-region-block-2026-05-10.md.

8. CPA / CLI Proxy API — preferred callback target

CPA succeeded where Codex2API failed. Use this when CPA_VPS_URL and CPA_VPS_PASSWORD are configured.

Derive API origin:

origin = new URL(CPA_VPS_URL).origin
# e.g. http://192.168.2.62:8317/management.html -> http://192.168.2.62:8317

Headers, matching original extension:

Authorization: Bearer [CPA_VPS_PASSWORD]
X-Management-Key: [CPA_VPS_PASSWORD]
Accept: application/json
Content-Type: application/json

Generate OAuth URL:

GET <origin>/v0/management/codex-auth-url
# UI also uses: GET <origin>/v0/management/codex-auth-url?is_webui=true

Extract URL from url|auth_url|authUrl|data.*; extract state from payload or URL. In Chrome 147/CDP, opening this URL via /json/new?... can route to OpenAI unknown_error; prefer navigating the current intended auth tab with Page.navigate when retrying fresh CPA URLs.

Submit callback:

POST <origin>/v0/management/oauth-callback
{"provider":"codex","redirect_url":"http://localhost:1455/auth/callback?code=[REDACTED]&state=[REDACTED]"}

Verify:

GET <origin>/v0/management/get-auth-status?state=<state>  -> {"status":"ok"}
GET <origin>/v0/management/auth-files                    -> codex-<email>-free.json active

OAuth recovery pitfalls after phone success:

  • Do not keep buying phone numbers once OpenAI has left phone-verification; report phone success separately from OAuth/CPA import status.
  • If Codex consent shows Workspaces not found in client auth session, the account/session lacks a usable ChatGPT workspace. Establish a valid ChatGPT web session/workspace first, then generate a new CPA OAuth URL; repeatedly clicking retry on the same consent error does not fix it.
  • If one-time-code login is needed after password login fails, request it from a fresh auth page/state. A stale password page may make 使用一次性验证码登录 return invalid_state; polling ClawEmail may still find a code, but submitting it on the stale error page will not recover.
  • If many fresh CPA URLs start returning OpenAI /error unknown_error despite normal URL parameters, close auth tabs/restart the automation Chrome and consider pausing/restarting CPA before generating another URL.

Do not use root /codex-auth-url or /api/auth/url; they can 404 or return unrelated amp upstream proxy not available.

References:

  • references/cpa-original-extension-api-notes-2026-05-10.md
  • references/cpa-panel-codex-oauth-success-2026-05-10.md

9. Codex2API target

Generate URL:

POST <origin>/api/admin/oauth/generate-auth-url
Header: X-Admin-Key: [CODEX2API_ADMIN_KEY]
Body: {}

Expected response contains:

{"auth_url":"...","session_id":"..."}

Exchange callback:

POST <origin>/api/admin/oauth/exchange-code
Header: X-Admin-Key: [CODEX2API_ADMIN_KEY]
{"session_id":"...","code":"[REDACTED]","state":"..."}

If callback/token exchange returns unsupported_country_region_territory, browser-side OAuth is not the issue. The backend token exchange path needs a supported outbound proxy or use CPA.

10. SUB2API target

Use original extension/content-script route for SUB2API panel login, group, proxy, priority, and callback exchange. Do not invent direct API endpoints unless re-confirmed from source/UI.

11. Browser/CDP hygiene

Before fresh OAuth recovery:

close stale auth.openai.com / phone-verification / localhost callback tabs
keep only the current intended target tab
prefer same-tab Page.navigate for CPA OAuth URLs; avoid Chrome /json/new?<oauth_url> when OpenAI starts returning unknown_error

Use visible Chrome with isolated profile. Chrome stable may ignore --load-extension; verify extension card/sidepanel if using the extension. Manual CDP flow is acceptable when BOSS only wants registration/OAuth tested; still follow all gates.

When connecting to Chrome CDP with websocket-client, Chrome may reject the WebSocket handshake with 403 Forbidden unless the client sends an allowed Origin or Chrome was launched with --remote-allow-origins=*. Prefer launching automation Chrome with --remote-allow-origins=*; for an already-running CDP instance, pass origin='http://127.0.0.1:<port>' or a matching allowed origin to websocket.create_connection(...) before assuming CDP is down.

12. Plus / GoPay

Default ordinary account test:

PLUS_MODE_ENABLED=false

If Plus is requested:

PLUS_PAYMENT_METHOD=gopay
GOPAY_OTP_SOURCE=manual
GOPAY_OTP empty by default

Stop immediately before paid confirmation and ask BOSS.

13. Verification checklist before final report

  • New mailbox external receive enabled and recorded.
  • OpenAI email verification completed or classified.
  • If phone appeared: all active 5sim orders are FINISHED or CANCELED.
  • If SMS succeeded: OpenAI left phone-verification page.
  • OAuth callback submitted to chosen target.
  • Target has active account/session/auth file.
  • Final report redacts secrets, callback codes, SMS/email codes, full phone numbers, API keys, passwords, proxy strings.
  • If new learning occurred, update this skill or a reference.

14. Evidence and history references

Full pre-rewrite skill was archived at:

references/SKILL-full-before-low-token-rewrite-2026-05-10.md

High-value references:

references/env-parsing-and-cdp-origin-pitfalls-2026-05-10.md
references/cpa-original-extension-api-notes-2026-05-10.md
references/cpa-panel-codex-oauth-success-2026-05-10.md
references/openai-phone-free-country-vietnam-sms-success-codex2api-region-block-2026-05-10.md
references/openai-add-phone-strict-country-gate-2026-05-10.md
references/openai-add-phone-free-country-runner-policy-2026-05-10.md
references/openai-login-recovery-gate-before-phone-runs-2026-05-10.md
references/openai-oauth-tab-cleanup-before-recovery-2026-05-10.md
references/openai-phone-country-scheduler-cyclic-chunks-2026-05-10.md
references/clawemail-external-receive-gate-openai-2026-05-10.md
references/openai-add-phone-chile-no-free-phones-2026-05-10.md
references/openai-add-phone-eu4-total20-real-activations-2026-05-10.md
references/openai-vietnam-phone-rejects-proxy1085-1083-2026-05-10.md
references/free-country-openai-phone-20-activation-failure-2026-05-11.md
references/openai-phone-free-country-continuation-1083-2026-05-11.md
references/openai-email-code-login-account-deactivated-2026-05-11.md
references/official-extension-phone-update-2026-05-10.mdenai-email-code-login-account-deactivated-2026-05-11.md
references/official-extension-phone-update-2026-05-10.md