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}