1use std::{collections::HashSet, time::Duration};
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value as JsonValue;
5
6use crate::{
7 api::{Method, Payload},
8 types::{
9 BusinessConnection,
10 BusinessMessagesDeleted,
11 CallbackQuery,
12 Chat,
13 ChatBoostRemoved,
14 ChatBoostUpdated,
15 ChatJoinRequest,
16 ChatMemberUpdated,
17 ChatPeerId,
18 ChatUsername,
19 ChosenInlineResult,
20 InlineQuery,
21 Integer,
22 ManagedBotUpdated,
23 MaybeInaccessibleMessage,
24 Message,
25 MessageReactionCountUpdated,
26 MessageReactionUpdated,
27 PaidMediaPurchased,
28 Poll,
29 PollAnswer,
30 PollAnswerVoter,
31 PreCheckoutQuery,
32 ShippingQuery,
33 User,
34 UserPeerId,
35 UserUsername,
36 },
37};
38
39#[derive(Clone, Debug, Deserialize, Serialize)]
41pub struct Update {
42 #[serde(rename = "update_id")]
51 pub id: Integer,
52 #[serde(flatten)]
54 pub update_type: UpdateType,
55}
56
57impl Update {
58 pub fn new(id: Integer, update_type: UpdateType) -> Self {
65 Self { id, update_type }
66 }
67
68 pub fn get_chat(&self) -> Option<&Chat> {
70 self.get_message().map(|msg| &msg.chat).or(match &self.update_type {
71 UpdateType::BotStatus(x) | UpdateType::UserStatus(x) => Some(&x.chat),
72 UpdateType::DeletedBusinessMessages(x) => Some(&x.chat),
73 UpdateType::ChatBoostRemoved(x) => Some(&x.chat),
74 UpdateType::ChatBoostUpdated(x) => Some(&x.chat),
75 UpdateType::ChatJoinRequest(x) => Some(&x.chat),
76 UpdateType::MessageReaction(x) => Some(&x.chat),
77 UpdateType::MessageReactionCount(x) => Some(&x.chat),
78 _ => None,
79 })
80 }
81
82 pub fn get_chat_id(&self) -> Option<ChatPeerId> {
84 self.get_chat().map(|chat| chat.get_id())
85 }
86
87 pub fn get_chat_username(&self) -> Option<&ChatUsername> {
89 self.get_chat().and_then(|chat| chat.get_username())
90 }
91
92 pub fn get_user(&self) -> Option<&User> {
94 Some(match &self.update_type {
95 UpdateType::BotStatus(x) | UpdateType::UserStatus(x) => &x.from,
96 UpdateType::BusinessConnection(x) => &x.user,
97 UpdateType::CallbackQuery(x) => &x.from,
98 UpdateType::ChatBoostRemoved(_) => return None,
99 UpdateType::ChatBoostUpdated(_) => return None,
100 UpdateType::ChatJoinRequest(x) => &x.from,
101 UpdateType::ChosenInlineResult(x) => &x.from,
102 UpdateType::DeletedBusinessMessages(_) => return None,
103 UpdateType::InlineQuery(x) => &x.from,
104 UpdateType::ManagedBot(x) => &x.user,
105 UpdateType::Message(x)
106 | UpdateType::BusinessMessage(x)
107 | UpdateType::ChannelPost(x)
108 | UpdateType::EditedBusinessMessage(x)
109 | UpdateType::EditedChannelPost(x)
110 | UpdateType::EditedMessage(x)
111 | UpdateType::GuestMessage(x) => return x.sender.get_user(),
112 UpdateType::MessageReaction(x) => return x.user.as_ref(),
113 UpdateType::MessageReactionCount(_) => return None,
114 UpdateType::Poll(_) => return None,
115 UpdateType::PollAnswer(x) => match &x.voter {
116 PollAnswerVoter::User(x) => x,
117 PollAnswerVoter::Chat(_) => return None,
118 },
119 UpdateType::PreCheckoutQuery(x) => &x.from,
120 UpdateType::PurchasedPaidMedia(x) => &x.from,
121 UpdateType::ShippingQuery(x) => &x.from,
122 UpdateType::Unknown(_) => return None,
123 })
124 }
125
126 pub fn get_user_id(&self) -> Option<UserPeerId> {
128 self.get_user().map(|user| user.id)
129 }
130
131 pub fn get_user_username(&self) -> Option<&UserUsername> {
133 self.get_user().and_then(|user| user.username.as_ref())
134 }
135
136 pub fn get_message(&self) -> Option<&Message> {
138 match &self.update_type {
139 UpdateType::Message(msg)
140 | UpdateType::BusinessMessage(msg)
141 | UpdateType::ChannelPost(msg)
142 | UpdateType::EditedBusinessMessage(msg)
143 | UpdateType::EditedChannelPost(msg)
144 | UpdateType::EditedMessage(msg)
145 | UpdateType::GuestMessage(msg) => Some(msg),
146 UpdateType::CallbackQuery(query) => match &query.message {
147 Some(MaybeInaccessibleMessage::Message(msg)) => Some(msg),
148 _ => None,
149 },
150 _ => None,
151 }
152 }
153}
154
155#[derive(Clone, Debug, Deserialize, Serialize)]
157#[serde(rename_all = "snake_case")]
158pub enum UpdateType {
159 #[serde(rename = "my_chat_member")]
164 BotStatus(Box<ChatMemberUpdated>),
165 BusinessConnection(Box<BusinessConnection>),
168 BusinessMessage(Box<Message>),
170 CallbackQuery(Box<CallbackQuery>),
172 ChannelPost(Box<Message>),
174 #[serde(rename = "removed_chat_boost")]
178 ChatBoostRemoved(Box<ChatBoostRemoved>),
179 #[serde(rename = "chat_boost")]
183 ChatBoostUpdated(Box<ChatBoostUpdated>),
184 ChatJoinRequest(Box<ChatJoinRequest>),
189 ChosenInlineResult(Box<ChosenInlineResult>),
196 DeletedBusinessMessages(Box<BusinessMessagesDeleted>),
198 EditedBusinessMessage(Box<Message>),
200 EditedChannelPost(Box<Message>),
202 EditedMessage(Box<Message>),
204 GuestMessage(Box<Message>),
206 InlineQuery(Box<InlineQuery>),
210 ManagedBot(ManagedBotUpdated),
212 Message(Box<Message>),
214 MessageReaction(Box<MessageReactionUpdated>),
222 MessageReactionCount(Box<MessageReactionCountUpdated>),
228 Poll(Box<Poll>),
232 PollAnswer(Box<PollAnswer>),
236 PreCheckoutQuery(Box<PreCheckoutQuery>),
240 PurchasedPaidMedia(Box<PaidMediaPurchased>),
242 ShippingQuery(Box<ShippingQuery>),
246 #[serde(rename = "chat_member")]
252 UserStatus(Box<ChatMemberUpdated>),
253 #[serde(untagged)]
258 Unknown(JsonValue),
259}
260
261pub struct UnexpectedUpdate(Update);
265
266impl From<UnexpectedUpdate> for Update {
267 fn from(value: UnexpectedUpdate) -> Self {
268 value.0
269 }
270}
271
272impl TryFrom<Update> for BusinessConnection {
273 type Error = UnexpectedUpdate;
274
275 fn try_from(value: Update) -> Result<Self, Self::Error> {
276 use self::UpdateType::*;
277 match value.update_type {
278 BusinessConnection(x) => Ok(*x),
279 _ => Err(UnexpectedUpdate(value)),
280 }
281 }
282}
283
284impl TryFrom<Update> for BusinessMessagesDeleted {
285 type Error = UnexpectedUpdate;
286
287 fn try_from(value: Update) -> Result<Self, Self::Error> {
288 use self::UpdateType::*;
289 match value.update_type {
290 DeletedBusinessMessages(x) => Ok(*x),
291 _ => Err(UnexpectedUpdate(value)),
292 }
293 }
294}
295
296impl TryFrom<Update> for ChatMemberUpdated {
297 type Error = UnexpectedUpdate;
298
299 fn try_from(value: Update) -> Result<Self, Self::Error> {
300 use self::UpdateType::*;
301 match value.update_type {
302 BotStatus(x) | UserStatus(x) => Ok(*x),
303 _ => Err(UnexpectedUpdate(value)),
304 }
305 }
306}
307
308impl TryFrom<Update> for CallbackQuery {
309 type Error = UnexpectedUpdate;
310
311 fn try_from(value: Update) -> Result<Self, Self::Error> {
312 use self::UpdateType::*;
313 match value.update_type {
314 CallbackQuery(x) => Ok(*x),
315 _ => Err(UnexpectedUpdate(value)),
316 }
317 }
318}
319
320impl TryFrom<Update> for ChatJoinRequest {
321 type Error = UnexpectedUpdate;
322
323 fn try_from(value: Update) -> Result<Self, Self::Error> {
324 use self::UpdateType::*;
325 match value.update_type {
326 ChatJoinRequest(x) => Ok(*x),
327 _ => Err(UnexpectedUpdate(value)),
328 }
329 }
330}
331
332impl TryFrom<Update> for ChosenInlineResult {
333 type Error = UnexpectedUpdate;
334
335 fn try_from(value: Update) -> Result<Self, Self::Error> {
336 use self::UpdateType::*;
337 match value.update_type {
338 ChosenInlineResult(x) => Ok(*x),
339 _ => Err(UnexpectedUpdate(value)),
340 }
341 }
342}
343
344impl TryFrom<Update> for InlineQuery {
345 type Error = UnexpectedUpdate;
346
347 fn try_from(value: Update) -> Result<Self, Self::Error> {
348 use self::UpdateType::*;
349 match value.update_type {
350 InlineQuery(x) => Ok(*x),
351 _ => Err(UnexpectedUpdate(value)),
352 }
353 }
354}
355
356impl TryFrom<Update> for Message {
357 type Error = UnexpectedUpdate;
358
359 fn try_from(value: Update) -> Result<Self, Self::Error> {
360 use self::UpdateType::*;
361 match value.update_type {
362 BusinessMessage(x)
363 | EditedBusinessMessage(x)
364 | EditedChannelPost(x)
365 | EditedMessage(x)
366 | GuestMessage(x)
367 | ChannelPost(x)
368 | Message(x) => Ok(*x),
369 _ => Err(UnexpectedUpdate(value)),
370 }
371 }
372}
373
374impl TryFrom<Update> for Poll {
375 type Error = UnexpectedUpdate;
376
377 fn try_from(value: Update) -> Result<Self, Self::Error> {
378 use self::UpdateType::*;
379 match value.update_type {
380 Poll(x) => Ok(*x),
381 _ => Err(UnexpectedUpdate(value)),
382 }
383 }
384}
385
386impl TryFrom<Update> for PollAnswer {
387 type Error = UnexpectedUpdate;
388
389 fn try_from(value: Update) -> Result<Self, Self::Error> {
390 use self::UpdateType::*;
391 match value.update_type {
392 PollAnswer(x) => Ok(*x),
393 _ => Err(UnexpectedUpdate(value)),
394 }
395 }
396}
397
398impl TryFrom<Update> for PreCheckoutQuery {
399 type Error = UnexpectedUpdate;
400
401 fn try_from(value: Update) -> Result<Self, Self::Error> {
402 use self::UpdateType::*;
403 match value.update_type {
404 PreCheckoutQuery(x) => Ok(*x),
405 _ => Err(UnexpectedUpdate(value)),
406 }
407 }
408}
409
410impl TryFrom<Update> for PaidMediaPurchased {
411 type Error = UnexpectedUpdate;
412
413 fn try_from(value: Update) -> Result<Self, Self::Error> {
414 use self::UpdateType::*;
415 match value.update_type {
416 PurchasedPaidMedia(x) => Ok(*x),
417 _ => Err(UnexpectedUpdate(value)),
418 }
419 }
420}
421
422impl TryFrom<Update> for ShippingQuery {
423 type Error = UnexpectedUpdate;
424
425 fn try_from(value: Update) -> Result<Self, Self::Error> {
426 use self::UpdateType::*;
427 match value.update_type {
428 ShippingQuery(x) => Ok(*x),
429 _ => Err(UnexpectedUpdate(value)),
430 }
431 }
432}
433
434#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
436#[serde(rename_all = "snake_case")]
437pub enum AllowedUpdate {
438 #[serde(rename = "my_chat_member")]
440 BotStatus,
441 BusinessConnection,
443 BusinessMessage,
445 CallbackQuery,
447 ChannelPost,
449 #[serde(rename = "removed_chat_boost")]
451 ChatBoostRemoved,
452 #[serde(rename = "chat_boost")]
454 ChatBoostUpdated,
455 ChatJoinRequest,
457 ChosenInlineResult,
459 DeletedBusinessMessages,
461 EditedBusinessMessage,
463 EditedChannelPost,
465 EditedMessage,
467 GuestMessage,
469 InlineQuery,
471 Message,
473 MessageReaction,
475 MessageReactionCount,
477 Poll,
479 PollAnswer,
481 PreCheckoutQuery,
483 PurchasedPaidMedia,
485 ShippingQuery,
487 #[serde(rename = "chat_member")]
489 UserStatus,
490}
491
492#[serde_with::skip_serializing_none]
493#[derive(Clone, Debug, Default, Serialize)]
495pub struct GetUpdates {
496 allowed_updates: Option<HashSet<AllowedUpdate>>,
497 limit: Option<Integer>,
498 offset: Option<Integer>,
499 timeout: Option<Integer>,
500}
501
502impl Method for GetUpdates {
503 type Response = Vec<Update>;
504
505 fn into_payload(self) -> Payload {
506 Payload::json("getUpdates", self)
507 }
508}
509
510impl GetUpdates {
511 pub fn add_allowed_update(mut self, value: AllowedUpdate) -> Self {
517 match self.allowed_updates {
518 Some(ref mut updates) => {
519 updates.insert(value);
520 }
521 None => {
522 let mut updates = HashSet::new();
523 updates.insert(value);
524 self.allowed_updates = Some(updates);
525 }
526 };
527 self
528 }
529
530 pub fn with_allowed_updates<T>(mut self, value: T) -> Self
544 where
545 T: IntoIterator<Item = AllowedUpdate>,
546 {
547 self.allowed_updates = Some(value.into_iter().collect());
548 self
549 }
550
551 pub fn with_limit(mut self, value: Integer) -> Self {
557 self.limit = Some(value);
558 self
559 }
560
561 pub fn with_offset(mut self, value: Integer) -> Self {
576 self.offset = Some(value);
577 self
578 }
579
580 pub fn with_timeout(mut self, value: Duration) -> Self {
587 self.timeout = Some(value.as_secs() as i64);
588 self
589 }
590}