Files
autoreg-skills-max/skills/bulk-account-registration/references/gsd-browser-gmail-autoreg.md

164 lines
6.9 KiB
Markdown

# gsd-browser Gmail Auto-Registration Pattern
> **Skill:** `bulk-account-registration`
> **Tool:** gsd-browser (68 MCP tools)
> **Alternative to:** Playwright-based flow (`references/gmail-playwright-flow.md`)
> **Discovered:** 2026-06-23 — gsd-browser installed at `C:\Users\User\.openagents\nodejs\gsd-browser.cmd`
## Why gsd-browser over raw Playwright
| Factor | Playwright | gsd-browser |
|--------|-----------|-------------|
| Lines of code | 500+ Python (stealth, behavior, signup, proxy) | 1 JSON `browser_batch` call |
| DOM resilience | Selectors break when Google updates UI | Semantic intents (`fill_form`, `act`) survive DOM changes |
| Session isolation | Manual `browser.new_context()` | `--session reg-1` flag, built-in |
| Credential storage | Manual JSON file | Encrypted vault (`browser_vault_save` + `GSD_BROWSER_VAULT_KEY`) |
| Anti-detection | Manual JS injection + launch args | Built-in (patched Chromium, fingerprint rotation) |
| Parallel batches | Manual threading | `--session` per worker, isolated cookies |
## Core Pattern: Gmail Signup as a Single `browser_batch`
```json
{
"session": "gmail-wave-1",
"steps": [
{"action": "navigate", "url": "https://accounts.google.com/signup/v2/webcreateaccount?hl=en&flowName=GlifWebSignIn&flowEntry=SignUp"},
{"action": "wait_for", "condition": "selector_visible", "value": "input[name='firstName']", "timeout": 15000},
{"action": "fill_form", "values": {
"First name": "John",
"Last name": "Smith"
}},
{"action": "act", "intent": "click_next_button"},
{"action": "wait_for", "condition": "selector_visible", "value": "select[name='month']"},
{"action": "fill_form", "values": {
"Month": "February",
"Day": "4",
"Year": "1990",
"Gender": "Male"
}},
{"action": "act", "intent": "click_next_button"},
{"action": "wait_for", "condition": "text_visible", "value": "Create your own Gmail address"},
{"action": "act", "intent": "click_element", "element": "Create your own Gmail address"},
{"action": "fill_form", "values": {
"Username": "johnsmith7894"
}},
{"action": "act", "intent": "click_next_button"},
{"action": "wait_for", "condition": "selector_visible", "value": "input[type='password']"},
{"action": "fill_form", "values": {
"Password": "Str0ngP@ss!2024",
"Confirm": "Str0ngP@ss!2024"
}},
{"action": "act", "intent": "click_next_button"},
{"action": "wait_for", "condition": "any", "values": [
{"text_visible": "Welcome"},
{"text_visible": "Verify your phone number"},
{"text_visible": "Privacy and Terms"}
], "timeout": 20000},
{"action": "screenshot", "name": "post-signup-state"},
{"action": "extract", "schema": {
"type": "object",
"properties": {
"on_welcome": {"type": "boolean"},
"phone_required": {"type": "boolean"},
"url": {"type": "string"}
}
}},
{"action": "save_state", "name": "session-johnsmith7894"}
],
"stop_on_failure": true,
"summary_only": false
}
```
## Phone Bypass Strategy Branches
After the password step, Google may or may not show phone verification. The `wait_for` with `condition: "any"` handles the fork:
### Branch A: No phone (ideal)
Google routes straight to Terms → "I Agree" → Welcome. Account created.
### Branch B: Skip button visible
```json
{"action": "act", "intent": "click_element", "element": "Skip"},
{"action": "wait_for", "condition": "text_visible", "value": "Privacy and Terms"}
```
### Branch C: Phone required, 5sim available
```json
{"action": "act", "intent": "fill_phone_number", "value": "${5SIM_PHONE}"},
{"action": "act", "intent": "click_next_button"},
{"action": "wait_for", "condition": "text_visible", "value": "Enter verification code", "timeout": 120000},
{"action": "fill_form", "values": {"Verification code": "${5SIM_CODE}"}},
{"action": "act", "intent": "click_verify_button"}
```
Note: 5sim phone purchase + SMS polling happens OUTSIDE the batch (Python/API), then phone + code are templated into the batch JSON.
## Integration with Existing Infrastructure
### Proxy Pool
41 live proxies at `C:\Users\User\live_proxies.txt`. For gsd-browser:
```bash
gsd-browser mcp --proxy "$(head -1 C:\Users\User\live_proxies.txt)" --session reg-1
```
### Session Isolation for Bulk
Each account gets its own session. Launch N sessions in parallel:
```bash
for i in $(seq 1 5); do
proxy=$(sed -n "${i}p" C:\Users\User\live_proxies.txt)
gsd-browser mcp --proxy "$proxy" --session "gmail-reg-$i" &
done
```
### Vault for Credential Reuse
If using the same password for multiple accounts:
```bash
# One-time setup
gsd-browser vault save --profile gmail-default --url https://accounts.google.com --username "default-user" --password "Str0ngP@ss!2024"
# Set env var (must be set BEFORE daemon starts)
export GSD_BROWSER_VAULT_KEY="your-secret-key"
```
## Recovery: Post-Registration Session Restore
After account creation, restore the session for account warming:
```json
{
"session": "gmail-warmup",
"steps": [
{"action": "restore_state", "name": "session-johnsmith7894"},
{"action": "navigate", "url": "https://mail.google.com"},
{"action": "wait_for", "condition": "text_visible", "value": "Welcome to your new inbox"},
{"action": "screenshot", "name": "gmail-inbox-warmed"}
]
}
```
## Pitfalls
1. **gsd-browser needs Chrome installed** — `browser_navigate` fails with "daemon exited during startup" if no Chrome binary found. Set `GSD_BROWSER_BROWSER_PATH` or pass `--browser-path`.
2. **Vault key at launch time only** — `GSD_BROWSER_VAULT_KEY` must be set BEFORE daemon starts. Cannot be set after.
3. **Google changes DOM frequently** — Semantic intents (`fill_form`, `act`) survive better than raw selectors. If `fill_form` misses a field, fall back to `act_instruction`.
4. **`fill_form` keys match labels, not `name` attributes** — "First name" matches the visible label, NOT `name='firstName'`.
5. **Session names are global** — `--session reg-1` stores state on disk. Clean up old sessions to avoid disk bloat.
6. **Batch `stop_on_failure=true`** — If any step fails, the entire batch stops. For Gmail where certain steps may be optional (phone screen absent), use `stop_on_failure=false` or handle branching with `condition: "any"`.
7. **Phone screen unpredictable** — Google's phone screen shows randomly (IP-based, fingerprint-based). Always include the `condition: "any"` branch. Don't assume it will or won't appear.
## When to use this vs Playwright
| Scenario | Use |
|----------|-----|
| API registration (aiqianshu, Stagewise) | gsd-browser batch |
| Gmail signup (high anti-detection needed) | gsd-browser batch (preferred) |
| Need full programmatic control (custom logic, loops) | Playwright (Python) |
| Headless server environment (no GUI) | Playwright with xvfb |
| User says "быстро", "batch", "gsd" | gsd-browser |
| User says "свой скрипт", "python" | Playwright flow |