55 lines
11 KiB
Markdown
55 lines
11 KiB
Markdown
# apiclaw.biz invite-flow + Outlook mailbox autoreg (ai-register-machine)
|
||
|
||
Два связанных пайплайна: (1) реверс invite-регистрации LiteLLM-гейтвея apiclaw.biz, (2) генерация свежих Outlook-ящиков через ai-register-machine как источник whitelist-почты.
|
||
|
||
## 1. apiclaw.biz — протокол регистрации (FastAPI за Next.js UI)
|
||
|
||
Whitelist доменов (точный текст 422 «Use an email from a supported provider»): Gmail, Yahoo, Outlook, Hotmail, AOL, iCloud, Proton, Zoho; t-online.de/web.de/gmx → 422. Проверено:
|
||
- `+plus` алиасы → **422** «Plus-addressed emails are…» — стратегия мертва, не использовать.
|
||
- dot-алиасы занятого ящика → **409** «You already have an account. Log in instead.» — 409 означает «ящик уже зареган», для E2E это допустимый сигнал (переходить к логину), а не ошибка прокси.
|
||
- **409 — НЕ всегда «ящик занят»: регистрация может быть глобально закрыта и маскироваться под 409.** Дифференциальная проба: signup РАНДОМНОГО несуществующего ящика whitelisted-домена (`brx<hex>@gmail.com`) → 409 = регистрация закрыта (валидации домена/плюса при этом продолжают работать — 422 приходит раньше 409, значит бэкенд жив). Повторить с другого egress (VPS-прокси) чтобы исключить IP-лимит: 409 с обоих = глобально закрыто. Не жечь часы на «починку» пайплайна, который упирается в закрытую регистрацию.
|
||
- На 409-аккаунты invitation письмо НЕ отправляется (inbox и spam пусты) — такие акки мертвы до открытия регистрации; не гонять на них mail-reader.
|
||
- Нужен свежий УНИКАЛЬНЫЙ ящик whitelisted-домена → ветки Outlook-авторега (§2) и Proton-фермы (references/proton-signup-slider-and-mail-reader.md).
|
||
- **Watcher закрытой регистрации**: тихий cron (no_agent, пустой stdout = нет доставки) раз в 30м шлёт probe-signup рандомным ящиком; 409 → молча exit 0; не-409 → алерт в TG + авто-прогон всего банка ящиков через E2E-конвейер. Скрипты: apiclaw_watch.py + wrapper scripts/apiclaw_watch_cron.py (venv-python проекта, relay stdout), cron job apiclaw-signup-watch.
|
||
|
||
Эндпоинты (порядок флоу):
|
||
1. `GET /public/auth-config` — содержит Turnstile sitekey (не хардкодить, читать в рантайме).
|
||
2. `POST /public/signup` payload `{user_email, turnstile_token, browser_session_id: <uuid4>}`; заголовки Chrome-UA + `Origin/Referer: https://apiclaw.biz`.
|
||
3. Invitation письмо, subject `APIClaw`, ссылка `https://apiclaw.biz/ui?invitation_id=<uuid>` (редирект `/ui/onboarding?invitation_id=`).
|
||
4. `GET /onboarding/get_token?invite_link=<uuid>` → outer JWT; в claims — inner key + user_id. Декодировать base64 payload.
|
||
5. `POST /onboarding/claim_token` с `Authorization: Bearer <inner key>`, body `{invitation_link, user_id, password}` — поле СТРОГО `invitation_link` (не `invitation_id`; с ним 400/401). claim возвращает user_id (внешний id юзера).
|
||
6. `POST /v2/login` — ТОЖЕ защищён Turnstile (отдельный solve на `https://apiclaw.biz/ui/login`), body `{username: <email>, password, turnstile_token, browser_session_id: <uuid4>}` — поле `username`, а не `email`/`user_id`; Referer `/ui/login`.
|
||
7. `POST /key/generate` (Bearer login-токен / cookie `token`) — body ОБЯЗАН содержать `user_id` (без него key не генерируется). Дальше `GET /public/model_hub`, LiteLLM-стиль `GET /v1/models` + `POST /v1/chat/completions` (sk-ключ len 25).
|
||
- Логин-токен = JWT: user_id/claims из base64 payload. Если login 401 при верном пароле — проверить ЧТО в `username`: типичный баг = скрипт берёт email из старого state-файла, а пароль от нового аккаунта (identity mismatch). Email для логина всегда читать из того же источника, что и пароль.
|
||
|
||
Turnstile решается локальным sidecar `http://127.0.0.1:8877/solve` payload `{type:"turnstile", sitekey, url, real_page:true, timeout_s:180}`. **real_page=true обязателен** — intercept-токены отбиваются siteverify (тот же паттерн что terrapolis/treg).
|
||
|
||
Публичный тулкит всего реверса: `github.com/gbonnet65923/apiclaw-toolkit` (локально `C:/Users/User/tmp/apiclaw-toolkit`) — REVERSE.md (протокол), apiclaw_e2e.py (stdlib E2E: signup→IMAP invitation→claim→login→sk-key), turnstile_client.py, dashboard.py (пул sk-ключей), passthrough_proxy.py, outlook_reg/ (DOB-патч + retry-луп). Секретов нет: sitekey рантаймом из auth-config, почта/пароли из env.
|
||
|
||
## 2. Outlook autoreg через ai-register-machine (slidex)
|
||
|
||
Проект: `C:/Users/User/tmp/ai-register-machine/` (upstream dengyie/ai-register-machine + slidex). Сетап:
|
||
- `uv venv --python 3.14 .venv`; **НЕ** `uv pip install -e .` (layout-ошибка) — ставить зависимости явно из pyproject + `slidex @ git+https://github.com/dengyie/slidex.git`; `patchright install chromium`.
|
||
- Запуск: `GROK_REGISTER_OUTLOOK_LIVE=1 PYTHONPATH=. .venv/Scripts/python.exe -m register_core run --profile profiles/outlook-live-nobind.yaml -n 1 --egress list --proxy-list <file> --proxy-rotate-every 1 -v > run.log 2>&1` (env-гейт обязателен, иначе dry-run). Профиль: `captcha_strategy: 2` = manual handoff, headless:false.
|
||
- Флоу провайдера: consent → email → password → DOB (Fluent dropdowns) → name → submit → risk-классификация (sentinel-тексты в `outlook_browser.py`: enforcementFrame = FunCaptcha, «abnormal activity», maintenance).
|
||
|
||
### Питфолы (проверено)
|
||
- **MS банит free/datacenter прокси**: signup.live.com/outlook.live.com через публичные пулы = connection reset/403. Прямой residential-IP (домашний) проходит. Тестировать reachability ТОЛЬКО curl_cffi `impersonate="chrome"` — urllib даёт ложный **417 Expectation Failed** по TLS-фингерпринту, это не вердикт хосту.
|
||
- **Pipeline требует непустой proxy** (`extra["proxy"]`), даже для direct-egress: поднять локальный passthrough-прокси (stdlib socket relay CONNECT+GET на 127.0.0.1:порт, ~60 строк) и скормить его как единственный элемент proxy-list. Проверка: `curl --proxy http://127.0.0.1:PORT https://ifconfig.me` = домашний IP.
|
||
- **Fluent UI dropdown: `<label for="BirthMonthDropdown">` перехватывает pointer events** — клик по триггеру висит 30с и падает. Фикс в `_open_dropdown_and_pick`: try click(10s) → fallback клик по `label[for=<trigger_id>]` (label-семантика открывает тот же дропдаун) → force click.
|
||
- **«abnormal activity» после submit = IP-риск-блок MS, НЕ решаемая капча** — солверы/handoff бесполезны. Короткий кулдаун НЕ лечит: ретрай-луп 3×20мин на флагнутом домашнем IP дал 3/3 провала — флаг держится часами+. Не сжигать время на ретраях: сразу pivот на чтение существующих ящиков (§3 ms_oauth handoff) или свежий residential egress. Флаг ставится после массовых OAuth/рега попыток с одного адреса — не долбить MS пачками с домашнего IP.
|
||
- Логи pipeline тихие во время браузерного флоу (INFO только старт/финал): прогон занимает ~7-9 мин, «молчит 5 минут» ≠ завис. Живость проверять по дереву процессов (patchright chromium main PID) и `wc -l` лога.
|
||
- Прокси-лист для MS готовить отдельным пре-фильтром против `https://outlook.live.com/mail/0/?prompt=create_account` через curl_cffi (200 + body >10KB), а не против signup.live.com.
|
||
|
||
## 3. Чтение существующих Outlook-ящиков (альтернатива регe)
|
||
|
||
Для акков из банков (gh_accounts.json и т.п.) парольный IMAP не работает — нужен MS device-code OAuth → refresh token → IMAP XOAUTH2 (`https://outlook.office.com/IMAP.AccessAsUser.All offline_access openid`, consumers endpoint). Челлендж «Verify your email» обходится ссылкой «Use your password». Headed-браузер + ручной handoff для добивания челленджа. Не подтверждено до конца — при возобновлении начинать с ms_oauth_poc.py в tmp/apiclaw_reg/.
|
||
|
||
## 4. Headed Selenium на этой машине (gmail-account-creator и подобные)
|
||
|
||
- `options.binary_location` пинить на установленный Chrome + chromedriver пинить на точный `.wdm/drivers/chromedriver/win64/<ver>/chromedriver-win32/chromedriver.exe` (авто-резолв кэша ломается при mismatch версий).
|
||
- `excludeSwitches`/`useAutomationExtension` в experimentalOptions → «session not created: Chrome instance exited» — убрать, без них стартует.
|
||
- Текущий Google signup: email-шаг = прямой Username input (без radio-вариантов), password-шаг = ДВА `input[type=password]`, DOB = Material combobox `id=month/day/year` (клик + `[role=option]`), Next-кнопка = XPath-fallback `VfPpkd-vQzf8d`/span Next/Далее.
|
||
- Gmail sign-in селекторы: email `#identifierId`, password `input[name='Passwd']`.
|
||
- Перед стартом очередного E2E-прогона убивать зомби-процессы прошлых (Chrome-сироты накапливаются), но НЕ трогать основной браузер Влада (taskkill chrome.exe запрещён).
|