Files
AgentsMeeting/gateway/scripts/usage_monitor/extract_cookies.py
T
hmo fefdc29d06 feat: OpenCode Go usage monitor — hybrid collector + 246-centric dashboard
- usage_collector.py v3.0: HTTP+stored cookies (primary) + CDP (bonus)
  - Cookie keepalive: captures Set-Cookie from responses, saves back to JSON
  - Per-metric regex for SSR parsing (handles nested \[N]={...} structure)
  - Cache merge: preserves other accounts' data on partial collection
- extract_cookies.py: one-time CDP /cookies endpoint → per-account JSON
- dashboard.py: /api/usage reads local file (no Windows bot dependency)
  - /api/usage/refresh: local subprocess collector
  - Auto-timer: 5min background thread (cookie keepalive + fresh data)
- xmpp_agent_core.py: /usage endpoint + auto-timer (for local testing)
- dashboard.html: usage-monitor section (4 cards × 3 metrics + alerts)
- accounts.json: 4 accounts configured (key1-4, gitignored)
- .gitignore: cookies/, accounts.json, usage_stats.json
2026-07-15 22:30:20 +08:00

116 lines
4.1 KiB
Python

#!/usr/bin/env python3
"""
extract_cookies.py — 提取并保存 opencode.ai cookies (含 httpOnly) 到 per-account JSON
===============================================================================
通过 CDP proxy /cookies 端点提取 Chrome 当前登录账号的全部 cookies,
过滤 opencode.ai domain (含 auth.opencode.ai),保存到 cookies/{key_id}.json。
用法:
python extract_cookies.py <key_id> [--workspace-id <wrk_XXX>]
python extract_cookies.py key1 --workspace-id wrk_01KQT521KYE2P2QRZ10N8MVPXA
依赖: 仅 Python stdlib (urllib, json) + CDP proxy localhost:3456
"""
import sys
import json
import urllib.request
from pathlib import Path
from datetime import datetime, timezone
CDP_PROXY_URL = 'http://localhost:3456'
COOKIES_DIR = Path(__file__).resolve().parent / 'cookies'
ACCOUNTS_FILE = Path(__file__).resolve().parent / 'accounts.json'
def fetch_cookies_from_cdp():
"""Call CDP proxy /cookies endpoint, return list of cookie dicts."""
url = f'{CDP_PROXY_URL}/cookies'
req = urllib.request.Request(url, method='GET')
with urllib.request.urlopen(req, timeout=15) as resp:
data = json.loads(resp.read().decode('utf-8'))
if isinstance(data, list):
return data
return data.get('cookies', data.get('result', {}).get('cookies', []))
def filter_opencode_cookies(cookies):
"""Filter to opencode.ai + auth.opencode.ai domain cookies."""
return [c for c in cookies if c.get('domain', '').endswith('opencode.ai')]
def save_cookies(key_id, cookies, workspace_id=None):
"""Save cookies to cookies/{key_id}.json along with metadata."""
COOKIES_DIR.mkdir(parents=True, exist_ok=True)
out_file = COOKIES_DIR / f'{key_id}.json'
data = {
'key_id': key_id,
'workspace_id': workspace_id,
'extracted_at': datetime.now(timezone.utc).isoformat(timespec='seconds'),
'cookie_count': len(cookies),
'cookies': cookies,
}
with open(str(out_file), 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
return out_file
def update_accounts_json(key_id, workspace_id):
"""Update the workspace_id for the given key_id in accounts.json."""
if not ACCOUNTS_FILE.exists() or not workspace_id:
return
try:
with open(str(ACCOUNTS_FILE), 'r', encoding='utf-8-sig') as f:
cfg = json.load(f)
except Exception:
return
updated = False
for acc in cfg.get('accounts', []):
if acc.get('key_id') == key_id:
if not acc.get('workspace_id') and workspace_id:
acc['workspace_id'] = workspace_id
updated = True
break
if updated:
with open(str(ACCOUNTS_FILE), 'w', encoding='utf-8') as f:
json.dump(cfg, f, ensure_ascii=False, indent=2)
print(f'Updated accounts.json: {key_id} → workspace_id={workspace_id}')
def main():
if len(sys.argv) < 2:
print('Usage: python extract_cookies.py <key_id> [--workspace-id <wrk_XXX>]')
sys.exit(1)
key_id = sys.argv[1]
workspace_id = None
if '--workspace-id' in sys.argv:
idx = sys.argv.index('--workspace-id')
workspace_id = sys.argv[idx + 1] if idx + 1 < len(sys.argv) else None
print(f'Extracting cookies for {key_id}...')
try:
all_cookies = fetch_cookies_from_cdp()
except Exception as e:
print(f'ERROR: CDP /cookies failed: {e}')
sys.exit(1)
print(f'Total cookies from Chrome: {len(all_cookies)}')
oc_cookies = filter_opencode_cookies(all_cookies)
print(f'opencode.ai cookies: {len(oc_cookies)}')
for c in oc_cookies:
print(f' {c["name"]}: domain={c["domain"]} httpOnly={c.get("httpOnly", False)} len={len(c.get("value", ""))}')
if not oc_cookies:
print('ERROR: No opencode.ai cookies found — is Chrome logged in to an opencode account?')
sys.exit(1)
out_file = save_cookies(key_id, oc_cookies, workspace_id)
print(f'Saved {len(oc_cookies)} cookies to {out_file}')
if workspace_id:
update_accounts_json(key_id, workspace_id)
print(f'Workspace ID: {workspace_id}')
if __name__ == '__main__':
main()