kick_rust/
types.rs

1//! Types and data structures for Kick WebSocket events
2
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5
6/// Connection state of the WebSocket
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum ConnectionState {
9    Disconnected,
10    Connecting,
11    Connected,
12    Reconnecting,
13    Error,
14}
15
16/// Event types that can be received from Kick WebSocket
17#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
18#[serde(rename_all = "snake_case")]
19pub enum KickEventType {
20    ChatMessage,
21    MessageDeleted,
22    UserBanned,
23    UserUnbanned,
24    Subscription,
25    GiftedSubscriptions,
26    PinnedMessageCreated,
27    StreamHost,
28    PollUpdate,
29    PollDelete,
30}
31
32/// Configuration options for the WebSocket connection
33#[derive(Debug, Clone)]
34pub struct KickWebSocketOptions {
35    pub debug: bool,
36    pub auto_reconnect: bool,
37    pub reconnect_interval: u64,
38    pub enable_buffer: bool,
39    pub buffer_size: usize,
40    pub filtered_events: Vec<KickEventType>,
41    pub custom_user_agent: Option<String>,
42    pub rotate_user_agent: bool,
43}
44
45impl Default for KickWebSocketOptions {
46    fn default() -> Self {
47        Self {
48            debug: false,
49            auto_reconnect: true,
50            reconnect_interval: 5000,
51            enable_buffer: false,
52            buffer_size: 1000,
53            filtered_events: vec![],
54            custom_user_agent: None,
55            rotate_user_agent: true,
56        }
57    }
58}
59
60/// Statistics for the message buffer
61#[derive(Debug, Clone)]
62pub struct BufferStats {
63    pub total: usize,
64    pub by_type: HashMap<String, usize>,
65    pub oldest_timestamp: Option<chrono::DateTime<chrono::Utc>>,
66    pub newest_timestamp: Option<chrono::DateTime<chrono::Utc>>,
67}
68
69/// Kick channel information
70#[derive(Debug, Clone, Serialize, Deserialize)]
71pub struct KickChannel {
72    pub id: u64,
73    pub slug: String,
74    pub user: KickUser,
75    pub chatroom: KickChatroom,
76}
77
78/// Kick user information
79#[derive(Debug, Clone, Serialize, Deserialize)]
80pub struct KickUser {
81    pub id: u64,
82    pub username: String,
83    pub display_name: Option<String>,
84    pub avatar_url: Option<String>,
85}
86
87/// Chat message event
88#[derive(Debug, Clone, Serialize, Deserialize)]
89pub struct ChatMessageEvent {
90    pub id: String,
91    pub content: String,
92    #[serde(rename = "type")]
93    pub message_type: String,
94    #[serde(rename = "created_at")]
95    pub created_at: String,
96    pub sender: KickUser,
97    pub chatroom: KickChatroom,
98}
99
100/// Message deleted event
101#[derive(Debug, Clone, Serialize, Deserialize)]
102pub struct MessageDeletedEvent {
103    #[serde(rename = "message_id")]
104    pub message_id: String,
105    #[serde(rename = "chatroom_id")]
106    pub chatroom_id: u64,
107    #[serde(rename = "type")]
108    pub event_type: String,
109}
110
111/// User banned event
112#[derive(Debug, Clone, Serialize, Deserialize)]
113pub struct UserBannedEvent {
114    pub username: String,
115    #[serde(rename = "type")]
116    pub event_type: String,
117}
118
119/// User unbanned event
120#[derive(Debug, Clone, Serialize, Deserialize)]
121pub struct UserUnbannedEvent {
122    pub username: String,
123    #[serde(rename = "type")]
124    pub event_type: String,
125}
126
127/// Subscription event
128#[derive(Debug, Clone, Serialize, Deserialize)]
129pub struct SubscriptionEvent {
130    pub username: String,
131    pub months: Option<u32>,
132    #[serde(rename = "type")]
133    pub event_type: String,
134}
135
136/// Gifted subscriptions event
137#[derive(Debug, Clone, Serialize, Deserialize)]
138pub struct GiftedSubscriptionsEvent {
139    #[serde(rename = "gifted_by")]
140    pub gifted_by: String,
141    pub recipients: Vec<String>,
142    #[serde(rename = "type")]
143    pub event_type: String,
144}
145
146/// Pinned message created event
147#[derive(Debug, Clone, Serialize, Deserialize)]
148pub struct PinnedMessageCreatedEvent {
149    pub message: ChatMessageEvent,
150    #[serde(rename = "type")]
151    pub event_type: String,
152}
153
154/// Stream host event
155#[derive(Debug, Clone, Serialize, Deserialize)]
156pub struct StreamHostEvent {
157    pub hoster: String,
158    #[serde(rename = "hosted_channel")]
159    pub hosted_channel: String,
160    #[serde(rename = "type")]
161    pub event_type: String,
162}
163
164/// Poll update event
165#[derive(Debug, Clone, Serialize, Deserialize)]
166pub struct PollUpdateEvent {
167    #[serde(rename = "poll_id")]
168    pub poll_id: String,
169    pub question: String,
170    pub options: Vec<PollOption>,
171    #[serde(rename = "type")]
172    pub event_type: String,
173}
174
175/// Poll option
176#[derive(Debug, Clone, Serialize, Deserialize)]
177pub struct PollOption {
178    pub id: String,
179    pub text: String,
180    pub votes: u32,
181}
182
183/// Poll delete event
184#[derive(Debug, Clone, Serialize, Deserialize)]
185pub struct PollDeleteEvent {
186    #[serde(rename = "poll_id")]
187    pub poll_id: String,
188    #[serde(rename = "type")]
189    pub event_type: String,
190}
191
192/// Kick chatroom information
193#[derive(Debug, Clone, Serialize, Deserialize)]
194pub struct KickChatroom {
195    pub id: u64,
196    pub channel_id: u64,
197    pub name: String,
198}
199
200/// Raw WebSocket message structure
201#[derive(Debug, Clone, Serialize, Deserialize)]
202pub struct WebSocketMessage {
203    pub event: String,
204    pub data: serde_json::Value,
205    pub channel: Option<String>,
206}
207
208/// Raw chat message data
209#[derive(Debug, Clone, Serialize, Deserialize)]
210pub struct RawChatMessageData {
211    pub id: String,
212    pub content: String,
213    #[serde(rename = "type")]
214    pub message_type: String,
215    #[serde(rename = "created_at")]
216    pub created_at: String,
217    pub sender: KickUser,
218    #[serde(rename = "chatroom_id")]
219    pub chatroom_id: u64,
220}
221
222/// Raw message deleted data
223#[derive(Debug, Clone, Serialize, Deserialize)]
224pub struct RawMessageDeletedData {
225    #[serde(rename = "message_id")]
226    pub message_id: String,
227    #[serde(rename = "chatroom_id")]
228    pub chatroom_id: u64,
229}
230
231/// Raw WebSocket message structure
232#[derive(Debug, Clone)]
233pub struct RawMessage {
234    pub event_type: String,
235    pub data: String,
236    pub raw_json: String,
237}
238
239/// Simple message structure for easy chat message handling
240#[derive(Debug, Clone)]
241pub struct SimpleMessage {
242    pub id: String,
243    pub username: String,
244    pub content: String,
245    pub created_at: String,
246}
247
248impl From<&ChatMessageEvent> for SimpleMessage {
249    fn from(chat_msg: &ChatMessageEvent) -> Self {
250        Self {
251            id: chat_msg.id.clone(),
252            username: chat_msg.sender.username.clone(),
253            content: chat_msg.content.clone(),
254            created_at: chat_msg.created_at.clone(),
255        }
256    }
257}
258
259/// Raw user banned data
260#[derive(Debug, Clone, Serialize, Deserialize)]
261pub struct RawUserBannedData {
262    pub username: Option<String>,
263    #[serde(rename = "banned_username")]
264    pub banned_username: Option<String>,
265}
266
267/// Raw user unbanned data
268#[derive(Debug, Clone, Serialize, Deserialize)]
269pub struct RawUserUnbannedData {
270    pub username: Option<String>,
271}
272
273/// Raw subscription data
274#[derive(Debug, Clone, Serialize, Deserialize)]
275pub struct RawSubscriptionData {
276    pub username: String,
277    pub months: Option<u32>,
278}
279
280/// Raw gifted subscriptions data
281#[derive(Debug, Clone, Serialize, Deserialize)]
282pub struct RawGiftedSubscriptionsData {
283    #[serde(rename = "gifted_by")]
284    pub gifted_by: Option<String>,
285    pub gifter: Option<serde_json::Value>,
286    pub recipients: Vec<serde_json::Value>,
287}
288
289/// Raw pinned message created data
290#[derive(Debug, Clone, Serialize, Deserialize)]
291pub struct RawPinnedMessageCreatedData {
292    pub message: RawChatMessageData,
293}
294
295/// Raw stream host data
296#[derive(Debug, Clone, Serialize, Deserialize)]
297pub struct RawStreamHostData {
298    pub hoster: serde_json::Value,
299    #[serde(rename = "hosted_channel")]
300    pub hosted_channel: serde_json::Value,
301}
302
303/// Raw poll update data
304#[derive(Debug, Clone, Serialize, Deserialize)]
305pub struct RawPollUpdateData {
306    pub id: String,
307    pub question: String,
308    pub options: Vec<RawPollOption>,
309}
310
311/// Raw poll option
312#[derive(Debug, Clone, Serialize, Deserialize)]
313pub struct RawPollOption {
314    pub id: String,
315    pub text: String,
316    pub votes: Option<u32>,
317}
318
319/// Raw poll delete data
320#[derive(Debug, Clone, Serialize, Deserialize)]
321pub struct RawPollDeleteData {
322    pub id: String,
323}
324
325/// Event data enum for all possible event types
326#[derive(Debug, Clone, Serialize, Deserialize)]
327#[serde(untagged)]
328pub enum KickEventData {
329    ChatMessage(ChatMessageEvent),
330    MessageDeleted(MessageDeletedEvent),
331    UserBanned(UserBannedEvent),
332    UserUnbanned(UserUnbannedEvent),
333    Subscription(SubscriptionEvent),
334    GiftedSubscriptions(GiftedSubscriptionsEvent),
335    PinnedMessageCreated(PinnedMessageCreatedEvent),
336    StreamHost(StreamHostEvent),
337    PollUpdate(PollUpdateEvent),
338    PollDelete(PollDeleteEvent),
339}
340
341/// Parsed message with event type and data
342#[derive(Debug, Clone)]
343pub struct ParsedMessage {
344    pub r#type: KickEventType,
345    pub data: KickEventData,
346}
347
348
349
350/// Error types for the WebSocket client
351#[derive(Debug, thiserror::Error)]
352pub enum KickError {
353    #[error("WebSocket error: {0}")]
354    WebSocket(#[from] tokio_tungstenite::tungstenite::Error),
355
356    #[error("JSON serialization/deserialization error: {0}")]
357    Json(#[from] serde_json::Error),
358
359    #[error("HTTP request error: {0}")]
360    Http(#[from] reqwest::Error),
361
362    #[error("Fetch error: {0}")]
363    Fetch(#[from] crate::fetch::types::FetchError),
364
365    #[error("Invalid message format: {0}")]
366    InvalidMessage(String),
367
368    #[error("Channel not found: {0}")]
369    ChannelNotFound(String),
370
371    #[error("Connection error: {0}")]
372    Connection(String),
373
374    #[error("Unknown event type: {0}")]
375    UnknownEventType(String),
376
377    #[error("URL parse error: {0}")]
378    UrlParse(#[from] url::ParseError),
379
380    #[error("Network error: {0}")]
381    NetworkError(String),
382}
383
384pub type Result<T> = std::result::Result<T, KickError>;