Skip to main content

kick_api/api/
chat.rs

1use crate::error::{KickApiError, Result};
2use crate::models::{SendMessageRequest, SendMessageResponse};
3use reqwest;
4
5/// Chat API - handles chat message endpoints
6///
7/// Scopes required: `chat:write`, `moderation:chat_message:manage`
8pub struct ChatApi<'a> {
9    client: &'a reqwest::Client,
10    token: &'a Option<String>,
11    base_url: &'a str,
12}
13
14impl<'a> ChatApi<'a> {
15    /// Create a new ChatApi instance
16    pub(crate) fn new(
17        client: &'a reqwest::Client,
18        token: &'a Option<String>,
19        base_url: &'a str,
20    ) -> Self {
21        Self {
22            client,
23            token,
24            base_url,
25        }
26    }
27
28    /// Send a chat message
29    ///
30    /// Requires OAuth token with `chat:write` scope
31    ///
32    /// # Example
33    /// ```no_run
34    /// use kick_api::SendMessageRequest;
35    ///
36    /// let request = SendMessageRequest {
37    ///     r#type: "user".to_string(),
38    ///     content: "Hello chat!".to_string(),
39    ///     broadcaster_user_id: Some(12345),
40    ///     reply_to_message_id: None,
41    /// };
42    /// let response = client.chat().send_message(request).await?;
43    /// println!("Message sent: {}", response.message_id);
44    /// ```
45    pub async fn send_message(&self, request: SendMessageRequest) -> Result<SendMessageResponse> {
46        super::require_token(self.token)?;
47
48        let url = format!("{}/chat", self.base_url);
49        let request = self
50            .client
51            .post(&url)
52            .header("Accept", "*/*")
53            .bearer_auth(self.token.as_ref().unwrap())
54            .json(&request);
55        let response = crate::http::send_with_retry(self.client, request).await?;
56
57        if response.status().is_success() {
58            let body = response.text().await?;
59
60            #[derive(serde::Deserialize)]
61            struct DataResponse {
62                data: SendMessageResponse,
63            }
64
65            let resp: DataResponse = serde_json::from_str(&body)
66                .map_err(|e| KickApiError::ApiError(format!("JSON parse error: {}", e)))?;
67
68            Ok(resp.data)
69        } else {
70            Err(KickApiError::ApiError(format!(
71                "Failed to send message: {}",
72                response.status()
73            )))
74        }
75    }
76
77    /// Delete a chat message
78    ///
79    /// Requires OAuth token with `moderation:chat_message:manage` scope
80    ///
81    /// # Example
82    /// ```no_run
83    /// client.chat().delete_message("message_id_here").await?;
84    /// ```
85    pub async fn delete_message(&self, message_id: &str) -> Result<()> {
86        super::require_token(self.token)?;
87
88        let url = format!("{}/chat/{}", self.base_url, message_id);
89        let request = self
90            .client
91            .delete(&url)
92            .header("Accept", "*/*")
93            .bearer_auth(self.token.as_ref().unwrap());
94        let response = crate::http::send_with_retry(self.client, request).await?;
95
96        if response.status().is_success() {
97            Ok(())
98        } else {
99            Err(KickApiError::ApiError(format!(
100                "Failed to delete message: {}",
101                response.status()
102            )))
103        }
104    }
105
106}