Files
kde-ai-credits-balance/contents/scripts/balance.sh
T

88 lines
3.2 KiB
Bash
Executable File

#!/usr/bin/env bash
# Backend del plasmoide AI Credits Balance.
# Chiama le API di DeepSeek (GET /user/balance) e OpenRouter
# (GET /api/v1/credits) e restituisce un JSON unificato. Gli errori sono
# gestiti per-provider: anche se uno fallisce, l'altro viene comunque riportato.
set -u
AUTH_JSON="${AI_AUTH_JSON:-$HOME/.pi/agent/auth.json}"
NOW="$(date +%s)"
DS_KEY=""
OR_KEY=""
if [ -f "$AUTH_JSON" ]; then
DS_KEY="$(jq -r '.["deepseek"].key // empty' "$AUTH_JSON" 2>/dev/null)"
OR_KEY="$(jq -r '.["openrouter"].key // empty' "$AUTH_JSON" 2>/dev/null)"
fi
[ -n "$DS_KEY" ] || DS_KEY="${DEEPSEEK_API_KEY:-}"
[ -n "$OR_KEY" ] || OR_KEY="${OPENROUTER_API_KEY:-}"
# --- DeepSeek -------------------------------------------------------------
ds_block() {
if [ -z "$DS_KEY" ]; then
printf '{"ok":false,"error":"no_api_key"}'
return
fi
local resp rc
resp="$(curl -sS --max-time 15 https://api.deepseek.com/user/balance \
-H "Authorization: Bearer $DS_KEY" 2>/dev/null)"
rc=$?
if [ "$rc" -ne 0 ] || [ -z "$resp" ]; then
printf '{"ok":false,"error":"fetch_failed","detail":"curl exit %s"}' "$rc"
return
fi
if ! printf '%s' "$resp" | jq -e '.balance_infos | type == "array"' >/dev/null 2>&1; then
printf '{"ok":false,"error":"bad_json","detail":"risposta non valida da DeepSeek"}'
return
fi
printf '%s' "$resp" | jq -c '{
ok:true,
available:(.is_available // false),
currency:((.balance_infos[0].currency) // "USD"),
total:((.balance_infos[0].total_balance) | tonumber),
granted:((.balance_infos[0].granted_balance) | tonumber),
topped_up:((.balance_infos[0].topped_up_balance) | tonumber)
}' 2>/dev/null || printf '{"ok":false,"error":"bad_json","detail":"impossibile elaborare DeepSeek"}'
}
# --- OpenRouter -----------------------------------------------------------
or_block() {
if [ -z "$OR_KEY" ]; then
printf '{"ok":false,"error":"no_api_key"}'
return
fi
local resp rc
resp="$(curl -sS --max-time 15 https://openrouter.ai/api/v1/credits \
-H "Authorization: Bearer $OR_KEY" 2>/dev/null)"
rc=$?
if [ "$rc" -ne 0 ] || [ -z "$resp" ]; then
printf '{"ok":false,"error":"fetch_failed","detail":"curl exit %s"}' "$rc"
return
fi
if ! printf '%s' "$resp" | jq -e '.data.total_credits | type == "number"' >/dev/null 2>&1; then
# 401/403 => la routing key non ha permessi sul /credits (serve management key).
printf '{"ok":false,"error":"bad_json","detail":"risposta non valida (la chiave potrebbe essere una routing key: serve una management key)"}'
return
fi
printf '%s' "$resp" | jq -c '{
ok:true,
total_credits:(.data.total_credits),
total_usage:(.data.total_usage),
remaining:((.data.total_credits) - (.data.total_usage))
}' 2>/dev/null || printf '{"ok":false,"error":"bad_json","detail":"impossibile elaborare OpenRouter"}'
}
DS_JSON="$(ds_block)"
OR_JSON="$(or_block)"
# ok globale = almeno un provider sano.
GLOBAL_OK="$(jq -n --argjson d "$DS_JSON" --argjson o "$OR_JSON" '($d.ok or $o.ok)')"
jq -nc \
--argjson ok "$GLOBAL_OK" \
--argjson deepseek "$DS_JSON" \
--argjson openrouter "$OR_JSON" \
--argjson fetched "$NOW" \
'{ok:$ok, deepseek:$deepseek, openrouter:$openrouter, fetched_at:$fetched}'
exit 0