telegram_types/bot/
types.rs

1//! Telegram bot object types.
2use super::games::CallbackGame;
3use super::inline_mode::{ChosenInlineResult, InlineQuery};
4use super::utils::falsum;
5#[cfg(feature = "high")]
6use chrono::naive::NaiveDateTime;
7
8macro_rules! impl_id {
9    ($Id: ident : $Ty: ty) => {
10        #[derive(
11            Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash,
12        )]
13        pub struct $Id(pub $Ty);
14
15        impl ::std::ops::Add<$Ty> for $Id {
16            type Output = $Id;
17            #[inline]
18            fn add(self, other: $Ty) -> $Id {
19                $Id(self.0 + other)
20            }
21        }
22
23        impl<'a> ::std::ops::Add<&'a $Ty> for $Id {
24            type Output = $Id;
25            #[inline]
26            fn add(self, other: &$Ty) -> Self::Output {
27                $Id(self.0 + other)
28            }
29        }
30
31        impl ::std::ops::Sub<$Ty> for $Id {
32            type Output = $Id;
33            #[inline]
34            fn sub(self, other: $Ty) -> $Id {
35                $Id(self.0 - other)
36            }
37        }
38        impl ::std::ops::AddAssign<$Ty> for $Id {
39            fn add_assign(&mut self, rhs: $Ty) {
40                self.0 += rhs
41            }
42        }
43        impl ::std::ops::SubAssign<$Ty> for $Id {
44            fn sub_assign(&mut self, rhs: $Ty) {
45                self.0 -= rhs
46            }
47        }
48    };
49}
50
51impl_id! {UserId : i64}
52
53impl_id! {ChatId : i64}
54
55impl_id! {MessageId : i64}
56
57impl_id! {UpdateId : i64}
58
59/// Unique identifier for a file
60/// # Sending by file_id
61/// * It is not possible to change the file type when resending by **file_id**. I.e. a [video](Video) can't be sent as a photo, a [photo](PhotoSize) can't be sent as a document, etc.
62/// * It is not possible to resend thumbnails.
63/// * Resending a photo by **file_id** will send all of its [sizes](PhotoSize).
64/// * **file_id** is unique for each individual bot and can't be transferred from one bot to another.
65#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
66pub struct FileId(pub String);
67
68/// This object represents a unique message identifier.
69#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
70pub struct MessageIdResult {
71    pub message_id: MessageId,
72}
73
74/// The UNIX timestamp
75#[cfg(not(feature = "high"))]
76#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
77pub struct Time(pub u64);
78
79/// The Datetime.
80#[cfg(feature = "high")]
81#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
82pub struct Time(#[serde(with = "timestamp_format")] pub NaiveDateTime);
83
84#[cfg(feature = "high")]
85mod timestamp_format {
86    use chrono::naive::NaiveDateTime;
87    use serde::{Deserialize, Deserializer, Serializer};
88
89    pub fn serialize<S>(date: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error>
90    where
91        S: Serializer,
92    {
93        serializer.serialize_i64(date.timestamp())
94    }
95
96    pub fn deserialize<'de, D>(deserializer: D) -> Result<NaiveDateTime, D::Error>
97    where
98        D: Deserializer<'de>,
99    {
100        let s = i64::deserialize(deserializer)?;
101        Ok(NaiveDateTime::from_timestamp(s, 0))
102    }
103}
104
105/// An incoming update.
106///
107/// At most one of the optional parameters can be present in any given update.
108#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
109pub struct Update {
110    /// The update‘s unique identifier.
111    pub update_id: UpdateId,
112    #[serde(flatten)]
113    // `Option` is a workaround for https://github.com/serde-rs/serde/issues/1626
114    pub content: Option<UpdateContent>,
115}
116
117#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
118#[serde(rename_all = "snake_case")]
119pub enum UpdateContent {
120    /// New incoming message of any kind — text, photo, sticker, etc.
121    Message(Message),
122    /// New version of a message that is known to the bot and was edited
123    EditedMessage(Message),
124    /// New incoming channel post of any kind — text, photo, sticker, etc.
125    ChannelPost(Message),
126    /// New version of a channel post that is known to the bot and was edited
127    EditedChannelPost(Message),
128    /// New incoming inline query
129    InlineQuery(InlineQuery),
130    /// The result of an [inline](https://core.telegram.org/bots/api#inline-mode) query that
131    /// was chosen by a user and sent to their chat partner.
132    ///
133    /// Please see our documentation on the
134    /// [feedback collecting](https://core.telegram.org/bots/inline#collecting-feedback) for
135    /// details on how to enable these updates for your bot.
136    ChosenInlineResult(ChosenInlineResult),
137    /// New incoming callback query
138    CallbackQuery(CallbackQuery),
139    /// The bot's chat member status was updated in a chat.
140    /// For private chats, this update is received only when the bot is blocked or unblocked by the user.
141    MyChatMember(ChatMemberUpdated),
142    /// A chat member's status was updated in a chat.
143    /// The bot must be an administrator in the chat and must explicitly
144    /// specify `"chat_member"` in the list of allowed_updates to receive these updates.
145    ChatMember(ChatMemberUpdated),
146    /// A request to join the chat has been sent.
147    /// The bot must have the `can_invite_users` administrator right in the chat to receive these updates.
148    ChatJoinRequest(ChatJoinRequest),
149    // TODO: implement these placeholders
150    #[doc(hidden)]
151    ShippingQuery(ShippingQuery),
152    #[doc(hidden)]
153    PreCheckoutQuery(PreCheckoutQuery),
154    #[doc(hidden)]
155    Poll(Poll),
156    #[doc(hidden)]
157    PollAnswer(PollAnswer),
158    /// Unknown update type
159    Unknown,
160}
161impl Default for UpdateContent {
162    fn default() -> Self {
163        UpdateContent::Unknown {}
164    }
165}
166
167#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
168pub struct ShippingQuery {}
169#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
170pub struct PreCheckoutQuery {}
171#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
172pub struct Poll {}
173#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
174pub struct PollAnswer {}
175
176/// This object represents changes in the status of a chat member.
177#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
178pub struct ChatMemberUpdated {
179    pub chat: Chat,
180    pub from: User,
181    pub date: Time,
182    /// Previous information about the chat member
183    pub old_chat_member: ChatMember,
184    /// New information about the chat member
185    pub new_chat_member: ChatMember,
186    /// Chat invite link, which was used by the user to join the chat;
187    /// for joining by invite link events only.
188    pub invite_link: Option<ChatInviteLink>,
189    /// True, if the user joined the chat after sending a direct join request
190    /// without using an invite link and being approved by an administrator
191    pub via_join_request: Option<bool>,
192    /// True, if the user joined the chat via a chat folder invite link
193    pub via_chat_folder_invite_link: Option<bool>,
194}
195
196#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
197pub struct ChatJoinRequest {
198    pub chat: Chat,
199    pub from: User,
200    pub user_chat_id: UserId,
201    pub date: Time,
202    /// Bio of the user.
203    pub bio: Option<String>,
204    /// Chat invite link that was used by the user to send the join request
205    pub invite_link: Option<ChatInviteLink>,
206}
207
208#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
209pub struct ChatInviteLink {
210    /// The invite link.
211    /// 
212    /// If the link was created by another chat administrator, then the second part of the link will be replaced with “…”.
213    invite_link: String,
214    /// Creator of the link
215    creator: User,
216    /// `True``, if users joining the chat via the link need to be approved by chat administrators
217    creates_join_request: bool,
218    is_primary: bool,
219    is_revoked: bool,
220    /// Invite link name
221    name: Option<String>,
222    /// Point in time (Unix timestamp) when the link will expire or has been expired
223    expire_date: Option<Time>,
224    /// The maximum number of users that can be members of the chat simultaneously
225    /// after joining the chat via this invite link; 1-99999
226    member_limit: Option<i32>,
227    /// Number of pending join requests created using this link
228    pending_join_request_count: Option<i32>,
229}
230
231/// Contains information about the current status of a webhook.
232#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
233pub struct WebhookInfo {
234    /// Webhook URL, may be empty if webhook is not set up
235    pub url: String,
236    /// True, if a custom certificate was provided for webhook certificate checks
237    pub has_custom_certificate: bool,
238    /// Number of updates awaiting delivery
239    pub pending_update_count: i32,
240    /// Currently used webhook IP address
241    pub ip_address: Option<String>,
242    /// Unix time for the most recent error that happened when trying to deliver an update via
243    /// webhook
244    pub last_error_date: Option<Time>,
245    /// Error message in human-readable format for the most recent error that happened when trying
246    /// to deliver an update via webhook
247    pub last_error_message: Option<String>,
248    /// Maximum allowed number of simultaneous HTTPS connections to the webhook for update delivery
249    pub max_connections: Option<i32>,
250    /// A list of update types the bot is subscribed to. Defaults to all update types
251    pub allowed_updates: Option<Vec<String>>,
252}
253
254/// A Telegram user or bot.
255#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
256pub struct User {
257    /// Unique identifier for this user or bot
258    pub id: UserId,
259    /// True, if this user is a bot
260    pub is_bot: bool,
261    /// User‘s or bot’s first name
262    pub first_name: String,
263    /// User‘s or bot’s last name
264    pub last_name: Option<String>,
265    /// User‘s or bot’s username
266    pub username: Option<String>,
267    /// [IETF language tag](https://en.wikipedia.org/wiki/IETF_language_tag) of the user's language
268    pub language_code: Option<String>,
269}
270
271/// Type of chat
272#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
273#[serde(tag = "type")]
274#[serde(rename_all = "snake_case")]
275pub enum ChatType {
276    Private {
277        username: Option<String>,
278        /// First name of the other party in a private chat
279        first_name: String,
280        /// Last name of the other party in a private chat
281        last_name: Option<String>,
282    },
283    Group {
284        title: String,
285        username: Option<String>,
286        /// True if a group has ‘All Members Are Admins’ enabled.
287        #[serde(default = "falsum")]
288        all_members_are_administrators: bool,
289    },
290    Supergroup {
291        title: String,
292        username: Option<String>,
293        /// True if a group has ‘All Members Are Admins’ enabled.
294        #[serde(default = "falsum")]
295        all_members_are_administrators: bool,
296        /// Pinned message. Returned only in `getChat`.
297        pinned_message: Option<Box<Message>>,
298        /// Name of group sticker set. Returned only in `getChat.`
299        sticker_set_name: Option<String>,
300        /// True, if the bot can change the group sticker set. Returned only in `getChat`.
301        can_set_sticker_set: Option<bool>,
302        /// Chat invite link/ Returned only in `getChat`.
303        invite_link: Option<String>,
304        /// Description. Returned only in `getChat`.
305        description: Option<String>,
306    },
307    Channel {
308        title: String,
309        username: Option<String>,
310        /// Pinned message. Returned only in `getChat`.
311        pinned_message: Option<Box<Message>>,
312        /// Chat invite link. Returned only in `getChat`.
313        invite_link: Option<String>,
314        /// Description. Returned only in `getChat`.
315        description: Option<String>,
316    },
317    #[serde(other)]
318    /// Unknown upstream data type.
319    Unknown,
320}
321
322#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
323pub struct Chat {
324    /// Unique identifier for this chat.
325    pub id: ChatId,
326    /// Chat photo. Returned only in `getChat`.
327    pub photo: Option<ChatPhoto>,
328    /// Type of chat
329    #[serde(flatten)]
330    #[serde(rename = "type")]
331    pub kind: ChatType,
332}
333
334// TODO: game, invoice, successful_payment
335#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
336pub struct Message {
337    /// Unique message identifier inside this chat
338    pub message_id: MessageId,
339    /// Sender, empty for messages sent to channels
340    pub from: Option<Box<User>>,
341    /// Sender of the message, sent on behalf of a chat.
342    /// The channel itself for channel messages.
343    /// The supergroup itself for messages from anonymous group administrators.
344    /// The linked channel for messages automatically forwarded to the discussion group
345    pub sender_chat: Option<Chat>,
346    /// Date the message was sent in Unix time
347    pub date: Time,
348    /// Conversation the message belongs to
349    pub chat: Box<Chat>,
350    /// For forwarded messages, sender of the original message
351    pub forward_from: Option<Box<User>>,
352    /// For messages forwarded from channels, information about the original channel
353    pub forward_from_chat: Option<Box<Chat>>,
354    /// For messages forwarded from channels, identifier of the original message in the channel
355    pub forward_from_message_id: Option<MessageId>,
356    /// For messages forwarded from channels, signature of the post author if present
357    pub forward_signature: Option<String>,
358    /// Sender's name for messages forwarded from users who disallow adding a link to their account
359    /// in forwarded messages
360    pub forward_sender_name: Option<String>,
361    /// For forwarded messages, date the original message was sent in Unix time
362    pub forward_date: Option<Time>,
363    /// For replies, the original message.
364    /// Note that the Message object in this field will not contain
365    /// further `reply_to_message` fields even if it itself is a reply.
366    pub reply_to_message: Option<Box<Message>>,
367    /// Date the message was last edited in Unix time
368    pub edit_date: Option<Time>,
369    /// The unique identifier of a media message group this message belongs to
370    pub media_group_id: Option<String>,
371    /// Signature of the post author for messages in channels
372    pub author_signature: Option<String>,
373    /// For text messages, the actual UTF-8 text of the message, 0-4096 characters.
374    pub text: Option<String>,
375    /// Message is a sticker, information about the sticker
376    pub sticker: Option<Box<Sticker>>,
377    /// Message is an audio file, information about the file
378    pub audio: Option<Audio>,
379    /// Message is a general file, information about the file
380    pub document: Option<Box<Document>>,
381    #[serde(default)]
382    pub photo: Vec<PhotoSize>,
383    /// For text messages, special entities like usernames, URLs, bot commands, etc.
384    /// that appear in the text
385    #[serde(default)]
386    pub entities: Vec<MessageEntity>,
387    /// Message is a voice message, information about the file
388    pub voice: Option<Box<Voice>>,
389    /// Message is a video, information about the video
390    pub video: Option<Video>,
391    /// Message is a video note, information about the video message
392    pub video_note: Option<Box<VideoNote>>,
393    /// Message is an animation, information about the animation.
394    ///
395    /// For backward compatibility, when this field is set, the document field will also be set
396    pub animation: Option<Box<Animation>>,
397    /// For messages with a caption, special entities like usernames, URLs, bot commands, etc.
398    /// that appear in the caption
399    #[serde(default)]
400    pub caption_entities: Vec<MessageEntity>,
401    /// Caption for the audio, document, photo, video or voice, 0-200 characters
402    pub caption: Option<String>,
403    /// Message is a shared contact, information about the contact
404    pub contact: Option<Box<Contact>>,
405    /// Message is a shared location, information about the location
406    pub location: Option<Box<Location>>,
407    /// Message is a venue, information about the venue
408    pub venue: Option<Box<Venue>>,
409    /// New members that were added to the group or supergroup and information about them
410    /// (the bot itself may be one of these members)
411    #[serde(default)]
412    pub new_chat_members: Vec<User>,
413    /// A member was removed from the group, information about them
414    /// (this member may be the bot itself)
415    pub left_chat_member: Option<Box<User>>,
416    /// A chat title was changed to this value
417    pub new_chat_title: Option<String>,
418    /// A chat photo was change to this value
419    #[serde(default)]
420    pub new_chat_photo: Vec<PhotoSize>,
421    /// Service message: the chat photo was deleted
422    #[serde(default = "falsum")]
423    pub delete_chat_photo: bool,
424    /// Service message: the group has been created
425    #[serde(default = "falsum")]
426    pub group_chat_created: bool,
427    /// Service message: the supergroup has been created.
428    /// This field can‘t be received in a message coming through updates, because bot can’t
429    /// be a member of a supergroup when it is created. It can only be found in reply_to_message
430    /// if someone replies to a very first message in a directly created supergroup.
431    #[serde(default = "falsum")]
432    pub supergroup_chat_created: bool,
433    /// Service message: the channel has been created.
434    ///
435    /// This field can‘t be received in a message coming through updates, because bot can’t be
436    /// a member of a channel when it is created. It can only be found in reply_to_message
437    /// if someone replies to a very first message in a channel.
438    #[serde(default = "falsum")]
439    pub channel_chat_created: bool,
440    /// The group has been migrated to a supergroup with the specified identifier.
441    pub migrate_to_chat_id: Option<ChatId>,
442    /// The supergroup has been migrated from a group with the specified identifier.
443    pub migrate_from_chat_id: Option<ChatId>,
444    /// Specified message was pinned. Note that the Message object in this field
445    /// will not contain further reply_to_message fields even if it is itself a reply.
446    pub pinned_message: Option<Box<Message>>,
447    /// The domain name of the website on which the user has logged in.
448    pub connected_website: Option<String>,
449    /// Inline keyboard attached to the message.
450    ///
451    /// `login_url` buttons are represented as ordinary `url` buttons.
452    pub reply_markup: Option<InlineKeyboardMarkup>,
453}
454
455/// One special entity in a text message.
456/// For example, hashtags, usernames, URLs, etc.
457#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
458pub struct MessageEntity {
459    /// Type of the entity.
460    #[serde(rename = "type")]
461    pub kind: MessageEntityKind,
462    /// Offset in UTF-16 code units to the start of the entity
463    pub offset: i32,
464    /// Length of the entity in UTF-16 code units
465    pub length: i32,
466    /// For “text_link” only, url that will be opened after user taps on the text
467    pub url: Option<String>,
468    /// For “text_mention” only, the mentioned user
469    pub user: Option<Box<User>>,
470}
471
472/// Type of the `MessageEntity`.
473#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
474#[serde(rename_all = "snake_case")]
475pub enum MessageEntityKind {
476    /// `@username`
477    Mention,
478    Hashtag,
479    Cashtag,
480    BotCommand,
481    Url,
482    Email,
483    PhoneNumber,
484    /// bold text
485    Bold,
486    /// italic text
487    Italic,
488    /// monowidth string
489    Code,
490    /// monowidth block
491    Pre,
492    /// for clickable text URLs
493    TextLink,
494    /// for users without usernames
495    TextMention,
496    #[serde(other)]
497    /// Unknown upstream data type.
498    Unknown,
499}
500
501/// A general file (as opposed to [photos](PhotoSize), [voice messages](Voice) and
502/// [audio files](Audio)).
503#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Hash, Eq)]
504pub struct Document {
505    /// Unique file identifier
506    pub file_id: FileId,
507    /// Document thumbnail as defined by sender
508    pub thumb: Option<PhotoSize>,
509    /// Original filename as defined by sender
510    pub file_name: Option<String>,
511    /// MIME type of the file as defined by sender
512    pub mime_type: Option<String>,
513    pub file_size: Option<i32>,
514}
515
516/// A video file.
517#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Hash, Eq)]
518pub struct Video {
519    /// Unique identifier for this file
520    pub file_id: FileId,
521    pub width: i32,
522    pub height: i32,
523    /// Duration of the video in seconds as defined by sender
524    pub duration: i32,
525    /// Video thumbnail
526    pub thumb: Option<PhotoSize>,
527    /// Mime type of a file as defined by sender
528    pub mime_type: Option<String>,
529    /// File size
530    pub file_size: Option<i32>,
531}
532
533/// An animation file (GIF or H.264/MPEG-4 AVC video without sound).
534#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Hash, Eq)]
535pub struct Animation {
536    /// Unique identifier for this file
537    pub file_id: FileId,
538    pub width: i32,
539    pub height: i32,
540    /// Duration of the video in seconds as defined by sender
541    pub duration: i32,
542    /// Video thumbnail
543    pub thumb: Option<PhotoSize>,
544    /// Original animation filename as defined by sender
545    pub file_name: Option<String>,
546    /// Mime type of a file as defined by sender
547    pub mime_type: Option<String>,
548    /// File size
549    pub file_size: Option<i32>,
550}
551
552/// An audio file to be treated as music by the Telegram clients.
553#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Hash, Eq)]
554pub struct Audio {
555    /// Unique identifier for this file
556    pub file_id: FileId,
557    /// Duration of the audio in seconds as defined by sender
558    pub duration: i32,
559    /// Performer of the audio as defined by sender or by audio tags
560    pub performer: Option<String>,
561    /// Title of the audio as defined by sender or by audio tags
562    pub title: Option<String>,
563    /// MIME type of the file as defined by sender
564    pub mime_type: Option<String>,
565    pub file_size: Option<i32>,
566    /// Thumbnail of the album cover to which the music file belongs
567    pub thumb: Option<PhotoSize>,
568}
569
570/// A voice note.
571#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
572pub struct Voice {
573    /// Unique identifier for this file
574    pub file_id: FileId,
575    /// Duration of the audio in seconds as defined by sender
576    pub duration: i32,
577    /// MIME type of the file as defined by sender
578    pub mime_type: Option<String>,
579    pub file_size: Option<i32>,
580}
581
582/// A video message (available in Telegram apps as of v.4.0).
583#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
584pub struct VideoNote {
585    /// Unique identifier for this file
586    pub file_id: FileId,
587    /// Video width and height as defined by sender
588    pub length: i32,
589    /// Duration of the audio in seconds as defined by sender
590    pub duration: i32,
591    pub thumb: Option<PhotoSize>,
592    pub file_size: Option<i32>,
593}
594
595/// A phone contact.
596#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
597pub struct Contact {
598    pub phone_number: String,
599    pub first_name: String,
600    pub last_name: Option<String>,
601    pub user_id: Option<UserId>,
602    /// Additional data about the contact in the form of a vCard
603    pub vcard: Option<String>,
604}
605
606/// A file ready to be downloaded.
607/// The file can be downloaded via the link `https://api.telegram.org/file/bot<token>/<file_path>`.
608/// It is guaranteed that the link will be valid for at least 1 hour. When the link expires,
609/// a new one can be requested by calling `getFile`.
610#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Hash)]
611pub struct File {
612    /// Unique identifier for this file
613    pub file_id: FileId,
614    /// File size, if known
615    pub file_size: Option<i32>,
616    /// Optional. File path. Use `https://api.telegram.org/file/bot<token>/<file_path>` to get the file.
617    pub file_path: Option<String>,
618}
619
620/// A point on the map.
621#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, PartialOrd)]
622pub struct Location {
623    /// Longitude as defined by sender
624    pub longitude: f32,
625    /// Latitude as defined by sender
626    pub latitude: f32,
627}
628
629#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, PartialOrd)]
630pub struct Venue {
631    /// Venue location
632    pub location: Location,
633    /// Name of the venue
634    pub title: String,
635    /// Address of the venue
636    pub address: String,
637    /// Foursquare identifier of the venue
638    pub foursquare_id: Option<String>,
639    /// Foursquare type of the venue. (For example, “arts_entertainment/default”,
640    /// “arts_entertainment/aquarium” or “food/icecream”.)
641    pub foursquare_type: Option<String>,
642}
643
644/// One size of a photo or a [file](Document) / [sticker](Sticker) thumbnail.
645#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
646pub struct PhotoSize {
647    /// Unique identifier for this file
648    pub file_id: FileId,
649    pub width: i32,
650    pub height: i32,
651    pub file_size: Option<i32>,
652}
653
654/// A user's profile pictures.
655#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
656pub struct UserProfilePhotos {
657    /// Total number of profile pictures the target user has
658    pub total_count: i32,
659    /// Requested profile pictures (in up to 4 sizes each)
660    #[serde(default)]
661    pub photos: Vec<PhotoSize>,
662}
663
664/// A [custom keyboard](https://core.telegram.org/bots#keyboards)
665/// with reply options (see [Introduction to bots](https://core.telegram.org/bots#keyboards)
666/// for details and examples).
667#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
668pub struct ReplyKeyboardMarkup {
669    /// Array of button rows, each represented by an Array of [`KeyboardButton`](KeyboardButton) objects
670    #[serde(default)]
671    pub keyboard: Vec<Vec<KeyboardButton>>,
672    /// Requests clients to resize the keyboard vertically for optimal fit
673    /// (e.g., make the keyboard smaller if there are just two rows of buttons).
674    /// Defaults to false, in which case the custom keyboard is always of the
675    /// same height as the app's standard keyboard.
676    pub resize_keyboard: Option<bool>,
677    /// Requests clients to hide the keyboard as soon as it's been used.
678    /// The keyboard will still be available, but clients will automatically display the usual
679    /// letter-keyboard in the chat – the user can press a special button in the input field
680    /// to see the custom keyboard again. Defaults to `false`.
681    pub one_time_keyboard: Option<bool>,
682    /// Use this parameter if you want to show the keyboard to specific users only. Targets: 1)
683    /// users that are @mentioned in the text of the [`Message`] object; 2)
684    /// if the bot's message is a reply (has reply_to_message_id),
685    /// sender of the original message.
686    ///
687    /// Example: A user requests to change the bot‘s language,
688    /// bot replies to the request with a keyboard to select the new language.
689    /// Other users in the group don’t see the keyboard.
690    pub selective: Option<bool>,
691}
692
693/// One button of the reply keyboard.
694/// For simple text buttons *String* can be used instead of this object to specify
695/// text of the button. Optional fields are mutually exclusive.
696///
697/// ## Note
698/// Note: request_contact and request_location options will only work in
699/// Telegram versions released after 9 April, 2016. Older clients will ignore them.
700#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
701pub struct KeyboardButton {
702    /// Text of the button. If none of the optional fields are used,
703    /// it will be sent as a message when the button is pressed
704    pub text: String,
705    /// If True, the user's phone number will be sent as a contact when the button is pressed.
706    /// Available in private chats only
707    pub request_contact: Option<bool>,
708    /// If True, the user's current location will be sent when the button is pressed.
709    /// Available in private chats only
710    pub request_location: Option<bool>,
711}
712
713/// Upon receiving a message with this object, Telegram clients will remove the current
714/// custom keyboard and display the default letter-keyboard.
715///
716/// By default, custom keyboards are displayed until a new keyboard is sent by a bot.
717/// An exception is made for one-time keyboards that are hidden immediately after the user
718/// presses a button (see [`ReplyKeyboardMarkup`]).
719#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
720pub struct ReplyKeyboardRemove {
721    /// Requests clients to remove the custom keyboard (user will not be able to summon this
722    /// keyboard; if you want to hide the keyboard from sight but keep it accessible,
723    /// use *one_time_keyboard* in [`ReplyKeyboardMarkup`])
724    pub remove_keyboard: bool,
725    /// *Optional*. Use this parameter if you want to remove the keyboard for specific users only.
726    /// Targets:
727    ///
728    /// 1. users that are @mentioned in the text of the Message object;
729    /// 2. if the bot's message is a reply (has reply_to_message_id),
730    /// sender of the original message.
731    ///
732    /// *Example*: A user votes in a poll, bot returns confirmation message in reply to the
733    /// vote and removes the keyboard for that user, while still showing the keyboard with poll
734    /// options to users who haven't voted yet.
735    pub selective: Option<bool>,
736}
737
738/// An inline keyboard that appears right next to the message it belongs to.
739///
740/// ## Note
741/// This will only work in Telegram versions released after 9 April, 2016.
742/// Older clients will display unsupported message.
743#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
744pub struct InlineKeyboardMarkup {
745    /// Array of button rows, each represented by an Array of [`InlineKeyboardButton`] objects
746    #[serde(default)]
747    pub inline_keyboard: Vec<Vec<InlineKeyboardButton>>,
748}
749
750/// One button of an inline keyboard.
751#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
752pub struct InlineKeyboardButton {
753    /// Label text on the button
754    pub text: String,
755    #[serde(flatten)]
756    pub pressed: InlineKeyboardButtonPressed,
757}
758
759#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
760#[serde(rename_all = "snake_case")]
761pub enum InlineKeyboardButtonPressed {
762    /// HTTP url to be opened when button is pressed
763    Url(String),
764    /// Data to be sent in a [callback query](CallbackQuery) to the bot when button is pressed,
765    /// 1-64 bytes
766    CallbackData(String),
767    /// If set, pressing the button will prompt the user to select one of their chats, open that
768    /// chat and insert the bot‘s username and the specified inline query in the input field.
769    /// Can be empty, in which case just the bot’s username will be inserted.
770    ///
771    /// ## Note
772    /// This offers an easy way for users to start using your bot in
773    /// [inline mode](https://core.telegram.org/bots/inline) when they are currently
774    /// in a private chat with it. Especially useful when combined with
775    /// *[switch_pm…](https://core.telegram.org/bots/api#answerinlinequery)* actions – in this
776    /// case the user will be automatically returned to the chat they switched from, skipping
777    /// the chat selection screen.
778    SwitchInlineQuery(String),
779    /// If set, pressing the button will insert the bot‘s username and the specified inline
780    /// query in the current chat's input field. Can be empty, in which case only
781    /// the bot’s username will be inserted.
782    ///
783    /// This offers a quick way for the user to open your bot in inline mode in the same chat –
784    /// good for selecting something from multiple options.
785    SwitchInlineQueryCurrentChat(String),
786    /// Description of the game that will be launched when the user presses the button.
787    ///
788    /// # NOTE
789    /// This type of button **must** always be the first button in the first row.
790    Pay(bool),
791    /// Description of the game that will be launched when the user presses the button.
792    ///
793    /// ## NOTE
794    /// This type of button **must** always be the first button in the first row.
795    CallbackGame(CallbackGame),
796    /// An HTTP URL used to automatically authorize the user.
797    LoginUrl(LoginUrl),
798    #[serde(other)]
799    /// Unknown upstream data type.
800    Unknown,
801}
802
803/// This object represents an incoming callback query from a callback button in an inline keyboard.
804/// If the button that originated the query was attached to a message sent by the bot, the field
805/// message will be present. If the button was attached to a message sent via the bot (in inline
806/// mode), the field inline_message_id will be present. Exactly one of the fields data
807/// or game_short_name will be present.
808///
809/// ## Note
810/// After the user presses a callback button, Telegram clients will display a progress bar until
811/// you call `answerCallbackQuery`. It is, therefore, necessary to react by calling
812/// `answerCallbackQuery` even if no notification to the user is needed (e.g., without
813/// specifying any of the optional parameters).
814#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
815pub struct CallbackQuery {
816    /// Unique identifier for this query
817    pub id: String,
818    /// Sender
819    pub from: Box<User>,
820    /// Message with the callback button that originated the query. Note that message content and
821    /// message date will not be available if the message is too old
822    pub message: Option<Box<Message>>,
823    /// Identifier of the message sent via the bot in inline mode, that originated the query.
824    pub inline_message_id: Option<String>,
825    /// Global identifier, uniquely corresponding to the chat to which the message with the
826    /// callback button was sent. Useful for high scores in games.
827    pub chat_instance: String,
828    /// Data associated with the callback button. Be aware that a bad client can send arbitrary data in this field.
829    pub data: Option<String>,
830    /// Short name of a Game to be returned, serves as the unique identifier for the game
831    pub game_short_name: Option<String>,
832}
833
834/// Upon receiving a message with this object, Telegram clients will display a reply interface
835/// to the user (act as if the user has selected the bot‘s message and tapped ’Reply'). This can
836/// be extremely useful if you want to create user-friendly step-by-step interfaces without having
837/// to sacrifice [privacy mode](https://core.telegram.org/bots#privacy-mode).
838#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
839pub struct ForceReply {
840    /// Shows reply interface to the user, as if they manually selected the bot‘s message and
841    /// tapped ’Reply'
842    pub force_reply: bool,
843    /// *Optional*. Use this parameter if you want to force reply from specific users only.
844    /// Targets:
845    ///
846    /// 1. users that are @mentioned in the text of the [`Message`] object;
847    /// 2. if the bot's message is a reply (has reply_to_message_id), sender of the original message.
848    pub selective: Option<bool>,
849}
850
851/// Contains information about why a request was unsuccessful.
852#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
853pub struct ResponseParameters {
854    /// *Optional*. The group has been migrated to a supergroup with the specified identifier.
855    pub migrate_to_chat_id: Option<ChatId>,
856    /// In case of exceeding flood control, the number of seconds left to wait before the request
857    /// can be repeated
858    pub retry_after: Option<i32>,
859}
860
861#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
862pub struct ChatPhoto {
863    /// Unique file identifier of small (160x160) chat photo.
864    /// This file_id can be used only for photo download.
865    pub small_file_id: FileId,
866    /// Unique file identifier of big (640x640) chat photo.
867    /// This file_id can be used only for photo download.
868    pub big_file_id: FileId,
869}
870
871/// This object contains information about one member of a chat.
872#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
873pub struct ChatMember {
874    /// Information about the user
875    pub user: Box<User>,
876    /// The member's status in the chat.
877    pub status: ChatMemberStatus,
878    /// Restricted and kicked only. Date when restrictions will be lifted for this user, unix time
879    pub until_date: Option<Time>,
880    /// Administrators only. True, if the bot is allowed to edit administrator privileges of
881    /// that user
882    pub can_be_edited: Option<bool>,
883    /// Administrators only. True, if the administrator can change the chat title, photo and
884    /// other settings
885    pub can_change_info: Option<bool>,
886    /// Administrators only. True, if the administrator can post in the channel, channels only
887    pub can_post_messages: Option<bool>,
888    /// Administrators only. True, if the administrator can edit messages of other users and can
889    /// pin messages, channels only
890    pub can_edit_messages: Option<bool>,
891    /// Administrators only. True, if the administrator can delete messages of other users
892    pub can_delete_messages: Option<bool>,
893    /// Administrators only. True, if the administrator can invite new users to the chat
894    pub can_invite_users: Option<bool>,
895    /// Administrators only. True, if the administrator can restrict, ban or unban chat members
896    pub can_restrict_members: Option<bool>,
897    /// Administrators only. True, if the administrator can pin messages, supergroups only
898    pub can_pin_messages: Option<bool>,
899    /// Administrators only. True, if the administrator can add new administrators with a subset
900    /// of his own privileges or demote administrators that he has promoted, directly or
901    /// indirectly (promoted by administrators that were appointed by the user)
902    pub can_promote_members: Option<bool>,
903    /// Restricted only. True, if the user is a member of the chat at the moment of the request
904    pub is_member: Option<bool>,
905    /// Restricted only. True, if the user can send text messages, contacts, locations and venues
906    pub can_send_messages: Option<bool>,
907    /// Restricted only. True, if the user can send audios, documents, photos, videos, video notes
908    /// and voice notes, implies can_send_messages
909    pub can_send_media_messages: Option<bool>,
910    /// Restricted only. True, if the user can send animations, games, stickers and use inline
911    /// bots, implies can_send_media_messages
912    pub can_send_other_messages: Option<bool>,
913    /// Restricted only. True, if user may add web page previews to his messages, implies
914    /// can_send_media_messages
915    pub can_add_web_page_previews: Option<bool>,
916}
917
918/// The member's status in the chat.
919#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
920#[serde(rename_all = "lowercase")]
921pub enum ChatMemberStatus {
922    Creator,
923    Administrator,
924    Member,
925    Restricted,
926    Left,
927    Kicked,
928    #[serde(other)]
929    /// Unknown upstream data type.
930    Unknown,
931}
932
933/// The contents of a file to be uploaded.
934///
935/// Must be posted using `multipart/form-data` in the usual way that
936/// files are uploaded via the browser.
937///
938/// [More info on Sending Files](https://core.telegram.org/bots/api#sending-files)
939#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
940pub struct InputFile(pub String);
941
942impl InputFile {
943    /// using `multipart/form-data` under <file_attach_name> name.
944    pub fn new<S: AsRef<str>>(file_attach_name: S) -> InputFile {
945        let attach = format!("attach://{}", file_attach_name.as_ref());
946        InputFile(attach)
947    }
948}
949
950/// There are three ways to send files
951///
952/// 1. If the file is already stored somewhere on the Telegram servers, you don't need to reupload it: each file object has a **file_id** field, simply pass this **file_id** as a parameter instead of uploading. There are **no limits** for files sent this way.
953/// 2. Provide Telegram with an HTTP URL for the file to be sent. Telegram will download and send the file. 5 MB max size for photos and 20 MB max for other types of content.
954/// 3. Post the file using multipart/form-data in the usual way that files are uploaded via the browser. 10 MB max size for photos, 50 MB for other files.
955#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
956#[serde(untagged)]
957pub enum FileToSend {
958    FileId(FileId),
959    Url(String),
960    InputFile(InputFile),
961}
962
963#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
964pub struct Sticker {
965    pub file_id: FileId,
966    pub width: i32,
967    pub height: i32,
968    pub thumb: Option<PhotoSize>,
969    /// Emoji associated with the sticker
970    pub emoji: Option<String>,
971    /// Name of the sticker set to which the sticker belongs
972    pub set_name: Option<String>,
973    /// For mask stickers, the position where the mask should be placed
974    pub mask_position: Option<MaskPosition>,
975    /// File size
976    pub file_size: i32,
977}
978
979/// A sticker set.
980#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
981pub struct StickerSet {
982    /// Sticker set name
983    pub name: String,
984    /// Sticker set title
985    pub title: String,
986    /// *True*, if the sticker set contains masks
987    pub contains_masks: bool,
988    /// List of all set stickers
989    #[serde(default)]
990    pub stickers: Vec<Sticker>,
991}
992
993/// The position on faces where a mask should be placed by default.
994#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
995pub struct MaskPosition {
996    /// The part of the face relative to which the mask should be placed. One of “forehead”, “eyes”,
997    /// “mouth”, or “chin”.
998    pub point: String,
999    /// Shift by X-axis measured in widths of the mask scaled to the face size, from left to right.
1000    /// For example, choosing -1.0 will place mask just to the left of the default mask position.
1001    pub x_shift: f32,
1002    /// Shift by Y-axis measured in heights of the mask scaled to the face size, from top to bottom.
1003    /// For example, 1.0 will place the mask just below the default mask position.
1004    pub y_shift: f32,
1005    /// Mask scaling coefficient. For example, 2.0 means double size.
1006    pub scale: f32,
1007}
1008
1009/// The content of a media message to be sent.
1010#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
1011#[serde(tag = "type")]
1012pub enum InputMedia {
1013    #[serde(rename = "video")]
1014    Video {
1015        /// File to send.
1016        ///
1017        /// Pass a file_id to send a file that exists on the Telegram servers (recommended),
1018        /// pass an HTTP URL for Telegram to get a file from the Internet, or pass
1019        /// "attach://<file_attach_name>" to upload a new one using multipart/form-data
1020        /// under <file_attach_name> name.
1021        ///
1022        /// [More info on Sending Files](https://core.telegram.org/bots/api#sending-files)
1023        media: FileToSend,
1024        /// *Optional*. Caption of the photo to be sent, 0-200 characters
1025        #[serde(skip_serializing_if = "Option::is_none")]
1026        caption: Option<String>,
1027        /// *Optional*. Send Markdown or HTML, if you want Telegram apps to show
1028        /// [bold, italic, fixed-width text or inline URLs](https://core.telegram.org/bots/api#formatting-options)
1029        /// in the media caption.
1030        #[serde(skip_serializing_if = "Option::is_none")]
1031        parse_mode: Option<ParseMode>,
1032        #[serde(skip_serializing_if = "Option::is_none")]
1033        width: Option<i32>,
1034        #[serde(skip_serializing_if = "Option::is_none")]
1035        height: Option<i32>,
1036        #[serde(skip_serializing_if = "Option::is_none")]
1037        duration: Option<i32>,
1038        /// Pass True, if the uploaded video is suitable for streaming
1039        #[serde(skip_serializing_if = "Option::is_none")]
1040        supports_streaming: Option<bool>,
1041    },
1042    #[serde(rename = "photo")]
1043    Photo {
1044        /// File to send.
1045        ///
1046        /// Pass a file_id to send a file that exists on the Telegram servers (recommended),
1047        /// pass an HTTP URL for Telegram to get a file from the Internet, or pass
1048        /// "attach://<file_attach_name>" to upload a new one using multipart/form-data
1049        /// under <file_attach_name> name.
1050        ///
1051        /// [More info on Sending Files](https://core.telegram.org/bots/api#sending-files)
1052        media: FileToSend,
1053        /// *Optional*. Caption of the photo to be sent, 0-200 characters
1054        #[serde(skip_serializing_if = "Option::is_none")]
1055        caption: Option<String>,
1056        /// *Optional*. Send Markdown or HTML, if you want Telegram apps to show
1057        /// [bold, italic, fixed-width text or inline URLs](https://core.telegram.org/bots/api#formatting-options)
1058        /// in the media caption.
1059        #[serde(skip_serializing_if = "Option::is_none")]
1060        parse_mode: Option<ParseMode>,
1061    },
1062    #[serde(rename = "animation")]
1063    Animation {
1064        /// File to send.
1065        ///
1066        /// Pass a file_id to send a file that exists on the Telegram servers (recommended),
1067        /// pass an HTTP URL for Telegram to get a file from the Internet, or pass
1068        /// "attach://<file_attach_name>" to upload a new one using multipart/form-data
1069        /// under <file_attach_name> name.
1070        ///
1071        /// [More info on Sending Files](https://core.telegram.org/bots/api#sending-files)
1072        media: FileToSend,
1073        /// Thumbnail of the file sent.
1074        ///
1075        /// The thumbnail should be in JPEG format and less than 200 kB in size.
1076        ///
1077        /// A thumbnail‘s width and height should not exceed 90.
1078        ///
1079        /// Ignored if the file is not uploaded using multipart/form-data.
1080        ///
1081        /// Thumbnails can’t be reused and can be only uploaded as a new file,
1082        /// so you can pass “attach://<file_attach_name>” if the thumbnail was uploaded
1083        /// using multipart/form-data under <file_attach_name>.
1084        #[serde(skip_serializing_if = "Option::is_none")]
1085        thumb: Option<InputFile>,
1086        #[serde(skip_serializing_if = "Option::is_none")]
1087        caption: Option<String>,
1088        #[serde(skip_serializing_if = "Option::is_none")]
1089        parse_mode: Option<ParseMode>,
1090        #[serde(skip_serializing_if = "Option::is_none")]
1091        width: Option<i32>,
1092        #[serde(skip_serializing_if = "Option::is_none")]
1093        height: Option<i32>,
1094        #[serde(skip_serializing_if = "Option::is_none")]
1095        duration: Option<i32>,
1096    },
1097    #[serde(rename = "audio")]
1098    Audio {
1099        media: FileToSend,
1100        #[serde(skip_serializing_if = "Option::is_none")]
1101        thumb: Option<InputFile>,
1102        #[serde(skip_serializing_if = "Option::is_none")]
1103        caption: Option<String>,
1104        #[serde(skip_serializing_if = "Option::is_none")]
1105        parse_mode: Option<ParseMode>,
1106        #[serde(skip_serializing_if = "Option::is_none")]
1107        duration: Option<i32>,
1108        #[serde(skip_serializing_if = "Option::is_none")]
1109        performer: Option<String>,
1110        #[serde(skip_serializing_if = "Option::is_none")]
1111        title: Option<String>,
1112    },
1113    #[serde(rename = "document")]
1114    Document {
1115        media: FileToSend,
1116        #[serde(skip_serializing_if = "Option::is_none")]
1117        thumb: Option<InputFile>,
1118        #[serde(skip_serializing_if = "Option::is_none")]
1119        caption: Option<String>,
1120        #[serde(skip_serializing_if = "Option::is_none")]
1121        parse_mode: Option<ParseMode>,
1122    },
1123    #[serde(other)]
1124    /// Unknown upstream data type.
1125    Unknown,
1126}
1127
1128/// a parameter of the inline keyboard button used to automatically authorize a user.
1129#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
1130pub struct LoginUrl {
1131    /// An HTTP URL to be opened with user authorization data added to the query string when
1132    /// the button is pressed.
1133    ///
1134    /// If the user refuses to provide authorization data, the original URL without information
1135    /// about the user will be opened. The data added is the same as described in
1136    /// [Receiving authorization data](https://core.telegram.org/widgets/login#receiving-authorization-data).
1137    ///
1138    /// ## Note
1139    ///
1140    /// You **must** always check the hash of the received data to verify the authentication and
1141    /// the integrity of the data as described in [Checking authorization](https://core.telegram.org/widgets/login#checking-authorization).
1142    pub url: String,
1143    /// New text of the button in forwarded messages.
1144    pub forward_text: Option<String>,
1145    /// Username of a bot, which will be used for user authorization.
1146    ///
1147    /// See Setting up a bot for more details.
1148    /// If not specified, the current bot's username will be assumed.
1149    /// The *url*'s domain must be the same as the domain linked with the bot.
1150    /// See [Linking your domain to the bot](https://core.telegram.org/widgets/login#linking-your-domain-to-the-bot)
1151    /// for more details.
1152    pub bot_username: Option<String>,
1153    /// Pass True to request the permission for your bot to send messages to the user.
1154    pub request_write_access: Option<bool>,
1155}
1156
1157/// Send *Markdown or HTML*, if you want Telegram apps to show
1158/// [bold, italic, fixed-width text or inline URLs](https://core.telegram.org/bots/api#formatting-options)
1159/// in the media caption.
1160#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
1161pub enum ParseMode {
1162    Markdown,
1163    MarkdownV2,
1164    HTML,
1165    #[serde(other)]
1166    /// Unknown upstream data type.
1167    Unknown,
1168}