1use crate::{Deserialise, Serialise};
2
3use crate::*;
4
5#[cfg(feature = "bevy")]
6use bevy_ecs::prelude::Event as BevyEvent;
7
8#[derive(Deserialise, Debug, Clone)]
9pub struct NewAccessTokenResponse {
10 pub access_token: String,
11 pub expires_in: u32,
12 pub token_type: String,
13 pub refresh_token: Option<String>,
14 pub scope: Option<Vec<String>>,
15}
16
17#[derive(Serialise, Deserialise, Debug, Clone)]
18pub struct Validation {
19 client_id: Option<String>,
20 login: Option<String>,
21 pub scopes: Option<Vec<String>>,
22 user_id: Option<String>,
23 pub expires_in: Option<u32>,
24 pub status: Option<u32>,
25 pub message: Option<String>,
26}
27
28impl Validation {
29 pub fn is_error(&self) -> bool {
30 self.status.is_some()
31 }
32
33 pub fn error_msg(&self) -> String {
34 if self.is_error() {
35 format!(
36 "status: {}, message: {}",
37 self.status.unwrap(),
38 self.message.clone().unwrap()
39 )
40 } else {
41 panic!("Validation Error message requested, when it isnt a error!");
42 }
43 }
44}
45
46#[derive(Serialise, Deserialise, Debug, Clone)]
47pub struct TimeoutRequestData {
48 pub user_id: String,
49 pub duration: u32,
50 pub reason: String,
51}
52
53#[derive(Serialise, Deserialise, Debug, Clone)]
54pub struct SendTimeoutRequest {
55 pub data: TimeoutRequestData,
56}
57
58#[derive(Serialise, Deserialise, Debug, Clone)]
59pub struct SendMessage {
60 pub broadcaster_id: String,
61 pub sender_id: String,
62 pub message: String,
63 pub reply_parent_message_id: Option<String>,
64}
65
66#[derive(Serialise, Deserialise, Debug, Clone, PartialEq)]
67pub struct Transport {
68 pub method: String,
69 pub session_id: String,
70}
71
72impl Transport {
73 pub fn new<S: Into<String>>(session_id: S) -> Transport {
74 Transport {
75 method: "websocket".to_string(),
76 session_id: session_id.into(),
77 }
78 }
79}
80
81#[derive(Serialise, Deserialise, Debug, Clone)]
82pub struct Session {
83 pub id: String,
84 pub status: String,
85 pub connected_at: String,
86 pub keepalive_timeout_seconds: Option<u32>,
87 pub reconnect_url: Option<String>, pub recovery_url: Option<String>, }
90
91#[derive(Serialise, Deserialise, Debug, Clone)]
92pub struct GMSubscription {
93 pub id: String,
94 pub status: Option<String>,
95 #[serde(rename = "type")]
96 pub kind: String,
97 pub version: String,
98 pub cost: i32,
99 pub condition: Option<Condition>,
100 pub transport: Transport,
101 pub created_at: String,
102 }
104
105#[repr(C)]
106#[derive(Serialise, Deserialise, Debug, Clone)]
107pub struct Mention {
108 pub user_id: String,
109 pub user_login: String,
110 pub user_name: String,
111}
112
113#[repr(C)]
114#[derive(Serialise, Deserialise, Debug, Clone)]
115pub struct Emote {
116 pub id: String,
117 pub emote_set_id: String,
118 pub owner_id: Option<String>,
119 pub format: Option<Vec<String>>,
120}
121
122#[repr(C)]
123#[derive(Serialise, Deserialise, Debug, Clone)]
124pub struct CheerMote {
125 pub prefix: String,
126 pub bits: u32,
127 pub tier: u32,
128}
129#[derive(Serialise, Deserialise, Clone, Debug, PartialEq)]
130pub enum FragmentType {
131 #[serde(rename = "text")]
132 Text,
133 #[serde(rename = "cheermote")]
134 CheerMote,
135 #[serde(rename = "emote")]
136 Emote,
137 #[serde(rename = "mention")]
138 Mention,
139 BttvEmote,
140}
141
142impl FragmentType {
143 pub fn from_string(v: &str) -> FragmentType {
144 match v {
145 "text" => FragmentType::Text,
146 "cheermote" => FragmentType::CheerMote,
147 "emote" => FragmentType::Emote,
148 "mention" => FragmentType::Mention,
149 "bttvemote" => FragmentType::BttvEmote,
150 _ => FragmentType::Text,
151 }
152 }
153}
154
155impl Into<String> for FragmentType {
156 fn into(self) -> String {
157 match self {
158 FragmentType::Text => "text",
159 FragmentType::CheerMote => "cheermote",
160 FragmentType::Emote => "emote",
161 FragmentType::Mention => "mention",
162 FragmentType::BttvEmote => "bttvemote",
163 }
164 .to_string()
165 }
166}
167
168#[repr(C)]
169#[derive(Serialise, Deserialise, Debug, Clone)]
170pub struct Fragments {
171 #[serde(rename = "type")]
172 pub kind: FragmentType,
173 pub text: String,
174 pub cheermote: Option<CheerMote>,
175 pub emote: Option<Emote>,
176 pub mention: Option<Mention>,
177}
178
179impl Message {
180 pub fn get_written_message(&self) -> Option<String> {
181 let mut text = None;
182 for fragment in &self.fragments {
183 if fragment.kind != FragmentType::Mention {
184 if let Some(ref mut text) = text {
185 *text = format!("{} {}", text, fragment.text);
186 } else {
187 text = Some(fragment.text.to_string().trim().to_string());
188 }
189 }
190 }
191 text
192 }
193}
194
195#[repr(C)]
196#[derive(Serialise, Deserialise, Debug, Clone)]
197pub struct Message {
198 pub text: String,
199 pub fragments: Vec<Fragments>,
200}
201
202#[repr(C)]
203#[derive(Serialise, Deserialise, Debug, Clone)]
204pub struct Badge {
205 pub set_id: String,
206 pub id: String,
207 pub info: String,
208}
209
210#[repr(C)]
211#[derive(Serialise, Deserialise, Debug, Clone)]
212pub struct Reply {
213 #[serde(flatten, with = "prefix_thread")]
214 pub thread: User,
215 #[serde(flatten, with = "prefix_parent")]
216 pub parent: User,
217 pub parent_message_id: String,
218 pub parent_message_body: String,
219 pub thread_message_id: String,
220}
221
222#[derive(Serialise, Deserialise, Debug, Clone, PartialEq)]
223pub struct Reward {
224 pub id: String,
225 pub title: String,
226 pub prompt: String,
227 pub cost: u32,
228}
229
230#[repr(C)]
231#[derive(Serialise, Deserialise, Debug, Clone)]
232pub struct Cheer {
233 pub bits: u32,
234}
235
236#[cfg_attr(
237 feature = "bevy",
238 derive(Serialise, Deserialise, Debug, Clone, BevyEvent)
239)]
240#[cfg_attr(not(feature = "bevy"), derive(Serialise, Deserialise, Debug, Clone))]
241#[serde(untagged)]
242pub enum TwitchEvent {
243 ChatMessage(MessageData),
244 Raid(RaidData),
245 Follow(FollowData),
246 PointsCustomRewardRedeem(CustomPointsRewardRedeemData),
247 AdBreakBegin(AdBreakBeginData),
248 NewSubscription(NewSubscriptionData),
249 GiftSubscription(GiftData),
250 Resubscription(ResubscriptionData),
251 Cheer(CheerData),
252 ChannelPointsAutoRewardRedeem(ChannelPointsAutoRewardRedeemData),
253 PollProgress(PollProgressData),
254 PollBegin(PollBeginData),
255 PollEnd(PollEndData),
256 PredictionProgress(PredicitonProgressData),
257 PredictionBegin(PredictionBeginData),
258 PredictionLock(PredictionLockData),
259 PredictionEnd(PredicitionEndData),
260 HypeTrainProgress(HypeTrainProgressData),
261 HypeTrainBegin(HypeTrainBeginData),
262 HypeTrainEnd(HypeTrainEndData),
263 MessageDeleted(MessageDeletedData),
264 ShoutoutRecieve(ShoutoutRecieveData),
265 ShoutoutCreate(ShoutoutCreateData),
266}
267
268#[derive(Serialise, Deserialise, Debug, Clone)]
269pub struct Payload {
270 pub session: Option<Session>,
271 pub subscription: Option<GMSubscription>,
272 pub event: Option<TwitchEvent>,
273}
274
275#[derive(Serialise, Deserialise, Debug, Clone)]
276pub struct MetaData {
277 pub message_id: String,
278 pub message_type: String,
279 pub message_timestamp: String,
280 pub subscription_type: Option<String>,
281 pub subscription_version: Option<String>,
282}
283
284#[derive(Serialise, Deserialise, Debug, Clone)]
285pub struct GenericMessage {
286 pub metadata: MetaData,
287 pub payload: Option<Payload>,
288 pub subscription_type: Option<String>,
289 pub subscription_version: Option<String>,
290}
291
292pub enum EventMessageType {
293 Welcome,
294 KeepAlive,
295 Notification,
296 Reconnect,
297 Unknown,
298}
299
300impl EventMessageType {
301 pub fn from_string(t: &str) -> EventMessageType {
302 match t {
303 "session_welcome" => EventMessageType::Welcome,
304 "session_keepalive" => EventMessageType::KeepAlive,
305 "notification" => EventMessageType::Notification,
306 "session_reconnect" => EventMessageType::Reconnect,
307 _ => EventMessageType::Unknown,
308 }
309 }
310}
311
312impl GenericMessage {
313 pub fn event_type(&self) -> EventMessageType {
314 EventMessageType::from_string(&self.metadata.message_type)
315 }
316
317 pub fn subscription_type(&self) -> Subscription {
318 Subscription::from_string(&self.metadata.subscription_type.clone().unwrap()).unwrap()
319 }
320}