1use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum ConnectionState {
9 Disconnected,
10 Connecting,
11 Connected,
12 Reconnecting,
13 Error,
14}
15
16#[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#[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#[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#[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#[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#[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#[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#[derive(Debug, Clone, Serialize, Deserialize)]
113pub struct UserBannedEvent {
114 pub username: String,
115 #[serde(rename = "type")]
116 pub event_type: String,
117}
118
119#[derive(Debug, Clone, Serialize, Deserialize)]
121pub struct UserUnbannedEvent {
122 pub username: String,
123 #[serde(rename = "type")]
124 pub event_type: String,
125}
126
127#[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#[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#[derive(Debug, Clone, Serialize, Deserialize)]
148pub struct PinnedMessageCreatedEvent {
149 pub message: ChatMessageEvent,
150 #[serde(rename = "type")]
151 pub event_type: String,
152}
153
154#[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#[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#[derive(Debug, Clone, Serialize, Deserialize)]
177pub struct PollOption {
178 pub id: String,
179 pub text: String,
180 pub votes: u32,
181}
182
183#[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#[derive(Debug, Clone, Serialize, Deserialize)]
194pub struct KickChatroom {
195 pub id: u64,
196 pub channel_id: u64,
197 pub name: String,
198}
199
200#[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#[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#[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#[derive(Debug, Clone)]
233pub struct RawMessage {
234 pub event_type: String,
235 pub data: String,
236 pub raw_json: String,
237}
238
239#[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#[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#[derive(Debug, Clone, Serialize, Deserialize)]
269pub struct RawUserUnbannedData {
270 pub username: Option<String>,
271}
272
273#[derive(Debug, Clone, Serialize, Deserialize)]
275pub struct RawSubscriptionData {
276 pub username: String,
277 pub months: Option<u32>,
278}
279
280#[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#[derive(Debug, Clone, Serialize, Deserialize)]
291pub struct RawPinnedMessageCreatedData {
292 pub message: RawChatMessageData,
293}
294
295#[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#[derive(Debug, Clone, Serialize, Deserialize)]
305pub struct RawPollUpdateData {
306 pub id: String,
307 pub question: String,
308 pub options: Vec<RawPollOption>,
309}
310
311#[derive(Debug, Clone, Serialize, Deserialize)]
313pub struct RawPollOption {
314 pub id: String,
315 pub text: String,
316 pub votes: Option<u32>,
317}
318
319#[derive(Debug, Clone, Serialize, Deserialize)]
321pub struct RawPollDeleteData {
322 pub id: String,
323}
324
325#[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#[derive(Debug, Clone)]
343pub struct ParsedMessage {
344 pub r#type: KickEventType,
345 pub data: KickEventData,
346}
347
348
349
350#[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>;