telbot_types/
message.rs

1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4
5use crate::chat::{Chat, ChatId, PinChatMessage, UnpinChatMessage};
6use crate::file::{
7    Animation, Audio, Document, InputFile, InputFileVariant, InputMedia, PhotoSize, Video,
8    VideoNote, Voice,
9};
10use crate::markup::{InlineKeyboardMarkup, MessageEntity, ParseMode, ReplyMarkup};
11use crate::payment::{Invoice, SuccessfulPayment};
12use crate::sticker::Sticker;
13use crate::user::User;
14use crate::{FileMethod, JsonMethod, TelegramMethod};
15
16/// This object represents a message.
17#[derive(Debug, Deserialize)]
18pub struct Message {
19    /// Unique message identifier inside this chat
20    pub message_id: i64,
21    /// Sender, empty for messages sent to channels
22    pub from: Option<User>,
23    /// Sender of the message, sent on behalf of a chat.
24    /// The channel itself for channel messages.
25    /// The supergroup itself for messages from anonymous group administrators.
26    /// The linked channel for messages automatically forwarded to the discussion group
27    pub sender_chat: Option<Chat>,
28    /// Date the message was sent in Unix time
29    pub date: u64,
30    /// Conversation the message belongs to
31    pub chat: Chat,
32    /// For forwarded messages, sender of the original message
33    pub forward_from: Option<User>,
34    /// For messages forwarded from channels or from anonymous administrators, information about the original sender chat
35    pub forward_from_chat: Option<Chat>,
36    /// For messages forwarded from channels, identifier of the original message in the channel
37    pub forward_from_message_id: Option<i64>,
38    /// For messages forwarded from channels, signature of the post author if present
39    pub forward_signature: Option<String>,
40    /// Sender's name for messages forwarded from users who disallow adding a link to their account in forwarded messages
41    pub forward_sender_name: Option<String>,
42    /// For forwarded messages, date the original message was sent in Unix time
43    pub forward_date: Option<u64>,
44    /// For replies, the original message.
45    /// Note that the Message object in this field will not contain further reply_to_message fields even if it itself is a reply.
46    pub reply_to_message: Option<Box<Message>>,
47    /// Bot through which the message was sent
48    pub via_bot: Option<User>,
49    /// Date the message was last edited in Unix time
50    pub edit_date: Option<u64>,
51    /// The unique identifier of a media message group this message belongs to
52    pub media_group_id: Option<String>,
53    /// Signature of the post author for messages in channels,
54    /// or the custom title of an anonymous group administrator
55    pub author_signature: Option<String>,
56    /// Additional information about the message.
57    #[serde(flatten)]
58    pub kind: MessageKind,
59    /// Inline keyboard attached to the message.
60    /// `login_url` buttons are represented as ordinary `url` buttons.
61    pub reply_markup: Option<InlineKeyboardMarkup>,
62}
63
64impl Message {
65    pub fn reply_text(&self, text: impl Into<String>) -> SendMessage {
66        SendMessage::new(self.chat.id, text).reply_to(self.message_id)
67    }
68
69    pub fn forward_to(&self, chat_id: impl Into<ChatId>) -> ForwardMessage {
70        ForwardMessage::new(chat_id, self.chat.id, self.message_id)
71    }
72
73    pub fn copy_to(&self, chat_id: impl Into<ChatId>) -> CopyMessage {
74        CopyMessage::new(chat_id, self.chat.id, self.message_id)
75    }
76
77    pub fn pin(&self) -> PinChatMessage {
78        PinChatMessage::new(self.chat.id, self.message_id)
79    }
80
81    pub fn unpin(&self) -> UnpinChatMessage {
82        UnpinChatMessage::new(self.chat.id, self.message_id)
83    }
84
85    pub fn edit_text(&self, text: impl Into<String>) -> EditMessageText {
86        EditMessageText::new(self.chat.id, self.message_id, text)
87    }
88
89    pub fn remove_caption(&self) -> EditMessageCaption {
90        EditMessageCaption::new_empty(self.chat.id, self.message_id)
91    }
92
93    pub fn edit_caption(&self, caption: impl Into<String>) -> EditMessageCaption {
94        EditMessageCaption::new(self.chat.id, self.message_id, caption)
95    }
96
97    pub fn edit_media(&self, media: impl Into<InputMedia>) -> EditMessageMedia {
98        EditMessageMedia::new(self.chat.id, self.message_id, media)
99    }
100
101    pub fn remove_reply_markup(&self) -> EditMessageReplyMarkup {
102        EditMessageReplyMarkup::new_empty(self.chat.id, self.message_id)
103    }
104
105    pub fn edit_reply_markup(
106        &self,
107        reply_markup: impl Into<InlineKeyboardMarkup>,
108    ) -> EditMessageReplyMarkup {
109        EditMessageReplyMarkup::new(self.chat.id, self.message_id, reply_markup)
110    }
111
112    pub fn stop_poll(&self) -> StopPoll {
113        StopPoll::new(self.chat.id, self.message_id)
114    }
115
116    pub fn delete(&self) -> DeleteMessage {
117        DeleteMessage::new(self.chat.id, self.message_id)
118    }
119}
120
121/// Variants of a message.
122#[derive(Debug, Deserialize)]
123#[serde(untagged)]
124pub enum MessageKind {
125    /// Text message
126    Text {
127        /// The actual UTF-8 text of the message, 0-4096 characters
128        text: String,
129        /// Special entities like usernames, URLs, bot commands, etc. that appear in the text
130        entities: Option<Vec<MessageEntity>>,
131    },
132    /// Animation message
133    Animation {
134        /// Information about the animation.
135        /// For backward compatibility, when this field is set, the document field will also be set
136        animation: Animation,
137        /// Information about the file
138        document: Document,
139        /// Caption for the animation, 0-1024 characters
140        caption: Option<String>,
141        /// For messages with a caption, special entities like usernames, URLs, bot commands, etc. that appear in the caption
142        caption_entities: Option<Vec<MessageEntity>>,
143    },
144    /// Audio message
145    Audio {
146        /// Information about the file
147        audio: Audio,
148        /// Caption for the audio, 0-1024 characters
149        caption: Option<String>,
150        /// For messages with a caption, special entities like usernames, URLs, bot commands, etc. that appear in the caption
151        caption_entities: Option<Vec<MessageEntity>>,
152    },
153    /// General file message
154    Document {
155        /// Information about the file
156        document: Document,
157        /// Caption for the document, 0-1024 characters
158        caption: Option<String>,
159        /// For messages with a caption, special entities like usernames, URLs, bot commands, etc. that appear in the caption
160        caption_entities: Option<Vec<MessageEntity>>,
161    },
162    /// Photo message
163    Photo {
164        /// Available sizes of the photo
165        photo: Vec<PhotoSize>,
166        /// Caption for the photo, 0-1024 characters
167        caption: Option<String>,
168        /// For messages with a caption, special entities like usernames, URLs, bot commands, etc. that appear in the caption
169        caption_entities: Option<Vec<MessageEntity>>,
170    },
171    /// Sticker message
172    Sticker {
173        /// Information about the sticker
174        sticker: Sticker,
175    },
176    /// Video message
177    Video {
178        /// Information about the video
179        video: Video,
180        /// Caption for the video, 0-1024 characters
181        caption: Option<String>,
182        /// For messages with a caption, special entities like usernames, URLs, bot commands, etc. that appear in the caption
183        caption_entities: Option<Vec<MessageEntity>>,
184    },
185    /// [Video note](https://telegram.org/blog/video-messages-and-telescope)
186    VideoNote {
187        /// Information about the video message
188        video_note: VideoNote,
189    },
190    /// Voice message
191    Voice {
192        /// Information about the file
193        voice: Voice,
194        /// Caption for the voice, 0-1024 characters
195        caption: Option<String>,
196        /// For messages with a caption, special entities like usernames, URLs, bot commands, etc. that appear in the caption
197        caption_entities: Option<Vec<MessageEntity>>,
198    },
199    /// Shared contact
200    Contact {
201        /// Information about the contact
202        contact: Contact,
203    },
204    Dice {
205        dice: Dice,
206    },
207    Game {
208        /// Information about the game.
209        /// [More about games »](https://core.telegram.org/bots/api#games)
210        game: Game,
211    },
212    /// Native Poll
213    Poll {
214        /// Information about the poll
215        poll: Poll,
216    },
217    /// Venue message
218    Venue {
219        /// Information about the venue.
220        /// For backward compatibility, when this field is set, the location field will also be set
221        venue: Venue,
222        /// Information about the location
223        location: Location,
224    },
225    /// Shared location
226    Location {
227        /// Information about the location
228        location: Location,
229    },
230    /// New chat members message
231    NewChatMembers {
232        /// New members that were added to the group or supergroup and information about them
233        /// (the bot itself may be one of these members)
234        new_chat_members: Vec<User>,
235    },
236    /// Chat members leave message
237    LeftChatMember {
238        /// A member was removed from the group, information about them
239        /// (this member may be the bot itself)
240        left_chat_member: User,
241    },
242    /// Chat title change message
243    NewChatTitle {
244        /// A chat title was changed to this value
245        new_chat_title: String,
246    },
247    /// Service message: the chat photo was deleted
248    DeleteChatPhoto {
249        /// Always true
250        delete_chat_photo: bool,
251    },
252    /// Service message: the group has been created
253    GroupChatCreated {
254        /// Always true
255        group_chat_created: bool,
256    },
257    /// Service message: the supergroup has been created.
258    /// This variant can't be received in a message coming through updates,
259    /// because bot can't be a member of a supergroup when it is created.
260    /// It can only be found in reply_to_message
261    /// if someone replies to a very first message in a directly created supergroup.
262    SupergroupChatCreated {
263        /// Always true
264        supergroup_chat_created: bool,
265    },
266    /// Service message: the channel has been created.
267    /// This variant can't be received in a message coming through updates,
268    /// because bot can't be a member of a channel when it is created.
269    /// It can only be found in reply_to_message
270    /// if someone replies to a very first message in a channel.
271    ChannelChatCreated {
272        /// Always true
273        channel_chat_created: bool,
274    },
275    /// Service message: auto-delete timer settings changed in the chat
276    MessageAutoDeleteTimerChanged {
277        message_auto_delete_timer_changed: MessageAutoDeleteTimerChanged,
278    },
279    /// Group migration message
280    GroupMigrated {
281        /// The group has been migrated to a supergroup with the specified identifier.
282        migrate_to_chat_id: i64,
283        /// The supergroup has been migrated from a group with the specified identifier.
284        migrate_from_chat_id: i64,
285    },
286    /// Pinned message
287    MessagePinned {
288        /// Specified message was pinned.
289        /// Note that the Message object in this field will not contain further reply_to_message fields even if it is itself a reply.
290        pinned_message: Box<Message>,
291    },
292    /// Invoice for a [payment](https://core.telegram.org/bots/api#payments)
293    Invoice {
294        /// Information about the invoice.
295        /// [More about payments »](https://core.telegram.org/bots/api#payments)
296        invoice: Invoice,
297    },
298    /// Service message about a successful payment
299    SuccessfulPayment {
300        /// Information about the payment.
301        /// [More about payments »](https://core.telegram.org/bots/api#payments)
302        successful_payment: SuccessfulPayment,
303    },
304    /// Login message.
305    Login {
306        /// The domain name of the website on which the user has logged in.
307        /// [More about Telegram Login »](https://core.telegram.org/widgets/login)
308        connected_website: String,
309        /// Telegram Passport data
310        passport_data: PassportData,
311    },
312    /// Service message: a user in the chat triggered another user's proximity alert while sharing Live Location
313    ProximityAlertTriggered {
314        proximity_alert_triggered: ProximityAlertTriggered,
315    },
316    /// Service message: voice chat scheduled
317    VoiceChatScheduled {
318        voice_chat_scheduled: VoiceChatScheduled,
319    },
320    /// Service message: voice chat started
321    VoiceChatStarted {
322        voice_chat_started: VoiceChatStarted,
323    },
324    /// Service message: voice chat ended
325    VoiceChatEnded {
326        voice_chat_ended: VoiceChatEnded,
327    },
328    /// Service message: new participants invited to a voice chat
329    VoiceChatParticipantsInvited {
330        voice_chat_participants_invited: VoiceChatParticipantsInvited,
331    },
332}
333
334impl MessageKind {
335    pub fn text(&self) -> Option<&str> {
336        match self {
337            Self::Text { text, .. } => Some(text),
338            _ => None,
339        }
340    }
341
342    pub fn entities(&self) -> Option<&[MessageEntity]> {
343        match self {
344            Self::Text { entities, .. } => entities.as_deref(),
345            _ => None,
346        }
347    }
348
349    pub fn animation(&self) -> Option<&Animation> {
350        match self {
351            Self::Animation { animation, .. } => Some(animation),
352            _ => None,
353        }
354    }
355
356    pub fn document(&self) -> Option<&Document> {
357        match self {
358            Self::Animation { document, .. } | Self::Document { document, .. } => Some(document),
359            _ => None,
360        }
361    }
362
363    pub fn caption(&self) -> Option<&str> {
364        match self {
365            Self::Animation { caption, .. }
366            | Self::Audio { caption, .. }
367            | Self::Document { caption, .. }
368            | Self::Photo { caption, .. }
369            | Self::Video { caption, .. }
370            | Self::Voice { caption, .. } => caption.as_deref(),
371            _ => None,
372        }
373    }
374
375    pub fn caption_entities(&self) -> Option<&[MessageEntity]> {
376        match self {
377            Self::Animation {
378                caption_entities, ..
379            }
380            | Self::Audio {
381                caption_entities, ..
382            }
383            | Self::Document {
384                caption_entities, ..
385            }
386            | Self::Photo {
387                caption_entities, ..
388            }
389            | Self::Video {
390                caption_entities, ..
391            }
392            | Self::Voice {
393                caption_entities, ..
394            } => caption_entities.as_deref(),
395            _ => None,
396        }
397    }
398
399    pub fn audio(&self) -> Option<&Audio> {
400        match self {
401            Self::Audio { audio, .. } => Some(audio),
402            _ => None,
403        }
404    }
405
406    pub fn photo(&self) -> Option<&[PhotoSize]> {
407        match self {
408            Self::Photo { photo, .. } => Some(photo.as_ref()),
409            _ => None,
410        }
411    }
412
413    pub fn sticker(&self) -> Option<&Sticker> {
414        match self {
415            Self::Sticker { sticker } => Some(sticker),
416            _ => None,
417        }
418    }
419
420    pub fn video(&self) -> Option<&Video> {
421        match self {
422            Self::Video { video, .. } => Some(video),
423            _ => None,
424        }
425    }
426
427    pub fn video_note(&self) -> Option<&VideoNote> {
428        match self {
429            Self::VideoNote { video_note } => Some(video_note),
430            _ => None,
431        }
432    }
433
434    pub fn voice(&self) -> Option<&Voice> {
435        match self {
436            Self::Voice { voice, .. } => Some(voice),
437            _ => None,
438        }
439    }
440
441    pub fn contact(&self) -> Option<&Contact> {
442        match self {
443            Self::Contact { contact } => Some(contact),
444            _ => None,
445        }
446    }
447
448    pub fn dice(&self) -> Option<&Dice> {
449        match self {
450            Self::Dice { dice } => Some(dice),
451            _ => None,
452        }
453    }
454
455    pub fn game(&self) -> Option<&Game> {
456        match self {
457            Self::Game { game } => Some(game),
458            _ => None,
459        }
460    }
461
462    pub fn poll(&self) -> Option<&Poll> {
463        match self {
464            Self::Poll { poll } => Some(poll),
465            _ => None,
466        }
467    }
468
469    pub fn venue(&self) -> Option<&Venue> {
470        match self {
471            Self::Venue { venue, .. } => Some(venue),
472            _ => None,
473        }
474    }
475
476    pub fn location(&self) -> Option<&Location> {
477        match self {
478            Self::Venue { location, .. } | Self::Location { location } => Some(location),
479            _ => None,
480        }
481    }
482
483    pub fn new_chat_members(&self) -> Option<&[User]> {
484        match self {
485            Self::NewChatMembers { new_chat_members } => Some(new_chat_members.as_ref()),
486            _ => None,
487        }
488    }
489
490    pub fn left_chat_member(&self) -> Option<&User> {
491        match self {
492            Self::LeftChatMember { left_chat_member } => Some(left_chat_member),
493            _ => None,
494        }
495    }
496
497    pub fn new_chat_title(&self) -> Option<&str> {
498        match self {
499            Self::NewChatTitle { new_chat_title } => Some(new_chat_title),
500            _ => None,
501        }
502    }
503
504    pub fn message_auto_delete_timer_changed(&self) -> Option<&MessageAutoDeleteTimerChanged> {
505        match self {
506            Self::MessageAutoDeleteTimerChanged {
507                message_auto_delete_timer_changed,
508            } => Some(message_auto_delete_timer_changed),
509            _ => None,
510        }
511    }
512
513    pub fn migrate_to_chat_id(&self) -> Option<i64> {
514        match self {
515            Self::GroupMigrated {
516                migrate_to_chat_id, ..
517            } => Some(*migrate_to_chat_id),
518            _ => None,
519        }
520    }
521
522    pub fn migrate_from_chat_id(&self) -> Option<i64> {
523        match self {
524            Self::GroupMigrated {
525                migrate_from_chat_id,
526                ..
527            } => Some(*migrate_from_chat_id),
528            _ => None,
529        }
530    }
531
532    pub fn pinned_message(&self) -> Option<&Message> {
533        match self {
534            Self::MessagePinned { pinned_message } => Some(pinned_message.as_ref()),
535            _ => None,
536        }
537    }
538
539    pub fn invoice(&self) -> Option<&Invoice> {
540        match self {
541            Self::Invoice { invoice } => Some(invoice),
542            _ => None,
543        }
544    }
545
546    pub fn successful_payment(&self) -> Option<&SuccessfulPayment> {
547        match self {
548            Self::SuccessfulPayment { successful_payment } => Some(successful_payment),
549            _ => None,
550        }
551    }
552
553    pub fn connected_website(&self) -> Option<&str> {
554        match self {
555            Self::Login {
556                connected_website, ..
557            } => Some(connected_website),
558            _ => None,
559        }
560    }
561
562    pub fn passport_data(&self) -> Option<&PassportData> {
563        match self {
564            Self::Login { passport_data, .. } => Some(passport_data),
565            _ => None,
566        }
567    }
568
569    pub fn proximity_alert_triggered(&self) -> Option<&ProximityAlertTriggered> {
570        match self {
571            Self::ProximityAlertTriggered {
572                proximity_alert_triggered,
573            } => Some(proximity_alert_triggered),
574            _ => None,
575        }
576    }
577
578    pub fn voice_chat_scheduled(&self) -> Option<&VoiceChatScheduled> {
579        match self {
580            Self::VoiceChatScheduled {
581                voice_chat_scheduled,
582            } => Some(voice_chat_scheduled),
583            _ => None,
584        }
585    }
586
587    pub fn voice_chat_started(&self) -> Option<&VoiceChatStarted> {
588        match self {
589            Self::VoiceChatStarted { voice_chat_started } => Some(voice_chat_started),
590            _ => None,
591        }
592    }
593
594    pub fn voice_chat_ended(&self) -> Option<&VoiceChatEnded> {
595        match self {
596            Self::VoiceChatEnded { voice_chat_ended } => Some(voice_chat_ended),
597            _ => None,
598        }
599    }
600
601    pub fn voice_chat_participants_invited(&self) -> Option<&VoiceChatParticipantsInvited> {
602        match self {
603            Self::VoiceChatParticipantsInvited {
604                voice_chat_participants_invited,
605            } => Some(voice_chat_participants_invited),
606            _ => None,
607        }
608    }
609
610    pub fn is_text(&self) -> bool {
611        matches!(self, Self::Text { .. })
612    }
613
614    pub fn is_animation(&self) -> bool {
615        matches!(self, Self::Animation { .. })
616    }
617
618    pub fn is_audio(&self) -> bool {
619        matches!(self, Self::Audio { .. })
620    }
621
622    pub fn is_document(&self) -> bool {
623        matches!(self, Self::Document { .. })
624    }
625
626    pub fn is_photo(&self) -> bool {
627        matches!(self, Self::Photo { .. })
628    }
629
630    pub fn is_sticker(&self) -> bool {
631        matches!(self, Self::Sticker { .. })
632    }
633
634    pub fn is_video(&self) -> bool {
635        matches!(self, Self::Video { .. })
636    }
637
638    pub fn is_video_note(&self) -> bool {
639        matches!(self, Self::VideoNote { .. })
640    }
641
642    pub fn is_voice(&self) -> bool {
643        matches!(self, Self::Voice { .. })
644    }
645
646    pub fn is_contact(&self) -> bool {
647        matches!(self, Self::Contact { .. })
648    }
649
650    pub fn is_dice(&self) -> bool {
651        matches!(self, Self::Dice { .. })
652    }
653
654    pub fn is_game(&self) -> bool {
655        matches!(self, Self::Game { .. })
656    }
657
658    pub fn is_poll(&self) -> bool {
659        matches!(self, Self::Poll { .. })
660    }
661
662    pub fn is_venue(&self) -> bool {
663        matches!(self, Self::Venue { .. })
664    }
665
666    pub fn is_location(&self) -> bool {
667        matches!(self, Self::Location { .. })
668    }
669
670    pub fn is_new_chat_members(&self) -> bool {
671        matches!(self, Self::NewChatMembers { .. })
672    }
673
674    pub fn is_left_chat_member(&self) -> bool {
675        matches!(self, Self::LeftChatMember { .. })
676    }
677
678    pub fn is_new_chat_title(&self) -> bool {
679        matches!(self, Self::NewChatTitle { .. })
680    }
681
682    pub fn is_delete_chat_photo(&self) -> bool {
683        matches!(self, Self::DeleteChatPhoto { .. })
684    }
685
686    pub fn is_group_chat_created(&self) -> bool {
687        matches!(self, Self::GroupChatCreated { .. })
688    }
689
690    pub fn is_supergroup_chat_created(&self) -> bool {
691        matches!(self, Self::SupergroupChatCreated { .. })
692    }
693
694    pub fn is_channel_chat_created(&self) -> bool {
695        matches!(self, Self::ChannelChatCreated { .. })
696    }
697
698    pub fn is_group_migrated(&self) -> bool {
699        matches!(self, Self::GroupMigrated { .. })
700    }
701
702    pub fn is_message_pinned(&self) -> bool {
703        matches!(self, Self::MessagePinned { .. })
704    }
705
706    pub fn is_invoice(&self) -> bool {
707        matches!(self, Self::Invoice { .. })
708    }
709
710    pub fn is_login(&self) -> bool {
711        matches!(self, Self::Login { .. })
712    }
713
714    pub fn is_proximity_alert_triggered(&self) -> bool {
715        matches!(self, Self::ProximityAlertTriggered { .. })
716    }
717
718    pub fn is_voice_chat_scheduled(&self) -> bool {
719        matches!(self, Self::VoiceChatScheduled { .. })
720    }
721
722    pub fn is_voice_chat_started(&self) -> bool {
723        matches!(self, Self::VoiceChatStarted { .. })
724    }
725
726    pub fn is_voice_chat_ended(&self) -> bool {
727        matches!(self, Self::VoiceChatEnded { .. })
728    }
729
730    pub fn is_voice_chat_participants_invited(&self) -> bool {
731        matches!(self, Self::VoiceChatParticipantsInvited { .. })
732    }
733}
734
735/// This object represents a unique message identifier.
736#[derive(Debug, Deserialize)]
737pub struct MessageId {
738    /// Unique message identifier
739    pub message_id: i64,
740}
741
742/// This object represents a point on the map.
743#[derive(Debug, Deserialize)]
744pub struct Location {
745    /// Longitude as defined by sender
746    pub longitude: f32,
747    /// Latitude as defined by sender
748    pub latitude: f32,
749    /// The radius of uncertainty for the location, measured in meters; 0-1500
750    pub horizontal_accuracy: Option<f32>,
751    /// Time relative to the message sending date, during which the location can be updated, in seconds.
752    /// For active live locations only.
753    pub live_period: Option<i32>,
754    /// The direction in which user is moving, in degrees; 1-360.
755    /// For active live locations only.
756    pub heading: Option<i32>,
757    /// Maximum distance for proximity alerts about approaching another chat member, in meters.
758    /// For sent live locations only.
759    pub proximity_alert_radius: Option<i32>,
760}
761
762/// This object represents a phone contact.
763#[derive(Debug, Deserialize)]
764pub struct Contact {
765    /// Contact's phone number
766    pub phone_number: String,
767    /// Contact's first name
768    pub first_name: String,
769    /// Contact's last name
770    pub last_name: Option<String>,
771    /// Contact's user identifier in Telegram.
772    pub user_id: Option<i64>,
773    /// Additional data about the contact in the form of a [vCard](https://en.wikipedia.org/wiki/VCard)
774    pub vcard: Option<String>,
775}
776
777/// This object represents an animated emoji that displays a random value.
778#[derive(Debug, Deserialize)]
779pub struct Dice {
780    /// Emoji on which the dice throw animation is based
781    pub emoji: String,
782    /// Value of the dice, 1-6 for “🎲”, “🎯” and “🎳” base emoji, 1-5 for “🏀” and “⚽” base emoji, 1-64 for “🎰” base emoji
783    pub value: i32,
784}
785
786#[derive(Debug, Deserialize)]
787pub struct Game {}
788
789/// This object contains information about one answer option in a poll.
790#[derive(Debug, Deserialize)]
791pub struct PollOption {
792    /// Option text, 1-100 characters
793    pub text: String,
794    /// Number of users that voted for this option
795    pub voter_count: u32,
796}
797
798/// This object represents an answer of a user in a non-anonymous poll.
799#[derive(Debug, Deserialize)]
800pub struct PollAnswer {
801    /// Unique poll identifier
802    pub poll_id: String,
803    /// The user, who changed the answer to the poll
804    pub user: User,
805    /// 0-based identifiers of answer options, chosen by the user.
806    /// May be empty if the user retracted their vote.
807    pub option_ids: Vec<u32>,
808}
809
810/// This object contains information about a poll.
811#[derive(Debug, Deserialize)]
812pub struct Poll {
813    /// Unique poll identifier
814    pub id: String,
815    /// Poll question, 1-300 characters
816    pub question: String,
817    /// List of poll options
818    pub options: Vec<PollOption>,
819    /// Total number of users that voted in the poll
820    pub total_voter_count: u32,
821    /// True, if the poll is closed
822    pub is_closed: bool,
823    /// True, if the poll is anonymous
824    pub is_anonymous: bool,
825    /// Poll type
826    #[serde(flatten)]
827    pub kind: PollKind,
828    /// True, if the poll allows multiple answers
829    pub allows_multiple_answers: bool,
830    /// Amount of time in seconds the poll will be active after creation
831    pub open_period: Option<u32>,
832    /// Point in time (Unix timestamp) when the poll will be automatically closed
833    pub close_date: Option<u64>,
834}
835
836/// Poll type
837#[derive(Debug, Deserialize)]
838#[serde(rename_all = "snake_case", tag = "type")]
839pub enum PollKind {
840    Regular,
841    Quiz {
842        /// 0-based identifier of the correct answer option.
843        /// Available only for polls in the quiz mode, which are closed,
844        /// or was sent (not forwarded) by the bot or to the private chat with the bot.
845        correct_option_id: Option<usize>,
846        /// Text that is shown when a user chooses an incorrect answer or taps on the lamp icon in a quiz-style poll,
847        /// 0-200 characters
848        explanation: Option<String>,
849        /// Special entities like usernames, URLs, bot commands, etc. that appear in the explanation
850        explanation_entities: Option<Vec<MessageEntity>>,
851    },
852}
853
854impl PollKind {
855    pub fn correct_option_id(&self) -> Option<usize> {
856        match self {
857            Self::Quiz {
858                correct_option_id, ..
859            } => *correct_option_id,
860            _ => None,
861        }
862    }
863
864    pub fn explanation(&self) -> Option<&str> {
865        match self {
866            Self::Quiz { explanation, .. } => explanation.as_deref(),
867            _ => None,
868        }
869    }
870
871    pub fn explanation_entities(&self) -> Option<&[MessageEntity]> {
872        match self {
873            Self::Quiz {
874                explanation_entities,
875                ..
876            } => explanation_entities.as_deref(),
877            _ => None,
878        }
879    }
880
881    pub fn is_regular(&self) -> bool {
882        matches!(self, Self::Regular)
883    }
884
885    pub fn is_quiz(&self) -> bool {
886        matches!(self, Self::Quiz { .. })
887    }
888}
889
890/// This object represents a venue.
891#[derive(Debug, Deserialize)]
892pub struct Venue {
893    /// Venue location. Can't be a live location
894    pub location: Location,
895    /// Name of the venue
896    pub title: String,
897    /// Address of the venue
898    pub address: String,
899    /// Foursquare identifier of the venue
900    pub foursquare_id: Option<String>,
901    /// Foursquare type of the venue.
902    ///
903    /// For example, “arts_entertainment/default”, “arts_entertainment/aquarium” or “food/icecream”.
904    pub foursquare_type: Option<String>,
905    /// Google Places identifier of the venue
906    pub google_place_id: Option<String>,
907    /// Google Places type of the venue. (See [supported types.](https://developers.google.com/places/web-service/supported_types))
908    pub google_place_type: String,
909}
910
911/// This object represents a service message about a change in auto-delete timer settings.
912#[derive(Debug, Deserialize)]
913pub struct MessageAutoDeleteTimerChanged {
914    /// New auto-delete time for messages in the chat
915    pub message_auto_delete_time: u32,
916}
917
918#[derive(Debug, Deserialize)]
919pub struct PassportData {}
920
921/// This object represents the content of a service message,
922/// sent whenever a user in the chat triggers a proximity alert set by another user.
923#[derive(Debug, Deserialize)]
924pub struct ProximityAlertTriggered {
925    /// User that triggered the alert
926    pub traveler: User,
927    /// User that set the alert
928    pub watcher: User,
929    /// The distance between the users
930    pub distance: u32,
931}
932
933/// This object represents a service message about a voice chat scheduled in the chat.
934#[derive(Debug, Deserialize)]
935pub struct VoiceChatScheduled {
936    /// Point in time (Unix timestamp) when the voice chat is supposed to be started by a chat administrator
937    pub start_date: u64,
938}
939
940/// This object represents a service message about a voice chat started in the chat.
941/// Currently holds no information.
942#[derive(Debug, Deserialize)]
943pub struct VoiceChatStarted;
944
945/// This object represents a service message about a voice chat ended in the chat.
946#[derive(Debug, Deserialize)]
947pub struct VoiceChatEnded {
948    /// Voice chat duration; in seconds
949    pub duration: u32,
950}
951
952/// This object represents a service message about new members invited to a voice chat.
953#[derive(Debug, Deserialize)]
954pub struct VoiceChatParticipantsInvited {
955    /// New members that were invited to the voice chat
956    pub users: Option<Vec<User>>,
957}
958
959/// Use this method to send text messages. On success, the sent Message is returned.
960#[derive(Clone, Serialize)]
961pub struct SendMessage {
962    /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
963    pub chat_id: ChatId,
964    /// Text of the message to be sent, 1-4096 characters after entities parsing
965    pub text: String,
966    /// Mode for parsing entities in the message text.
967    /// See [formatting options](https://core.telegram.org/bots/api#formatting-options) for more details.
968    #[serde(skip_serializing_if = "Option::is_none")]
969    pub parse_mode: Option<ParseMode>,
970    /// List of special entities that appear in message text,
971    /// which can be specified instead of *parse_mode*
972    #[serde(skip_serializing_if = "Option::is_none")]
973    pub entities: Option<Vec<MessageEntity>>,
974    /// Disables link previews for links in the sent message
975    #[serde(skip_serializing_if = "Option::is_none")]
976    pub disable_web_page_preview: Option<bool>,
977    /// Sends the message [silently](https://telegram.org/blog/channels-2-0#silent-messages).
978    /// Users will receive a notification with no sound.
979    #[serde(skip_serializing_if = "Option::is_none")]
980    pub disable_notification: Option<bool>,
981    /// If the message is a reply, ID of the original message
982    #[serde(skip_serializing_if = "Option::is_none")]
983    pub reply_to_message_id: Option<i64>,
984    /// Pass *True*, if the message should be sent even if the specified replied-to message is not found
985    #[serde(skip_serializing_if = "Option::is_none")]
986    pub allow_sending_without_reply: Option<bool>,
987    /// Additional interface options.
988    /// A JSON-serialized object for an [inline keyboard](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating),
989    /// [custom reply keyboard](https://core.telegram.org/bots#keyboards),
990    /// instructions to remove reply keyboard or to force a reply from the user.
991    #[serde(skip_serializing_if = "Option::is_none")]
992    pub reply_markup: Option<ReplyMarkup>,
993    /// Protects the contents of the sent message from forwarding and saving
994    #[serde(skip_serializing_if = "Option::is_none")]
995    pub protect_content: Option<bool>,
996}
997
998impl SendMessage {
999    /// Create a new sendMessage request
1000    pub fn new(chat_id: impl Into<ChatId>, text: impl Into<String>) -> Self {
1001        Self {
1002            chat_id: chat_id.into(),
1003            text: text.into(),
1004            parse_mode: None,
1005            entities: None,
1006            disable_web_page_preview: None,
1007            disable_notification: None,
1008            reply_to_message_id: None,
1009            allow_sending_without_reply: None,
1010            reply_markup: None,
1011            protect_content: None,
1012        }
1013    }
1014    /// Set parse mode
1015    pub fn with_parse_mode(self, parse_mode: ParseMode) -> Self {
1016        Self {
1017            parse_mode: Some(parse_mode),
1018            ..self
1019        }
1020    }
1021    /// Set entities
1022    pub fn with_entities(self, entities: Vec<MessageEntity>) -> Self {
1023        Self {
1024            entities: Some(entities),
1025            ..self
1026        }
1027    }
1028    /// Add one entity
1029    pub fn with_entity(mut self, entity: MessageEntity) -> Self {
1030        let entities = self.entities.get_or_insert_with(Default::default);
1031        entities.push(entity);
1032        self
1033    }
1034    /// Disable web preview
1035    pub fn disable_web_page_preview(self) -> Self {
1036        Self {
1037            disable_web_page_preview: Some(true),
1038            ..self
1039        }
1040    }
1041    /// Disable notification
1042    pub fn disable_notification(self) -> Self {
1043        Self {
1044            disable_notification: Some(true),
1045            ..self
1046        }
1047    }
1048    /// Reply to message
1049    pub fn reply_to(self, message_id: i64) -> Self {
1050        Self {
1051            reply_to_message_id: Some(message_id),
1052            ..self
1053        }
1054    }
1055    /// Allow sending message even if the replying message isn't present
1056    pub fn allow_sending_without_reply(self) -> Self {
1057        Self {
1058            allow_sending_without_reply: Some(true),
1059            ..self
1060        }
1061    }
1062    /// Set reply markup
1063    pub fn with_reply_markup(self, markup: impl Into<ReplyMarkup>) -> Self {
1064        Self {
1065            reply_markup: Some(markup.into()),
1066            ..self
1067        }
1068    }
1069    /// Protect content
1070    pub fn protect_content(self) -> Self {
1071        Self {
1072            protect_content: Some(true),
1073            ..self
1074        }
1075    }
1076}
1077
1078impl TelegramMethod for SendMessage {
1079    type Response = Message;
1080
1081    fn name() -> &'static str {
1082        "sendMessage"
1083    }
1084}
1085
1086impl JsonMethod for SendMessage {}
1087
1088/// Use this method to forward messages of any kind. Service messages can't be forwarded.
1089/// On success, the sent [Message](https://core.telegram.org/bots/api#message) is returned.
1090#[derive(Clone, Serialize)]
1091pub struct ForwardMessage {
1092    /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1093    pub chat_id: ChatId,
1094    /// Unique identifier for the chat where the original message was sent (in the format `@channelusername`)
1095    pub from_chat_id: ChatId,
1096    /// Sends the message [silently](https://telegram.org/blog/channels-2-0#silent-messages).
1097    /// Users will receive a notification with no sound.
1098    #[serde(skip_serializing_if = "Option::is_none")]
1099    pub disable_notification: Option<bool>,
1100    /// Message identifier in the chat specified in *from_chat_id*
1101    pub message_id: i64,
1102    /// Protects the contents of the sent message from forwarding and saving
1103    #[serde(skip_serializing_if = "Option::is_none")]
1104    pub protect_content: Option<bool>,
1105}
1106
1107impl ForwardMessage {
1108    /// Create a new forwardMessage request
1109    pub fn new(to: impl Into<ChatId>, from: impl Into<ChatId>, message: i64) -> Self {
1110        Self {
1111            chat_id: to.into(),
1112            from_chat_id: from.into(),
1113            disable_notification: None,
1114            message_id: message,
1115            protect_content: None,
1116        }
1117    }
1118    /// Disable notification
1119    pub fn disable_notification(self) -> Self {
1120        Self {
1121            disable_notification: Some(true),
1122            ..self
1123        }
1124    }
1125    /// Protect content
1126    pub fn protect_content(self) -> Self {
1127        Self {
1128            protect_content: Some(true),
1129            ..self
1130        }
1131    }
1132}
1133
1134impl TelegramMethod for ForwardMessage {
1135    type Response = Message;
1136
1137    fn name() -> &'static str {
1138        "forwardMessage"
1139    }
1140}
1141
1142impl JsonMethod for ForwardMessage {}
1143
1144/// Use this method to copy messages of any kind.
1145/// Service messages and invoice messages can't be copied.
1146/// The method is analogous to the method [forwardMessage](https://core.telegram.org/bots/api#forwardmessage), but the copied message doesn't have a link to the original message.
1147/// Returns the [MessageId](https://core.telegram.org/bots/api#messageid) of the sent message on success.
1148#[derive(Clone, Serialize)]
1149pub struct CopyMessage {
1150    /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1151    pub chat_id: ChatId,
1152    /// Unique identifier for the chat where the original message was sent (in the format `@channelusername`)
1153    pub from_chat_id: ChatId,
1154    /// Message identifier in the chat specified in *from_chat_id*
1155    pub message_id: i64,
1156    /// New caption for media, 0-1024 characters after entities parsing.
1157    /// If not specified, the original caption is kept
1158    pub caption: Option<String>,
1159    /// Mode for parsing entities in the new caption.
1160    /// See [formatting options](https://core.telegram.org/bots/api#formatting-options) for more details.
1161    pub parse_mode: Option<ParseMode>,
1162    /// List of special entities that appear in the new caption, which can be specified instead of *parse_mode*
1163    pub caption_entities: Option<Vec<MessageEntity>>,
1164    /// Sends the message [silently](https://telegram.org/blog/channels-2-0#silent-messages).
1165    /// Users will receive a notification with no sound.
1166    #[serde(skip_serializing_if = "Option::is_none")]
1167    pub disable_notification: Option<bool>,
1168    /// If the message is a reply, ID of the original message
1169    #[serde(skip_serializing_if = "Option::is_none")]
1170    pub reply_to_message_id: Option<i64>,
1171    /// Pass *True*, if the message should be sent even if the specified replied-to message is not found
1172    #[serde(skip_serializing_if = "Option::is_none")]
1173    pub allow_sending_without_reply: Option<bool>,
1174    /// Additional interface options.
1175    /// A JSON-serialized object for an [inline keyboard](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating),
1176    /// [custom reply keyboard](https://core.telegram.org/bots#keyboards),
1177    /// instructions to remove reply keyboard or to force a reply from the user.
1178    #[serde(skip_serializing_if = "Option::is_none")]
1179    pub reply_markup: Option<ReplyMarkup>,
1180    /// Protects the contents of the sent message from forwarding and saving
1181    #[serde(skip_serializing_if = "Option::is_none")]
1182    pub protect_content: Option<bool>,
1183}
1184
1185impl CopyMessage {
1186    /// Create a new forwardMessage request
1187    pub fn new(to: impl Into<ChatId>, from: impl Into<ChatId>, message: i64) -> Self {
1188        Self {
1189            chat_id: to.into(),
1190            from_chat_id: from.into(),
1191            message_id: message,
1192            caption: None,
1193            parse_mode: None,
1194            caption_entities: None,
1195            disable_notification: None,
1196            reply_to_message_id: None,
1197            allow_sending_without_reply: None,
1198            reply_markup: None,
1199            protect_content: None,
1200        }
1201    }
1202    /// Set caption
1203    pub fn with_caption(self, caption: impl Into<String>) -> Self {
1204        Self {
1205            caption: Some(caption.into()),
1206            ..self
1207        }
1208    }
1209    /// Set parse mode
1210    pub fn with_parse_mode(self, parse_mode: ParseMode) -> Self {
1211        Self {
1212            parse_mode: Some(parse_mode),
1213            ..self
1214        }
1215    }
1216    /// Set caption entities
1217    pub fn with_entities(self, entities: Vec<MessageEntity>) -> Self {
1218        Self {
1219            caption_entities: Some(entities),
1220            ..self
1221        }
1222    }
1223    /// Add one entity
1224    pub fn with_entity(mut self, entity: MessageEntity) -> Self {
1225        let entities = self.caption_entities.get_or_insert_with(Default::default);
1226        entities.push(entity);
1227        self
1228    }
1229    /// Disable notification
1230    pub fn disable_notification(self) -> Self {
1231        Self {
1232            disable_notification: Some(true),
1233            ..self
1234        }
1235    }
1236    /// Reply to message
1237    pub fn reply_to(self, message_id: i64) -> Self {
1238        Self {
1239            reply_to_message_id: Some(message_id),
1240            ..self
1241        }
1242    }
1243    /// Allow sending message even if the replying message isn't present
1244    pub fn allow_sending_without_reply(self) -> Self {
1245        Self {
1246            allow_sending_without_reply: Some(true),
1247            ..self
1248        }
1249    }
1250    /// Set reply markup
1251    pub fn with_reply_markup(self, markup: impl Into<ReplyMarkup>) -> Self {
1252        Self {
1253            reply_markup: Some(markup.into()),
1254            ..self
1255        }
1256    }
1257    /// Protect content
1258    pub fn protect_content(self) -> Self {
1259        Self {
1260            protect_content: Some(true),
1261            ..self
1262        }
1263    }
1264}
1265
1266impl TelegramMethod for CopyMessage {
1267    type Response = MessageId;
1268
1269    fn name() -> &'static str {
1270        "copyMessage"
1271    }
1272}
1273
1274impl JsonMethod for CopyMessage {}
1275
1276/// Use this method to send photos.
1277/// On success, the sent [Message](https://core.telegram.org/bots/api#message) is returned.
1278#[derive(Clone, Serialize)]
1279pub struct SendPhoto {
1280    /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1281    pub chat_id: ChatId,
1282    /// Photo to send.
1283    /// Pass a file_id as String to send a photo that exists on the Telegram servers (recommended),
1284    /// pass an HTTP URL as a String for Telegram to get a photo from the Internet,
1285    /// or upload a new photo using multipart/form-data.
1286    /// The photo must be at most 10 MB in size.
1287    /// The photo's width and height must not exceed 10000 in total.
1288    /// Width and height ratio must be at most 20.
1289    /// [More info on Sending Files »](https://core.telegram.org/bots/api#sending-files)
1290    pub photo: InputFileVariant,
1291    /// Photo caption (may also be used when resending photos by *file_id*), 0-1024 characters after entities parsing
1292    #[serde(skip_serializing_if = "Option::is_none")]
1293    pub caption: Option<String>,
1294    /// Mode for parsing entities in the message text.
1295    /// See [formatting options](https://core.telegram.org/bots/api#formatting-options) for more details.
1296    #[serde(skip_serializing_if = "Option::is_none")]
1297    pub parse_mode: Option<ParseMode>,
1298    /// List of special entities that appear in the caption, which can be specified instead of *parse_mode*
1299    #[serde(skip_serializing_if = "Option::is_none")]
1300    pub caption_entities: Option<Vec<MessageEntity>>,
1301    /// Sends the message [silently](https://telegram.org/blog/channels-2-0#silent-messages).
1302    /// Users will receive a notification with no sound.
1303    #[serde(skip_serializing_if = "Option::is_none")]
1304    pub disable_notification: Option<bool>,
1305    /// If the message is a reply, ID of the original message
1306    #[serde(skip_serializing_if = "Option::is_none")]
1307    pub reply_to_message_id: Option<i64>,
1308    /// Pass *True*, if the message should be sent even if the specified replied-to message is not found
1309    #[serde(skip_serializing_if = "Option::is_none")]
1310    pub allow_sending_without_reply: Option<bool>,
1311    /// Additional interface options.
1312    /// A JSON-serialized object for an [inline keyboard](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating),
1313    /// [custom reply keyboard](https://core.telegram.org/bots#keyboards),
1314    /// instructions to remove reply keyboard or to force a reply from the user.
1315    #[serde(skip_serializing_if = "Option::is_none")]
1316    pub reply_markup: Option<ReplyMarkup>,
1317    /// Protects the contents of the sent message from forwarding and saving
1318    #[serde(skip_serializing_if = "Option::is_none")]
1319    pub protect_content: Option<bool>,
1320}
1321
1322impl SendPhoto {
1323    /// Create a new sendPhoto request
1324    pub fn new(chat_id: impl Into<ChatId>, photo: impl Into<InputFileVariant>) -> Self {
1325        Self {
1326            chat_id: chat_id.into(),
1327            photo: photo.into(),
1328            caption: None,
1329            parse_mode: None,
1330            caption_entities: None,
1331            disable_notification: None,
1332            reply_to_message_id: None,
1333            allow_sending_without_reply: None,
1334            reply_markup: None,
1335            protect_content: None,
1336        }
1337    }
1338    /// Set caption
1339    pub fn with_caption(self, caption: impl Into<String>) -> Self {
1340        Self {
1341            caption: Some(caption.into()),
1342            ..self
1343        }
1344    }
1345    /// Set parse mode
1346    pub fn with_parse_mode(self, parse_mode: ParseMode) -> Self {
1347        Self {
1348            parse_mode: Some(parse_mode),
1349            ..self
1350        }
1351    }
1352    /// Set caption entities
1353    pub fn with_entities(self, entities: Vec<MessageEntity>) -> Self {
1354        Self {
1355            caption_entities: Some(entities),
1356            ..self
1357        }
1358    }
1359    /// Add one entity
1360    pub fn with_entity(mut self, entity: MessageEntity) -> Self {
1361        let entities = self.caption_entities.get_or_insert_with(Default::default);
1362        entities.push(entity);
1363        self
1364    }
1365    /// Disable notification
1366    pub fn disable_notification(self) -> Self {
1367        Self {
1368            disable_notification: Some(true),
1369            ..self
1370        }
1371    }
1372    /// Reply to message
1373    pub fn reply_to(self, message_id: i64) -> Self {
1374        Self {
1375            reply_to_message_id: Some(message_id),
1376            ..self
1377        }
1378    }
1379    /// Allow sending message even if the replying message isn't present
1380    pub fn allow_sending_without_reply(self) -> Self {
1381        Self {
1382            allow_sending_without_reply: Some(true),
1383            ..self
1384        }
1385    }
1386    /// Set reply markup
1387    pub fn with_reply_markup(self, markup: impl Into<ReplyMarkup>) -> Self {
1388        Self {
1389            reply_markup: Some(markup.into()),
1390            ..self
1391        }
1392    }
1393    /// Protect content
1394    pub fn protect_content(self) -> Self {
1395        Self {
1396            protect_content: Some(true),
1397            ..self
1398        }
1399    }
1400}
1401
1402impl TelegramMethod for SendPhoto {
1403    type Response = Message;
1404
1405    fn name() -> &'static str {
1406        "sendPhoto"
1407    }
1408}
1409
1410impl FileMethod for SendPhoto {
1411    fn files(&self) -> Option<HashMap<&str, &InputFile>> {
1412        if let InputFileVariant::File(file) = &self.photo {
1413            let mut map = HashMap::new();
1414            map.insert("photo", file);
1415            Some(map)
1416        } else {
1417            None
1418        }
1419    }
1420}
1421
1422/// Use this method to send audio files, if you want Telegram clients to display them in the music player.
1423/// Your audio must be in the .MP3 or .M4A format.
1424/// On success, the sent [Message](https://core.telegram.org/bots/api#message) is returned.
1425// Bots can currently send audio files of up to 50 MB in size, this limit may be changed in the future.
1426///
1427/// For sending voice messages, use the sendVoice method instead.
1428#[derive(Clone, Serialize)]
1429pub struct SendAudio {
1430    /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1431    pub chat_id: ChatId,
1432    /// Audio file to send.
1433    /// Pass a file_id as String to send an audio file that exists on the Telegram servers (recommended),
1434    /// pass an HTTP URL as a String for Telegram to get an audio file from the Internet,
1435    /// or upload a new one using multipart/form-data.
1436    /// [More info on Sending Files »](https://core.telegram.org/bots/api#sending-files)
1437    pub audio: InputFileVariant,
1438    /// Duration of the audio in seconds
1439    #[serde(skip_serializing_if = "Option::is_none")]
1440    pub duration: Option<u32>,
1441    /// Performer
1442    #[serde(skip_serializing_if = "Option::is_none")]
1443    pub performer: Option<String>,
1444    /// Track name
1445    #[serde(skip_serializing_if = "Option::is_none")]
1446    pub title: Option<String>,
1447    /// Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side.
1448    /// The thumbnail should be in JPEG format and less than 200 kB in size.
1449    /// A thumbnail's width and height should not exceed 320.
1450    /// Ignored if the file is not uploaded using multipart/form-data.
1451    /// Thumbnails can't be reused and can be only uploaded as a new file, so you can pass “attach://<file_attach_name>” if the thumbnail was uploaded using multipart/form-data under <file_attach_name>.
1452    #[serde(skip_serializing_if = "Option::is_none")]
1453    pub thumb: Option<InputFileVariant>,
1454    /// Audio caption, 0-1024 characters after entities parsing
1455    #[serde(skip_serializing_if = "Option::is_none")]
1456    pub caption: Option<String>,
1457    /// Mode for parsing entities in the message text.
1458    /// See [formatting options](https://core.telegram.org/bots/api#formatting-options) for more details.
1459    #[serde(skip_serializing_if = "Option::is_none")]
1460    pub parse_mode: Option<ParseMode>,
1461    /// List of special entities that appear in the caption, which can be specified instead of *parse_mode*
1462    #[serde(skip_serializing_if = "Option::is_none")]
1463    pub caption_entities: Option<Vec<MessageEntity>>,
1464    /// Sends the message [silently](https://telegram.org/blog/channels-2-0#silent-messages).
1465    /// Users will receive a notification with no sound.
1466    #[serde(skip_serializing_if = "Option::is_none")]
1467    pub disable_notification: Option<bool>,
1468    /// If the message is a reply, ID of the original message
1469    #[serde(skip_serializing_if = "Option::is_none")]
1470    pub reply_to_message_id: Option<i64>,
1471    /// Pass *True*, if the message should be sent even if the specified replied-to message is not found
1472    #[serde(skip_serializing_if = "Option::is_none")]
1473    pub allow_sending_without_reply: Option<bool>,
1474    /// Additional interface options.
1475    /// A JSON-serialized object for an [inline keyboard](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating),
1476    /// [custom reply keyboard](https://core.telegram.org/bots#keyboards),
1477    /// instructions to remove reply keyboard or to force a reply from the user.
1478    #[serde(skip_serializing_if = "Option::is_none")]
1479    pub reply_markup: Option<ReplyMarkup>,
1480    /// Protects the contents of the sent message from forwarding and saving
1481    #[serde(skip_serializing_if = "Option::is_none")]
1482    pub protect_content: Option<bool>,
1483}
1484
1485impl SendAudio {
1486    /// Create a new sendAudio request
1487    pub fn new(chat_id: impl Into<ChatId>, audio: impl Into<InputFileVariant>) -> Self {
1488        Self {
1489            chat_id: chat_id.into(),
1490            audio: audio.into(),
1491            duration: None,
1492            performer: None,
1493            title: None,
1494            thumb: None,
1495            caption: None,
1496            parse_mode: None,
1497            caption_entities: None,
1498            disable_notification: None,
1499            reply_to_message_id: None,
1500            allow_sending_without_reply: None,
1501            reply_markup: None,
1502            protect_content: None,
1503        }
1504    }
1505    /// Set duration
1506    pub fn with_duration(self, duration: u32) -> Self {
1507        Self {
1508            duration: Some(duration),
1509            ..self
1510        }
1511    }
1512    /// Set performer
1513    pub fn with_performer(self, performer: impl Into<String>) -> Self {
1514        Self {
1515            performer: Some(performer.into()),
1516            ..self
1517        }
1518    }
1519    /// Set title
1520    pub fn with_title(self, title: impl Into<String>) -> Self {
1521        Self {
1522            title: Some(title.into()),
1523            ..self
1524        }
1525    }
1526    /// Set thumbnail
1527    pub fn with_thumbnail(self, thumbnail: impl Into<InputFileVariant>) -> Self {
1528        Self {
1529            thumb: Some(thumbnail.into()),
1530            ..self
1531        }
1532    }
1533    /// Set caption
1534    pub fn with_caption(self, caption: impl Into<String>) -> Self {
1535        Self {
1536            caption: Some(caption.into()),
1537            ..self
1538        }
1539    }
1540    /// Set parse mode
1541    pub fn with_parse_mode(self, parse_mode: ParseMode) -> Self {
1542        Self {
1543            parse_mode: Some(parse_mode),
1544            ..self
1545        }
1546    }
1547    /// Set caption entities
1548    pub fn with_entities(self, entities: Vec<MessageEntity>) -> Self {
1549        Self {
1550            caption_entities: Some(entities),
1551            ..self
1552        }
1553    }
1554    /// Add one entity
1555    pub fn with_entity(mut self, entity: MessageEntity) -> Self {
1556        let entities = self.caption_entities.get_or_insert_with(Default::default);
1557        entities.push(entity);
1558        self
1559    }
1560    /// Disable notification
1561    pub fn disable_notification(self) -> Self {
1562        Self {
1563            disable_notification: Some(true),
1564            ..self
1565        }
1566    }
1567    /// Reply to message
1568    pub fn reply_to(self, message_id: i64) -> Self {
1569        Self {
1570            reply_to_message_id: Some(message_id),
1571            ..self
1572        }
1573    }
1574    /// Allow sending message even if the replying message isn't present
1575    pub fn allow_sending_without_reply(self) -> Self {
1576        Self {
1577            allow_sending_without_reply: Some(true),
1578            ..self
1579        }
1580    }
1581    /// Set reply markup
1582    pub fn with_reply_markup(self, markup: impl Into<ReplyMarkup>) -> Self {
1583        Self {
1584            reply_markup: Some(markup.into()),
1585            ..self
1586        }
1587    }
1588    /// Protect content
1589    pub fn protect_content(self) -> Self {
1590        Self {
1591            protect_content: Some(true),
1592            ..self
1593        }
1594    }
1595}
1596
1597impl TelegramMethod for SendAudio {
1598    type Response = Message;
1599
1600    fn name() -> &'static str {
1601        "sendAudio"
1602    }
1603}
1604
1605impl FileMethod for SendAudio {
1606    fn files(&self) -> Option<HashMap<&str, &InputFile>> {
1607        let mut map = HashMap::new();
1608        if let InputFileVariant::File(file) = &self.audio {
1609            map.insert("audio", file);
1610        }
1611        if let Some(InputFileVariant::File(file)) = &self.thumb {
1612            map.insert("thumb", file);
1613        }
1614        if map.is_empty() {
1615            None
1616        } else {
1617            Some(map)
1618        }
1619    }
1620}
1621
1622/// Use this method to send general files. On success, the sent Message is returned.
1623/// Bots can currently send files of any type of up to 50 MB in size, this limit may be changed in the future.
1624#[derive(Clone, Serialize)]
1625pub struct SendDocument {
1626    /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1627    pub chat_id: ChatId,
1628    /// File to send. Pass a file_id as String to send a file that exists on the Telegram servers (recommended),
1629    /// pass an HTTP URL as a String for Telegram to get a file from the Internet,
1630    /// or upload a new one using multipart/form-data.
1631    /// [More info on Sending Files »](https://core.telegram.org/bots/api#sending-files)
1632    pub document: InputFileVariant,
1633    /// Disables automatic server-side content type detection for files uploaded using multipart/form-data
1634    #[serde(skip_serializing_if = "Option::is_none")]
1635    pub disable_content_type_detection: Option<bool>,
1636    /// Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side.
1637    /// The thumbnail should be in JPEG format and less than 200 kB in size.
1638    /// A thumbnail's width and height should not exceed 320.
1639    /// Ignored if the file is not uploaded using multipart/form-data.
1640    /// Thumbnails can't be reused and can be only uploaded as a new file, so you can pass “attach://<file_attach_name>” if the thumbnail was uploaded using multipart/form-data under <file_attach_name>.
1641    #[serde(skip_serializing_if = "Option::is_none")]
1642    pub thumb: Option<InputFileVariant>,
1643    /// Document caption (may also be used when resending documents by file_id), 0-1024 characters after entities parsing
1644    #[serde(skip_serializing_if = "Option::is_none")]
1645    pub caption: Option<String>,
1646    /// Mode for parsing entities in the message text.
1647    /// See [formatting options](https://core.telegram.org/bots/api#formatting-options) for more details.
1648    #[serde(skip_serializing_if = "Option::is_none")]
1649    pub parse_mode: Option<ParseMode>,
1650    /// List of special entities that appear in the caption, which can be specified instead of *parse_mode*
1651    #[serde(skip_serializing_if = "Option::is_none")]
1652    pub caption_entities: Option<Vec<MessageEntity>>,
1653    /// Sends the message [silently](https://telegram.org/blog/channels-2-0#silent-messages).
1654    /// Users will receive a notification with no sound.
1655    #[serde(skip_serializing_if = "Option::is_none")]
1656    pub disable_notification: Option<bool>,
1657    /// If the message is a reply, ID of the original message
1658    #[serde(skip_serializing_if = "Option::is_none")]
1659    pub reply_to_message_id: Option<i64>,
1660    /// Pass *True*, if the message should be sent even if the specified replied-to message is not found
1661    #[serde(skip_serializing_if = "Option::is_none")]
1662    pub allow_sending_without_reply: Option<bool>,
1663    /// Additional interface options.
1664    /// A JSON-serialized object for an [inline keyboard](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating),
1665    /// [custom reply keyboard](https://core.telegram.org/bots#keyboards),
1666    /// instructions to remove reply keyboard or to force a reply from the user.
1667    #[serde(skip_serializing_if = "Option::is_none")]
1668    pub reply_markup: Option<ReplyMarkup>,
1669    /// Protects the contents of the sent message from forwarding and saving
1670    #[serde(skip_serializing_if = "Option::is_none")]
1671    pub protect_content: Option<bool>,
1672}
1673
1674impl SendDocument {
1675    /// Create a new sendDocument request
1676    pub fn new(chat_id: impl Into<ChatId>, document: impl Into<InputFileVariant>) -> Self {
1677        Self {
1678            chat_id: chat_id.into(),
1679            document: document.into(),
1680            disable_content_type_detection: None,
1681            thumb: None,
1682            caption: None,
1683            parse_mode: None,
1684            caption_entities: None,
1685            disable_notification: None,
1686            reply_to_message_id: None,
1687            allow_sending_without_reply: None,
1688            reply_markup: None,
1689            protect_content: None,
1690        }
1691    }
1692    /// Set thumbnail
1693    pub fn with_thumbnail(self, thumbnail: impl Into<InputFileVariant>) -> Self {
1694        Self {
1695            thumb: Some(thumbnail.into()),
1696            ..self
1697        }
1698    }
1699    /// Disable file type detection
1700    pub fn disable_content_type_detection(self) -> Self {
1701        Self {
1702            disable_content_type_detection: Some(true),
1703            ..self
1704        }
1705    }
1706    /// Set caption
1707    pub fn with_caption(self, caption: impl Into<String>) -> Self {
1708        Self {
1709            caption: Some(caption.into()),
1710            ..self
1711        }
1712    }
1713    /// Set parse mode
1714    pub fn with_parse_mode(self, parse_mode: ParseMode) -> Self {
1715        Self {
1716            parse_mode: Some(parse_mode),
1717            ..self
1718        }
1719    }
1720    /// Set caption entities
1721    pub fn with_entities(self, entities: Vec<MessageEntity>) -> Self {
1722        Self {
1723            caption_entities: Some(entities),
1724            ..self
1725        }
1726    }
1727    /// Add one entity
1728    pub fn with_entity(mut self, entity: MessageEntity) -> Self {
1729        let entities = self.caption_entities.get_or_insert_with(Default::default);
1730        entities.push(entity);
1731        self
1732    }
1733    /// Disable notification
1734    pub fn disable_notification(self) -> Self {
1735        Self {
1736            disable_notification: Some(true),
1737            ..self
1738        }
1739    }
1740    /// Reply to message
1741    pub fn reply_to(self, message_id: i64) -> Self {
1742        Self {
1743            reply_to_message_id: Some(message_id),
1744            ..self
1745        }
1746    }
1747    /// Allow sending message even if the replying message isn't present
1748    pub fn allow_sending_without_reply(self) -> Self {
1749        Self {
1750            allow_sending_without_reply: Some(true),
1751            ..self
1752        }
1753    }
1754    /// Set reply markup
1755    pub fn with_reply_markup(self, markup: impl Into<ReplyMarkup>) -> Self {
1756        Self {
1757            reply_markup: Some(markup.into()),
1758            ..self
1759        }
1760    }
1761    /// Protect content
1762    pub fn protect_content(self) -> Self {
1763        Self {
1764            protect_content: Some(true),
1765            ..self
1766        }
1767    }
1768}
1769
1770impl TelegramMethod for SendDocument {
1771    type Response = Message;
1772
1773    fn name() -> &'static str {
1774        "sendDocument"
1775    }
1776}
1777
1778impl FileMethod for SendDocument {
1779    fn files(&self) -> Option<HashMap<&str, &InputFile>> {
1780        let mut map = HashMap::new();
1781        if let InputFileVariant::File(file) = &self.document {
1782            map.insert("document", file);
1783        }
1784        if let Some(InputFileVariant::File(file)) = &self.thumb {
1785            map.insert("thumb", file);
1786        }
1787        if map.is_empty() {
1788            None
1789        } else {
1790            Some(map)
1791        }
1792    }
1793}
1794
1795/// Use this method to send video files, Telegram clients support mp4 videos (other formats may be sent as [Document](https://core.telegram.org/bots/api#document)).
1796/// On success, the sent [Message](https://core.telegram.org/bots/api#message) is returned.
1797/// Bots can currently send video files of up to 50 MB in size, this limit may be changed in the future.
1798#[derive(Clone, Serialize)]
1799pub struct SendVideo {
1800    /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
1801    pub chat_id: ChatId,
1802    /// Video to send. Pass a file_id as String to send a video that exists on the Telegram servers (recommended),
1803    /// pass an HTTP URL as a String for Telegram to get a video from the Internet,
1804    /// or upload a new video using multipart/form-data.
1805    /// [More info on Sending Files »](https://core.telegram.org/bots/api#sending-files)
1806    pub video: InputFileVariant,
1807    /// Duration of sent video in seconds
1808    #[serde(skip_serializing_if = "Option::is_none")]
1809    pub duration: Option<u32>,
1810    /// Video width
1811    #[serde(skip_serializing_if = "Option::is_none")]
1812    pub width: Option<u32>,
1813    /// Video height
1814    #[serde(skip_serializing_if = "Option::is_none")]
1815    pub height: Option<u32>,
1816    /// Pass *True*, if the uploaded video is suitable for streaming
1817    #[serde(skip_serializing_if = "Option::is_none")]
1818    pub supports_streaming: Option<bool>,
1819    /// Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side.
1820    /// The thumbnail should be in JPEG format and less than 200 kB in size.
1821    /// A thumbnail's width and height should not exceed 320.
1822    /// Ignored if the file is not uploaded using multipart/form-data.
1823    /// Thumbnails can't be reused and can be only uploaded as a new file, so you can pass “attach://<file_attach_name>” if the thumbnail was uploaded using multipart/form-data under <file_attach_name>.
1824    #[serde(skip_serializing_if = "Option::is_none")]
1825    pub thumb: Option<InputFileVariant>,
1826    /// Video caption (may also be used when resending videos by *file_id*), 0-1024 characters after entities parsing
1827    #[serde(skip_serializing_if = "Option::is_none")]
1828    pub caption: Option<String>,
1829    /// Mode for parsing entities in the message text.
1830    /// See [formatting options](https://core.telegram.org/bots/api#formatting-options) for more details.
1831    #[serde(skip_serializing_if = "Option::is_none")]
1832    pub parse_mode: Option<ParseMode>,
1833    /// List of special entities that appear in the caption, which can be specified instead of *parse_mode*
1834    #[serde(skip_serializing_if = "Option::is_none")]
1835    pub caption_entities: Option<Vec<MessageEntity>>,
1836    /// Sends the message [silently](https://telegram.org/blog/channels-2-0#silent-messages).
1837    /// Users will receive a notification with no sound.
1838    #[serde(skip_serializing_if = "Option::is_none")]
1839    pub disable_notification: Option<bool>,
1840    /// If the message is a reply, ID of the original message
1841    #[serde(skip_serializing_if = "Option::is_none")]
1842    pub reply_to_message_id: Option<i64>,
1843    /// Pass *True*, if the message should be sent even if the specified replied-to message is not found
1844    #[serde(skip_serializing_if = "Option::is_none")]
1845    pub allow_sending_without_reply: Option<bool>,
1846    /// Additional interface options.
1847    /// A JSON-serialized object for an [inline keyboard](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating),
1848    /// [custom reply keyboard](https://core.telegram.org/bots#keyboards),
1849    /// instructions to remove reply keyboard or to force a reply from the user.
1850    #[serde(skip_serializing_if = "Option::is_none")]
1851    pub reply_markup: Option<ReplyMarkup>,
1852    /// Protects the contents of the sent message from forwarding and saving
1853    #[serde(skip_serializing_if = "Option::is_none")]
1854    pub protect_content: Option<bool>,
1855}
1856
1857impl SendVideo {
1858    /// Create a new sendVideo request
1859    pub fn new(chat_id: impl Into<ChatId>, video: impl Into<InputFileVariant>) -> Self {
1860        Self {
1861            chat_id: chat_id.into(),
1862            video: video.into(),
1863            duration: None,
1864            width: None,
1865            height: None,
1866            supports_streaming: None,
1867            thumb: None,
1868            caption: None,
1869            parse_mode: None,
1870            caption_entities: None,
1871            disable_notification: None,
1872            reply_to_message_id: None,
1873            allow_sending_without_reply: None,
1874            reply_markup: None,
1875            protect_content: None,
1876        }
1877    }
1878    /// Set duration
1879    pub fn with_duration(self, duration: u32) -> Self {
1880        Self {
1881            duration: Some(duration),
1882            ..self
1883        }
1884    }
1885    /// Set width
1886    pub fn with_width(self, width: u32) -> Self {
1887        Self {
1888            width: Some(width),
1889            ..self
1890        }
1891    }
1892    /// Set height
1893    pub fn with_height(self, height: u32) -> Self {
1894        Self {
1895            height: Some(height),
1896            ..self
1897        }
1898    }
1899    /// Set as streaming video
1900    pub fn set_streaming(self) -> Self {
1901        Self {
1902            supports_streaming: Some(true),
1903            ..self
1904        }
1905    }
1906    /// Set thumbnail
1907    pub fn with_thumbnail(self, thumbnail: impl Into<InputFileVariant>) -> Self {
1908        Self {
1909            thumb: Some(thumbnail.into()),
1910            ..self
1911        }
1912    }
1913    /// Set caption
1914    pub fn with_caption(self, caption: impl Into<String>) -> Self {
1915        Self {
1916            caption: Some(caption.into()),
1917            ..self
1918        }
1919    }
1920    /// Set parse mode
1921    pub fn with_parse_mode(self, parse_mode: ParseMode) -> Self {
1922        Self {
1923            parse_mode: Some(parse_mode),
1924            ..self
1925        }
1926    }
1927    /// Set caption entities
1928    pub fn with_entities(self, entities: Vec<MessageEntity>) -> Self {
1929        Self {
1930            caption_entities: Some(entities),
1931            ..self
1932        }
1933    }
1934    /// Add one entity
1935    pub fn with_entity(mut self, entity: MessageEntity) -> Self {
1936        let entities = self.caption_entities.get_or_insert_with(Default::default);
1937        entities.push(entity);
1938        self
1939    }
1940    /// Disable notification
1941    pub fn disable_notification(self) -> Self {
1942        Self {
1943            disable_notification: Some(true),
1944            ..self
1945        }
1946    }
1947    /// Reply to message
1948    pub fn reply_to(self, message_id: i64) -> Self {
1949        Self {
1950            reply_to_message_id: Some(message_id),
1951            ..self
1952        }
1953    }
1954    /// Allow sending message even if the replying message isn't present
1955    pub fn allow_sending_without_reply(self) -> Self {
1956        Self {
1957            allow_sending_without_reply: Some(true),
1958            ..self
1959        }
1960    }
1961    /// Set reply markup
1962    pub fn with_reply_markup(self, markup: impl Into<ReplyMarkup>) -> Self {
1963        Self {
1964            reply_markup: Some(markup.into()),
1965            ..self
1966        }
1967    }
1968    /// Protect content
1969    pub fn protect_content(self) -> Self {
1970        Self {
1971            protect_content: Some(true),
1972            ..self
1973        }
1974    }
1975}
1976
1977impl TelegramMethod for SendVideo {
1978    type Response = Message;
1979
1980    fn name() -> &'static str {
1981        "sendVideo"
1982    }
1983}
1984
1985impl FileMethod for SendVideo {
1986    fn files(&self) -> Option<HashMap<&str, &InputFile>> {
1987        let mut map = HashMap::new();
1988        if let InputFileVariant::File(file) = &self.video {
1989            map.insert("video", file);
1990        }
1991        if let Some(InputFileVariant::File(file)) = &self.thumb {
1992            map.insert("thumb", file);
1993        }
1994        if map.is_empty() {
1995            None
1996        } else {
1997            Some(map)
1998        }
1999    }
2000}
2001
2002/// Use this method to send animation files (GIF or H.264/MPEG-4 AVC video without sound).
2003/// On success, the sent [Message](https://core.telegram.org/bots/api#message) is returned.
2004/// Bots can currently send video files of up to 50 MB in size, this limit may be changed in the future.
2005#[derive(Clone, Serialize)]
2006pub struct SendAnimation {
2007    /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
2008    pub chat_id: ChatId,
2009    /// Animation to send. Pass a file_id as String to send an animation that exists on the Telegram servers (recommended),
2010    /// pass an HTTP URL as a String for Telegram to get a video from the Internet,
2011    /// or upload a new video using multipart/form-data.
2012    /// [More info on Sending Files »](https://core.telegram.org/bots/api#sending-files)
2013    pub animation: InputFileVariant,
2014    /// Duration of sent animation in seconds
2015    #[serde(skip_serializing_if = "Option::is_none")]
2016    pub duration: Option<u32>,
2017    /// Animation width
2018    #[serde(skip_serializing_if = "Option::is_none")]
2019    pub width: Option<u32>,
2020    /// Animation height
2021    #[serde(skip_serializing_if = "Option::is_none")]
2022    pub height: Option<u32>,
2023    /// Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side.
2024    /// The thumbnail should be in JPEG format and less than 200 kB in size.
2025    /// A thumbnail's width and height should not exceed 320.
2026    /// Ignored if the file is not uploaded using multipart/form-data.
2027    /// Thumbnails can't be reused and can be only uploaded as a new file, so you can pass “attach://<file_attach_name>” if the thumbnail was uploaded using multipart/form-data under <file_attach_name>.
2028    #[serde(skip_serializing_if = "Option::is_none")]
2029    pub thumb: Option<InputFileVariant>,
2030    /// Video caption (may also be used when resending videos by *file_id*), 0-1024 characters after entities parsing
2031    #[serde(skip_serializing_if = "Option::is_none")]
2032    pub caption: Option<String>,
2033    /// Mode for parsing entities in the message text.
2034    /// See [formatting options](https://core.telegram.org/bots/api#formatting-options) for more details.
2035    #[serde(skip_serializing_if = "Option::is_none")]
2036    pub parse_mode: Option<ParseMode>,
2037    /// List of special entities that appear in the caption, which can be specified instead of *parse_mode*
2038    #[serde(skip_serializing_if = "Option::is_none")]
2039    pub caption_entities: Option<Vec<MessageEntity>>,
2040    /// Sends the message [silently](https://telegram.org/blog/channels-2-0#silent-messages).
2041    /// Users will receive a notification with no sound.
2042    #[serde(skip_serializing_if = "Option::is_none")]
2043    pub disable_notification: Option<bool>,
2044    /// If the message is a reply, ID of the original message
2045    #[serde(skip_serializing_if = "Option::is_none")]
2046    pub reply_to_message_id: Option<i64>,
2047    /// Pass *True*, if the message should be sent even if the specified replied-to message is not found
2048    #[serde(skip_serializing_if = "Option::is_none")]
2049    pub allow_sending_without_reply: Option<bool>,
2050    /// Additional interface options.
2051    /// A JSON-serialized object for an [inline keyboard](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating),
2052    /// [custom reply keyboard](https://core.telegram.org/bots#keyboards),
2053    /// instructions to remove reply keyboard or to force a reply from the user.
2054    #[serde(skip_serializing_if = "Option::is_none")]
2055    pub reply_markup: Option<ReplyMarkup>,
2056    /// Protects the contents of the sent message from forwarding and saving
2057    #[serde(skip_serializing_if = "Option::is_none")]
2058    pub protect_content: Option<bool>,
2059}
2060
2061impl SendAnimation {
2062    /// Create a new sendAnimation request
2063    pub fn new(chat_id: impl Into<ChatId>, animation: impl Into<InputFileVariant>) -> Self {
2064        Self {
2065            chat_id: chat_id.into(),
2066            animation: animation.into(),
2067            duration: None,
2068            width: None,
2069            height: None,
2070            thumb: None,
2071            caption: None,
2072            parse_mode: None,
2073            caption_entities: None,
2074            disable_notification: None,
2075            reply_to_message_id: None,
2076            allow_sending_without_reply: None,
2077            reply_markup: None,
2078            protect_content: None,
2079        }
2080    }
2081    /// Set duration
2082    pub fn with_duration(self, duration: u32) -> Self {
2083        Self {
2084            duration: Some(duration),
2085            ..self
2086        }
2087    }
2088    /// Set width
2089    pub fn with_width(self, width: u32) -> Self {
2090        Self {
2091            width: Some(width),
2092            ..self
2093        }
2094    }
2095    /// Set height
2096    pub fn with_height(self, height: u32) -> Self {
2097        Self {
2098            height: Some(height),
2099            ..self
2100        }
2101    }
2102    /// Set thumbnail
2103    pub fn with_thumbnail(self, thumbnail: impl Into<InputFileVariant>) -> Self {
2104        Self {
2105            thumb: Some(thumbnail.into()),
2106            ..self
2107        }
2108    }
2109    /// Set caption
2110    pub fn with_caption(self, caption: impl Into<String>) -> Self {
2111        Self {
2112            caption: Some(caption.into()),
2113            ..self
2114        }
2115    }
2116    /// Set parse mode
2117    pub fn with_parse_mode(self, parse_mode: ParseMode) -> Self {
2118        Self {
2119            parse_mode: Some(parse_mode),
2120            ..self
2121        }
2122    }
2123    /// Set caption entities
2124    pub fn with_entities(self, entities: Vec<MessageEntity>) -> Self {
2125        Self {
2126            caption_entities: Some(entities),
2127            ..self
2128        }
2129    }
2130    /// Add one entity
2131    pub fn with_entity(mut self, entity: MessageEntity) -> Self {
2132        let entities = self.caption_entities.get_or_insert_with(Default::default);
2133        entities.push(entity);
2134        self
2135    }
2136    /// Disable notification
2137    pub fn disable_notification(self) -> Self {
2138        Self {
2139            disable_notification: Some(true),
2140            ..self
2141        }
2142    }
2143    /// Reply to message
2144    pub fn reply_to(self, message_id: i64) -> Self {
2145        Self {
2146            reply_to_message_id: Some(message_id),
2147            ..self
2148        }
2149    }
2150    /// Allow sending message even if the replying message isn't present
2151    pub fn allow_sending_without_reply(self) -> Self {
2152        Self {
2153            allow_sending_without_reply: Some(true),
2154            ..self
2155        }
2156    }
2157    /// Set reply markup
2158    pub fn with_reply_markup(self, markup: impl Into<ReplyMarkup>) -> Self {
2159        Self {
2160            reply_markup: Some(markup.into()),
2161            ..self
2162        }
2163    }
2164    /// Protect content
2165    pub fn protect_content(self) -> Self {
2166        Self {
2167            protect_content: Some(true),
2168            ..self
2169        }
2170    }
2171}
2172
2173impl TelegramMethod for SendAnimation {
2174    type Response = Message;
2175
2176    fn name() -> &'static str {
2177        "sendAnimation"
2178    }
2179}
2180
2181impl FileMethod for SendAnimation {
2182    fn files(&self) -> Option<HashMap<&str, &InputFile>> {
2183        let mut map = HashMap::new();
2184        if let InputFileVariant::File(file) = &self.animation {
2185            map.insert("animation", file);
2186        }
2187        if let Some(InputFileVariant::File(file)) = &self.thumb {
2188            map.insert("thumb", file);
2189        }
2190        if map.is_empty() {
2191            None
2192        } else {
2193            Some(map)
2194        }
2195    }
2196}
2197
2198/// Use this method to send audio files, if you want Telegram clients to display the file as a playable voice message.
2199/// For this to work, your audio must be in an .OGG file encoded with OPUS
2200/// (other formats may be sent as [Audio](https://core.telegram.org/bots/api#audio) or [Document](https://core.telegram.org/bots/api#document)).
2201/// On success, the sent [Message](https://core.telegram.org/bots/api#message) is returned.
2202/// Bots can currently send video files of up to 50 MB in size, this limit may be changed in the future.
2203#[derive(Clone, Serialize)]
2204pub struct SendVoice {
2205    /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
2206    pub chat_id: ChatId,
2207    /// Audio file to send. Pass a file_id as String to send a file that exists on the Telegram servers (recommended),
2208    /// pass an HTTP URL as a String for Telegram to get a video from the Internet,
2209    /// or upload a new video using multipart/form-data.
2210    /// [More info on Sending Files »](https://core.telegram.org/bots/api#sending-files)
2211    pub voice: InputFileVariant,
2212    /// Duration of the voice message in seconds
2213    #[serde(skip_serializing_if = "Option::is_none")]
2214    pub duration: Option<u32>,
2215    /// Video caption (may also be used when resending videos by *file_id*), 0-1024 characters after entities parsing
2216    #[serde(skip_serializing_if = "Option::is_none")]
2217    pub caption: Option<String>,
2218    /// Mode for parsing entities in the message text.
2219    /// See [formatting options](https://core.telegram.org/bots/api#formatting-options) for more details.
2220    #[serde(skip_serializing_if = "Option::is_none")]
2221    pub parse_mode: Option<ParseMode>,
2222    /// List of special entities that appear in the caption, which can be specified instead of *parse_mode*
2223    #[serde(skip_serializing_if = "Option::is_none")]
2224    pub caption_entities: Option<Vec<MessageEntity>>,
2225    /// Sends the message [silently](https://telegram.org/blog/channels-2-0#silent-messages).
2226    /// Users will receive a notification with no sound.
2227    #[serde(skip_serializing_if = "Option::is_none")]
2228    pub disable_notification: Option<bool>,
2229    /// If the message is a reply, ID of the original message
2230    #[serde(skip_serializing_if = "Option::is_none")]
2231    pub reply_to_message_id: Option<i64>,
2232    /// Pass *True*, if the message should be sent even if the specified replied-to message is not found
2233    #[serde(skip_serializing_if = "Option::is_none")]
2234    pub allow_sending_without_reply: Option<bool>,
2235    /// Additional interface options.
2236    /// A JSON-serialized object for an [inline keyboard](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating),
2237    /// [custom reply keyboard](https://core.telegram.org/bots#keyboards),
2238    /// instructions to remove reply keyboard or to force a reply from the user.
2239    #[serde(skip_serializing_if = "Option::is_none")]
2240    pub reply_markup: Option<ReplyMarkup>,
2241    /// Protects the contents of the sent message from forwarding and saving
2242    #[serde(skip_serializing_if = "Option::is_none")]
2243    pub protect_content: Option<bool>,
2244}
2245
2246impl SendVoice {
2247    /// Create a new sendVoice request
2248    pub fn new(chat_id: impl Into<ChatId>, voice: impl Into<InputFileVariant>) -> Self {
2249        Self {
2250            chat_id: chat_id.into(),
2251            voice: voice.into(),
2252            duration: None,
2253            caption: None,
2254            parse_mode: None,
2255            caption_entities: None,
2256            disable_notification: None,
2257            reply_to_message_id: None,
2258            allow_sending_without_reply: None,
2259            reply_markup: None,
2260            protect_content: None,
2261        }
2262    }
2263    /// Set duration
2264    pub fn with_duration(self, duration: u32) -> Self {
2265        Self {
2266            duration: Some(duration),
2267            ..self
2268        }
2269    }
2270    /// Set caption
2271    pub fn with_caption(self, caption: impl Into<String>) -> Self {
2272        Self {
2273            caption: Some(caption.into()),
2274            ..self
2275        }
2276    }
2277    /// Set parse mode
2278    pub fn with_parse_mode(self, parse_mode: ParseMode) -> Self {
2279        Self {
2280            parse_mode: Some(parse_mode),
2281            ..self
2282        }
2283    }
2284    /// Set caption entities
2285    pub fn with_entities(self, entities: Vec<MessageEntity>) -> Self {
2286        Self {
2287            caption_entities: Some(entities),
2288            ..self
2289        }
2290    }
2291    /// Add one entity
2292    pub fn with_entity(mut self, entity: MessageEntity) -> Self {
2293        let entities = self.caption_entities.get_or_insert_with(Default::default);
2294        entities.push(entity);
2295        self
2296    }
2297    /// Disable notification
2298    pub fn disable_notification(self) -> Self {
2299        Self {
2300            disable_notification: Some(true),
2301            ..self
2302        }
2303    }
2304    /// Reply to message
2305    pub fn reply_to(self, message_id: i64) -> Self {
2306        Self {
2307            reply_to_message_id: Some(message_id),
2308            ..self
2309        }
2310    }
2311    /// Allow sending message even if the replying message isn't present
2312    pub fn allow_sending_without_reply(self) -> Self {
2313        Self {
2314            allow_sending_without_reply: Some(true),
2315            ..self
2316        }
2317    }
2318    /// Set reply markup
2319    pub fn with_reply_markup(self, markup: impl Into<ReplyMarkup>) -> Self {
2320        Self {
2321            reply_markup: Some(markup.into()),
2322            ..self
2323        }
2324    }
2325    /// Protect content
2326    pub fn protect_content(self) -> Self {
2327        Self {
2328            protect_content: Some(true),
2329            ..self
2330        }
2331    }
2332}
2333
2334impl TelegramMethod for SendVoice {
2335    type Response = Message;
2336
2337    fn name() -> &'static str {
2338        "sendVoice"
2339    }
2340}
2341
2342impl FileMethod for SendVoice {
2343    fn files(&self) -> Option<HashMap<&str, &InputFile>> {
2344        if let InputFileVariant::File(file) = &self.voice {
2345            let mut map = HashMap::new();
2346            map.insert("voice", file);
2347            Some(map)
2348        } else {
2349            None
2350        }
2351    }
2352}
2353
2354/// As of [v.4.0](https://telegram.org/blog/video-messages-and-telescope), Telegram clients support rounded square mp4 videos of up to 1 minute long.
2355/// Use this method to send video messages.
2356/// On success, the sent [Message](https://core.telegram.org/bots/api#message) is returned.
2357#[derive(Clone, Serialize)]
2358pub struct SendVideoNote {
2359    /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
2360    pub chat_id: ChatId,
2361    /// Video note to send. Pass a file_id as String to send a video note that exists on the Telegram servers (recommended)
2362    /// or upload a new video using multipart/form-data.
2363    /// [More info on Sending Files »](https://core.telegram.org/bots/api#sending-files)
2364    /// Sending video notes by a URL is currently unsupported
2365    pub video_note: InputFileVariant,
2366    /// Duration of sent video in seconds
2367    #[serde(skip_serializing_if = "Option::is_none")]
2368    pub duration: Option<u32>,
2369    /// Video width and height, i.e. diameter of the video message
2370    #[serde(skip_serializing_if = "Option::is_none")]
2371    pub length: Option<u32>,
2372    /// Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side.
2373    /// The thumbnail should be in JPEG format and less than 200 kB in size.
2374    /// A thumbnail's width and height should not exceed 320.
2375    /// Ignored if the file is not uploaded using multipart/form-data.
2376    /// Thumbnails can't be reused and can be only uploaded as a new file, so you can pass “attach://<file_attach_name>” if the thumbnail was uploaded using multipart/form-data under <file_attach_name>.
2377    #[serde(skip_serializing_if = "Option::is_none")]
2378    pub thumb: Option<InputFileVariant>,
2379    /// Sends the message [silently](https://telegram.org/blog/channels-2-0#silent-messages).
2380    /// Users will receive a notification with no sound.
2381    #[serde(skip_serializing_if = "Option::is_none")]
2382    pub disable_notification: Option<bool>,
2383    /// If the message is a reply, ID of the original message
2384    #[serde(skip_serializing_if = "Option::is_none")]
2385    pub reply_to_message_id: Option<i64>,
2386    /// Pass *True*, if the message should be sent even if the specified replied-to message is not found
2387    #[serde(skip_serializing_if = "Option::is_none")]
2388    pub allow_sending_without_reply: Option<bool>,
2389    /// Additional interface options.
2390    /// A JSON-serialized object for an [inline keyboard](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating),
2391    /// [custom reply keyboard](https://core.telegram.org/bots#keyboards),
2392    /// instructions to remove reply keyboard or to force a reply from the user.
2393    #[serde(skip_serializing_if = "Option::is_none")]
2394    pub reply_markup: Option<ReplyMarkup>,
2395    // Protects the contents of the sent message from forwarding and saving
2396    #[serde(skip_serializing_if = "Option::is_none")]
2397    pub protect_content: Option<bool>,
2398}
2399
2400impl SendVideoNote {
2401    /// Create a new sendVideoNote request
2402    pub fn new(chat_id: impl Into<ChatId>, video_note: impl Into<InputFileVariant>) -> Self {
2403        Self {
2404            chat_id: chat_id.into(),
2405            video_note: video_note.into(),
2406            duration: None,
2407            length: None,
2408            thumb: None,
2409            disable_notification: None,
2410            reply_to_message_id: None,
2411            allow_sending_without_reply: None,
2412            reply_markup: None,
2413            protect_content: None,
2414        }
2415    }
2416    /// Set duration
2417    pub fn with_duration(self, duration: u32) -> Self {
2418        Self {
2419            duration: Some(duration),
2420            ..self
2421        }
2422    }
2423    /// Set length
2424    pub fn with_length(self, length: u32) -> Self {
2425        Self {
2426            length: Some(length),
2427            ..self
2428        }
2429    }
2430    /// Set thumbnail
2431    pub fn with_thumbnail(self, thumbnail: impl Into<InputFileVariant>) -> Self {
2432        Self {
2433            thumb: Some(thumbnail.into()),
2434            ..self
2435        }
2436    }
2437    /// Disable notification
2438    pub fn disable_notification(self) -> Self {
2439        Self {
2440            disable_notification: Some(true),
2441            ..self
2442        }
2443    }
2444    /// Reply to message
2445    pub fn reply_to(self, message_id: i64) -> Self {
2446        Self {
2447            reply_to_message_id: Some(message_id),
2448            ..self
2449        }
2450    }
2451    /// Allow sending message even if the replying message isn't present
2452    pub fn allow_sending_without_reply(self) -> Self {
2453        Self {
2454            allow_sending_without_reply: Some(true),
2455            ..self
2456        }
2457    }
2458    /// Set reply markup
2459    pub fn with_reply_markup(self, markup: impl Into<ReplyMarkup>) -> Self {
2460        Self {
2461            reply_markup: Some(markup.into()),
2462            ..self
2463        }
2464    }
2465    /// Protect content
2466    pub fn protect_content(self) -> Self {
2467        Self {
2468            protect_content: Some(true),
2469            ..self
2470        }
2471    }
2472}
2473
2474impl TelegramMethod for SendVideoNote {
2475    type Response = Message;
2476
2477    fn name() -> &'static str {
2478        "sendVideoNote"
2479    }
2480}
2481
2482impl FileMethod for SendVideoNote {
2483    fn files(&self) -> Option<HashMap<&str, &InputFile>> {
2484        let mut map = HashMap::new();
2485        if let InputFileVariant::File(file) = &self.video_note {
2486            map.insert("video_note", file);
2487        }
2488        if let Some(InputFileVariant::File(file)) = &self.thumb {
2489            map.insert("thumb", file);
2490        }
2491        if map.is_empty() {
2492            None
2493        } else {
2494            Some(map)
2495        }
2496    }
2497}
2498
2499/// Use this method to send a group of photos, videos, documents or audios as an album. Documents and audio files can be only grouped in an album with messages of the same type.
2500/// On success, an array of Messages that were sent is returned.
2501#[derive(Clone, Serialize)]
2502pub struct SendMediaGroup {
2503    /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
2504    pub chat_id: ChatId,
2505    /// A JSON-serialized array describing messages to be sent, must include 2-10 items
2506    pub media: Vec<InputMedia>,
2507    /// Sends the message [silently](https://telegram.org/blog/channels-2-0#silent-messages).
2508    /// Users will receive a notification with no sound.
2509    #[serde(skip_serializing_if = "Option::is_none")]
2510    pub disable_notification: Option<bool>,
2511    /// If the message is a reply, ID of the original message
2512    #[serde(skip_serializing_if = "Option::is_none")]
2513    pub reply_to_message_id: Option<i64>,
2514    /// Pass *True*, if the message should be sent even if the specified replied-to message is not found
2515    #[serde(skip_serializing_if = "Option::is_none")]
2516    pub allow_sending_without_reply: Option<bool>,
2517    /// Protects the contents of the sent message from forwarding and saving
2518    #[serde(skip_serializing_if = "Option::is_none")]
2519    pub protect_content: Option<bool>,
2520}
2521
2522impl SendMediaGroup {
2523    /// Create a new sendMediaGroup request
2524    pub fn new(chat_id: impl Into<ChatId>) -> Self {
2525        Self {
2526            chat_id: chat_id.into(),
2527            media: vec![],
2528            disable_notification: None,
2529            reply_to_message_id: None,
2530            allow_sending_without_reply: None,
2531            protect_content: None,
2532        }
2533    }
2534    /// Set media group
2535    pub fn with_media_group(self, media_group: Vec<InputMedia>) -> Self {
2536        Self {
2537            media: media_group,
2538            ..self
2539        }
2540    }
2541    /// Add one media file
2542    pub fn with_media(mut self, media: impl Into<InputMedia>) -> Self {
2543        self.media.push(media.into());
2544        self
2545    }
2546    /// Disable notification
2547    pub fn disable_notification(self) -> Self {
2548        Self {
2549            disable_notification: Some(true),
2550            ..self
2551        }
2552    }
2553    /// Reply to message
2554    pub fn reply_to(self, message_id: i64) -> Self {
2555        Self {
2556            reply_to_message_id: Some(message_id),
2557            ..self
2558        }
2559    }
2560    /// Allow sending message even if the replying message isn't present
2561    pub fn allow_sending_without_reply(self) -> Self {
2562        Self {
2563            allow_sending_without_reply: Some(true),
2564            ..self
2565        }
2566    }
2567    /// Protect content
2568    pub fn protect_content(self) -> Self {
2569        Self {
2570            protect_content: Some(true),
2571            ..self
2572        }
2573    }
2574}
2575
2576impl TelegramMethod for SendMediaGroup {
2577    type Response = Vec<Message>;
2578
2579    fn name() -> &'static str {
2580        "sendMediaGroup"
2581    }
2582}
2583
2584/// Use this method to send point on the map.
2585/// On success, the sent [Message](https://core.telegram.org/bots/api#message) is returned.
2586#[derive(Clone, Serialize)]
2587pub struct SendLocation {
2588    /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
2589    pub chat_id: ChatId,
2590    /// Latitude of the location
2591    pub latitude: f32,
2592    /// Longitude of the location
2593    pub longitude: f32,
2594    /// The radius of uncertainty for the location, measured in meters; 0-1500
2595    pub horizontal_accuracy: f32,
2596    /// Period in seconds for which the location can be updated
2597    /// (see [Live Locations](https://telegram.org/blog/live-locations)), should be between 60 and 86400.
2598    #[serde(skip_serializing_if = "Option::is_none")]
2599    pub live_period: Option<u32>,
2600    /// For live locations, a direction in which the user is moving, in degrees.
2601    /// Must be between 1 and 360 if specified.
2602    #[serde(skip_serializing_if = "Option::is_none")]
2603    pub heading: Option<u32>,
2604    /// For live locations, a maximum distance for proximity alerts about approaching another chat member, in meters.
2605    /// Must be between 1 and 100000 if specified.
2606    #[serde(skip_serializing_if = "Option::is_none")]
2607    pub proximity_alert_radius: Option<u32>,
2608    /// Sends the message [silently](https://telegram.org/blog/channels-2-0#silent-messages).
2609    /// Users will receive a notification with no sound.
2610    #[serde(skip_serializing_if = "Option::is_none")]
2611    pub disable_notification: Option<bool>,
2612    /// If the message is a reply, ID of the original message
2613    #[serde(skip_serializing_if = "Option::is_none")]
2614    pub reply_to_message_id: Option<i64>,
2615    /// Pass *True*, if the message should be sent even if the specified replied-to message is not found
2616    #[serde(skip_serializing_if = "Option::is_none")]
2617    pub allow_sending_without_reply: Option<bool>,
2618    /// Additional interface options.
2619    /// A JSON-serialized object for an [inline keyboard](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating),
2620    /// [custom reply keyboard](https://core.telegram.org/bots#keyboards),
2621    /// instructions to remove reply keyboard or to force a reply from the user.
2622    #[serde(skip_serializing_if = "Option::is_none")]
2623    pub reply_markup: Option<ReplyMarkup>,
2624    /// Protects the contents of the sent message from forwarding and saving
2625    #[serde(skip_serializing_if = "Option::is_none")]
2626    pub protect_content: Option<bool>,
2627}
2628
2629impl SendLocation {
2630    /// Create a new sendLocation request
2631    pub fn new(
2632        chat_id: impl Into<ChatId>,
2633        latitude: f32,
2634        longitude: f32,
2635        horizontal_accuracy: f32,
2636    ) -> Self {
2637        Self {
2638            chat_id: chat_id.into(),
2639            latitude,
2640            longitude,
2641            horizontal_accuracy,
2642            live_period: None,
2643            heading: None,
2644            proximity_alert_radius: None,
2645            disable_notification: None,
2646            reply_to_message_id: None,
2647            allow_sending_without_reply: None,
2648            reply_markup: None,
2649            protect_content: None,
2650        }
2651    }
2652    /// Set live period
2653    pub fn with_live_period(self, live_period: u32) -> Self {
2654        Self {
2655            live_period: Some(live_period),
2656            ..self
2657        }
2658    }
2659    /// Set heading
2660    pub fn with_heading(self, direction: u32) -> Self {
2661        Self {
2662            heading: Some(direction),
2663            ..self
2664        }
2665    }
2666    /// Set proximity alert radius
2667    pub fn proximity_alert_within(self, radius: u32) -> Self {
2668        Self {
2669            proximity_alert_radius: Some(radius),
2670            ..self
2671        }
2672    }
2673    /// Disable notification
2674    pub fn disable_notification(self) -> Self {
2675        Self {
2676            disable_notification: Some(true),
2677            ..self
2678        }
2679    }
2680    /// Reply to message
2681    pub fn reply_to(self, message_id: i64) -> Self {
2682        Self {
2683            reply_to_message_id: Some(message_id),
2684            ..self
2685        }
2686    }
2687    /// Allow sending message even if the replying message isn't present
2688    pub fn allow_sending_without_reply(self) -> Self {
2689        Self {
2690            allow_sending_without_reply: Some(true),
2691            ..self
2692        }
2693    }
2694    /// Set reply markup
2695    pub fn with_reply_markup(self, markup: impl Into<ReplyMarkup>) -> Self {
2696        Self {
2697            reply_markup: Some(markup.into()),
2698            ..self
2699        }
2700    }
2701    /// Protect content
2702    pub fn protect_content(self) -> Self {
2703        Self {
2704            protect_content: Some(true),
2705            ..self
2706        }
2707    }
2708}
2709
2710impl TelegramMethod for SendLocation {
2711    type Response = Message;
2712
2713    fn name() -> &'static str {
2714        "sendLocation"
2715    }
2716}
2717
2718impl JsonMethod for SendLocation {}
2719
2720/// Use this method to edit live location messages.
2721/// A location can be edited until its *live_period* expires
2722/// or editing is explicitly disabled by a call to [stopMessageLiveLocation](https://core.telegram.org/bots/api#stopmessagelivelocation).
2723/// On success, the edited [Message](https://core.telegram.org/bots/api#message) is returned.
2724#[derive(Clone, Serialize)]
2725pub struct EditMessageLiveLocation {
2726    /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
2727    pub chat_id: ChatId,
2728    /// Identifier of the message to edit
2729    pub message_id: i64,
2730    /// Latitude of new location
2731    pub latitude: f32,
2732    /// Longitude of new location
2733    pub longitude: f32,
2734    /// The radius of uncertainty for the location, measured in meters; 0-1500
2735    pub horizontal_accuracy: Option<f32>,
2736    /// For live locations, a direction in which the user is moving, in degrees.
2737    /// Must be between 1 and 360 if specified.
2738    #[serde(skip_serializing_if = "Option::is_none")]
2739    pub heading: Option<u32>,
2740    /// For live locations, a maximum distance for proximity alerts about approaching another chat member, in meters.
2741    /// Must be between 1 and 100000 if specified.
2742    #[serde(skip_serializing_if = "Option::is_none")]
2743    pub proximity_alert_radius: Option<u32>,
2744    /// A JSON-serialized object for a new [inline keyboard](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating).
2745    #[serde(skip_serializing_if = "Option::is_none")]
2746    pub reply_markup: Option<InlineKeyboardMarkup>,
2747}
2748
2749impl EditMessageLiveLocation {
2750    /// Create a new editMessageLiveLocation request
2751    pub fn new(chat_id: impl Into<ChatId>, message_id: i64, latitude: f32, longitude: f32) -> Self {
2752        Self {
2753            chat_id: chat_id.into(),
2754            message_id,
2755            latitude,
2756            longitude,
2757            horizontal_accuracy: None,
2758            heading: None,
2759            proximity_alert_radius: None,
2760            reply_markup: None,
2761        }
2762    }
2763    /// Set horizontal accuracy
2764    pub fn with_horizontal_accuracy(self, accuracy: f32) -> Self {
2765        Self {
2766            horizontal_accuracy: Some(accuracy),
2767            ..self
2768        }
2769    }
2770    /// Set heading
2771    pub fn with_heading(self, direction: u32) -> Self {
2772        Self {
2773            heading: Some(direction),
2774            ..self
2775        }
2776    }
2777    /// Set proximity alert radius
2778    pub fn proximity_alert_within(self, radius: u32) -> Self {
2779        Self {
2780            proximity_alert_radius: Some(radius),
2781            ..self
2782        }
2783    }
2784    /// Set reply markup
2785    pub fn with_reply_markup(self, markup: impl Into<InlineKeyboardMarkup>) -> Self {
2786        Self {
2787            reply_markup: Some(markup.into()),
2788            ..self
2789        }
2790    }
2791}
2792
2793impl TelegramMethod for EditMessageLiveLocation {
2794    type Response = Message;
2795
2796    fn name() -> &'static str {
2797        "editMessageLiveLocation"
2798    }
2799}
2800
2801impl JsonMethod for EditMessageLiveLocation {}
2802
2803/// Use this method to edit live location messages.
2804/// A location can be edited until its *live_period* expires
2805/// or editing is explicitly disabled by a call to [stopMessageLiveLocation](https://core.telegram.org/bots/api#stopmessagelivelocation).
2806/// On success, _True_ is returned.
2807#[derive(Clone, Serialize)]
2808pub struct EditInlineMessageLiveLocation {
2809    /// Identifier of the inline message
2810    pub inline_message_id: String,
2811    /// Latitude of new location
2812    pub latitude: f32,
2813    /// Longitude of new location
2814    pub longitude: f32,
2815    /// The radius of uncertainty for the location, measured in meters; 0-1500
2816    pub horizontal_accuracy: Option<f32>,
2817    /// For live locations, a direction in which the user is moving, in degrees.
2818    /// Must be between 1 and 360 if specified.
2819    #[serde(skip_serializing_if = "Option::is_none")]
2820    pub heading: Option<u32>,
2821    /// For live locations, a maximum distance for proximity alerts about approaching another chat member, in meters.
2822    /// Must be between 1 and 100000 if specified.
2823    #[serde(skip_serializing_if = "Option::is_none")]
2824    pub proximity_alert_radius: Option<u32>,
2825    /// A JSON-serialized object for a new [inline keyboard](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating).
2826    #[serde(skip_serializing_if = "Option::is_none")]
2827    pub reply_markup: Option<InlineKeyboardMarkup>,
2828}
2829
2830impl EditInlineMessageLiveLocation {
2831    /// Create a new editMessageLiveLocation request
2832    pub fn new(inline_message_id: impl Into<String>, latitude: f32, longitude: f32) -> Self {
2833        Self {
2834            inline_message_id: inline_message_id.into(),
2835            latitude,
2836            longitude,
2837            horizontal_accuracy: None,
2838            heading: None,
2839            proximity_alert_radius: None,
2840            reply_markup: None,
2841        }
2842    }
2843    /// Set horizontal accuracy
2844    pub fn with_horizontal_accuracy(self, accuracy: f32) -> Self {
2845        Self {
2846            horizontal_accuracy: Some(accuracy),
2847            ..self
2848        }
2849    }
2850    /// Set heading
2851    pub fn with_heading(self, direction: u32) -> Self {
2852        Self {
2853            heading: Some(direction),
2854            ..self
2855        }
2856    }
2857    /// Set proximity alert radius
2858    pub fn proximity_alert_within(self, radius: u32) -> Self {
2859        Self {
2860            proximity_alert_radius: Some(radius),
2861            ..self
2862        }
2863    }
2864    /// Set reply markup
2865    pub fn with_reply_markup(self, markup: impl Into<InlineKeyboardMarkup>) -> Self {
2866        Self {
2867            reply_markup: Some(markup.into()),
2868            ..self
2869        }
2870    }
2871}
2872
2873impl TelegramMethod for EditInlineMessageLiveLocation {
2874    type Response = bool;
2875
2876    fn name() -> &'static str {
2877        "editMessageLiveLocation"
2878    }
2879}
2880
2881impl JsonMethod for EditInlineMessageLiveLocation {}
2882
2883/// Use this method to stop updating a live location message before live_period expires.
2884/// On success, the edited [Message](https://core.telegram.org/bots/api#message) is returned.
2885#[derive(Clone, Serialize)]
2886pub struct StopMessageLiveLocation {
2887    /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
2888    pub chat_id: ChatId,
2889    /// Identifier of the message to edit
2890    pub message_id: i64,
2891    /// A JSON-serialized object for a new [inline keyboard](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating).
2892    #[serde(skip_serializing_if = "Option::is_none")]
2893    pub reply_markup: Option<InlineKeyboardMarkup>,
2894}
2895
2896impl StopMessageLiveLocation {
2897    /// Create a new stopMessageLiveLocation request from chat message id
2898    pub fn from_chat(chat_id: impl Into<ChatId>, message_id: i64) -> Self {
2899        Self {
2900            chat_id: chat_id.into(),
2901            message_id,
2902            reply_markup: None,
2903        }
2904    }
2905    /// Set reply markup
2906    pub fn with_reply_markup(self, markup: impl Into<InlineKeyboardMarkup>) -> Self {
2907        Self {
2908            reply_markup: Some(markup.into()),
2909            ..self
2910        }
2911    }
2912}
2913
2914impl TelegramMethod for StopMessageLiveLocation {
2915    type Response = Message;
2916
2917    fn name() -> &'static str {
2918        "stopMessageLiveLocation"
2919    }
2920}
2921
2922impl JsonMethod for StopMessageLiveLocation {}
2923
2924/// Use this method to stop updating a live location message before live_period expires.
2925/// On success, _True_ is returned.
2926#[derive(Clone, Serialize)]
2927pub struct StopInlineMessageLiveLocation {
2928    /// Identifier of the inline message
2929    pub inline_message_id: String,
2930    /// A JSON-serialized object for a new [inline keyboard](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating).
2931    #[serde(skip_serializing_if = "Option::is_none")]
2932    pub reply_markup: Option<InlineKeyboardMarkup>,
2933}
2934
2935impl StopInlineMessageLiveLocation {
2936    /// Create a new stopMessageLiveLocation request
2937    pub fn new(inline_message_id: impl Into<String>) -> Self {
2938        Self {
2939            inline_message_id: inline_message_id.into(),
2940            reply_markup: None,
2941        }
2942    }
2943    /// Set reply markup
2944    pub fn with_reply_markup(self, markup: impl Into<InlineKeyboardMarkup>) -> Self {
2945        Self {
2946            reply_markup: Some(markup.into()),
2947            ..self
2948        }
2949    }
2950}
2951
2952impl TelegramMethod for StopInlineMessageLiveLocation {
2953    type Response = bool;
2954
2955    fn name() -> &'static str {
2956        "stopMessageLiveLocation"
2957    }
2958}
2959
2960impl JsonMethod for StopInlineMessageLiveLocation {}
2961
2962/// Use this method to send information about a venue.
2963/// On success, the sent [Message](https://core.telegram.org/bots/api#message) is returned.
2964#[derive(Clone, Serialize)]
2965pub struct SendVenue {
2966    /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
2967    pub chat_id: ChatId,
2968    /// Latitude of the venue
2969    pub latitude: f32,
2970    /// Longitude of the venue
2971    pub longitude: f32,
2972    /// Name of the venue
2973    pub title: String,
2974    /// Address of the venue
2975    pub address: String,
2976    /// Foursquare identifier of the venue, if known
2977    #[serde(skip_serializing_if = "Option::is_none")]
2978    pub foursquare_id: Option<String>,
2979    /// Foursquare type of the venue, if known.
2980    /// (For example, “arts_entertainment/default”, “arts_entertainment/aquarium” or “food/icecream”.)
2981    #[serde(skip_serializing_if = "Option::is_none")]
2982    pub foursquare_type: Option<String>,
2983    /// Google Places identifier of the venue
2984    #[serde(skip_serializing_if = "Option::is_none")]
2985    pub google_place_id: Option<String>,
2986    /// Google Places type of the venue. (See [supported types.](https://developers.google.com/places/web-service/supported_types))
2987    #[serde(skip_serializing_if = "Option::is_none")]
2988    pub google_place_type: Option<String>,
2989    /// Sends the message [silently](https://telegram.org/blog/channels-2-0#silent-messages).
2990    /// Users will receive a notification with no sound.
2991    #[serde(skip_serializing_if = "Option::is_none")]
2992    pub disable_notification: Option<bool>,
2993    /// If the message is a reply, ID of the original message
2994    #[serde(skip_serializing_if = "Option::is_none")]
2995    pub reply_to_message_id: Option<i64>,
2996    /// Pass *True*, if the message should be sent even if the specified replied-to message is not found
2997    #[serde(skip_serializing_if = "Option::is_none")]
2998    pub allow_sending_without_reply: Option<bool>,
2999    /// Additional interface options.
3000    /// A JSON-serialized object for an [inline keyboard](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating),
3001    /// [custom reply keyboard](https://core.telegram.org/bots#keyboards),
3002    /// instructions to remove reply keyboard or to force a reply from the user.
3003    #[serde(skip_serializing_if = "Option::is_none")]
3004    pub reply_markup: Option<ReplyMarkup>,
3005    /// Protects the contents of the sent message from forwarding and saving
3006    #[serde(skip_serializing_if = "Option::is_none")]
3007    pub protect_content: Option<bool>,
3008}
3009
3010impl SendVenue {
3011    /// Create a new sendVenue request
3012    pub fn new(
3013        chat_id: impl Into<ChatId>,
3014        latitude: f32,
3015        longitude: f32,
3016        title: impl Into<String>,
3017        address: impl Into<String>,
3018    ) -> Self {
3019        Self {
3020            chat_id: chat_id.into(),
3021            latitude,
3022            longitude,
3023            title: title.into(),
3024            address: address.into(),
3025            foursquare_id: None,
3026            foursquare_type: None,
3027            google_place_id: None,
3028            google_place_type: None,
3029            disable_notification: None,
3030            reply_to_message_id: None,
3031            allow_sending_without_reply: None,
3032            reply_markup: None,
3033            protect_content: None,
3034        }
3035    }
3036    /// Set foursquare id and type
3037    pub fn with_foursqaure(self, id: impl Into<String>, kind: Option<String>) -> Self {
3038        Self {
3039            foursquare_id: Some(id.into()),
3040            foursquare_type: kind,
3041            ..self
3042        }
3043    }
3044    /// Set google place id and type
3045    pub fn with_google_place(self, id: impl Into<String>, kind: Option<String>) -> Self {
3046        Self {
3047            google_place_id: Some(id.into()),
3048            google_place_type: kind,
3049            ..self
3050        }
3051    }
3052    /// Disable notification
3053    pub fn disable_notification(self) -> Self {
3054        Self {
3055            disable_notification: Some(true),
3056            ..self
3057        }
3058    }
3059    /// Reply to message
3060    pub fn reply_to(self, message_id: i64) -> Self {
3061        Self {
3062            reply_to_message_id: Some(message_id),
3063            ..self
3064        }
3065    }
3066    /// Allow sending message even if the replying message isn't present
3067    pub fn allow_sending_without_reply(self) -> Self {
3068        Self {
3069            allow_sending_without_reply: Some(true),
3070            ..self
3071        }
3072    }
3073    /// Set reply markup
3074    pub fn with_reply_markup(self, markup: impl Into<ReplyMarkup>) -> Self {
3075        Self {
3076            reply_markup: Some(markup.into()),
3077            ..self
3078        }
3079    }
3080    /// Protect content
3081    pub fn protect_content(self) -> Self {
3082        Self {
3083            protect_content: Some(true),
3084            ..self
3085        }
3086    }
3087}
3088
3089impl TelegramMethod for SendVenue {
3090    type Response = Message;
3091
3092    fn name() -> &'static str {
3093        "sendVenue"
3094    }
3095}
3096
3097impl JsonMethod for SendVenue {}
3098
3099/// Use this method to send text messages. On success, the sent [Message](https://core.telegram.org/bots/api#message) is returned.
3100#[derive(Clone, Serialize)]
3101pub struct SendContact {
3102    /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
3103    pub chat_id: ChatId,
3104    /// Contact's phone number
3105    pub phone_number: String,
3106    /// Contact's first name
3107    pub first_name: String,
3108    /// Contact's last name
3109    #[serde(skip_serializing_if = "Option::is_none")]
3110    pub last_name: Option<String>,
3111    /// Additional data about the contact in the form of a [vCard](https://en.wikipedia.org/wiki/VCard), 0-2048 bytes
3112    #[serde(skip_serializing_if = "Option::is_none")]
3113    pub vcard: Option<String>,
3114    /// Sends the message [silently](https://telegram.org/blog/channels-2-0#silent-messages).
3115    /// Users will receive a notification with no sound.
3116    #[serde(skip_serializing_if = "Option::is_none")]
3117    pub disable_notification: Option<bool>,
3118    /// If the message is a reply, ID of the original message
3119    #[serde(skip_serializing_if = "Option::is_none")]
3120    pub reply_to_message_id: Option<i64>,
3121    /// Pass *True*, if the message should be sent even if the specified replied-to message is not found
3122    #[serde(skip_serializing_if = "Option::is_none")]
3123    pub allow_sending_without_reply: Option<bool>,
3124    /// Additional interface options.
3125    /// A JSON-serialized object for an [inline keyboard](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating),
3126    /// [custom reply keyboard](https://core.telegram.org/bots#keyboards),
3127    /// instructions to remove reply keyboard or to force a reply from the user.
3128    #[serde(skip_serializing_if = "Option::is_none")]
3129    pub reply_markup: Option<ReplyMarkup>,
3130    /// Protects the contents of the sent message from forwarding and saving
3131    #[serde(skip_serializing_if = "Option::is_none")]
3132    pub protect_content: Option<bool>,
3133}
3134
3135impl SendContact {
3136    /// Create a new sendContact request
3137    pub fn new(
3138        chat_id: impl Into<ChatId>,
3139        phone_number: impl Into<String>,
3140        first_name: impl Into<String>,
3141    ) -> Self {
3142        Self {
3143            chat_id: chat_id.into(),
3144            phone_number: phone_number.into(),
3145            first_name: first_name.into(),
3146            last_name: None,
3147            vcard: None,
3148            disable_notification: None,
3149            reply_to_message_id: None,
3150            allow_sending_without_reply: None,
3151            reply_markup: None,
3152            protect_content: None,
3153        }
3154    }
3155    /// Set last name
3156    pub fn with_last_name(self, last_name: impl Into<String>) -> Self {
3157        Self {
3158            last_name: Some(last_name.into()),
3159            ..self
3160        }
3161    }
3162    /// Set vcard
3163    pub fn with_vcard(self, vcard: impl Into<String>) -> Self {
3164        Self {
3165            vcard: Some(vcard.into()),
3166            ..self
3167        }
3168    }
3169    /// Disable notification
3170    pub fn disable_notification(self) -> Self {
3171        Self {
3172            disable_notification: Some(true),
3173            ..self
3174        }
3175    }
3176    /// Reply to message
3177    pub fn reply_to(self, message_id: i64) -> Self {
3178        Self {
3179            reply_to_message_id: Some(message_id),
3180            ..self
3181        }
3182    }
3183    /// Allow sending message even if the replying message isn't present
3184    pub fn allow_sending_without_reply(self) -> Self {
3185        Self {
3186            allow_sending_without_reply: Some(true),
3187            ..self
3188        }
3189    }
3190    /// Set reply markup
3191    pub fn with_reply_markup(self, markup: impl Into<ReplyMarkup>) -> Self {
3192        Self {
3193            reply_markup: Some(markup.into()),
3194            ..self
3195        }
3196    }
3197    /// Protect content
3198    pub fn protect_content(self) -> Self {
3199        Self {
3200            protect_content: Some(true),
3201            ..self
3202        }
3203    }
3204}
3205
3206impl TelegramMethod for SendContact {
3207    type Response = Message;
3208
3209    fn name() -> &'static str {
3210        "sendContact"
3211    }
3212}
3213
3214impl JsonMethod for SendContact {}
3215
3216/// Use this method to send a native poll. On success, the sent [Message](https://core.telegram.org/bots/api#message) is returned.
3217#[derive(Clone, Serialize)]
3218pub struct SendPoll {
3219    /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
3220    pub chat_id: ChatId,
3221    /// Poll question, 1-300 characters
3222    pub question: String,
3223    /// A JSON-serialized list of answer options, 2-10 strings 1-100 characters each
3224    pub options: Vec<String>,
3225    /// True, if the poll needs to be anonymous, defaults to *True*
3226    #[serde(skip_serializing_if = "Option::is_none")]
3227    pub is_anonymous: Option<bool>,
3228    /// Poll type, “quiz” or “regular”, defaults to “regular”
3229    #[serde(skip_serializing_if = "Option::is_none")]
3230    #[serde(rename = "type")]
3231    pub kind: Option<String>,
3232    /// True, if the poll allows multiple answers, ignored for polls in quiz mode, defaults to *False*
3233    #[serde(skip_serializing_if = "Option::is_none")]
3234    pub allows_multiple_answers: Option<bool>,
3235    /// 0-based identifier of the correct answer option, required for polls in quiz mode
3236    #[serde(skip_serializing_if = "Option::is_none")]
3237    pub correct_option_id: Option<u32>,
3238    /// Text that is shown when a user chooses an incorrect answer or taps on the lamp icon in a quiz-style poll,
3239    /// 0-200 characters with at most 2 line feeds after entities parsing
3240    #[serde(skip_serializing_if = "Option::is_none")]
3241    pub explanation: Option<String>,
3242    /// Mode for parsing entities in the explanation.
3243    /// See [formatting options](https://core.telegram.org/bots/api#formatting-options) for more details.
3244    #[serde(skip_serializing_if = "Option::is_none")]
3245    pub explanation_parse_mode: Option<ParseMode>,
3246    /// List of special entities that appear in the poll explanation, which can be specified instead of *parse_mode*
3247    #[serde(skip_serializing_if = "Option::is_none")]
3248    pub explanation_entities: Option<Vec<MessageEntity>>,
3249    /// Amount of time in seconds the poll will be active after creation, 5-600. Can't be used together with *close_date*.
3250    #[serde(skip_serializing_if = "Option::is_none")]
3251    pub open_period: Option<u32>,
3252    /// Point in time (Unix timestamp) when the poll will be automatically closed.
3253    /// Must be at least 5 and no more than 600 seconds in the future.
3254    /// Can't be used together with open_period.
3255    #[serde(skip_serializing_if = "Option::is_none")]
3256    pub close_date: Option<u64>,
3257    /// Pass *True*, if the poll needs to be immediately closed.
3258    /// This can be useful for poll preview.
3259    #[serde(skip_serializing_if = "Option::is_none")]
3260    pub is_closed: Option<bool>,
3261    /// Sends the message [silently](https://telegram.org/blog/channels-2-0#silent-messages).
3262    /// Users will receive a notification with no sound.
3263    #[serde(skip_serializing_if = "Option::is_none")]
3264    pub disable_notification: Option<bool>,
3265    /// If the message is a reply, ID of the original message
3266    #[serde(skip_serializing_if = "Option::is_none")]
3267    pub reply_to_message_id: Option<i64>,
3268    /// Pass *True*, if the message should be sent even if the specified replied-to message is not found
3269    #[serde(skip_serializing_if = "Option::is_none")]
3270    pub allow_sending_without_reply: Option<bool>,
3271    /// Additional interface options.
3272    /// A JSON-serialized object for an [inline keyboard](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating),
3273    /// [custom reply keyboard](https://core.telegram.org/bots#keyboards),
3274    /// instructions to remove reply keyboard or to force a reply from the user.
3275    #[serde(skip_serializing_if = "Option::is_none")]
3276    pub reply_markup: Option<ReplyMarkup>,
3277    /// Protects the contents of the sent message from forwarding and saving
3278    #[serde(skip_serializing_if = "Option::is_none")]
3279    pub protect_content: Option<bool>,
3280}
3281
3282impl SendPoll {
3283    /// Create a new sendPoll request to send a regular poll
3284    pub fn new_regular(
3285        chat_id: impl Into<ChatId>,
3286        question: impl Into<String>,
3287        options: Vec<String>,
3288    ) -> Self {
3289        Self {
3290            chat_id: chat_id.into(),
3291            question: question.into(),
3292            options,
3293            is_anonymous: None,
3294            kind: Some("quiz".into()),
3295            allows_multiple_answers: None,
3296            correct_option_id: None,
3297            explanation: None,
3298            explanation_parse_mode: None,
3299            explanation_entities: None,
3300            open_period: None,
3301            close_date: None,
3302            is_closed: None,
3303            disable_notification: None,
3304            reply_to_message_id: None,
3305            allow_sending_without_reply: None,
3306            reply_markup: None,
3307            protect_content: None,
3308        }
3309    }
3310    /// Create a new sendPoll request to send a quiz
3311    pub fn new_quiz(
3312        chat_id: impl Into<ChatId>,
3313        question: impl Into<String>,
3314        options: Vec<String>,
3315        correct_option_id: u32,
3316    ) -> Self {
3317        Self {
3318            chat_id: chat_id.into(),
3319            question: question.into(),
3320            options,
3321            is_anonymous: None,
3322            kind: Some("quiz".into()),
3323            allows_multiple_answers: None,
3324            correct_option_id: Some(correct_option_id),
3325            explanation: None,
3326            explanation_parse_mode: None,
3327            explanation_entities: None,
3328            open_period: None,
3329            close_date: None,
3330            is_closed: None,
3331            disable_notification: None,
3332            reply_to_message_id: None,
3333            allow_sending_without_reply: None,
3334            reply_markup: None,
3335            protect_content: None,
3336        }
3337    }
3338    /// Set the poll as anonymous
3339    pub fn anonymous(self) -> Self {
3340        Self {
3341            is_anonymous: Some(true),
3342            ..self
3343        }
3344    }
3345    /// Allow multiple answers
3346    pub fn allow_multiple_answers(self) -> Self {
3347        Self {
3348            allows_multiple_answers: Some(true),
3349            ..self
3350        }
3351    }
3352    /// Set explanation
3353    pub fn with_explanation(self, explanation: impl Into<String>) -> Self {
3354        Self {
3355            explanation: Some(explanation.into()),
3356            ..self
3357        }
3358    }
3359    /// Set explanation parse mode
3360    pub fn with_parse_mode(self, parse_mode: ParseMode) -> Self {
3361        Self {
3362            explanation_parse_mode: Some(parse_mode),
3363            ..self
3364        }
3365    }
3366    /// Set explanation entities
3367    pub fn with_entities(self, entities: Vec<MessageEntity>) -> Self {
3368        Self {
3369            explanation_entities: Some(entities),
3370            ..self
3371        }
3372    }
3373    /// Add explanation entity
3374    pub fn with_entity(mut self, entity: MessageEntity) -> Self {
3375        let entities = self
3376            .explanation_entities
3377            .get_or_insert_with(Default::default);
3378        entities.push(entity);
3379        self
3380    }
3381    /// Set open period. This sets `close_date` to `None`
3382    pub fn with_open_period(self, period: u32) -> Self {
3383        Self {
3384            open_period: Some(period),
3385            close_date: None,
3386            ..self
3387        }
3388    }
3389    /// Set close date. This sets `open_period` to `None`
3390    pub fn with_close_date(self, close_date: u64) -> Self {
3391        Self {
3392            close_date: Some(close_date),
3393            open_period: None,
3394            ..self
3395        }
3396    }
3397    /// Set the poll as closed
3398    pub fn closed(self) -> Self {
3399        Self {
3400            is_closed: Some(true),
3401            ..self
3402        }
3403    }
3404    /// Disable notification
3405    pub fn disable_notification(self) -> Self {
3406        Self {
3407            disable_notification: Some(true),
3408            ..self
3409        }
3410    }
3411    /// Reply to message
3412    pub fn reply_to(self, message_id: i64) -> Self {
3413        Self {
3414            reply_to_message_id: Some(message_id),
3415            ..self
3416        }
3417    }
3418    /// Allow sending message even if the replying message isn't present
3419    pub fn allow_sending_without_reply(self) -> Self {
3420        Self {
3421            allow_sending_without_reply: Some(true),
3422            ..self
3423        }
3424    }
3425    /// Set reply markup
3426    pub fn with_reply_markup(self, markup: impl Into<ReplyMarkup>) -> Self {
3427        Self {
3428            reply_markup: Some(markup.into()),
3429            ..self
3430        }
3431    }
3432    /// Protect content
3433    pub fn protect_content(self) -> Self {
3434        Self {
3435            protect_content: Some(true),
3436            ..self
3437        }
3438    }
3439}
3440
3441impl TelegramMethod for SendPoll {
3442    type Response = Message;
3443
3444    fn name() -> &'static str {
3445        "sendPoll"
3446    }
3447}
3448
3449impl JsonMethod for SendPoll {}
3450
3451/// Use this method to send an animated emoji that will display a random value.
3452/// On success, the sent [Message](https://core.telegram.org/bots/api#message) is returned.
3453#[derive(Clone, Serialize)]
3454pub struct SendDice {
3455    /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
3456    pub chat_id: ChatId,
3457    /// Emoji on which the dice throw animation is based.
3458    /// Currently, must be one of “🎲”, “🎯”, “🏀”, “⚽”, “🎳”, or “🎰”.
3459    /// Dice can have values 1-6 for “🎲”, “🎯” and “🎳”, values 1-5 for “🏀” and “⚽”, and values 1-64 for “🎰”. Defaults to “🎲”
3460    #[serde(skip_serializing_if = "Option::is_none")]
3461    pub emoji: Option<String>,
3462    /// Sends the message [silently](https://telegram.org/blog/channels-2-0#silent-messages).
3463    /// Users will receive a notification with no sound.
3464    #[serde(skip_serializing_if = "Option::is_none")]
3465    pub disable_notification: Option<bool>,
3466    /// If the message is a reply, ID of the original message
3467    #[serde(skip_serializing_if = "Option::is_none")]
3468    pub reply_to_message_id: Option<i64>,
3469    /// Pass *True*, if the message should be sent even if the specified replied-to message is not found
3470    #[serde(skip_serializing_if = "Option::is_none")]
3471    pub allow_sending_without_reply: Option<bool>,
3472    /// Additional interface options.
3473    /// A JSON-serialized object for an [inline keyboard](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating),
3474    /// [custom reply keyboard](https://core.telegram.org/bots#keyboards),
3475    /// instructions to remove reply keyboard or to force a reply from the user.
3476    #[serde(skip_serializing_if = "Option::is_none")]
3477    pub reply_markup: Option<ReplyMarkup>,
3478    /// Protects the contents of the sent message from forwarding and saving
3479    #[serde(skip_serializing_if = "Option::is_none")]
3480    pub protect_content: Option<bool>,
3481}
3482
3483impl SendDice {
3484    /// Create a new sendDice request.
3485    pub fn new(chat_id: impl Into<ChatId>) -> Self {
3486        Self {
3487            chat_id: chat_id.into(),
3488            emoji: None,
3489            disable_notification: None,
3490            reply_to_message_id: None,
3491            allow_sending_without_reply: None,
3492            reply_markup: None,
3493            protect_content: None,
3494        }
3495    }
3496    /// Set emoji
3497    pub fn with_emoji(self, emoji: impl Into<String>) -> Self {
3498        Self {
3499            emoji: Some(emoji.into()),
3500            ..self
3501        }
3502    }
3503    /// Disable notification
3504    pub fn disable_notification(self) -> Self {
3505        Self {
3506            disable_notification: Some(true),
3507            ..self
3508        }
3509    }
3510    /// Reply to message
3511    pub fn reply_to(self, message_id: i64) -> Self {
3512        Self {
3513            reply_to_message_id: Some(message_id),
3514            ..self
3515        }
3516    }
3517    /// Allow sending message even if the replying message isn't present
3518    pub fn allow_sending_without_reply(self) -> Self {
3519        Self {
3520            allow_sending_without_reply: Some(true),
3521            ..self
3522        }
3523    }
3524    /// Set reply markup
3525    pub fn with_reply_markup(self, markup: impl Into<ReplyMarkup>) -> Self {
3526        Self {
3527            reply_markup: Some(markup.into()),
3528            ..self
3529        }
3530    }
3531    /// Protect content
3532    pub fn protect_content(self) -> Self {
3533        Self {
3534            protect_content: Some(true),
3535            ..self
3536        }
3537    }
3538}
3539
3540impl TelegramMethod for SendDice {
3541    type Response = Message;
3542
3543    fn name() -> &'static str {
3544        "sendDice"
3545    }
3546}
3547
3548impl JsonMethod for SendDice {}
3549
3550/// Chat action type
3551#[derive(Clone, Serialize)]
3552#[serde(rename_all = "snake_case")]
3553pub enum ChatActionKind {
3554    Typing,
3555    UploadPhoto,
3556    RecordVideo,
3557    UploadVideo,
3558    RecordVoice,
3559    UploadVoice,
3560    UplaodDocument,
3561    FindLocation,
3562    RecordVideoNote,
3563    UploadVideoNote,
3564}
3565
3566/// Use this method when you need to tell the user that something is happening on the bot's side.
3567/// The status is set for 5 seconds or less (when a message arrives from your bot, Telegram clients clear its typing status).
3568/// Returns True on success.
3569///
3570/// > Example: The [ImageBot](https://t.me/imagebot) needs some time to process a request and upload the image.
3571/// > Instead of sending a text message along the lines of “Retrieving image, please wait…”, the bot may use sendChatAction with action = upload_photo.
3572/// > The user will see a “sending photo” status for the bot.
3573///
3574/// It is recommended to use this method only when a response from the bot will take a noticeable amount of time to arrive.
3575#[derive(Clone, Serialize)]
3576pub struct SendChatAction {
3577    /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
3578    pub chat_id: ChatId,
3579    /// Type of action to broadcast.
3580    pub action: ChatActionKind,
3581}
3582
3583impl SendChatAction {
3584    /// Create a new sendChatAction request.
3585    pub fn new(chat_id: impl Into<ChatId>, action: ChatActionKind) -> Self {
3586        Self {
3587            chat_id: chat_id.into(),
3588            action,
3589        }
3590    }
3591}
3592
3593impl TelegramMethod for SendChatAction {
3594    type Response = Message;
3595
3596    fn name() -> &'static str {
3597        "sendChatAction"
3598    }
3599}
3600
3601impl JsonMethod for SendChatAction {}
3602
3603/// Use this method to edit text and [game](https://core.telegram.org/bots/api#games) messages.
3604/// On success, if the edited message is not an inline message, the edited [Message](https://core.telegram.org/bots/api#message) is returned,
3605/// otherwise _True_ is returned.
3606#[derive(Clone, Serialize)]
3607pub struct EditMessageText {
3608    /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
3609    pub chat_id: ChatId,
3610    /// Identifier of the message to edit
3611    pub message_id: i64,
3612    /// New text of the message, 1-4096 characters after entities parsing
3613    pub text: String,
3614    /// Mode for parsing entities in the message text.
3615    /// See [formatting options](https://core.telegram.org/bots/api#formatting-options) for more details.
3616    #[serde(skip_serializing_if = "Option::is_none")]
3617    pub parse_mode: Option<ParseMode>,
3618    /// List of special entities that appear in message text,
3619    /// which can be specified instead of *parse_mode*
3620    #[serde(skip_serializing_if = "Option::is_none")]
3621    pub entities: Option<Vec<MessageEntity>>,
3622    /// Disables link previews for links in the sent message
3623    #[serde(skip_serializing_if = "Option::is_none")]
3624    pub disable_web_page_preview: Option<bool>,
3625    /// A JSON-serialized object for a new [inline keyboard](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating).
3626    #[serde(skip_serializing_if = "Option::is_none")]
3627    pub reply_markup: Option<InlineKeyboardMarkup>,
3628}
3629
3630impl EditMessageText {
3631    /// Create a new editMessageText request
3632    pub fn new(chat_id: impl Into<ChatId>, message_id: i64, text: impl Into<String>) -> Self {
3633        Self {
3634            chat_id: chat_id.into(),
3635            message_id,
3636            text: text.into(),
3637            parse_mode: None,
3638            entities: None,
3639            disable_web_page_preview: None,
3640            reply_markup: None,
3641        }
3642    }
3643    /// Set parse mode
3644    pub fn with_parse_mode(self, parse_mode: ParseMode) -> Self {
3645        Self {
3646            parse_mode: Some(parse_mode),
3647            ..self
3648        }
3649    }
3650    /// Set entities
3651    pub fn with_entities(self, entities: Vec<MessageEntity>) -> Self {
3652        Self {
3653            entities: Some(entities),
3654            ..self
3655        }
3656    }
3657    /// Add one entity
3658    pub fn with_entity(mut self, entity: MessageEntity) -> Self {
3659        let entities = self.entities.get_or_insert_with(Default::default);
3660        entities.push(entity);
3661        self
3662    }
3663    /// Disable web preview
3664    pub fn disable_web_page_preview(self) -> Self {
3665        Self {
3666            disable_web_page_preview: Some(true),
3667            ..self
3668        }
3669    }
3670    /// Set reply markup
3671    pub fn with_reply_markup(self, markup: impl Into<InlineKeyboardMarkup>) -> Self {
3672        Self {
3673            reply_markup: Some(markup.into()),
3674            ..self
3675        }
3676    }
3677}
3678
3679impl TelegramMethod for EditMessageText {
3680    type Response = Message;
3681
3682    fn name() -> &'static str {
3683        "editMessageText"
3684    }
3685}
3686
3687impl JsonMethod for EditMessageText {}
3688
3689/// Use this method to edit text and [game](https://core.telegram.org/bots/api#games) messages.
3690/// On success, _True_ is returned.
3691#[derive(Clone, Serialize)]
3692pub struct EditInlineMessageText {
3693    /// Identifier of the inline message
3694    pub inline_message_id: String,
3695    /// New text of the message, 1-4096 characters after entities parsing
3696    pub text: String,
3697    /// Mode for parsing entities in the message text.
3698    /// See [formatting options](https://core.telegram.org/bots/api#formatting-options) for more details.
3699    #[serde(skip_serializing_if = "Option::is_none")]
3700    pub parse_mode: Option<ParseMode>,
3701    /// List of special entities that appear in message text,
3702    /// which can be specified instead of *parse_mode*
3703    #[serde(skip_serializing_if = "Option::is_none")]
3704    pub entities: Option<Vec<MessageEntity>>,
3705    /// Disables link previews for links in the sent message
3706    #[serde(skip_serializing_if = "Option::is_none")]
3707    pub disable_web_page_preview: Option<bool>,
3708    /// A JSON-serialized object for a new [inline keyboard](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating).
3709    #[serde(skip_serializing_if = "Option::is_none")]
3710    pub reply_markup: Option<InlineKeyboardMarkup>,
3711}
3712
3713impl EditInlineMessageText {
3714    /// Create a new editMessageText request
3715    pub fn new(inline_message_id: impl Into<String>, text: impl Into<String>) -> Self {
3716        Self {
3717            inline_message_id: inline_message_id.into(),
3718            text: text.into(),
3719            parse_mode: None,
3720            entities: None,
3721            disable_web_page_preview: None,
3722            reply_markup: None,
3723        }
3724    }
3725    /// Set parse mode
3726    pub fn with_parse_mode(self, parse_mode: ParseMode) -> Self {
3727        Self {
3728            parse_mode: Some(parse_mode),
3729            ..self
3730        }
3731    }
3732    /// Set entities
3733    pub fn with_entities(self, entities: Vec<MessageEntity>) -> Self {
3734        Self {
3735            entities: Some(entities),
3736            ..self
3737        }
3738    }
3739    /// Add one entity
3740    pub fn with_entity(mut self, entity: MessageEntity) -> Self {
3741        let entities = self.entities.get_or_insert_with(Default::default);
3742        entities.push(entity);
3743        self
3744    }
3745    /// Disable web preview
3746    pub fn disable_web_page_preview(self) -> Self {
3747        Self {
3748            disable_web_page_preview: Some(true),
3749            ..self
3750        }
3751    }
3752    /// Set reply markup
3753    pub fn with_reply_markup(self, markup: impl Into<InlineKeyboardMarkup>) -> Self {
3754        Self {
3755            reply_markup: Some(markup.into()),
3756            ..self
3757        }
3758    }
3759}
3760
3761impl TelegramMethod for EditInlineMessageText {
3762    type Response = bool;
3763
3764    fn name() -> &'static str {
3765        "editMessageText"
3766    }
3767}
3768
3769impl JsonMethod for EditInlineMessageText {}
3770
3771/// Use this method to edit captions of messages. On success, the edited Message is returned.
3772#[derive(Clone, Serialize)]
3773pub struct EditMessageCaption {
3774    /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
3775    pub chat_id: ChatId,
3776    /// Identifier of the message to edit
3777    pub message_id: i64,
3778    /// New caption of the message, 0-1024 characters after entities parsing
3779    pub caption: Option<String>,
3780    /// For messages with a caption, special entities like usernames, URLs, bot commands, etc. that appear in the caption
3781    #[serde(skip_serializing_if = "Option::is_none")]
3782    pub caption_entities: Option<Vec<MessageEntity>>,
3783    /// Mode for parsing entities in the message text.
3784    /// See [formatting options](https://core.telegram.org/bots/api#formatting-options) for more details.
3785    #[serde(skip_serializing_if = "Option::is_none")]
3786    pub parse_mode: Option<ParseMode>,
3787    /// Disables link previews for links in the sent message
3788    #[serde(skip_serializing_if = "Option::is_none")]
3789    pub disable_web_page_preview: Option<bool>,
3790    /// A JSON-serialized object for a new [inline keyboard](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating).
3791    #[serde(skip_serializing_if = "Option::is_none")]
3792    pub reply_markup: Option<InlineKeyboardMarkup>,
3793}
3794
3795impl EditMessageCaption {
3796    /// Create a new editMessageCaption request with no caption
3797    pub fn new_empty(chat_id: impl Into<ChatId>, message_id: i64) -> Self {
3798        Self {
3799            chat_id: chat_id.into(),
3800            message_id,
3801            caption: None,
3802            parse_mode: None,
3803            caption_entities: None,
3804            disable_web_page_preview: None,
3805            reply_markup: None,
3806        }
3807    }
3808    /// Create a new editMessageCaption request with caption
3809    pub fn new(chat_id: impl Into<ChatId>, message_id: i64, caption: impl Into<String>) -> Self {
3810        Self {
3811            chat_id: chat_id.into(),
3812            message_id,
3813            caption: Some(caption.into()),
3814            parse_mode: None,
3815            caption_entities: None,
3816            disable_web_page_preview: None,
3817            reply_markup: None,
3818        }
3819    }
3820    /// Set parse mode
3821    pub fn with_parse_mode(self, parse_mode: ParseMode) -> Self {
3822        Self {
3823            parse_mode: Some(parse_mode),
3824            ..self
3825        }
3826    }
3827    /// Set caption entities
3828    pub fn with_entities(self, entities: Vec<MessageEntity>) -> Self {
3829        Self {
3830            caption_entities: Some(entities),
3831            ..self
3832        }
3833    }
3834    /// Add one entity
3835    pub fn with_entity(mut self, entity: MessageEntity) -> Self {
3836        let entities = self.caption_entities.get_or_insert_with(Default::default);
3837        entities.push(entity);
3838        self
3839    }
3840    /// Disable web preview
3841    pub fn disable_web_page_preview(self) -> Self {
3842        Self {
3843            disable_web_page_preview: Some(true),
3844            ..self
3845        }
3846    }
3847    /// Set reply markup
3848    pub fn with_reply_markup(self, markup: impl Into<InlineKeyboardMarkup>) -> Self {
3849        Self {
3850            reply_markup: Some(markup.into()),
3851            ..self
3852        }
3853    }
3854}
3855
3856impl TelegramMethod for EditMessageCaption {
3857    type Response = Message;
3858
3859    fn name() -> &'static str {
3860        "editMessageCaption"
3861    }
3862}
3863
3864impl JsonMethod for EditMessageCaption {}
3865
3866/// Use this method to edit captions of messages. On success, the edited Message is returned.
3867#[derive(Clone, Serialize)]
3868pub struct EditInlineMessageCaption {
3869    /// Identifier of the inline message
3870    pub inline_message_id: String,
3871    /// New caption of the message, 0-1024 characters after entities parsing
3872    #[serde(skip_serializing_if = "Option::is_none")]
3873    pub caption: Option<String>,
3874    /// For messages with a caption, special entities like usernames, URLs, bot commands, etc. that appear in the caption
3875    #[serde(skip_serializing_if = "Option::is_none")]
3876    pub caption_entities: Option<Vec<MessageEntity>>,
3877    /// Mode for parsing entities in the message text.
3878    /// See [formatting options](https://core.telegram.org/bots/api#formatting-options) for more details.
3879    #[serde(skip_serializing_if = "Option::is_none")]
3880    pub parse_mode: Option<ParseMode>,
3881    /// Disables link previews for links in the sent message
3882    #[serde(skip_serializing_if = "Option::is_none")]
3883    pub disable_web_page_preview: Option<bool>,
3884    /// A JSON-serialized object for a new [inline keyboard](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating).
3885    #[serde(skip_serializing_if = "Option::is_none")]
3886    pub reply_markup: Option<InlineKeyboardMarkup>,
3887}
3888
3889impl EditInlineMessageCaption {
3890    /// Create a new editMessageCaption request with no caption
3891    pub fn new_empty(inline_message_id: impl Into<String>) -> Self {
3892        Self {
3893            inline_message_id: inline_message_id.into(),
3894            caption: None,
3895            parse_mode: None,
3896            caption_entities: None,
3897            disable_web_page_preview: None,
3898            reply_markup: None,
3899        }
3900    }
3901    /// Create a new editMessageCaption request with caption
3902    pub fn new(inline_message_id: impl Into<String>, caption: impl Into<String>) -> Self {
3903        Self {
3904            inline_message_id: inline_message_id.into(),
3905            caption: Some(caption.into()),
3906            parse_mode: None,
3907            caption_entities: None,
3908            disable_web_page_preview: None,
3909            reply_markup: None,
3910        }
3911    }
3912    /// Set parse mode
3913    pub fn with_parse_mode(self, parse_mode: ParseMode) -> Self {
3914        Self {
3915            parse_mode: Some(parse_mode),
3916            ..self
3917        }
3918    }
3919    /// Set caption entities
3920    pub fn with_entities(self, entities: Vec<MessageEntity>) -> Self {
3921        Self {
3922            caption_entities: Some(entities),
3923            ..self
3924        }
3925    }
3926    /// Add one entity
3927    pub fn with_entity(mut self, entity: MessageEntity) -> Self {
3928        let entities = self.caption_entities.get_or_insert_with(Default::default);
3929        entities.push(entity);
3930        self
3931    }
3932    /// Disable web preview
3933    pub fn disable_web_page_preview(self) -> Self {
3934        Self {
3935            disable_web_page_preview: Some(true),
3936            ..self
3937        }
3938    }
3939    /// Set reply markup
3940    pub fn with_reply_markup(self, markup: impl Into<InlineKeyboardMarkup>) -> Self {
3941        Self {
3942            reply_markup: Some(markup.into()),
3943            ..self
3944        }
3945    }
3946}
3947
3948impl TelegramMethod for EditInlineMessageCaption {
3949    type Response = bool;
3950
3951    fn name() -> &'static str {
3952        "editMessageCaption"
3953    }
3954}
3955
3956impl JsonMethod for EditInlineMessageCaption {}
3957
3958/// Use this method to edit animation, audio, document, photo, or video messages.
3959/// If a message is part of a message album, then it can be edited only to an audio for audio albums,
3960/// only to a document for document albums and to a photo or a video otherwise.
3961/// When an inline message is edited, a new file can't be uploaded;
3962/// use a previously uploaded file via its file_id or specify a URL.
3963/// On success, the edited [Message](https://core.telegram.org/bots/api#message) is returned.
3964#[derive(Clone, Serialize)]
3965pub struct EditMessageMedia {
3966    /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
3967    pub chat_id: ChatId,
3968    /// Identifier of the message to edit
3969    pub message_id: i64,
3970    /// A JSON-serialized object for a new media content of the message
3971    pub media: InputMedia,
3972    /// A JSON-serialized object for a new [inline keyboard](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating).
3973    #[serde(skip_serializing_if = "Option::is_none")]
3974    pub reply_markup: Option<InlineKeyboardMarkup>,
3975}
3976
3977impl EditMessageMedia {
3978    /// Create a new editMessageMedia request
3979    pub fn new(chat_id: impl Into<ChatId>, message_id: i64, media: impl Into<InputMedia>) -> Self {
3980        Self {
3981            chat_id: chat_id.into(),
3982            message_id,
3983            media: media.into(),
3984            reply_markup: None,
3985        }
3986    }
3987    /// Set reply markup
3988    pub fn with_reply_markup(self, markup: impl Into<InlineKeyboardMarkup>) -> Self {
3989        Self {
3990            reply_markup: Some(markup.into()),
3991            ..self
3992        }
3993    }
3994}
3995
3996impl TelegramMethod for EditMessageMedia {
3997    type Response = Message;
3998
3999    fn name() -> &'static str {
4000        "editMessageMedia"
4001    }
4002}
4003
4004impl JsonMethod for EditMessageMedia {}
4005
4006/// Use this method to edit animation, audio, document, photo, or video messages.
4007/// If a message is part of a message album, then it can be edited only to an audio for audio albums,
4008/// only to a document for document albums and to a photo or a video otherwise.
4009/// When an inline message is edited, a new file can't be uploaded;
4010/// use a previously uploaded file via its file_id or specify a URL.
4011/// On success, _True_ is returned.
4012#[derive(Clone, Serialize)]
4013pub struct EditInlineMessageMedia {
4014    /// Identifier of the inline message
4015    pub inline_message_id: String,
4016    /// A JSON-serialized object for a new media content of the message
4017    pub media: InputMedia,
4018    /// A JSON-serialized object for a new [inline keyboard](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating).
4019    #[serde(skip_serializing_if = "Option::is_none")]
4020    pub reply_markup: Option<InlineKeyboardMarkup>,
4021}
4022
4023impl EditInlineMessageMedia {
4024    /// Create a new editMessageMedia request
4025    pub fn new(inline_message_id: impl Into<String>, media: impl Into<InputMedia>) -> Self {
4026        Self {
4027            inline_message_id: inline_message_id.into(),
4028            media: media.into(),
4029            reply_markup: None,
4030        }
4031    }
4032    /// Set reply markup
4033    pub fn with_reply_markup(self, markup: impl Into<InlineKeyboardMarkup>) -> Self {
4034        Self {
4035            reply_markup: Some(markup.into()),
4036            ..self
4037        }
4038    }
4039}
4040
4041impl TelegramMethod for EditInlineMessageMedia {
4042    type Response = bool;
4043
4044    fn name() -> &'static str {
4045        "editMessageMedia"
4046    }
4047}
4048
4049impl JsonMethod for EditInlineMessageMedia {}
4050
4051/// Use this method to edit only the reply markup of messages. On success, the edited Message is returned.
4052#[derive(Clone, Serialize)]
4053pub struct EditMessageReplyMarkup {
4054    /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
4055    pub chat_id: ChatId,
4056    /// Identifier of the message to edit
4057    pub message_id: i64,
4058    /// A JSON-serialized object for a new [inline keyboard](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating).
4059    #[serde(skip_serializing_if = "Option::is_none")]
4060    pub reply_markup: Option<InlineKeyboardMarkup>,
4061}
4062
4063impl EditMessageReplyMarkup {
4064    /// Create a new editMessageReplyMarkup request with no reply markup
4065    pub fn new_empty(chat_id: impl Into<ChatId>, message_id: i64) -> Self {
4066        Self {
4067            chat_id: chat_id.into(),
4068            message_id,
4069            reply_markup: None,
4070        }
4071    }
4072    /// Create a new editMessageReplyMarkup with reply markup
4073    pub fn new(
4074        chat_id: impl Into<ChatId>,
4075        message_id: i64,
4076        reply_markup: impl Into<InlineKeyboardMarkup>,
4077    ) -> Self {
4078        Self {
4079            chat_id: chat_id.into(),
4080            message_id,
4081            reply_markup: Some(reply_markup.into()),
4082        }
4083    }
4084}
4085
4086impl TelegramMethod for EditMessageReplyMarkup {
4087    type Response = Message;
4088
4089    fn name() -> &'static str {
4090        "editMessageReplyMarkup"
4091    }
4092}
4093
4094impl JsonMethod for EditMessageReplyMarkup {}
4095
4096/// Use this method to edit only the reply markup of messages. On success, _True_ is returned.
4097#[derive(Clone, Serialize)]
4098pub struct EditInlineMessageReplyMarkup {
4099    /// Identifier of the inline message
4100    pub inline_message_id: String,
4101    /// A JSON-serialized object for a new [inline keyboard](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating).
4102    #[serde(skip_serializing_if = "Option::is_none")]
4103    pub reply_markup: Option<InlineKeyboardMarkup>,
4104}
4105
4106impl EditInlineMessageReplyMarkup {
4107    /// Create a new editMessageReplyMarkup request with no reply markup
4108    pub fn new_empty(inline_message_id: impl Into<String>) -> Self {
4109        Self {
4110            inline_message_id: inline_message_id.into(),
4111            reply_markup: None,
4112        }
4113    }
4114    /// Create a new editMessageReplyMarkup with reply markup
4115    pub fn new(
4116        inline_message_id: impl Into<String>,
4117        reply_markup: impl Into<InlineKeyboardMarkup>,
4118    ) -> Self {
4119        Self {
4120            inline_message_id: inline_message_id.into(),
4121            reply_markup: Some(reply_markup.into()),
4122        }
4123    }
4124}
4125
4126impl TelegramMethod for EditInlineMessageReplyMarkup {
4127    type Response = bool;
4128
4129    fn name() -> &'static str {
4130        "editMessageReplyMarkup"
4131    }
4132}
4133
4134impl JsonMethod for EditInlineMessageReplyMarkup {}
4135
4136/// Use this method to stop a poll which was sent by the bot.
4137/// On success, the stopped [Poll](https://core.telegram.org/bots/api#poll) is returned.
4138#[derive(Clone, Serialize)]
4139pub struct StopPoll {
4140    /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
4141    pub chat_id: ChatId,
4142    /// Identifier of the original message with the poll
4143    pub message_id: i64,
4144    /// A JSON-serialized object for a new [inline keyboard](https://core.telegram.org/bots#inline-keyboards-and-on-the-fly-updating).
4145    #[serde(skip_serializing_if = "Option::is_none")]
4146    pub reply_markup: Option<InlineKeyboardMarkup>,
4147}
4148
4149impl StopPoll {
4150    /// Create a new stopPoll request
4151    pub fn new(chat_id: impl Into<ChatId>, message_id: i64) -> Self {
4152        Self {
4153            chat_id: chat_id.into(),
4154            message_id,
4155            reply_markup: None,
4156        }
4157    }
4158    /// Set reply markup
4159    pub fn with_reply_markup(self, markup: impl Into<InlineKeyboardMarkup>) -> Self {
4160        Self {
4161            reply_markup: Some(markup.into()),
4162            ..self
4163        }
4164    }
4165}
4166
4167impl TelegramMethod for StopPoll {
4168    type Response = Poll;
4169
4170    fn name() -> &'static str {
4171        "stopPoll"
4172    }
4173}
4174
4175impl JsonMethod for StopPoll {}
4176
4177/// Use this method to delete a message, including service messages, with the following limitations:
4178/// - A message can only be deleted if it was sent less than 48 hours ago.
4179/// - A dice message in a private chat can only be deleted if it was sent more than 24 hours ago.
4180/// - Bots can delete outgoing messages in private chats, groups, and supergroups.
4181/// - Bots can delete incoming messages in private chats.
4182/// - Bots granted *can_post_messages* permissions can delete outgoing messages in channels.
4183/// - If the bot is an administrator of a group, it can delete any message there.
4184/// - If the bot has *can_delete_messages* permission in a supergroup or a channel, it can delete any message there.
4185/// Returns _True_ on success.
4186#[derive(Clone, Serialize)]
4187pub struct DeleteMessage {
4188    /// Unique identifier for the target chat or username of the target channel (in the format `@channelusername`)
4189    pub chat_id: ChatId,
4190    /// Identifier of the message to delete
4191    pub message_id: i64,
4192}
4193
4194impl DeleteMessage {
4195    /// Create a new deleteMessage request
4196    pub fn new(chat_id: impl Into<ChatId>, message_id: i64) -> Self {
4197        Self {
4198            chat_id: chat_id.into(),
4199            message_id,
4200        }
4201    }
4202}
4203
4204impl TelegramMethod for DeleteMessage {
4205    type Response = bool;
4206
4207    fn name() -> &'static str {
4208        "deleteMessage"
4209    }
4210}
4211
4212impl JsonMethod for DeleteMessage {}