kick_api/lib.rs
1//! # kick-api
2//!
3//! Rust client for the [Kick.com](https://kick.com) API.
4//!
5//! Covers channels, users, chat, moderation, rewards, event subscriptions, and
6//! live chat over WebSocket. Handles OAuth 2.1 (PKCE) authentication and
7//! automatic retry on rate limits (429).
8//!
9//! ## Live Chat (no auth required)
10//!
11//! ```no_run
12//! use kick_api::LiveChatClient;
13//!
14//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
15//! // Connect by username
16//! let mut chat = LiveChatClient::connect_by_username("xqc").await?;
17//!
18//! // Or connect by chatroom ID directly
19//! // let mut chat = LiveChatClient::connect(668).await?;
20//!
21//! while let Some(msg) = chat.next_message().await? {
22//! println!("{}: {}", msg.sender.username, msg.content);
23//! }
24//! # Ok(())
25//! # }
26//! ```
27//!
28//! ## REST API (requires OAuth token)
29//!
30//! ```no_run
31//! use kick_api::{KickApiClient, SendMessageRequest};
32//!
33//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
34//! let client = KickApiClient::with_token("your_oauth_token".to_string());
35//!
36//! // Channels
37//! let channel = client.channels().get("xqc").await?;
38//!
39//! // Users
40//! let me = client.users().get_me().await?;
41//!
42//! // Chat
43//! let msg = SendMessageRequest {
44//! r#type: "user".to_string(),
45//! content: "Hello chat!".to_string(),
46//! broadcaster_user_id: Some(12345),
47//! reply_to_message_id: None,
48//! };
49//! client.chat().send_message(msg).await?;
50//! # Ok(())
51//! # }
52//! ```
53//!
54//! ## Unofficial API
55//!
56//! Some features use Kick's **internal v2 API** (`kick.com/api/v2/...`) rather
57//! than the public API. These are reverse-engineered and **may break without
58//! notice**. They use `curl` as a subprocess to bypass Cloudflare TLS
59//! fingerprinting.
60//!
61//! | Function | Auth | Description |
62//! |----------|------|-------------|
63//! | [`LiveChatClient`] | None | Real-time chat via Pusher WebSocket |
64//! | [`fetch_channel_info`] | None | Chatroom settings, badges, livestream status |
65//! | [`fetch_followed_channels`] | Session token | Channels the authenticated user follows |
66//!
67//! ```no_run
68//! use kick_api::{fetch_channel_info, fetch_followed_channels};
69//!
70//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
71//! // Public — no auth
72//! let info = fetch_channel_info("xqc").await?;
73//! println!("Chatroom ID: {}", info.chatroom.id);
74//!
75//! // Requires session token (from browser cookies, not an OAuth app token)
76//! let followed = fetch_followed_channels("your_session_token").await?;
77//! for ch in &followed {
78//! println!("{}", ch.slug);
79//! }
80//! # Ok(())
81//! # }
82//! ```
83//!
84//! ## Authentication
85//!
86//! Kick uses OAuth 2.1 with PKCE. Use [`KickOAuth`] to handle the flow:
87//!
88//! ```no_run
89//! use kick_api::KickOAuth;
90//!
91//! # fn example() -> Result<(), Box<dyn std::error::Error>> {
92//! // Load from KICK_CLIENT_ID, KICK_CLIENT_SECRET, KICK_REDIRECT_URI
93//! let oauth = KickOAuth::from_env()?;
94//! let scopes = vec!["chat:write", "user:read", "channel:read"];
95//! let (auth_url, csrf_token, pkce_verifier) = oauth.get_authorization_url(scopes);
96//! // Send the user to auth_url, then exchange the code:
97//! // let token = oauth.exchange_code(code, pkce_verifier).await?;
98//! # Ok(())
99//! # }
100//! ```
101//!
102//! For server-to-server access (no user interaction), use an App Access Token:
103//!
104//! ```no_run
105//! use kick_api::KickOAuth;
106//!
107//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
108//! // Only needs KICK_CLIENT_ID and KICK_CLIENT_SECRET
109//! let oauth = KickOAuth::from_env_server()?;
110//! let token = oauth.get_app_access_token().await?;
111//! let client = kick_api::KickApiClient::with_token(token.access_token);
112//! # Ok(())
113//! # }
114//! ```
115
116mod error;
117mod client;
118mod http;
119mod live_chat;
120mod models;
121mod oauth;
122mod api;
123
124pub use error::{KickApiError, Result};
125pub use client::KickApiClient;
126pub use live_chat::{LiveChatClient, fetch_channel_info, fetch_followed_channels};
127pub use models::*;
128pub use oauth::{KickOAuth, OAuthTokenResponse};
129pub use api::{ChannelsApi, ChatApi, EventsApi, LivestreamsApi, ModerationApi, RewardsApi, UsersApi};