Skip to content

Repository files navigation

Qoder Farm

Automated Qoder.com account registration + PAT creation via Google OAuth.

Overview

  • Signup: Google OAuth (GSuite accounts) via CloakBrowser + proxy rotation
  • PAT Creation: Direct API call (POST /api/v1/me/personal-access-tokens) with custom expiry
  • No CAPTCHA: Google OAuth path bypasses Aliyun CAPTCHA entirely
  • Proxy Rotation: Round-robin from proxies.txt, fallback to direct if empty
  • Portable: No external paths — everything stays inside the repo

Quick Start

1. Install

git clone <repo-url> qoder-farm
cd qoder-farm
pip install cloakbrowser

2. Configure

Create accounts.txt (GSuite accounts, email|password per line):

your-email@your-domain.com|your-password
another@your-domain.com|your-password

Create proxies.txt (one proxy per line, supports multiple formats, or leave empty for direct):

# Full URLs
socks5://127.0.0.1:1081
socks5://user:pass@203.0.113.1:1080
http://user:pass@proxy.example.com:8080

# Colon-delimited (auto-converted to socks5://)
31.56.127.193:7684:qyduzmmu:zxcbbqirra5h

# host:port only (no auth)
203.0.113.1:1080

Empty proxies.txt = direct connection (no proxy).

3. Run

./run.sh                 # Run with defaults (2 concurrent workers)
./run.sh --verify        # Verify PATs after creation
./run.sh --workers 4     # 4 concurrent workers
./run.sh --workers 1     # Sequential mode (old behavior)
./run.sh --expiry-days 730  # Custom expiry

Or directly with Python:

python3 main.py
python3 main.py --verify
python3 main.py --accounts-file custom.txt --proxies-file custom_proxies.txt

4. Results

Output goes to results/:

results/
├── pats.txt              # email|pat format (one per line)
├── results.json          # Full JSON with timestamps, proxies, verification status
└── screenshots/          # Failure screenshots for debugging

Architecture

qoder-farm/
├── run.sh                     # One-command runner (reads accounts.txt + proxies.txt)
├── main.py                    # CLI entrypoint (argparse)
├── accounts.txt               # GSuite accounts (gitignored)
├── proxies.txt                # Proxy list (gitignored)
├── accounts.txt.example       # Template
├── proxies.txt.example        # Template
├── requirements.txt
├── .gitignore
├── README.md
├── src/
│   └── qoder_farm/
│       ├── __init__.py
│       ├── config.py          # Paths, defaults, API endpoints (all relative to repo)
│       ├── browser.py         # CloakBrowser lifecycle (launch with proxy, close)
│       ├── proxy_pool.py      # ProxyRotator (round-robin from proxies.txt)
│       ├── google_oauth.py    # Google OAuth flow (email → password → consent → Qoder)
│       ├── qoder_api.py       # PAT create/list/verify via Qoder API
│       ├── pipeline.py        # Orchestrator (proxy rotation + signup + PAT + results)
│       └── utils.py           # Timestamp calc, PAT file I/O, logging, validation
├── scripts/
│   └── register_single.sh     # Quick wrapper for single account
├── results/                   # Output (gitignored except .gitkeep)
│   ├── pats.txt
│   ├── results.json
│   └── screenshots/
└── tests/
    └── test_utils.py          # Unit tests

CLI Options

--accounts-file PATH    Accounts file (default: accounts.txt)
--proxies-file PATH     Proxies file (default: proxies.txt, empty=direct)
--pat-name NAME         PAT display name (default: hermes-cli)
--expiry-days N         PAT expiry in days (default: 365)
--pat-file PATH         PAT output file (default: results/pats.txt)
--results-file PATH     JSON results file (default: results/results.json)
--workers N             Number of concurrent workers (default: 2, 1=sequential)
--verify                Verify PAT via openapi.qoder.sh after creation

API Reference (Discovered)

PAT Creation

POST https://qoder.com/api/v1/me/personal-access-tokens
Content-Type: application/json
x-csrf-token: _echo_csrf_using_sec_fetch_site_
x-requested-with: XMLHttpRequest
bx-v: 2.5.35
Cookie: qoder_session_cookie=... (set after Google OAuth login)

Body: {"name": "hermes-cli", "expires_at": <epoch_ms>}
Response: 201 → {"token": "pt-...", "expires_at": <ts>, ...}

Key insight: expires_at is epoch milliseconds. Set to now + 365 days for 1-year PAT. CSRF uses Sec-Fetch-Site header validation (no separate token needed).

PAT Verification

curl -s -X POST https://openapi.qoder.sh/api/v1/jobToken/exchange \
  -H "Content-Type: application/json" \
  -d '{"personal_token": "pt-..."}'

Returns {"token": "jt-...", "refresh_token": "jrt-..."} — PAT is valid.

Environment Variables

Variable Default Description
QODER_PAT_NAME hermes-cli Default PAT name
QODER_PAT_EXPIRY_DAYS 365 PAT expiry in days
QODER_HEADLESS true Run browser headless
QODER_WORKERS 2 Number of concurrent workers

Running Tests

python3 -m pytest tests/ -v

License

MIT

About

Automated Qoder.com account registration + PAT creation via Google OAuth

Resources

Stars

8 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages