ohmyapi Claude Opus 4.6 (1M context) commited on
Commit
6343462
Β·
1 Parent(s): 35efd6e

feat: CI auto-import, updated Dockerfile, docs, and env config

Browse files

- GitHub Actions auto-imports registered accounts to admin panel
- Added OUTLOOK2API_URL, ADMIN_PASSWORD secrets for CI
- Updated Dockerfile.api with SQLite data directory
- Updated .env.example with DATABASE_URL and admin config
- Comprehensive README with admin API documentation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

.env.example CHANGED
@@ -2,11 +2,13 @@
2
  OUTLOOK2API_JWT_SECRET=change-me-in-production
3
  OUTLOOK2API_HOST=0.0.0.0
4
  OUTLOOK2API_PORT=8001
5
- OUTLOOK2API_ACCOUNTS_FILE=data/outlook_accounts.json
6
-
7
- # === Admin ===
8
  ADMIN_PASSWORD=admin
 
 
 
9
  DATABASE_URL=sqlite+aiosqlite:///./data/outlook2api.db
 
 
10
 
11
  # === Registration (captcha) ===
12
  CAPTCHA_CLIENT_KEY= # YesCaptcha / CapSolver API key
@@ -15,3 +17,7 @@ FUNCAPTCHA_PUBLIC_KEY=B7D8911C-5CC8-A9A3-35B0-554ACEE604DA
15
 
16
  # === Optional ===
17
  PROXY_URL= # HTTP/SOCKS5 proxy for registration
 
 
 
 
 
2
  OUTLOOK2API_JWT_SECRET=change-me-in-production
3
  OUTLOOK2API_HOST=0.0.0.0
4
  OUTLOOK2API_PORT=8001
 
 
 
5
  ADMIN_PASSWORD=admin
6
+
7
+ # === Database ===
8
+ # SQLite (default, no setup needed):
9
  DATABASE_URL=sqlite+aiosqlite:///./data/outlook2api.db
10
+ # PostgreSQL (production):
11
+ # DATABASE_URL=postgresql://user:pass@host:5432/outlook2api
12
 
13
  # === Registration (captcha) ===
14
  CAPTCHA_CLIENT_KEY= # YesCaptcha / CapSolver API key
 
17
 
18
  # === Optional ===
19
  PROXY_URL= # HTTP/SOCKS5 proxy for registration
20
+
21
+ # === CI Auto-Import ===
22
+ # Set OUTLOOK2API_URL in GitHub Actions to auto-import registered accounts
23
+ # OUTLOOK2API_URL=https://ohmyapi-outlook2api.hf.space
.github/workflows/register-outlook.yml CHANGED
@@ -17,8 +17,6 @@ on:
17
  env:
18
  CAPTCHA_CLIENT_KEY: ${{ secrets.CAPTCHA_CLIENT_KEY }}
19
  PROXY_URL: ${{ secrets.PROXY_URL }}
20
- OUTLOOK2API_URL: ${{ secrets.OUTLOOK2API_URL }}
21
- ADMIN_PASSWORD: ${{ secrets.ADMIN_PASSWORD }}
22
 
23
  jobs:
24
  register:
@@ -70,33 +68,64 @@ jobs:
70
 
71
  - name: Auto-import to admin panel
72
  if: success()
 
 
 
73
  run: |
74
  if [ -z "$OUTLOOK2API_URL" ] || [ -z "$ADMIN_PASSWORD" ]; then
75
- echo "OUTLOOK2API_URL or ADMIN_PASSWORD not set, skipping import"
 
 
 
 
 
 
 
 
76
  exit 0
77
  fi
78
- # Extract accounts from the generated zip file
79
- ACCOUNTS=$(python -c "
80
- import json, glob, zipfile
 
 
81
  accs = []
82
- for zf in glob.glob('output/*Outlook.zip'):
83
  try:
84
- with zipfile.ZipFile(zf) as z:
85
- data = z.read('accounts.txt').decode().strip()
86
- for line in data.splitlines():
87
- if ':' in line:
88
- accs.append(line.strip())
89
  except: pass
90
  print(json.dumps(accs))
91
  ")
92
- if [ "$ACCOUNTS" = "[]" ]; then
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  echo "No accounts to import"
94
  exit 0
95
  fi
96
- echo "Importing accounts to $OUTLOOK2API_URL..."
97
- curl -sf -X POST "${OUTLOOK2API_URL}/admin/api/accounts/bulk" \
98
- -H "Authorization: Bearer ${ADMIN_PASSWORD}" \
99
- -H "Content-Type: application/json" \
100
- -d "{\"accounts\": $ACCOUNTS, \"source\": \"ci\"}" \
101
- && echo "Import successful" \
102
- || echo "Import failed (non-fatal)"
 
17
  env:
18
  CAPTCHA_CLIENT_KEY: ${{ secrets.CAPTCHA_CLIENT_KEY }}
19
  PROXY_URL: ${{ secrets.PROXY_URL }}
 
 
20
 
21
  jobs:
22
  register:
 
68
 
69
  - name: Auto-import to admin panel
70
  if: success()
71
+ env:
72
+ OUTLOOK2API_URL: ${{ secrets.OUTLOOK2API_URL }}
73
+ ADMIN_PASSWORD: ${{ secrets.ADMIN_PASSWORD }}
74
  run: |
75
  if [ -z "$OUTLOOK2API_URL" ] || [ -z "$ADMIN_PASSWORD" ]; then
76
+ echo "Skipping auto-import (OUTLOOK2API_URL or ADMIN_PASSWORD not set)"
77
+ exit 0
78
+ fi
79
+ # Login and get token
80
+ TOKEN=$(curl -sf -X POST "$OUTLOOK2API_URL/admin/api/login" \
81
+ -H 'Content-Type: application/json' \
82
+ -d "{\"password\": \"$ADMIN_PASSWORD\"}" | python3 -c "import sys,json;print(json.load(sys.stdin)['token'])" 2>/dev/null)
83
+ if [ -z "$TOKEN" ]; then
84
+ echo "Admin login failed, skipping import"
85
  exit 0
86
  fi
87
+ # Collect accounts from staging files
88
+ ACCOUNTS="[]"
89
+ if [ -d "output/.staging_outlook" ]; then
90
+ ACCOUNTS=$(python3 -c "
91
+ import os, json, glob
92
  accs = []
93
+ for f in glob.glob('output/.staging_outlook/outlook_*.json'):
94
  try:
95
+ d = json.load(open(f))
96
+ if d.get('email') and d.get('password'):
97
+ accs.append(d['email'] + ':' + d['password'])
 
 
98
  except: pass
99
  print(json.dumps(accs))
100
  ")
101
+ fi
102
+ # Also try the zip file
103
+ for z in output/*Outlook.zip; do
104
+ [ -f "$z" ] || continue
105
+ python3 -c "
106
+ import zipfile, json, sys
107
+ with zipfile.ZipFile('$z') as zf:
108
+ for name in zf.namelist():
109
+ if name.endswith('.txt'):
110
+ content = zf.read(name).decode('utf-8', errors='replace')
111
+ existing = json.loads(sys.argv[1]) if sys.argv[1] != '[]' else []
112
+ for line in content.strip().splitlines():
113
+ line = line.strip()
114
+ if ':' in line and line not in existing:
115
+ existing.append(line)
116
+ print(json.dumps(existing))
117
+ sys.exit(0)
118
+ print(sys.argv[1])
119
+ " "$ACCOUNTS" > /tmp/accs.json && ACCOUNTS=$(cat /tmp/accs.json)
120
+ done
121
+ COUNT=$(echo "$ACCOUNTS" | python3 -c "import sys,json;print(len(json.load(sys.stdin)))")
122
+ if [ "$COUNT" = "0" ]; then
123
  echo "No accounts to import"
124
  exit 0
125
  fi
126
+ echo "Importing $COUNT accounts..."
127
+ RESULT=$(curl -sf -X POST "$OUTLOOK2API_URL/admin/api/accounts/bulk" \
128
+ -H "Authorization: Bearer $TOKEN" \
129
+ -H 'Content-Type: application/json' \
130
+ -d "{\"accounts\": $ACCOUNTS, \"source\": \"ci\"}")
131
+ echo "Import result: $RESULT"
 
Dockerfile.api CHANGED
@@ -8,4 +8,8 @@ RUN pip install --no-cache-dir -r requirements-api.txt
8
  COPY outlook2api/ outlook2api/
9
  COPY pyproject.toml .
10
 
 
 
 
 
11
  CMD ["uvicorn", "outlook2api.app:app", "--host", "0.0.0.0", "--port", "8001"]
 
8
  COPY outlook2api/ outlook2api/
9
  COPY pyproject.toml .
10
 
11
+ RUN mkdir -p /tmp/data
12
+
13
+ ENV DATABASE_URL=sqlite+aiosqlite:////tmp/data/outlook2api.db
14
+
15
  CMD ["uvicorn", "outlook2api.app:app", "--host", "0.0.0.0", "--port", "8001"]
README.md CHANGED
@@ -1,45 +1,47 @@
1
  # Outlook2API
2
 
3
- Mail.tm-compatible REST API for Outlook/Hotmail/Live accounts with admin panel, batch registration, and CI auto-import.
4
 
5
  ## Features
6
 
7
- - Mail.tm-compatible Hydra API (drop-in replacement for Outlook accounts)
8
- - Admin panel with account management, bulk import, and API docs
9
- - Batch account registration via GitHub Actions (DrissionPage + YesCaptcha)
10
- - CI auto-import: registered accounts automatically pushed to admin database
11
- - SQLite/PostgreSQL backend
12
- - HuggingFace Spaces deployment
13
 
14
  ## Quick Start
15
 
16
  ```bash
 
17
  pip install -r requirements-api.txt
 
 
18
  python -m outlook2api.app
19
- # Open http://localhost:8001 (homepage) or http://localhost:8001/admin (admin panel)
20
- # Default admin password: admin
 
21
  ```
22
 
23
- ## Admin Panel
24
 
25
- Access at `/admin`. Features:
26
- - Dashboard with account stats
27
- - Account management (search, filter, toggle, delete)
28
- - Bulk import (text, file upload, CI API)
29
- - Full API documentation with curl examples
30
 
31
  ## API Endpoints
32
 
33
- ### Mail API (mail.tm-compatible)
34
 
35
  | Method | Path | Auth | Description |
36
  |--------|------|------|-------------|
37
- | GET | `/domains` | No | List supported domains |
38
- | POST | `/accounts` | No | Register account (IMAP validation) |
39
- | POST | `/token` | No | Get JWT token |
40
  | GET | `/me` | Bearer | Current user info |
41
- | GET | `/messages` | Bearer | List messages |
42
- | GET | `/messages/{id}` | Bearer | Get message |
43
  | GET | `/messages/{id}/code` | Bearer | Extract verification code |
44
  | DELETE | `/accounts/me` | Bearer | Delete account |
45
 
@@ -48,61 +50,66 @@ Access at `/admin`. Features:
48
  | Method | Path | Description |
49
  |--------|------|-------------|
50
  | POST | `/admin/api/login` | Login (returns token) |
51
- | GET | `/admin/api/stats` | Dashboard stats |
52
- | GET | `/admin/api/accounts` | List accounts (paginated) |
53
  | POST | `/admin/api/accounts` | Add single account |
54
- | POST | `/admin/api/accounts/bulk` | Bulk import |
55
- | POST | `/admin/api/accounts/upload` | File upload import |
56
- | PATCH | `/admin/api/accounts/{id}` | Update account |
57
  | DELETE | `/admin/api/accounts/{id}` | Delete account |
58
- | GET | `/admin/api/export` | Export all accounts |
 
59
 
60
  ## CI Auto-Import
61
 
62
- GitHub Actions workflow registers accounts and auto-imports to admin panel.
63
 
64
- Required secrets:
65
- - `CAPTCHA_CLIENT_KEY` β€” YesCaptcha API key
66
- - `PROXY_URL` β€” Residential proxy
67
- - `OUTLOOK2API_URL` β€” Admin panel URL (e.g. `https://ohmyapi-outlook2api.hf.space`)
68
- - `ADMIN_PASSWORD` β€” Admin password
69
 
70
  ```bash
71
- gh workflow run register-outlook.yml --repo shenhao-stu/outlook2api -f count=5
 
72
  ```
73
 
74
  ## Environment Variables
75
 
76
  | Name | Default | Description |
77
  |------|---------|-------------|
 
78
  | `ADMIN_PASSWORD` | `admin` | Admin panel password |
79
  | `DATABASE_URL` | `sqlite+aiosqlite:///./data/outlook2api.db` | Database URL |
80
- | `OUTLOOK2API_JWT_SECRET` | `change-me-in-production` | JWT secret |
81
- | `OUTLOOK2API_PORT` | `8001` | API port |
82
 
83
- ## Deployment
84
 
85
- Live at: **https://ohmyapi-outlook2api.hf.space**
86
 
87
  ## Project Structure
88
 
89
  ```
90
  outlook2api/
91
- β”œβ”€β”€ outlook2api/
92
- β”‚ β”œβ”€β”€ app.py # FastAPI entry point
93
- β”‚ β”œβ”€β”€ database.py # SQLAlchemy models + async DB
94
- β”‚ β”œβ”€β”€ admin_routes.py # Admin API (CRUD, import, export)
95
- β”‚ β”œβ”€β”€ routes.py # Mail.tm-compatible API
96
- β”‚ β”œβ”€β”€ auth.py # JWT authentication
97
- β”‚ β”œβ”€β”€ config.py # Configuration
98
- β”‚ β”œβ”€β”€ outlook_imap.py # IMAP client
99
- β”‚ β”œβ”€β”€ store.py # Legacy JSON store
100
- β”‚ └── static/ # Frontend (index.html, admin.html)
101
- β”œβ”€β”€ register/
102
- β”‚ β”œβ”€β”€ outlook_register.py # Batch registrar
103
- β”‚ └── captcha.py # FunCaptcha solver
 
 
104
  β”œβ”€β”€ .github/workflows/
105
- β”‚ └── register-outlook.yml # CI with auto-import
106
  β”œβ”€β”€ Dockerfile.api
107
  β”œβ”€β”€ Dockerfile.register
108
  β”œβ”€β”€ docker-compose.yml
 
1
  # Outlook2API
2
 
3
+ Mail.tm-compatible REST API for Outlook/Hotmail/Live accounts with admin panel and batch account registration.
4
 
5
  ## Features
6
 
7
+ - **Mail API** β€” Mail.tm-compatible Hydra API endpoints (domains, accounts, token, messages)
8
+ - **Admin Panel** β€” Web UI for account management, bulk import/export, stats dashboard
9
+ - **Batch Registration** β€” Automated Outlook account creation via GitHub Actions
10
+ - **CI Auto-Import** β€” Registered accounts automatically imported to admin panel
11
+ - **Verification Code Extraction** β€” `GET /messages/{id}/code` extracts OTP from emails
 
12
 
13
  ## Quick Start
14
 
15
  ```bash
16
+ # Install dependencies
17
  pip install -r requirements-api.txt
18
+
19
+ # Start the API server
20
  python -m outlook2api.app
21
+
22
+ # Open http://localhost:8001 for homepage
23
+ # Open http://localhost:8001/admin for admin panel (default password: admin)
24
  ```
25
 
26
+ ### Docker
27
 
28
+ ```bash
29
+ cp .env.example .env
30
+ docker compose up -d outlook2api
31
+ ```
 
32
 
33
  ## API Endpoints
34
 
35
+ ### Mail API (Mail.tm-compatible)
36
 
37
  | Method | Path | Auth | Description |
38
  |--------|------|------|-------------|
39
+ | GET | `/domains` | No | List supported email domains |
40
+ | POST | `/accounts` | No | Register account (validates IMAP) |
41
+ | POST | `/token` | No | Get JWT bearer token |
42
  | GET | `/me` | Bearer | Current user info |
43
+ | GET | `/messages` | Bearer | List inbox messages |
44
+ | GET | `/messages/{id}` | Bearer | Get single message |
45
  | GET | `/messages/{id}/code` | Bearer | Extract verification code |
46
  | DELETE | `/accounts/me` | Bearer | Delete account |
47
 
 
50
  | Method | Path | Description |
51
  |--------|------|-------------|
52
  | POST | `/admin/api/login` | Login (returns token) |
53
+ | GET | `/admin/api/stats` | Dashboard statistics |
54
+ | GET | `/admin/api/accounts` | List accounts (search, filter, paginate) |
55
  | POST | `/admin/api/accounts` | Add single account |
56
+ | POST | `/admin/api/accounts/bulk` | Bulk import (`["email:pass",...]`) |
57
+ | POST | `/admin/api/accounts/upload` | File upload (email:password per line) |
58
+ | PATCH | `/admin/api/accounts/{id}` | Toggle active / update notes |
59
  | DELETE | `/admin/api/accounts/{id}` | Delete account |
60
+ | GET | `/admin/api/accounts/{id}/password` | Reveal password |
61
+ | GET | `/admin/api/export` | Export all active accounts |
62
 
63
  ## CI Auto-Import
64
 
65
+ GitHub Actions automatically imports registered accounts to the admin panel.
66
 
67
+ **Required secrets:**
68
+ - `CAPTCHA_CLIENT_KEY` β€” YesCaptcha/CapSolver API key
69
+ - `PROXY_URL` β€” HTTP/SOCKS5 proxy
70
+ - `OUTLOOK2API_URL` β€” Admin panel URL (e.g., `https://ohmyapi-outlook2api.hf.space`)
71
+ - `ADMIN_PASSWORD` β€” Admin panel password
72
 
73
  ```bash
74
+ # Trigger registration + auto-import
75
+ gh workflow run register-outlook.yml -f count=5 -f threads=1
76
  ```
77
 
78
  ## Environment Variables
79
 
80
  | Name | Default | Description |
81
  |------|---------|-------------|
82
+ | `OUTLOOK2API_JWT_SECRET` | `change-me-in-production` | JWT signing secret |
83
  | `ADMIN_PASSWORD` | `admin` | Admin panel password |
84
  | `DATABASE_URL` | `sqlite+aiosqlite:///./data/outlook2api.db` | Database URL |
85
+ | `OUTLOOK2API_HOST` | `0.0.0.0` | API bind host |
86
+ | `OUTLOOK2API_PORT` | `8001` | API bind port |
87
 
88
+ ## HuggingFace Deployment
89
 
90
+ Deployed at: **https://ohmyapi-outlook2api.hf.space**
91
 
92
  ## Project Structure
93
 
94
  ```
95
  outlook2api/
96
+ β”œβ”€β”€ outlook2api/ # FastAPI mail API + admin
97
+ β”‚ β”œβ”€β”€ app.py # Application entry point
98
+ β”‚ β”œβ”€β”€ routes.py # Mail.tm-compatible API routes
99
+ β”‚ β”œβ”€β”€ admin_routes.py # Admin API routes
100
+ β”‚ β”œβ”€β”€ database.py # SQLAlchemy models (Account)
101
+ β”‚ β”œβ”€β”€ auth.py # JWT auth helpers
102
+ β”‚ β”œβ”€β”€ config.py # Environment config
103
+ β”‚ β”œβ”€β”€ outlook_imap.py # IMAP client
104
+ β”‚ β”œβ”€β”€ store.py # Legacy JSON file store
105
+ β”‚ └── static/ # Frontend
106
+ β”‚ β”œβ”€β”€ index.html # Homepage
107
+ β”‚ └── admin.html # Admin panel
108
+ β”œβ”€β”€ register/ # Batch registration
109
+ β”‚ β”œβ”€β”€ outlook_register.py # DrissionPage registrar
110
+ β”‚ └── captcha.py # FunCaptcha cloud solver
111
  β”œβ”€β”€ .github/workflows/
112
+ β”‚ └── register-outlook.yml # CI: register + auto-import
113
  β”œβ”€β”€ Dockerfile.api
114
  β”œβ”€β”€ Dockerfile.register
115
  β”œβ”€β”€ docker-compose.yml