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        super::require_token(self.token)?;
37
38        let url = format!("{}/channels", self.base_url);
39        let request = self
40            .client
41            .get(&url)
42            .header("Accept", "*/*")
43            .query(&[("slug", channel_slug)])
44            .bearer_auth(self.token.as_ref().unwrap());
45
46        let response = crate::http::send_with_retry(self.client, request).await?;
47        if response.status().is_success() {
48            let body = response.text().await?;
49
50            #[derive(serde::Deserialize)]
51            struct ChannelsResponse {
52                data: Vec<Channel>,
53            }
54
55            let resp: ChannelsResponse = serde_json::from_str(&body)
56                .map_err(|e| KickApiError::ApiError(format!("JSON parse error: {}", e)))?;
57
58            resp.data
59                .into_iter()
60                .next()
61                .ok_or_else(|| KickApiError::ApiError("Channel not found".to_string()))
62        } else {
63            Err(KickApiError::ApiError(format!(
64                "Failed to get channel: {}",
65                response.status()
66            )))
67        }
68    }
69
70    /// Get your own channels (the authenticated user's channels)
71    ///
72    /// Requires OAuth token with `channel:read` scope
73    ///
74    /// # Example
75    /// ```no_run
76    /// let my_channels = client.channels().get_mine().await?;
77    /// for channel in my_channels {
78    ///     println!("My channel: {}", channel.slug);
79    /// }
80    /// ```
81    pub async fn get_mine(&self) -> Result<Vec<Channel>> {
82        super::require_token(self.token)?;
83
84        let url = format!("{}/channels", self.base_url);
85        let request = self
86            .client
87            .get(&url)
88            .header("Accept", "*/*")
89            .bearer_auth(self.token.as_ref().unwrap());
90
91        let response = crate::http::send_with_retry(self.client, request).await?;
92        if response.status().is_success() {
93            let body = response.text().await?;
94
95            #[derive(serde::Deserialize)]
96            struct ChannelsResponse {
97                data: Vec<Channel>,
98            }
99
100            let resp: ChannelsResponse = serde_json::from_str(&body)
101                .map_err(|e| KickApiError::ApiError(format!("JSON parse error: {}", e)))?;
102
103            Ok(resp.data)
104        } else {
105            Err(KickApiError::ApiError(format!(
106                "Failed to get channels: {}",
107                response.status()
108            )))
109        }
110    }
111}