Skip to main content

kick_api/api/
channels.rs

1use crate::error::{KickApiError, Result};
2use crate::models::Channel;
3use reqwest;
4
5/// Channels API - handles all channel-related endpoints
6pub struct ChannelsApi<'a> {
7    client: &'a reqwest::Client,
8    token: &'a Option<String>,
9    base_url: &'a str,
10}
11
12impl<'a> ChannelsApi<'a> {
13    /// Create a new ChannelsApi instance
14    pub(crate) fn new(
15        client: &'a reqwest::Client,
16        token: &'a Option<String>,
17        base_url: &'a str,
18    ) -> Self {
19        Self {
20            client,
21            token,
22            base_url,
23        }
24    }
25
26    /// Get a channel by slug
27    ///
28    /// Requires OAuth token with `channel:read` scope
29    ///
30    /// # Example
31    /// ```no_run
32    /// let channel = client.channels().get("xqc").await?;
33    /// println!("Channel: {}", channel.slug);
34    /// ```
35    pub async fn get(&self, channel_slug: &str) -> Result<Channel> {
36        let url = format!("{}/channels", self.base_url);
37
38        let mut request = self
39            .client
40            .get(&url)
41            .header("Accept", "*/*")
42            .query(&[("slug", channel_slug)]);
43
44        if let Some(token) = self.token {
45            request = request.bearer_auth(token);
46        } else {
47            return Err(KickApiError::ApiError(
48                "OAuth token required for this endpoint".to_string(),
49            ));
50        }
51
52        let response = crate::http::send_with_retry(self.client, request).await?;
53        if response.status().is_success() {
54            let body = response.text().await?;
55
56            #[derive(serde::Deserialize)]
57            struct ChannelsResponse {
58                data: Vec<Channel>,
59            }
60
61            let resp: ChannelsResponse = serde_json::from_str(&body)
62                .map_err(|e| KickApiError::ApiError(format!("JSON parse error: {}", e)))?;
63
64            resp.data
65                .into_iter()
66                .next()
67                .ok_or_else(|| KickApiError::ApiError("Channel not found".to_string()))
68        } else {
69            Err(KickApiError::ApiError(format!(
70                "Failed to get channel: {}",
71                response.status()
72            )))
73        }
74    }
75
76    /// Get your own channels (the authenticated user's channels)
77    ///
78    /// Requires OAuth token with `channel:read` scope
79    ///
80    /// # Example
81    /// ```no_run
82    /// let my_channels = client.channels().get_mine().await?;
83    /// for channel in my_channels {
84    ///     println!("My channel: {}", channel.slug);
85    /// }
86    /// ```
87    pub async fn get_mine(&self) -> Result<Vec<Channel>> {
88        let url = format!("{}/channels", self.base_url);
89
90        let mut request = self.client.get(&url).header("Accept", "*/*");
91
92        if let Some(token) = self.token {
93            request = request.bearer_auth(token);
94        } else {
95            return Err(KickApiError::ApiError(
96                "OAuth token required for this endpoint".to_string(),
97            ));
98        }
99
100        let response = crate::http::send_with_retry(self.client, request).await?;
101        if response.status().is_success() {
102            let body = response.text().await?;
103
104            #[derive(serde::Deserialize)]
105            struct ChannelsResponse {
106                data: Vec<Channel>,
107            }
108
109            let resp: ChannelsResponse = serde_json::from_str(&body)
110                .map_err(|e| KickApiError::ApiError(format!("JSON parse error: {}", e)))?;
111
112            Ok(resp.data)
113        } else {
114            Err(KickApiError::ApiError(format!(
115                "Failed to get channels: {}",
116                response.status()
117            )))
118        }
119    }
120}