69 lines
2.7 KiB
Bash
Executable File
69 lines
2.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Backend del plasmoide OpenAI Codex Usage.
|
|
# Chiama l'endpoint (non documentato) GET https://chatgpt.com/backend-api/wham/usage
|
|
# con OAuth Bearer e chatgpt-account-id.
|
|
set -u
|
|
|
|
AUTH_JSON="${CODEX_AUTH_JSON:-$HOME/.pi/agent/auth.json}"
|
|
TOKEN=""
|
|
ACCOUNT_ID=""
|
|
if [ -f "$AUTH_JSON" ]; then
|
|
TOKEN="$(jq -r '.["openai-codex"].access // empty' "$AUTH_JSON" 2>/dev/null)"
|
|
ACCOUNT_ID="$(jq -r '.["openai-codex"].accountId // empty' "$AUTH_JSON" 2>/dev/null)"
|
|
fi
|
|
[ -n "$TOKEN" ] || TOKEN="${CODEX_ACCESS_TOKEN:-}"
|
|
[ -n "$TOKEN" ] || TOKEN="${OPENAI_CODEX_ACCESS_TOKEN:-}"
|
|
|
|
if [ -z "$TOKEN" ]; then
|
|
printf '{"ok":false,"error":"no_token","detail":"nessun token Codex in %s"}\n' "$AUTH_JSON"
|
|
exit 0
|
|
fi
|
|
|
|
REQ_HEADERS=(-H "Authorization: Bearer $TOKEN")
|
|
if [ -n "$ACCOUNT_ID" ]; then
|
|
REQ_HEADERS+=(-H "chatgpt-account-id: $ACCOUNT_ID")
|
|
fi
|
|
REQ_HEADERS+=(-H "User-Agent: pi-agent/1.0")
|
|
|
|
RESP="$(curl -sS --max-time 15 "${REQ_HEADERS[@]}" "https://chatgpt.com/backend-api/wham/usage" 2>/dev/null)"
|
|
CURL_RC=$?
|
|
if [ "$CURL_RC" -ne 0 ] || [ -z "$RESP" ]; then
|
|
printf '{"ok":false,"error":"fetch_failed","detail":"curl exit %s"}\n' "$CURL_RC"
|
|
exit 0
|
|
fi
|
|
|
|
# Se il token è scaduto o non valido, l'API non restituisce rate_limit.
|
|
if ! printf '%s' "$RESP" | jq -e '.rate_limit.primary_window.used_percent | type == "number"' >/dev/null 2>&1; then
|
|
printf '{"ok":false,"error":"token_expired","detail":"token Codex scaduto o non valido, riesegui /login in pi"}\n'
|
|
exit 0
|
|
fi
|
|
|
|
printf '%s' "$RESP" | jq -c '{
|
|
ok: true,
|
|
plan_type: (.plan_type // "—"),
|
|
allowed: (.rate_limit.allowed // true),
|
|
limit_reached: (.rate_limit.limit_reached // false),
|
|
primary_window: {
|
|
used_percent: (.rate_limit.primary_window.used_percent // 0),
|
|
remaining: ((100 - (.rate_limit.primary_window.used_percent // 0)) / 100),
|
|
reset_at: .rate_limit.primary_window.reset_at,
|
|
limit_window_seconds: (.rate_limit.primary_window.limit_window_seconds // 18000),
|
|
reset_after_seconds: .rate_limit.primary_window.reset_after_seconds
|
|
},
|
|
secondary_window: {
|
|
used_percent: (.rate_limit.secondary_window.used_percent // 0),
|
|
remaining: ((100 - (.rate_limit.secondary_window.used_percent // 0)) / 100),
|
|
reset_at: .rate_limit.secondary_window.reset_at,
|
|
limit_window_seconds: (.rate_limit.secondary_window.limit_window_seconds // 604800),
|
|
reset_after_seconds: .rate_limit.secondary_window.reset_after_seconds
|
|
},
|
|
reset_credits: (.rate_limit_reset_credits.available_count // 0),
|
|
credits: {
|
|
balance: (.credits.balance // "0"),
|
|
has_credits: (.credits.has_credits // false)
|
|
},
|
|
spend_reached: (.spend_control.reached // false)
|
|
}' 2>/dev/null || printf '{"ok":false,"error":"bad_json","detail":"risposta non valida da wham/usage"}\n'
|
|
|
|
exit 0
|