Skip to main content

grammers_client/update/
update.rs

1// Copyright 2020 - developers of the `grammers` project.
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9use grammers_session::updates::State;
10use grammers_tl_types as tl;
11
12use super::{CallbackQuery, InlineQuery, InlineSend, Message, MessageDeletion, Raw};
13use crate::{Client, peer::PeerMap, utils};
14
15/// An update that indicates some event, which may be of interest to the logged-in account, has occured.
16///
17/// Only updates pertaining to messages are guaranteed to be delivered, and can be fetched on-demand if
18/// they occured while the client was offline by enabling [`catch_up`](crate::client::UpdatesConfiguration::catch_up).
19#[non_exhaustive]
20#[derive(Debug, Clone)]
21pub enum Update {
22    /// Occurs whenever a new text message or a message with media is produced.
23    NewMessage(Message),
24    /// Occurs when a message is updated.
25    MessageEdited(Message),
26    /// Occurs when a message is deleted.
27    MessageDeleted(MessageDeletion),
28    /// Occurs when Telegram calls back into your bot because an inline callback
29    /// button was pressed.
30    CallbackQuery(CallbackQuery),
31    /// Occurs whenever you sign in as a bot and a user sends an inline query
32    /// such as `@bot query`.
33    InlineQuery(InlineQuery),
34    /// Represents an update of user choosing the result of inline query and sending it to their peer partner.
35    InlineSend(InlineSend),
36    /// Raw events are not actual events.
37    /// Instead, they are the raw Update object that Telegram sends. You
38    /// normally shouldn’t need these.
39    ///
40    /// <div class="warning">The library can "move" raw update types into
41    /// a separate update wrapper variant during minor version bumps, so use
42    /// this only as a workaround when such variant is not available yet.</div>
43    Raw(Raw),
44}
45
46impl Update {
47    /// Create new friendly to use `Update`` from its raw version and peer map.
48    pub fn from_raw(
49        client: &Client,
50        update: tl::enums::Update,
51        state: State,
52        peers: PeerMap,
53    ) -> Self {
54        match &update {
55            // NewMessage
56            tl::enums::Update::NewMessage(raw) => {
57                if utils::peer_from_message(&raw.message).is_none() {
58                    return Self::Raw(Raw { raw: update, state });
59                }
60
61                Self::NewMessage(Message {
62                    msg: crate::message::Message::from_raw(
63                        client,
64                        raw.message.clone(),
65                        None,
66                        peers,
67                    ),
68                    raw: update,
69                    state,
70                })
71            }
72
73            tl::enums::Update::NewChannelMessage(raw) => {
74                if utils::peer_from_message(&raw.message).is_none() {
75                    return Self::Raw(Raw { raw: update, state });
76                }
77
78                Self::NewMessage(Message {
79                    msg: crate::message::Message::from_raw(
80                        client,
81                        raw.message.clone(),
82                        None,
83                        peers,
84                    ),
85                    raw: update,
86                    state,
87                })
88            }
89
90            // MessageEdited
91            tl::enums::Update::EditMessage(raw) => {
92                if utils::peer_from_message(&raw.message).is_none() {
93                    return Self::Raw(Raw { raw: update, state });
94                }
95
96                Self::MessageEdited(Message {
97                    msg: crate::message::Message::from_raw(
98                        client,
99                        raw.message.clone(),
100                        None,
101                        peers,
102                    ),
103                    raw: update,
104                    state,
105                })
106            }
107            tl::enums::Update::EditChannelMessage(raw) => Self::MessageEdited(Message {
108                msg: crate::message::Message::from_raw(client, raw.message.clone(), None, peers),
109                raw: update,
110                state,
111            }),
112
113            // MessageDeleted
114            tl::enums::Update::DeleteMessages(_) => {
115                Self::MessageDeleted(MessageDeletion { raw: update, state })
116            }
117            tl::enums::Update::DeleteChannelMessages(_) => {
118                Self::MessageDeleted(MessageDeletion { raw: update, state })
119            }
120
121            // CallbackQuery
122            tl::enums::Update::BotCallbackQuery(_) => Self::CallbackQuery(CallbackQuery {
123                raw: update,
124                state,
125                client: client.clone(),
126                peers,
127            }),
128
129            // InlineCallbackQuery
130            tl::enums::Update::InlineBotCallbackQuery(_) => Self::CallbackQuery(CallbackQuery {
131                raw: update,
132                state,
133                client: client.clone(),
134                peers,
135            }),
136
137            // InlineQuery
138            tl::enums::Update::BotInlineQuery(_) => Self::InlineQuery(InlineQuery {
139                raw: update,
140                state,
141                client: client.clone(),
142                peers,
143            }),
144
145            // InlineSend
146            tl::enums::Update::BotInlineSend(_) => Self::InlineSend(InlineSend {
147                raw: update,
148                state,
149                client: client.clone(),
150                peers,
151            }),
152
153            // Raw
154            _ => Self::Raw(Raw { raw: update, state }),
155        }
156    }
157
158    /// Update state.
159    pub fn state(&self) -> &State {
160        match self {
161            Update::NewMessage(update) => &update.state,
162            Update::MessageEdited(update) => &update.state,
163            Update::MessageDeleted(update) => &update.state,
164            Update::CallbackQuery(update) => &update.state,
165            Update::InlineQuery(update) => &update.state,
166            Update::InlineSend(update) => &update.state,
167            Update::Raw(update) => &update.state,
168        }
169    }
170
171    /// Raw update, as sent by Telegram.
172    ///
173    /// Only contains the individual [`Update`](tl::enums::Update),
174    /// not the [`Updates`](tl::enums::Updates) container from which it may have come from.
175    pub fn raw(&self) -> &tl::enums::Update {
176        match self {
177            Update::NewMessage(update) => &update.raw,
178            Update::MessageEdited(update) => &update.raw,
179            Update::MessageDeleted(update) => &update.raw,
180            Update::CallbackQuery(update) => &update.raw,
181            Update::InlineQuery(update) => &update.raw,
182            Update::InlineSend(update) => &update.raw,
183            Update::Raw(update) => &update.raw,
184        }
185    }
186}