Bulk-add Google (GSuite) accounts to the Antigravity provider on a 9Router instance via its REST API, with browser automation only for Google OAuth login.
How It Works
9Router API Google OAuth (browser)
─────────── ─────────────────────
POST /api/auth/login ──► auth cookie
GET /api/oauth/authorize ──► authUrl ──► Chrome opens ──► email/password ──► consent ──► auth code
POST /api/oauth/exchange ◄── code ◄──────────────────────────────────────────────────────┘
- 9Router interaction is done entirely via REST API (fast, no fragile CSS selectors).
- Google OAuth login is done via browser (DrissionPage + Chrome) because Google blocks programmatic login.
- Each account gets a fresh browser profile (temp directory) — your existing Chrome profile is never touched.
Requirements
- Python 3.8+
- Google Chrome installed
- 9Router instance running (local or remote)
Installation
git clone https://github.com/mhiqrambg/gsuite2router.git
cd gsuite2router
python3 -m venv venv
source venv/bin/activate # Linux/macOS
# venv\Scripts\activate # Windows
pip install -e .
Quick Start
1. Initialize config
Save your 9Router URL and password so you don't have to type them every time.
# Interactive
gsuite2router init
# Or pass directly
gsuite2router init --url http://localhost:20128 --password 'yourpassword'
Config is saved to .gs2router.json in the current directory.
Note: If your password contains special characters (
&,%,@,!), wrap it in single quotes.
2. Create account file
Create akun.txt in the current directory with one account per line:
user1@yourdomain.com|password123
user2@yourdomain.com|password456
user3@yourdomain.com|password789
Format: email|password
3. Add accounts
gsuite2router add
The tool will:
- Login to 9Router via API
- For each account, open Chrome, login to Google, handle consent pages
- Exchange the OAuth code via API to create a connection
- Remove successfully added accounts from
akun.txt
4. Delete exhausted accounts (optional)
Scan for and remove Antigravity connections that have hit quota limits:
# Scan and delete
gsuite2router delete
# Scan only (dry run)
gsuite2router delete --dry-run
Commands
gsuite2router init
Initialize config with router URL and password.
Options:
--url URL 9Router URL (default: http://localhost:20128)
--password PASSWORD 9Router password (default: 123456)
gsuite2router add
Add accounts from akun.txt to the Antigravity provider.
Options:
--url URL 9Router URL (overrides config)
--password PASSWORD 9Router password (overrides config)
--file FILE Path to account file (default: akun.txt in CWD)
--fast Fast mode (good internet, minimal delays)
--delay DELAY Delay between accounts in seconds (default: 3)
--redirect-uri URI OAuth redirect URI (default: http://localhost:20128/callback)
gsuite2router delete
Delete exhausted/quota-exceeded Antigravity connections.
Options:
--url URL 9Router URL (overrides config)
--password PASSWORD 9Router password (overrides config)
--dry-run Scan only, do not delete
Examples
# Basic usage (reads URL/password from .gs2router.json)
gsuite2router add
# Fast mode with custom delay
gsuite2router add --fast --delay 1
# Use a different account file
gsuite2router add --file /path/to/accounts.txt
# Override config for a one-off run
gsuite2router add --url http://192.168.1.100:20128 --password 'otherpass'
# Dry-run delete (scan only)
gsuite2router delete --dry-run
Config Priority
Values are resolved in this order:
- CLI argument (e.g.
--url,--password) - Config file (
.gs2router.json) - Default (
http://localhost:20128,123456)
Project Structure
gsuite2router/
├── gsuite2router/
│ ├── __init__.py # Version
│ ├── __main__.py # python -m gsuite2router
│ ├── cli.py # CLI (init/add/delete subcommands)
│ ├── config.py # Constants, timing profiles, config file I/O
│ ├── router_api.py # 9Router REST API client
│ ├── google_auth.py # Google OAuth via DrissionPage
│ ├── accounts.py # Account file read/write
│ └── delete.py # Quota scan + delete exhausted
├── requirements.txt
├── setup.py
├── akun.txt # Account file (email|password)
└── .gs2router.json # Saved config (gitignored)
Troubleshooting
"Cannot connect to ... make sure 9Router is running"
- 9Router is not running or the URL is wrong. Check with
curl <url>/api/auth/login.
"Login failed (403): error code: 1010"
- Cloudflare is blocking the request. This is handled automatically with proper User-Agent headers.
"redirect_uri_mismatch"
- The OAuth redirect URI doesn't match what's registered in Google Cloud Console. Use
--redirect-urito override.
Permission denied on akun.txt
- The file is owned by root. Fix with
sudo chown $USER akun.txt.
Password with special characters
- Always wrap passwords in single quotes:
--password 'my&pass%word'
Comments