Files

236 lines
9.9 KiB
Markdown

# conol.ai Registration (2026-07-30)
conol.ai is an AI agent platform at `https://conol.ai` (Next.js, Vercel, better-auth).
Registration uses reCAPTCHA v3 with strict IP binding — external captcha solvers fail.
## Registration Endpoint
- `POST /api/invites/register` with `{email, password, name}`
- Required header: `x-captcha-response: <reCAPTCHA v3 token>`
- Without header: `400 CAPTCHA_MISSING`
- With invalid token: `403 CAPTCHA_VERIFICATION_FAILED`
- Success: `200 {"success":true,"user":{"id":"...","email":"...","name":"..."}}`
## Working Method: Chrome CDP + On-Page recaptcha
**THIS IS THE ONLY PROVEN WORKING METHOD (2026-07-30, 35+ successful registrations):**
1. Connect to Chrome via CDP (port 9228), NOT headless — use real Chrome with `--remote-debugging-port=9228`
2. Navigate to `/sign-up`
3. Inject recaptcha script ON THE PAGE:
```js
await page.evaluate(`
async () => {
await new Promise((resolve, reject) => {
const s = document.createElement('script');
s.src = 'https://www.recaptcha.net/recaptcha/api.js?render=${SITE_KEY}';
s.onload = resolve;
s.onerror = reject;
document.head.appendChild(s);
});
await new Promise(r => window.grecaptcha.ready(r));
}
`);
```
4. Execute recaptcha AND send registration IN THE SAME `page.evaluate()` call:
```js
const token = await window.grecaptcha.execute(SITE_KEY, {action: 'sign_up'});
const r = await fetch('/api/invites/register', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-captcha-response': token,
},
body: JSON.stringify({email, password, name})
});
```
5. **CRITICAL**: The token must be used within the same `page.evaluate()` call.
Even a separate `page.evaluate()` (milliseconds later) can fail — Google verifies the token's
origin context against the request context.
## Why External Captcha Solvers FAIL
- 2captcha/anticaptcha/capsolver generate tokens from THEIR infrastructure
- Google recaptcha cross-checks the token's origin IP with the request IP
- Token from external IP → Google rejects server-side → `CAPTCHA_VERIFICATION_FAILED`
- Tested: anti-captcha.com (`CAPTCHA_KEY...`) successfully solves recaptcha v3 (score 0.9),
but the token is rejected by conol.ai server-side because the request IP differs
- **DO NOT use 2captcha/anticaptcha for recaptcha on conol.ai** — they cannot work
## Rate Limiting
- `POST /api/invites/register`: after successful registrations, add 8-14s delays between accounts
- HTTP-based authenticated requests (quest farming with cookies): `429 Too Many Requests` on ALL accounts
once rate-limited — the IP gets blocked globally
- Browser CDP does NOT trigger the same rate limit for registration — 3/3 OK works consecutively
- For quest/credit farming, use CDP (not HTTP) to avoid 429
## recAPTCHA v3 Details
- Sitekey: `6Lc3wmAtAAAAAB9YBPXQtT9uGGsH3ul6LQBc5AUu`
- Page action: `sign_up`
- Chrome CDP (non-headless) consistently passes with real Chrome fingerprint
- Headless Playwright fails — score < 0.5
## No Invite Token Required
Despite the endpoint being `/api/invites/register`, registration works WITHOUT an invite token.
The `token` field in the JSON body can be `null`. The invite-only gate appears to have been
removed or is not enforced server-side.
## GitHub OAuth = DOES NOT WORK for sign-up
- Callback returns `?error=account_not_linked`
- Backend only links existing accounts, does not create new ones
## Full Registration Flow (Python + Playwright)
See `eni_conol.py reg N` in the conol_autoreg project for the complete implementation.
Key steps:
1. `connect_over_cdp("http://127.0.0.1:9228")`
2. **Create a FRESH incognito context** per registration (NOT `browser.contexts[0]`)
3. Navigate to `/sign-up` → wait for reCAPTCHA script to load (`wait_for_function`)
4. `page.evaluate()` with recaptcha.execute() + fetch() in ONE call
5. Save cookies via `context.cookies()`
6. Close page AND context in `finally`
7. Append to `conol_accounts_pool.jsonl`
8. POST `/pool/reload` on gateway
## CRITICAL: Fresh Incognito Context Per Registration (v7.1 Fix)
**Problem (2026-07-30):** Reusing `browser.contexts[0]` + `context.clear_cookies()` for multiple
registrations causes reCAPTCHA v3 to fail after 1-2 accounts. The reCAPTCHA v3 score degrades
because Google fingerprints the browser context (canvas, WebGL, audio, fonts) — clearing cookies
does NOT reset the fingerprint. After 1-2 registrations, score drops below threshold →
`CAPTCHA_VERIFICATION_FAILED` on all subsequent attempts.
**Fix — fresh incognito context with randomized fingerprint per registration:**
```python
import random
# Create a FRESH context per registration — NOT browser.contexts[0]
context = await browser.new_context(
user_agent=f"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
f"(KHTML, like Gecko) Chrome/138.0.{random.randint(1000,9999)}.{random.randint(10,99)} Safari/537.36",
viewport={"width": 1920, "height": random.randint(900, 1080)},
locale="en-US",
)
page = await context.new_page()
# ... registration logic ...
# ALWAYS close both in finally:
finally:
try:
await page.close()
await context.close()
except Exception:
pass
```
**Why this works:**
- `browser.new_context()` creates an incognito context with a fresh fingerprint
- Randomized User-Agent + viewport breaks the fingerprint pattern
- Google reCAPTCHA v3 sees a "new browser" each time → score stays high
- Context isolation prevents cross-account cookie/fingerprint contamination
## CRITICAL: Captcha Retry with Backoff
When reCAPTCHA fails (HTTP 403 or error contains `captcha`/`recaptcha`/`robot`/`challenge`),
retry with exponential backoff — do NOT give up on first failure:
```python
# Detect captcha-specific errors
err_text = (response.get("data") or {}).get("error", "") or response.get("text", "")
is_captcha_err = any(k in str(err_text).lower() for k in ["captcha", "recaptcha", "robot", "challenge", "unusual"])
if status not in (200, 201) and is_captcha_err and attempt < 3:
wait = 30 * (attempt + 1) + random.randint(5, 15) # 35s, 65s, 95s + jitter
print(f"captcha fail, retry {attempt+1}/3 after {wait}s...")
await page.close()
await context.close()
await asyncio.sleep(wait)
return await register_one(browser, idx, attempt + 1) # recursive retry
```
**Key parameters:**
- Max retries: 3 (signup), 3 (verify-email)
- Backoff: `30s * (attempt+1) + random(5-15s)` — gives Google time to reset score
- Random jitter prevents synchronized retry patterns
- Close context before retry — next attempt gets a fresh fingerprint
## CRITICAL: Longer Warmup for reCAPTCHA v3
reCAPTCHA v3 needs time to load its scripts and collect browser signals before `execute()`:
```python
await page.goto(f"{BASE_URL}/sign-up", wait_until="domcontentloaded", timeout=45000)
await page.wait_for_timeout(3000)
# Wait for reCAPTCHA script to be present on page
await page.wait_for_function(
"typeof window.grecaptcha !== 'undefined' || document.querySelector('script[src*=\"recaptcha\"]')",
timeout=15000
)
await page.wait_for_timeout(2000 + random.randint(500, 2000)) # extra random delay
```
Short warmup (1-2s) → reCAPTCHA not ready → low score → fail.
3s + script-ready wait + 2-4s random = reliable.
## Random Delays Between Registrations
```python
delay = REG_DELAY_BASE + i * REG_DELAY_PER + random.randint(3, 12)
await asyncio.sleep(delay)
```
Fixed delays create patterns that reCAPTCHA v3 behavioral analysis can detect.
Adding `random(3-12s)` jitter per account avoids this.
## Complete Toolset (conol_autoreg v7.0, 2026-07-30)
Project location: `C:\Users\User\Desktop\conol_autoreg\`
### Registration tools
- `eni_conol.py reg N` — register N accounts via Chrome CDP, one-by-one with delays
- `multi_reg.py <per_email> <max_parallel>` — multi-threaded registration from `email_queue.jsonl`;
each email in queue gets `per_email` accounts registered in `max_parallel` parallel threads.
Reads queue entries with `status=queued`, marks them `processing`→`done`/`failed`.
- `eni_conol.py queue add <email>` — add an email to the registration queue
- Dashboard web UI (`dashboard_server.py`, port 9988) — add emails to queue via web form,
trigger registration with buttons (runs in background via subprocess.Popen)
### Email queue format (`email_queue.jsonl`)
```json
{"email":"user@gmail.com","password":null,"added_at":1730000000,"added_human":"2026-07-30 12:00:00","status":"queued","accounts_registered":0,"accounts_target":3}
```
Statuses: `queued` → `processing` → `done` / `failed`
### Post-registration pipeline
1. Cookies saved → `cookies_conol<id>.json`
2. Account appended → `conol_accounts_pool.jsonl`
3. Gateway auto-reloads pool via `/pool/reload` endpoint
4. New account immediately available for API requests via round-robin
### Packaging for distribution
```bash
cd C:\Users\User\Desktop
"/c/Program Files/7-Zip/7z.exe" a -tzip -mx9 conol_autoreg_ENI_v7.zip conol_autoreg/ \
-xr!__pycache__ -xr!*.pyc -xr!gateway.log -xr!dashboard.log -xr!reg.log -xr!multi_reg.log -xr!quests.log
```
Result: ~58 KB archive with 58 files (including ~40 cookie files).
## Quest/Credit Farming
- HTTP method (sending cookies in headers): works for ~1-2 accounts, then 429 rate limit on ALL
- CDP method: navigate to `/chat`, check credits via DOM — avoids 429
- New accounts start with 800 credits
## API Endpoints (authenticated)
- `POST /api/sessions` — create chat session
- `GET /api/sessions/{id}/messages?logDeltas=1` — SSE stream
- `PUT /api/sessions/{id}/stop` — stop generation
- `GET /api/agent-servers` — list models
- `GET /api/billing/balance` — credit balance
- Auth: `better-auth` session token (cookie `__Secure-better-auth.session_token`)