its-matrix-bot/src/its_api.rs

78 lines
2.0 KiB
Rust

use reqwest::{Client, Url};
use thiserror::Error;
use tracing::{event, instrument, Level};
#[derive(Debug, Error)]
pub enum Error {
#[error("invalid URL")]
InvalidUrl(#[from] url::ParseError),
#[error("invalid response")]
InvalidResponse(reqwest::Error),
#[error("network request failed")]
Network(reqwest::Error),
}
/// Handler for the IT-Syndikat API.
#[derive(Clone, Debug)]
pub struct ItsApi {
base_url: Url,
spaceping_token: String,
client: Client,
}
impl ItsApi {
/// Constructs a new IT-Syndikat API handler.
#[instrument]
pub fn new(base_url: Url, spaceping_token: String) -> Self {
Self {
base_url,
spaceping_token,
client: Client::new(),
}
}
/// Request the SpaceAPI status.
///
/// # Errors
///
/// This function returns an error if the network request fails, or if the
/// returned data can not be parsed as a valid SpaceAPI response.
#[instrument]
pub async fn status(&self) -> Result<spaceapi::Status, Error> {
event!(Level::DEBUG, "requesting spaceapi status");
let status = self
.client
.get(self.base_url.join("status.php")?)
.send()
.await
.map_err(Error::Network)?
.json()
.await
.map_err(Error::InvalidResponse)?;
event!(Level::DEBUG, ?status);
Ok(status)
}
/// Makes the box in the space beep.
///
/// # Errors
///
/// This function returns an error if the network request fails.
#[instrument]
pub async fn ping(&self) -> Result<(), Error> {
event!(Level::INFO, "sending spaceping");
self.client
.post(self.base_url.join("ping.php")?)
.query(&[("apikey", &self.spaceping_token)])
.send()
.await
.map_err(Error::Network)?
.error_for_status()
.map_err(Error::InvalidResponse)?;
Ok(())
}
}