Files
codex-oauth-plus-onboarding…/skill/codex-oauth-plus-onboarding/references/sms-provider-abstraction-and-luban-2026-05-11.md
T

2.3 KiB

OpenAI phone verification provider abstraction — Luban SMS lessons

This note captures reusable lessons from adding Luban SMS as a second SMS provider for Codex/OpenAI phone verification.

Why provider abstraction matters

The original runner assumed 5sim semantics:

activation id = id
phone field = phone
poll = /user/check/<id>
cancel = /user/cancel/<id>
finish = /user/finish/<id>

Luban semantics differ:

activation id = request_id
phone field = number
poll = /getSms?request_id=...
cancel/release = /setStatus?request_id=...&status=reject
finish = no explicit API; local no-op after browser accepts code

Future SMS providers should be added behind functions like:

sms_buy(country) -> {activation_id, phone, metadata}
sms_check(activation_id) -> wait/success/code/expired
sms_cancel(activation_id)
sms_finish(activation_id)

Keep browser/OpenAI page logic independent from provider-specific APIs.

Verification before spending

When adding a new SMS provider, first do non-spending probes only:

  1. Balance/profile endpoint.
  2. Service/country lookup endpoint.
  3. Resolve target OpenAI/ChatGPT service id.
  4. Compile/smoke-test helper scripts.

Do not buy a number just to prove integration unless BOSS explicitly asks.

Luban-specific quirks

  • API docs say all requests are GET under https://lubansms.com/v2/api with apikey query parameter.
  • Python urllib without a browser-like User-Agent returned HTTP 403; adding a Chrome UA returned HTTP 200.
  • Service lookup uses /List?country=<countryName>&service=OpenAI&language=en&page=1.
  • OpenAI can appear as OpenAI, OpenAI / ChatGpt, etc.; dynamic matching is safer than hardcoding a service id.
  • /getSms states:
    • {"code":0,"msg":"wait",...} -> keep polling
    • {"code":0,"msg":"success","sms_code":"123456"} -> submit code
    • {"code":400,"msg":"wrong_status"} -> expired/closed/no longer usable
  • Release with /setStatus?...&status=reject.

Logging/redaction

Never print:

apikey
full phone number
SMS code
OAuth callback code/state

Safe logs:

{"http":200,"ok":true,"balance":"2.000"}
{"ok":true,"selected":{"service_id":"...","country_en":"...","service_name":"OpenAI","provider":"...","cost":0.05}}

Phone numbers should be redacted to suffix-only at most, e.g. [REDACTED]1234.