Skip to main content

rustigram_types/
update.rs

1use serde::{Deserialize, Serialize};
2
3use crate::chat::ChatJoinRequest;
4use crate::inline::{ChosenInlineResult, InlineQuery};
5use crate::message::Message;
6use crate::payments::{BotSubscriptionUpdated, PreCheckoutQuery, ShippingQuery};
7use crate::poll::{Poll, PollAnswer};
8use crate::user::User;
9
10/// An incoming update from Telegram.
11///
12/// Only one of the optional fields will be `Some` per update.
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct Update {
15    /// Unique sequential identifier.
16    pub update_id: i64,
17    /// The kind of update and its payload.
18    #[serde(flatten)]
19    pub kind: UpdateKind,
20}
21
22/// The specific kind of an incoming update.
23#[derive(Debug, Clone, Serialize, Deserialize)]
24#[serde(rename_all = "snake_case")]
25pub enum UpdateKind {
26    /// New incoming message.
27    Message(Message),
28    /// New version of a message.
29    EditedMessage(Message),
30    /// New incoming channel post.
31    ChannelPost(Message),
32    /// New version of a channel post.
33    EditedChannelPost(Message),
34    /// A message from a business account.
35    BusinessMessage(Message),
36    /// Edited message from a business account.
37    EditedBusinessMessage(Message),
38    /// New incoming inline query.
39    InlineQuery(InlineQuery),
40    /// The result of an inline query that was chosen.
41    ChosenInlineResult(ChosenInlineResult),
42    /// New incoming callback query.
43    CallbackQuery(Box<CallbackQuery>),
44    /// New incoming shipping query (only for invoices with flexible price).
45    ShippingQuery(ShippingQuery),
46    /// New incoming pre-checkout query.
47    PreCheckoutQuery(PreCheckoutQuery),
48    /// New poll state.
49    Poll(Poll),
50    /// A user changed their answer in a non-anonymous poll.
51    PollAnswer(PollAnswer),
52    /// Bot's chat member status was updated in a chat.
53    MyChatMember(ChatMemberUpdated),
54    /// A chat member's status was updated in a chat.
55    ChatMember(ChatMemberUpdated),
56    /// A request to join the chat has been sent.
57    ChatJoinRequest(ChatJoinRequest),
58    /// A reaction to a message was changed by a user.
59    MessageReaction(MessageReactionUpdated),
60    /// Reactions to a message with anonymous reactions were changed.
61    MessageReactionCount(MessageReactionCountUpdated),
62    /// A chat boost was added or changed.
63    ChatBoost(ChatBoostUpdated),
64    /// A boost was removed from a chat.
65    RemovedChatBoost(ChatBoostRemoved),
66    /// A managed bot was connected or disconnected.
67    ManagedBot(ManagedBotUpdated),
68    /// A business connection was established or removed.
69    BusinessConnection(BusinessConnection),
70    /// Messages were deleted from a connected business account.
71    DeletedBusinessMessages(BusinessMessagesDeleted),
72    /// Purchased paid media.
73    PurchasedPaidMedia(PaidMediaPurchased),
74    /// New guest message — the bot can reply using [`answerGuestQuery`](https://core.telegram.org/bots/api#answerguestquery).
75    GuestMessage(Message),
76    /// User payment subscription toward the bot has changed.
77    Subscription(BotSubscriptionUpdated),
78}
79
80impl Update {
81    /// Returns the `chat_id` if the update contains a message or callback query.
82    #[must_use]
83    pub fn chat_id(&self) -> Option<i64> {
84        match &self.kind {
85            UpdateKind::Message(m)
86            | UpdateKind::EditedMessage(m)
87            | UpdateKind::ChannelPost(m)
88            | UpdateKind::EditedChannelPost(m)
89            | UpdateKind::BusinessMessage(m)
90            | UpdateKind::EditedBusinessMessage(m)
91            | UpdateKind::GuestMessage(m) => Some(m.chat.id),
92            UpdateKind::CallbackQuery(q) => q.message.as_ref().map(|m| m.chat.id),
93            _ => None,
94        }
95    }
96
97    /// Returns the `from` user if available.
98    #[must_use]
99    pub fn from(&self) -> Option<&User> {
100        match &self.kind {
101            UpdateKind::Message(m)
102            | UpdateKind::EditedMessage(m)
103            | UpdateKind::ChannelPost(m)
104            | UpdateKind::EditedChannelPost(m)
105            | UpdateKind::BusinessMessage(m)
106            | UpdateKind::EditedBusinessMessage(m)
107            | UpdateKind::GuestMessage(m) => m.from.as_ref(),
108            UpdateKind::CallbackQuery(q) => Some(&q.from),
109            UpdateKind::InlineQuery(q) => Some(&q.from),
110            UpdateKind::ShippingQuery(q) => Some(&q.from),
111            UpdateKind::PreCheckoutQuery(q) => Some(&q.from),
112            UpdateKind::PollAnswer(a) => a.user.as_ref(),
113            UpdateKind::Subscription(s) => Some(&s.user),
114            _ => None,
115        }
116    }
117}
118
119/// Incoming callback query from a callback button in an inline keyboard.
120#[derive(Debug, Clone, Serialize, Deserialize)]
121pub struct CallbackQuery {
122    /// Unique identifier for this query.
123    pub id: String,
124    /// User who sent the query.
125    pub from: User,
126    /// Message sent by the bot with the button that originated the query.
127    #[serde(skip_serializing_if = "Option::is_none")]
128    pub message: Option<Message>,
129    /// Identifier of the message sent via the bot in inline mode.
130    #[serde(skip_serializing_if = "Option::is_none")]
131    pub inline_message_id: Option<String>,
132    /// Global identifier, uniquely corresponding to the chat where the query originated.
133    pub chat_instance: String,
134    /// Data associated with the callback button.
135    #[serde(skip_serializing_if = "Option::is_none")]
136    pub data: Option<String>,
137    /// Short name of a Game to be returned.
138    #[serde(skip_serializing_if = "Option::is_none")]
139    pub game_short_name: Option<String>,
140}
141
142/// A chat member's status change.
143#[derive(Debug, Clone, Serialize, Deserialize)]
144pub struct ChatMemberUpdated {
145    /// The chat where the change occurred.
146    pub chat: crate::chat::Chat,
147    /// The user who triggered the change.
148    pub from: User,
149    /// Date of the change, as a Unix timestamp.
150    pub date: i64,
151    /// Previous chat member status.
152    pub old_chat_member: crate::chat_member::ChatMember,
153    /// New chat member status.
154    pub new_chat_member: crate::chat_member::ChatMember,
155    /// Invite link used to join the chat, if any.
156    #[serde(skip_serializing_if = "Option::is_none")]
157    pub invite_link: Option<crate::chat::ChatInviteLink>,
158    /// `true` if the user joined via a join request.
159    #[serde(skip_serializing_if = "Option::is_none")]
160    pub via_join_request: Option<bool>,
161    /// `true` if the user joined via a folder invite link.
162    #[serde(skip_serializing_if = "Option::is_none")]
163    pub via_chat_folder_invite_link: Option<bool>,
164}
165
166/// A reaction to a message changed by a user.
167#[derive(Debug, Clone, Serialize, Deserialize)]
168pub struct MessageReactionUpdated {
169    /// The chat containing the message.
170    pub chat: crate::chat::Chat,
171    /// Identifier of the message that was reacted to.
172    pub message_id: i64,
173    /// The user who changed the reaction (non-anonymous reactions only).
174    #[serde(skip_serializing_if = "Option::is_none")]
175    pub user: Option<User>,
176    /// The chat that changed the reaction (anonymous reactions in groups).
177    #[serde(skip_serializing_if = "Option::is_none")]
178    pub actor_chat: Option<crate::chat::Chat>,
179    /// Date of the change, as a Unix timestamp.
180    pub date: i64,
181    /// Previous list of reactions.
182    pub old_reaction: Vec<crate::message::ReactionType>,
183    /// New list of reactions.
184    pub new_reaction: Vec<crate::message::ReactionType>,
185}
186
187/// Anonymous reactions to a message were changed.
188#[derive(Debug, Clone, Serialize, Deserialize)]
189pub struct MessageReactionCountUpdated {
190    /// The chat containing the message.
191    pub chat: crate::chat::Chat,
192    /// Identifier of the message.
193    pub message_id: i64,
194    /// Date of the change, as a Unix timestamp.
195    pub date: i64,
196    /// Updated list of reactions with counts.
197    pub reactions: Vec<ReactionCount>,
198}
199
200/// Count of a specific reaction type.
201#[derive(Debug, Clone, Serialize, Deserialize)]
202pub struct ReactionCount {
203    /// The reaction type.
204    #[serde(rename = "type")]
205    pub kind: crate::message::ReactionType,
206    /// Total number of reactions of this type.
207    pub total_count: u32,
208}
209
210/// A boost was added or changed in a chat.
211#[derive(Debug, Clone, Serialize, Deserialize)]
212pub struct ChatBoostUpdated {
213    /// The chat that was boosted.
214    pub chat: crate::chat::Chat,
215    /// Information about the boost.
216    pub boost: ChatBoost,
217}
218
219/// Information about a chat boost.
220#[derive(Debug, Clone, Serialize, Deserialize)]
221pub struct ChatBoost {
222    /// Unique identifier of the boost.
223    pub boost_id: String,
224    /// Unix timestamp when the boost was added.
225    pub add_date: i64,
226    /// Unix timestamp when the boost expires.
227    pub expiration_date: i64,
228    /// Source of the boost.
229    pub source: ChatBoostSource,
230}
231
232/// How a chat boost was obtained.
233#[derive(Debug, Clone, Serialize, Deserialize)]
234#[serde(tag = "source", rename_all = "snake_case")]
235pub enum ChatBoostSource {
236    /// The boost was obtained by subscribing to Telegram Premium or gifting it.
237    Premium(ChatBoostSourcePremium),
238    /// The boost was obtained by the creation of Telegram Premium gift codes.
239    GiftCode(ChatBoostSourceGiftCode),
240    /// The boost was obtained by the creation of a Telegram Premium or Star giveaway.
241    Giveaway(ChatBoostSourceGiveaway),
242}
243
244/// A boost obtained by subscribing to Telegram Premium or gifting it.
245#[derive(Debug, Clone, Serialize, Deserialize)]
246#[non_exhaustive]
247pub struct ChatBoostSourcePremium {
248    /// User that boosted the chat.
249    pub user: User,
250}
251
252/// A boost obtained by the creation of Telegram Premium gift codes.
253#[derive(Debug, Clone, Serialize, Deserialize)]
254#[non_exhaustive]
255pub struct ChatBoostSourceGiftCode {
256    /// User for which the gift code was created.
257    pub user: User,
258}
259
260/// A boost obtained by the creation of a giveaway.
261#[derive(Debug, Clone, Serialize, Deserialize)]
262#[non_exhaustive]
263pub struct ChatBoostSourceGiveaway {
264    /// Identifier of the message with the giveaway in the chat.
265    pub giveaway_message_id: i64,
266    /// User that won the prize in the giveaway, if any.
267    #[serde(skip_serializing_if = "Option::is_none")]
268    pub user: Option<User>,
269    /// Number of Telegram Stars to be split among winners; Star giveaways only.
270    #[serde(skip_serializing_if = "Option::is_none")]
271    pub prize_star_count: Option<i64>,
272    /// `true` if the giveaway was completed but no user won the prize.
273    #[serde(skip_serializing_if = "Option::is_none")]
274    pub is_unclaimed: Option<bool>,
275}
276
277/// Service message: the chat was boosted.
278#[derive(Debug, Clone, Default, Serialize, Deserialize)]
279#[non_exhaustive]
280pub struct ChatBoostAdded {
281    /// Number of boosts added by the user.
282    pub boost_count: u32,
283}
284
285/// A boost was removed from a chat.
286#[derive(Debug, Clone, Serialize, Deserialize)]
287pub struct ChatBoostRemoved {
288    /// The chat that lost the boost.
289    pub chat: crate::chat::Chat,
290    /// Unique identifier of the boost.
291    pub boost_id: String,
292    /// Unix timestamp when the boost was removed.
293    pub remove_date: i64,
294    /// Source of the removed boost.
295    pub source: ChatBoostSource,
296}
297
298/// A managed bot was connected or disconnected.
299#[derive(Debug, Clone, Serialize, Deserialize)]
300pub struct ManagedBotUpdated {
301    /// The user who connected or disconnected the managed bot.
302    pub user: User,
303    /// The managed bot.
304    pub bot: User,
305}
306
307/// Represents the rights of a business bot.
308///
309/// All fields are optional — a missing field means the right is not granted.
310#[derive(Debug, Clone, Default, Serialize, Deserialize)]
311pub struct BusinessBotRights {
312    /// `true` if the bot can send and edit messages in private chats that had
313    /// incoming messages in the last 24 hours.
314    #[serde(skip_serializing_if = "Option::is_none")]
315    pub can_reply: Option<bool>,
316    /// `true` if the bot can mark incoming private messages as read.
317    #[serde(skip_serializing_if = "Option::is_none")]
318    pub can_read_messages: Option<bool>,
319    /// `true` if the bot can delete messages sent by the bot.
320    #[serde(skip_serializing_if = "Option::is_none")]
321    pub can_delete_sent_messages: Option<bool>,
322    /// `true` if the bot can delete all private messages in managed chats.
323    #[serde(skip_serializing_if = "Option::is_none")]
324    pub can_delete_all_messages: Option<bool>,
325    /// `true` if the bot can edit the first and last name of the business account.
326    #[serde(skip_serializing_if = "Option::is_none")]
327    pub can_edit_name: Option<bool>,
328    /// `true` if the bot can edit the bio of the business account.
329    #[serde(skip_serializing_if = "Option::is_none")]
330    pub can_edit_bio: Option<bool>,
331    /// `true` if the bot can edit the profile photo of the business account.
332    #[serde(skip_serializing_if = "Option::is_none")]
333    pub can_edit_profile_photo: Option<bool>,
334    /// `true` if the bot can edit the username of the business account.
335    #[serde(skip_serializing_if = "Option::is_none")]
336    pub can_edit_username: Option<bool>,
337    /// `true` if the bot can change gift privacy settings for the business account.
338    #[serde(skip_serializing_if = "Option::is_none")]
339    pub can_change_gift_settings: Option<bool>,
340    /// `true` if the bot can view gifts and the Telegram Stars balance of the business account.
341    #[serde(skip_serializing_if = "Option::is_none")]
342    pub can_view_gifts_and_stars: Option<bool>,
343    /// `true` if the bot can convert regular gifts owned by the business account to Telegram Stars.
344    #[serde(skip_serializing_if = "Option::is_none")]
345    pub can_convert_gifts_to_stars: Option<bool>,
346    /// `true` if the bot can transfer and upgrade gifts owned by the business account.
347    #[serde(skip_serializing_if = "Option::is_none")]
348    pub can_transfer_and_upgrade_gifts: Option<bool>,
349    /// `true` if the bot can transfer Telegram Stars received by the business account.
350    #[serde(skip_serializing_if = "Option::is_none")]
351    pub can_transfer_stars: Option<bool>,
352    /// `true` if the bot can post, edit, and delete stories on behalf of the business account.
353    #[serde(skip_serializing_if = "Option::is_none")]
354    pub can_manage_stories: Option<bool>,
355}
356
357/// A business connection was established or removed.
358#[derive(Debug, Clone, Serialize, Deserialize)]
359pub struct BusinessConnection {
360    /// Unique identifier of the business connection.
361    pub id: String,
362    /// The business account user.
363    pub user: User,
364    /// Identifier of the private chat with the user.
365    pub user_chat_id: i64,
366    /// Date the connection was established as a Unix timestamp.
367    pub date: i64,
368    /// `true` if the connection is active.
369    pub is_enabled: bool,
370    /// Rights granted to the bot within this business connection.
371    #[serde(skip_serializing_if = "Option::is_none")]
372    pub rights: Option<BusinessBotRights>,
373}
374
375/// A list of boosts added to a chat by a user.
376///
377/// Returned by [`getUserChatBoosts`](https://core.telegram.org/bots/api#getuserchatboosts).
378#[derive(Debug, Clone, Serialize, Deserialize)]
379pub struct UserChatBoosts {
380    /// The list of boosts added to the chat by the user.
381    pub boosts: Vec<ChatBoost>,
382}
383
384/// Business messages that were deleted.
385#[derive(Debug, Clone, Serialize, Deserialize)]
386pub struct BusinessMessagesDeleted {
387    /// Unique identifier of the business connection.
388    pub business_connection_id: String,
389    /// The chat in which the messages were deleted.
390    pub chat: crate::chat::Chat,
391    /// Identifiers of the deleted messages.
392    pub message_ids: Vec<i64>,
393}
394
395/// Purchased paid media.
396#[derive(Debug, Clone, Serialize, Deserialize)]
397pub struct PaidMediaPurchased {
398    /// The user who purchased the media.
399    pub from: User,
400    /// Bot-specified paid media payload.
401    pub paid_media_payload: String,
402}