feat: add Owncast API client for sending messages and checking status
Made-with: Cursor
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
mod config;
|
mod config;
|
||||||
mod events;
|
mod events;
|
||||||
mod html;
|
mod html;
|
||||||
|
mod owncast_api;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("owncast-irc-bridge");
|
println!("owncast-irc-bridge");
|
||||||
|
|||||||
78
src/owncast_api.rs
Normal file
78
src/owncast_api.rs
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
use reqwest::Client;
|
||||||
|
use tracing::{error, warn};
|
||||||
|
|
||||||
|
pub struct OwncastApiClient {
|
||||||
|
client: Client,
|
||||||
|
base_url: String,
|
||||||
|
access_token: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OwncastApiClient {
|
||||||
|
pub fn new(base_url: String, access_token: String) -> Self {
|
||||||
|
Self {
|
||||||
|
client: Client::new(),
|
||||||
|
base_url: base_url.trim_end_matches('/').to_string(),
|
||||||
|
access_token,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn send_chat_message(&self, body: &str) -> anyhow::Result<()> {
|
||||||
|
let url = format!("{}/api/integrations/chat/send", self.base_url);
|
||||||
|
let resp = self
|
||||||
|
.client
|
||||||
|
.post(&url)
|
||||||
|
.bearer_auth(&self.access_token)
|
||||||
|
.json(&serde_json::json!({ "body": body }))
|
||||||
|
.send()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let status = resp.status();
|
||||||
|
if status.is_success() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let resp_body = resp.text().await.unwrap_or_default();
|
||||||
|
if status.is_client_error() {
|
||||||
|
error!(status = %status, body = %resp_body, "Owncast API client error (not retrying)");
|
||||||
|
anyhow::bail!("Owncast API returned {status}");
|
||||||
|
}
|
||||||
|
|
||||||
|
warn!(status = %status, body = %resp_body, "Owncast API server error, retrying once");
|
||||||
|
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
||||||
|
|
||||||
|
let retry_resp = self
|
||||||
|
.client
|
||||||
|
.post(&url)
|
||||||
|
.bearer_auth(&self.access_token)
|
||||||
|
.json(&serde_json::json!({ "body": body }))
|
||||||
|
.send()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let retry_status = retry_resp.status();
|
||||||
|
if retry_status.is_success() {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
let retry_body = retry_resp.text().await.unwrap_or_default();
|
||||||
|
error!(status = %retry_status, body = %retry_body, "Owncast API retry failed");
|
||||||
|
anyhow::bail!("Owncast API retry returned {}", retry_status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_status(&self) -> anyhow::Result<OwncastStatus> {
|
||||||
|
let url = format!("{}/api/status", self.base_url);
|
||||||
|
let resp = self.client.get(&url).send().await?;
|
||||||
|
let status: OwncastStatus = resp.json().await?;
|
||||||
|
Ok(status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, serde::Deserialize)]
|
||||||
|
pub struct OwncastStatus {
|
||||||
|
pub online: bool,
|
||||||
|
#[serde(default)]
|
||||||
|
#[serde(rename = "streamTitle")]
|
||||||
|
pub stream_title: Option<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
#[serde(rename = "viewerCount")]
|
||||||
|
pub viewer_count: Option<u64>,
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user