#!/bin/bash set -e DATA_DIR="${HOME:-/data}/.chat2api" DATA_FILE="$DATA_DIR/data.json" mkdir -p "$DATA_DIR" # ============================================================ # If data.json exists, use it as-is (imported from local GUI) # ============================================================ if [ -f "$DATA_FILE" ] && [ -s "$DATA_FILE" ]; then echo "[init] Using existing data.json from $DATA_FILE" else echo "[init] No existing data.json, generating from environment variables..." echo '{}' > "$DATA_FILE" fi # ============================================================ # Helper: read a JSON value by path # ============================================================ json_get() { python3 -c " import json, sys data = json.load(open('$DATA_FILE')) keys = '$1'.split('.') val = data for k in keys: val = val.get(k, {}) print(json.dumps(val) if not isinstance(val, str) else val) " 2>/dev/null || echo "null" } # Helper: set a JSON value by path json_set() { python3 -c " import json, sys data = json.load(open('$DATA_FILE')) keys = '$1'.split('.') val = json.loads('''$2''') target = data for k in keys[:-1]: if k not in target: target[k] = {} target = target[k] target[keys[-1]] = val json.dump(data, open('$DATA_FILE', 'w'), indent=2) print(' -> set $1 = $2') " } # ============================================================ # Environment variables -> config # ============================================================ # --- Proxy settings --- [ -n "${C2A_PROXY_PORT:-}" ] && json_set "config.proxyPort" "$C2A_PROXY_PORT" [ -n "${C2A_PROXY_HOST:-}" ] && json_set "config.proxyHost" "\"$C2A_PROXY_HOST\"" json_set "config.autoStartProxy" "true" # --- Management API --- if [ -n "${C2A_MANAGEMENT_SECRET:-}" ]; then MANAGEMENT_CONFIG=$(python3 -c " import json print(json.dumps({ 'enableManagementApi': True, 'managementApiSecret': '$C2A_MANAGEMENT_SECRET' })) ") json_set "config.managementApi" "$MANAGEMENT_CONFIG" echo "[init] Management API enabled (secret: ${C2A_MANAGEMENT_SECRET:0:4}...)" fi # --- API Key auth for proxy --- if [ -n "${C2A_API_KEYS:-}" ]; then json_set "config.enableApiKey" "true" API_KEYS_JSON=$(python3 -c " import json, time keys = '$C2A_API_KEYS'.split(',') result = [] for k in keys: k = k.strip() if k: result.append({ 'id': f'apikey-{int(time.time()*1000)}-{len(result)}', 'key': k, 'name': f'env-key-{len(result)+1}', 'enabled': True, 'usageCount': 0, 'lastUsedAt': 0 }) print(json.dumps(result)) ") json_set "config.apiKeys" "$API_KEYS_JSON" echo "[init] API Key auth enabled ($(echo "$C2A_API_KEYS" | tr ',' '\n' | grep -c .) keys)" fi # --- Providers and Accounts --- if [ -n "${C2A_PROVIDERS:-}" ]; then json_set "providers" "$C2A_PROVIDERS" echo "[init] Providers loaded from C2A_PROVIDERS" fi if [ -n "${C2A_ACCOUNTS:-}" ]; then json_set "accounts" "$C2A_ACCOUNTS" echo "[init] Accounts loaded from C2A_ACCOUNTS" fi # --- One-click provider+account setup --- # Format: C2A_ADD_PROVIDER=deepseek:sk-xxx,kimi:token-xxx,glm:refresh-xxx if [ -n "${C2A_ADD_PROVIDER:-}" ]; then echo "[init] Parsing C2A_ADD_PROVIDER..." python3 -c " import json, time, os data = json.load(open('$DATA_FILE')) providers = data.get('providers', []) accounts = data.get('accounts', []) # Built-in provider metadata (id -> {name, authType, credentialField}) BUILTIN = { 'deepseek': {'name': 'DeepSeek', 'authType': 'user_token', 'field': 'token'}, 'glm': {'name': 'GLM', 'authType': 'refresh_token','field': 'token'}, 'kimi': {'name': 'Kimi', 'authType': 'jwt_token', 'field': 'token'}, 'minimax': {'name': 'MiniMax', 'authType': 'jwt_token', 'field': 'token'}, 'qwen': {'name': 'Qwen CN', 'authType': 'sso_ticket', 'field': 'token'}, 'qwen-ai': {'name': 'Qwen AI', 'authType': 'jwt_token', 'field': 'token'}, 'mimo': {'name': 'MiMo', 'authType': 'cookie', 'field': 'cookie'}, 'perplexity': {'name': 'Perplexity','authType': 'cookie', 'field': 'cookie'}, 'zai': {'name': 'Z.ai', 'authType': 'jwt_token', 'field': 'token'}, } entries = [e.strip() for e in '$C2A_ADD_PROVIDER'.split(',') if e.strip()] for entry in entries: parts = entry.split(':', 1) provider_id = parts[0].strip() credential = parts[1].strip() if len(parts) > 1 else '' meta = BUILTIN.get(provider_id) if not meta: print(f' [warn] Unknown provider: {provider_id}, skipping') continue # Add provider if not exists existing = [p for p in providers if p.get('id') == provider_id] if not existing: now = int(time.time() * 1000) providers.append({ 'id': provider_id, 'name': meta['name'], 'type': 'builtin', 'authType': meta['authType'], 'enabled': True, 'createdAt': now, 'updatedAt': now, }) print(f' + provider: {provider_id} ({meta[\"name\"]})') # Add account with credential if credential: now = int(time.time() * 1000) account = { 'id': f'{provider_id}-env-{now}', 'providerId': provider_id, 'name': f'{meta[\"name\"]}-env', 'credentials': {meta['field']: credential}, 'status': 'active', 'createdAt': now, 'updatedAt': now, } accounts.append(account) print(f' + account: {provider_id} ({meta[\"field\"]}=***)') data['providers'] = providers data['accounts'] = accounts json.dump(data, open('$DATA_FILE', 'w'), indent=2) print(f'[init] Total: {len(providers)} providers, {len(accounts)} accounts') " fi echo "[init] Configuration ready" echo "============================================" cat "$DATA_FILE" | python3 -c " import json, sys d = json.load(sys.stdin) c = d.get('config', {}) print(' autoStartProxy:', c.get('autoStartProxy')) print(' proxyPort:', c.get('proxyPort')) print(' proxyHost:', c.get('proxyHost')) print(' managementApi:', 'enabled' if c.get('managementApi',{}).get('enableManagementApi') else 'disabled') print(' providers:', len(d.get('providers', []))) print(' accounts:', len(d.get('accounts', []))) " echo "============================================" # ============================================================ # Start Electron application # ============================================================ exec xvfb-run -a --server-args="-screen 0 1024x768x24" \ /opt/Chat2API/chat2api --no-sandbox --disable-gpu