Spaces:
Paused
Paused
| 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 | |