# 2nd-no.com — бесплатные польские номера (ПОЛНЫЙ АВТОМАТ, проверено live 2026-09-20) Сервис «2nd» из постов Влада = **2nd-no.com** (польский 2nr.pl; backend API `https://2no.pl`). Бесплатные временные номера +48 (Польша) для SMS-верификаций. Лимиты: **3 номера на аккаунт** (`number_limit:3` в API-ответах), номер живёт 3 дня, автопродлевается при получении SMS. **Готовый модуль**: `Desktop/gitlab-autoreg/providers/secondno.py` — класс `SecondNo` (register/login/get_number/read_sms/wait_otp) + `full_cycle(count)`. Обкатан live: 2 аккаунта с нуля + 2 номера зарезервированы (`success:true`, `expires +3 дня`), состояние в `tmp/glar_stage/2ndno_state.json`. ## Полный автоматизированный цикл (все шаги проверены) 1. **Temp-почта**: `POST https://api.tempmail.lol/v2/inbox/create` → `{address, token}`. Домены ротируются (prominentghost.com, imagesthere.com...) → фактически неограниченный запас аккаунтов. 2. **Регистрация** `https://2nd-no.com/auth/register` (Vue SPA): - Поля: `input[type=text]` (email!), `input[type=password]` ×2, checkbox (terms), `button[type=submit]`. - **Гидрация кривая**: `locator.fill()` виснет 30с хотя тело отрендерено → заполнять через `page.evaluate` + native value setter: ```js const setter = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(el), 'value').set; setter.call(el, v); el.dispatchEvent(new Event('input',{bubbles:true})); el.dispatchEvent(new Event('change',{bubbles:true})); ``` - Сабмит: `document.querySelector('button[type=submit]').click()` в evaluate. Ответ «Confirm email» = успех. 3. **Подтверждение почты**: письмо от `kontakt@2nr.pl`. Чтение инбокса: `GET https://api.tempmail.lol/v2/inbox?token=` — **токен В QUERY, не Bearer** (Bearer → 200 с `{"error":"Expected token in query parameter"}`, письмо «не приходит» вечно). Ссылка `https://2nd-no.com/auth/create-account/?email=...&token=*** → goto → «Account created». 4. **Логин** ОБЯЗАТЕЛЕН отдельным шагом после confirm (в той же сессии токена нет): `https://2nd-no.com/auth/login` → JS-fill email/password → submit → `wait_for_url("**/app/**")`. 5. **Auth-токен**: после логина лежит в `sessionStorage["2NR-TOKEN"]`, передаётся хедером **`x-auth-token`** (не Authorization!) в `POST https://2no.pl/`. 6. **Получение номера — чисто через API, без кликов по модалу**: - `{"id":310}` (getRandomNumberV2) → `{"result":[{"id":79935,"number":"729756039"}],"captcha":"turnstile"}` - Решить Turnstile: sitekey **`0x4AAAAAAAh6YYTPTzEcN3Ep`** (вытащен из бандла `https://2nd-no.com/assets/index-ff34328d.js`), pageurl `https://2nd-no.com/`. YesCaptcha тип задачи — **`TurnstileTaskProxyless`** (`AntiTurnstileTaskProxyLess` → ERROR_TASK_NOT_SUPPORTED). Решается ~8с. - `{"id":301,"query":{"number_id":,"name":"gl","color":"Red","right_to_transfer_number":true,"response_key":""}}` (reserveNumber) → `{"password":"...","success":true}` - Проверка: `{"id":311,"query":{"offset":0,"limit":10}}` (getUserNumbersV2) → в `result[0]` есть `id` (user_number_id), `number`, `reservation_to`. 7. **Чтение SMS**: `{"id":415,"query":{"phone":,"number_id":,"limit":20,"offset":0}}` (getMessagesForNumber_v2), ответ `data.messages[]`. `wait_otp()` в модуле поллит с regex `\b\d{4,8}\b`. ## API-карта (полная — `GET https://2no.pl/config`, 109 действий) Полный дамп: `tmp/glar_stage/2no_config.json`. Ключевые id: - **auth**: 101 login `{email,password}`, 103 register, 104 confirm `{token,email}`, 109 google_auth - **number**: 300 getRandomNumber, **301 reserveNumber** `{number_id,name,color,availability_days,hour_from,hour_to,marketing,response_key}`, 302/311 getUserNumbers(V2), 304 removeNumber, 305 extendNumberValidity - **sms**: 400 get, 401 send, 403 getMessages `{number}`, **415 getMessagesForNumber_v2** `{phone,number_id}`, 411 getUnreadCount - **call**: 600 start, 601 getHistory; **voicemail**: 800 getVoicemailList - **shop**: 506 getCurrentPrices, 508 getInternalItems_v2 (лимит 5 номеров = 500 zł — платно) **Снаружи браузера всё = 403 Cloudflare.** Рабочий способ: `page.evaluate(fetch('https://2no.pl/', {method:'POST', headers:{'Content-Type':'application/json','x-auth-token':tok}, body:JSON.stringify({id,query})}))` внутри залогиненного контекста. ## Pitfalls (все проверены на практике) 1. **`x-auth-token`, не Bearer/Authorization** — иначе `{"error":1003,"code":401,"reason":"login"}`. 2. **register НЕ логинит** — после confirm ссылки обязателен явный login-шаг, иначе 401 на всех API. 3. **UI-модал «Add new number» — тупик для автоматизации**: кнопка модала `disabled` пока невидимый turnstile-виджет не даст ответ; `window.turnstile` есть, но `getResponse()` = null, sitekey в DOM не лежит (рендерится лениво). Обход — чистый API-путь (id 310 → turnstile → id 301), модал не трогать вообще. 4. **tempmail.lol**: токен в query (см. шаг 3). 5. **Playwright sync**: `resp.text()` внутри `page.on("response")` = дедлок гидрации. Логировать только method/status/url. 6. **Клики по элементам под label-overlay**: искать по innerText через `document.querySelectorAll` + `offsetParent!==null` в evaluate; `get_by_text().click()` → «intercepts pointer events» 30с timeout. 7. **Кнопки с одинаковым текстом** («Add new number» есть и на странице, и в модале) — брать `els[els.length-1]` из отфильтрованных по `offsetParent!==null`. 8. **Cloudflare снаружи**: прямой httpx/curl к `2no.pl` и к `2nd-no.com` → 403/«Attention Required». Только браузерный контекст (headless Chromium с `--no-sandbox` проходит нормально — сам сайт не детектит playwright, в отличие от gitlab.com). ## Ёмкость фермы 3 номера × неограниченные tempmail-домены = масштабируется. Каждый аккаунт независим (email+password+номера в state-файле). Номер продлевается при получении SMS → для активной верификации живёт дольше 3 дней. ## Интеграция - FastAPI `Desktop/gitlab-autoreg/app.py`: `POST /sms-number {"count":N}` (фон), `GET /sms-state` (номер+креды). - Для GitLab phone-verify: `SecondNo.get_number()` → номер `+48...` в форму GitLab → `wait_otp(number_id, user_number_id)` → код. - Связанный референс по GitLab-стороне: `ai-provider-autoreg` → `references/gitlab-autoreg-project.md`.