use anyhow::{Result, anyhow};
use serde::Deserialize;
const BIRDEYE_CREDITS_URL: &str = "https://public-api.birdeye.so/utils/v1/credits";
#[derive(Deserialize, Debug)]
pub struct BirdeyeCreditsResponse {
data: Option<BirdeyeCreditsData>,
remaining: Option<BirdeyeRemaining>, }
#[derive(Deserialize, Debug)]
pub struct BirdeyeCreditsData {
remaining: BirdeyeRemaining,
usage: BirdeyeUsage,
}
#[derive(Deserialize, Debug)]
pub struct BirdeyeRemaining {
total: f64,
}
#[derive(Deserialize, Debug)]
pub struct BirdeyeUsage {
total: f64,
}
#[derive(Clone)]
pub struct BirdeyeClient {
api_key: String,
client: reqwest::Client,
}
impl BirdeyeClient {
pub fn new(api_key: &str) -> Self {
Self {
api_key: api_key.to_string(),
client: reqwest::Client::new(),
}
}
pub async fn get_credits(&self) -> Result<(f64, f64)> {
let res = self
.client
.get(BIRDEYE_CREDITS_URL)
.header("X-API-KEY", &self.api_key)
.header("accept", "application/json")
.send()
.await?;
if !res.status().is_success() {
let status = res.status();
let text = res.text().await?;
return Err(anyhow!(
"Birdeye credits request failed: {} - {}",
status,
text
));
}
let json: BirdeyeCreditsResponse = res.json().await?;
let (remaining, total) = if let Some(data) = json.data {
let remaining = data.remaining.total;
let usage_total = data.usage.total;
(remaining, remaining + usage_total)
} else if let Some(remaining_data) = json.remaining {
let remaining = remaining_data.total;
(remaining, remaining) } else {
(0.0, 0.0)
};
Ok((remaining, total))
}
}