tgbot/types/definitions/message/
methods.rs

1use serde::Serialize;
2
3use crate::{
4    api::{Form, Method, Payload},
5    types::{
6        ChatId,
7        EditMessageResult,
8        Float,
9        InlineKeyboardError,
10        InlineKeyboardMarkup,
11        InputMedia,
12        Integer,
13        LinkPreviewOptions,
14        Message,
15        MessageId,
16        ParseMode,
17        ReplyMarkup,
18        ReplyParameters,
19        SuggestedPostParameters,
20        TextEntities,
21        TextEntity,
22    },
23};
24
25/// Copies a message.
26///
27/// Service messages, paid media messages, giveaway messages, giveaway winners messages,
28/// and invoice messages can't be copied.
29/// A quiz poll can be copied only if the value of the field `correct_option_id` is known to the bot.
30/// The method is analogous to the method [`ForwardMessage`],
31/// but the copied message doesn't have a link to the original message.
32#[serde_with::skip_serializing_none]
33#[derive(Clone, Debug, Serialize)]
34pub struct CopyMessage {
35    chat_id: ChatId,
36    from_chat_id: ChatId,
37    message_id: Integer,
38    allow_paid_broadcast: Option<bool>,
39    caption: Option<String>,
40    caption_entities: Option<TextEntities>,
41    direct_messages_topic_id: Option<Integer>,
42    disable_notification: Option<bool>,
43    message_thread_id: Option<Integer>,
44    parse_mode: Option<ParseMode>,
45    protect_content: Option<bool>,
46    reply_markup: Option<ReplyMarkup>,
47    reply_parameters: Option<ReplyParameters>,
48    show_caption_above_media: Option<bool>,
49    suggested_post_parameters: Option<SuggestedPostParameters>,
50    video_start_timestamp: Option<Integer>,
51}
52
53impl CopyMessage {
54    /// Creates a new `CopyMessage`.
55    ///
56    /// # Arguments
57    ///
58    /// * `chat_id` - Unique identifier of the target chat.
59    /// * `from_chat_id` - Unique identifier of the chat where the original message was sent.
60    /// * `message_id` - Message identifier in the chat specified in `from_chat_id`.
61    pub fn new<A, B>(chat_id: A, from_chat_id: B, message_id: Integer) -> Self
62    where
63        A: Into<ChatId>,
64        B: Into<ChatId>,
65    {
66        Self {
67            chat_id: chat_id.into(),
68            from_chat_id: from_chat_id.into(),
69            message_id,
70            allow_paid_broadcast: None,
71            caption: None,
72            caption_entities: None,
73            direct_messages_topic_id: None,
74            disable_notification: None,
75            message_thread_id: None,
76            parse_mode: None,
77            protect_content: None,
78            reply_markup: None,
79            reply_parameters: None,
80            show_caption_above_media: None,
81            suggested_post_parameters: None,
82            video_start_timestamp: None,
83        }
84    }
85
86    /// Sets a new value for the `allow_paid_broadcast` flag.
87    ///
88    /// # Arguments
89    ///
90    /// * `value` - Whether to allow up to 1000 messages per second, ignoring broadcasting limits
91    ///   for a fee of 0.1 Telegram Stars per message.
92    ///   The relevant Stars will be withdrawn from the bot's balance.
93    pub fn with_allow_paid_broadcast(mut self, value: bool) -> Self {
94        self.allow_paid_broadcast = Some(value);
95        self
96    }
97
98    /// Sets a new caption.
99    ///
100    /// # Arguments
101    ///
102    /// * `value` - Caption; 0-1024 characters after entities parsing.
103    ///
104    /// If not specified, the original caption is kept.
105    pub fn with_caption<T>(mut self, value: T) -> Self
106    where
107        T: Into<String>,
108    {
109        self.caption = Some(value.into());
110        self
111    }
112
113    /// Sets a new list of caption entities.
114    ///
115    /// # Arguments
116    ///
117    /// * `value` - The list of special entities that appear in the caption.
118    ///
119    /// Caption parse mode will be set to [`None`] when this method is called.
120    pub fn with_caption_entities<T>(mut self, value: T) -> Self
121    where
122        T: IntoIterator<Item = TextEntity>,
123    {
124        self.caption_entities = Some(value.into_iter().collect());
125        self.parse_mode = None;
126        self
127    }
128
129    /// Sets a new caption parse mode.
130    ///
131    /// # Arguments
132    ///
133    /// * `value` - Parse mode.
134    ///
135    /// Caption entities will be set to [`None`] when this method is called.
136    pub fn with_caption_parse_mode(mut self, value: ParseMode) -> Self {
137        self.parse_mode = Some(value);
138        self.caption_entities = None;
139        self
140    }
141
142    /// Sets a new direct messages topic ID
143    ///
144    /// * `value` - Identifier of the direct messages topic to which the message will be sent.
145    ///
146    /// Required if the message is sent to a direct messages chat.
147    pub fn with_direct_messages_topic_id(mut self, value: Integer) -> Self {
148        self.direct_messages_topic_id = Some(value);
149        self
150    }
151
152    /// Sets a new value for the `disable_notification` flag.
153    ///
154    /// # Arguments
155    ///
156    /// * `value` - Indicates whether to send the message silently or not;
157    ///   a user will receive a notification without sound.
158    pub fn with_disable_notification(mut self, value: bool) -> Self {
159        self.disable_notification = Some(value);
160        self
161    }
162
163    /// Sets a new message thread ID.
164    ///
165    /// # Arguments
166    ///
167    /// * `value` - Unique identifier of the target message thread;
168    ///   supergroups only.
169    pub fn with_message_thread_id(mut self, value: Integer) -> Self {
170        self.message_thread_id = Some(value);
171        self
172    }
173
174    /// Sets a new value for the `protect_content` flag.
175    ///
176    /// # Arguments
177    ///
178    /// * `value` - Indicates whether to protect the contents
179    ///   of the sent message from forwarding and saving.
180    pub fn with_protect_content(mut self, value: bool) -> Self {
181        self.protect_content = Some(value);
182        self
183    }
184
185    /// Sets a new reply markup.
186    ///
187    /// # Arguments
188    ///
189    /// * `value` - Reply markup.
190    pub fn with_reply_markup<T>(mut self, value: T) -> Self
191    where
192        T: Into<ReplyMarkup>,
193    {
194        self.reply_markup = Some(value.into());
195        self
196    }
197
198    /// Sets new reply parameters.
199    ///
200    /// # Arguments
201    ///
202    /// * `value` - Description of the message to reply to.
203    pub fn with_reply_parameters(mut self, value: ReplyParameters) -> Self {
204        self.reply_parameters = Some(value);
205        self
206    }
207
208    /// Sets a new value for the `show_caption_above_media` flag.
209    ///
210    /// # Arguments
211    ///
212    /// `value` - Whether the caption must be shown above the message media;
213    ///   ignored if a new caption isn't specified.
214    pub fn with_show_caption_above_media(mut self, value: bool) -> Self {
215        self.show_caption_above_media = Some(value);
216        self
217    }
218
219    /// Sets a new suggested post parameters.
220    ///
221    /// # Arguments
222    ///
223    /// * `value` - An object containing the parameters of the suggested post to send.
224    ///
225    /// For direct messages chats only.
226    ///
227    /// If the message is sent as a reply to another suggested post, then that suggested post is automatically declined.
228    pub fn with_suggested_post_parameters(mut self, value: SuggestedPostParameters) -> Self {
229        self.suggested_post_parameters = Some(value);
230        self
231    }
232
233    /// Sets a new video start timestamp.
234    ///
235    /// # Arguments
236    ///
237    /// * `value` - New start timestamp for the copied video in the message.
238    pub fn with_video_start_timestamp(mut self, value: Integer) -> Self {
239        self.video_start_timestamp = Some(value);
240        self
241    }
242}
243
244impl Method for CopyMessage {
245    type Response = MessageId;
246
247    fn into_payload(self) -> Payload {
248        Payload::json("copyMessage", self)
249    }
250}
251
252/// Copies messages of any kind.
253///
254/// If some of the specified messages can't be found or copied, they are skipped.
255/// Service messages, paid media messages, giveaway messages, giveaway winners messages,
256/// and invoice messages can't be copied.
257/// A quiz poll can be copied only if the value of the field `correct_option_id` is known to the bot.
258/// The method is analogous to the method [`ForwardMessages`],
259/// but the copied messages don't have a link to the original message.
260/// Album grouping is kept for copied messages.
261#[serde_with::skip_serializing_none]
262#[derive(Clone, Debug, Serialize)]
263pub struct CopyMessages {
264    chat_id: ChatId,
265    from_chat_id: ChatId,
266    message_ids: Vec<Integer>,
267    direct_messages_topic_id: Option<Integer>,
268    disable_notification: Option<bool>,
269    message_thread_id: Option<Integer>,
270    protect_content: Option<bool>,
271    remove_caption: Option<bool>,
272}
273
274impl CopyMessages {
275    /// Creates a new `CopyMessages`.
276    ///
277    /// # Arguments
278    ///
279    /// * `chat_id` - Unique identifier for the target chat.
280    /// * `from_chat_id` - Unique identifier for the chat where the original messages were sent.
281    /// * `message_ids` - Identifiers of 1-100 messages in the chat from_chat_id to copy;
282    ///   the identifiers must be specified in a strictly increasing order.
283    pub fn new<A, B, C>(chat_id: A, from_chat_id: B, message_ids: C) -> Self
284    where
285        A: Into<ChatId>,
286        B: Into<ChatId>,
287        C: IntoIterator<Item = Integer>,
288    {
289        Self {
290            chat_id: chat_id.into(),
291            from_chat_id: from_chat_id.into(),
292            message_ids: message_ids.into_iter().collect(),
293            direct_messages_topic_id: None,
294            disable_notification: None,
295            message_thread_id: None,
296            protect_content: None,
297            remove_caption: None,
298        }
299    }
300
301    /// Sets a new direct messages topic ID
302    ///
303    /// * `value` - Identifier of the direct messages topic to which the message will be sent.
304    ///
305    /// Required if the message is sent to a direct messages chat.
306    pub fn with_direct_messages_topic_id(mut self, value: Integer) -> Self {
307        self.direct_messages_topic_id = Some(value);
308        self
309    }
310
311    /// Sets a new value for the `disable_notification` flag.
312    ///
313    /// # Arguments
314    ///
315    /// * `value` - Indicates whether to send the message silently or not;
316    ///   a user will receive a notification without sound.
317    pub fn with_disable_notification(mut self, value: bool) -> Self {
318        self.disable_notification = Some(value);
319        self
320    }
321
322    /// Sets a new message thread ID.
323    ///
324    /// # Arguments
325    ///
326    /// * `value` - Unique identifier of the target message thread;
327    ///   supergroups only.
328    pub fn with_message_thread_id(mut self, value: Integer) -> Self {
329        self.message_thread_id = Some(value);
330        self
331    }
332
333    /// Sets a new value for the `protect_content` flag.
334    ///
335    /// # Arguments
336    ///
337    /// * `value` - Indicates whether to protect the contents
338    ///   of the sent message from forwarding and saving.
339    pub fn with_protect_content(mut self, value: bool) -> Self {
340        self.protect_content = Some(value);
341        self
342    }
343
344    /// Sets a new value for the `remove_caption` flag.
345    ///
346    /// # Arguments
347    ///
348    /// * `value` - Indicates whether to copy the messages without their captions.
349    pub fn with_remove_caption(mut self, value: bool) -> Self {
350        self.remove_caption = Some(value);
351        self
352    }
353}
354
355impl Method for CopyMessages {
356    type Response = Vec<MessageId>;
357
358    fn into_payload(self) -> Payload {
359        Payload::json("copyMessages", self)
360    }
361}
362
363/// Deletes a message.
364///
365/// Limitations:
366///
367/// - A message can only be deleted if it was sent less than 48 hours ago.
368/// - Service messages about a supergroup, channel, or forum topic creation can't be deleted.
369/// - A dice message in a private chat can only be deleted if it was sent more than 24 hours ago.
370/// - Bots can delete outgoing messages in private chats, groups, and supergroups.
371/// - Bots can delete incoming messages in private chats.
372/// - Bots granted can_post_messages permissions can delete outgoing messages in channels.
373/// - If the bot is an administrator of a group, it can delete any message there.
374/// - If the bot has `can_delete_messages` permission in a supergroup or a channel,
375///   it can delete any message there.
376#[derive(Clone, Debug, Serialize)]
377pub struct DeleteMessage {
378    chat_id: ChatId,
379    message_id: Integer,
380}
381
382impl DeleteMessage {
383    /// Creates a new `DeleteMessage`.
384    ///
385    /// # Arguments
386    ///
387    /// * `chat_id` - Unique identifier of the target chat.
388    /// * `message_id` - Identifier of the message to delete.
389    pub fn new<T>(chat_id: T, message_id: Integer) -> Self
390    where
391        T: Into<ChatId>,
392    {
393        Self {
394            chat_id: chat_id.into(),
395            message_id,
396        }
397    }
398}
399
400impl Method for DeleteMessage {
401    type Response = bool;
402
403    fn into_payload(self) -> Payload {
404        Payload::json("deleteMessage", self)
405    }
406}
407
408/// Deletes multiple messages simultaneously.
409///
410/// If some of the specified messages can't be found, they are skipped.
411///
412/// See [`DeleteMessage`] for limitations on which messages can be deleted.
413#[derive(Clone, Debug, Serialize)]
414pub struct DeleteMessages {
415    chat_id: ChatId,
416    message_ids: Vec<Integer>,
417}
418
419impl DeleteMessages {
420    /// Creates a new `DeleteMessages`.
421    ///
422    /// # Arguments
423    ///
424    /// * `chat_id` - Unique identifier of the target chat.
425    /// * `message_ids` - Identifiers of 1-100 messages to delete.
426    pub fn new<A, B>(chat_id: A, message_ids: B) -> Self
427    where
428        A: Into<ChatId>,
429        B: IntoIterator<Item = Integer>,
430    {
431        Self {
432            chat_id: chat_id.into(),
433            message_ids: message_ids.into_iter().collect(),
434        }
435    }
436}
437
438impl Method for DeleteMessages {
439    type Response = bool;
440
441    fn into_payload(self) -> Payload {
442        Payload::json("deleteMessages", self)
443    }
444}
445
446/// Changes a caption of a message.
447#[serde_with::skip_serializing_none]
448#[derive(Clone, Debug, Serialize)]
449pub struct EditMessageCaption {
450    business_connection_id: Option<String>,
451    caption: Option<String>,
452    caption_entities: Option<TextEntities>,
453    chat_id: Option<ChatId>,
454    inline_message_id: Option<String>,
455    message_id: Option<Integer>,
456    parse_mode: Option<ParseMode>,
457    reply_markup: Option<InlineKeyboardMarkup>,
458    show_caption_above_media: Option<bool>,
459}
460
461impl EditMessageCaption {
462    /// Creates a new `EditMessageCaption` for a chat message.
463    ///
464    /// # Arguments
465    ///
466    /// * `chat_id` - Unique identifier of the target chat.
467    /// * `message_id` - Identifier of the sent message.
468    pub fn for_chat_message<T>(chat_id: T, message_id: Integer) -> Self
469    where
470        T: Into<ChatId>,
471    {
472        Self {
473            business_connection_id: None,
474            caption: None,
475            caption_entities: None,
476            chat_id: Some(chat_id.into()),
477            inline_message_id: None,
478            message_id: Some(message_id),
479            parse_mode: None,
480            reply_markup: None,
481            show_caption_above_media: None,
482        }
483    }
484
485    /// Creates a new `EditMessageCaption` for an inline message.
486    ///
487    /// # Arguments
488    ///
489    /// * `inline_message_id` - Identifier of the inline message.
490    pub fn for_inline_message<T>(inline_message_id: T) -> Self
491    where
492        T: Into<String>,
493    {
494        Self {
495            business_connection_id: None,
496            caption: None,
497            caption_entities: None,
498            chat_id: None,
499            inline_message_id: Some(inline_message_id.into()),
500            message_id: None,
501            parse_mode: None,
502            reply_markup: None,
503            show_caption_above_media: None,
504        }
505    }
506
507    /// Sets a new business connection ID.
508    ///
509    /// # Arguments
510    ///
511    /// * `value` - Unique identifier of the business connection on behalf of which the message to be edited was sent.
512    pub fn with_business_connection_id<T>(mut self, value: T) -> Self
513    where
514        T: Into<String>,
515    {
516        self.business_connection_id = Some(value.into());
517        self
518    }
519
520    /// Sets a new caption.
521    ///
522    /// # Arguments
523    ///
524    /// * `value` - Caption; 0-1024 characters.
525    pub fn with_caption<T>(mut self, value: T) -> Self
526    where
527        T: Into<String>,
528    {
529        self.caption = Some(value.into());
530        self
531    }
532
533    /// Sets a new list of caption entities.
534    ///
535    /// # Arguments
536    ///
537    /// * `value` - The list of special entities that appear in the caption.
538    ///
539    /// Caption parse mode will be set to [`None`] when this method is called.
540    pub fn with_caption_entities<T>(mut self, value: T) -> Self
541    where
542        T: IntoIterator<Item = TextEntity>,
543    {
544        self.caption_entities = Some(value.into_iter().collect());
545        self.parse_mode = None;
546        self
547    }
548
549    /// Sets a new caption parse mode.
550    ///
551    /// # Arguments
552    ///
553    /// * `value` - Parse mode.
554    ///
555    /// Caption entities will be set to [`None`] when this method is called.
556    pub fn with_caption_parse_mode(mut self, value: ParseMode) -> Self {
557        self.parse_mode = Some(value);
558        self.caption_entities = None;
559        self
560    }
561
562    /// Sets a new reply markup.
563    ///
564    /// # Arguments
565    ///
566    /// * `value` - Reply markup.
567    pub fn with_reply_markup<T>(mut self, value: T) -> Self
568    where
569        T: Into<InlineKeyboardMarkup>,
570    {
571        self.reply_markup = Some(value.into());
572        self
573    }
574
575    /// Sets a new value for the `show_caption_above_media` flag.
576    ///
577    /// # Arguments
578    ///
579    /// `value` - Whether the caption must be shown above the message media;
580    ///   supported only for animation, photo and video messages.
581    pub fn with_show_caption_above_media(mut self, value: bool) -> Self {
582        self.show_caption_above_media = Some(value);
583        self
584    }
585}
586
587impl Method for EditMessageCaption {
588    type Response = EditMessageResult;
589
590    fn into_payload(self) -> Payload {
591        Payload::json("editMessageCaption", self)
592    }
593}
594
595/// Changes a live location message.
596///
597/// A location can be edited until its `live_period` expires or editing
598/// is explicitly disabled by a call to [`StopMessageLiveLocation`].
599#[serde_with::skip_serializing_none]
600#[derive(Clone, Debug, Serialize)]
601pub struct EditMessageLiveLocation {
602    latitude: Float,
603    longitude: Float,
604    business_connection_id: Option<String>,
605    chat_id: Option<ChatId>,
606    heading: Option<Integer>,
607    horizontal_accuracy: Option<Float>,
608    inline_message_id: Option<String>,
609    live_period: Option<Integer>,
610    message_id: Option<Integer>,
611    proximity_alert_radius: Option<Integer>,
612    reply_markup: Option<InlineKeyboardMarkup>,
613}
614
615impl EditMessageLiveLocation {
616    /// Creates a new `EditMessageLiveLocation` for a chat message.
617    ///
618    /// # Arguments
619    ///
620    /// * `chat_id` - Unique identifier of the target chat.
621    /// * `message_id` - Identifier of the sent message.
622    /// * `latitude` - Latitude of new location.
623    /// * `longitude` Longitude of new location.
624    pub fn for_chat_message<T>(chat_id: T, message_id: Integer, latitude: Float, longitude: Float) -> Self
625    where
626        T: Into<ChatId>,
627    {
628        Self {
629            latitude,
630            longitude,
631            business_connection_id: None,
632            chat_id: Some(chat_id.into()),
633            inline_message_id: None,
634            live_period: None,
635            heading: None,
636            horizontal_accuracy: None,
637            message_id: Some(message_id),
638            proximity_alert_radius: None,
639            reply_markup: None,
640        }
641    }
642
643    /// Creates a new `EditMessageLiveLocation` for an inline message.
644    ///
645    /// # Arguments
646    ///
647    /// * `inline_message_id` - Identifier of the inline message.
648    /// * `latitude` - Latitude of new location.
649    /// * `longitude` - Longitude of new location.
650    pub fn for_inline_message<T>(inline_message_id: T, latitude: Float, longitude: Float) -> Self
651    where
652        T: Into<String>,
653    {
654        Self {
655            latitude,
656            longitude,
657            business_connection_id: None,
658            chat_id: None,
659            heading: None,
660            horizontal_accuracy: None,
661            inline_message_id: Some(inline_message_id.into()),
662            live_period: None,
663            message_id: None,
664            proximity_alert_radius: None,
665            reply_markup: None,
666        }
667    }
668
669    /// Sets a new business connection ID.
670    ///
671    /// # Arguments
672    ///
673    /// * `value` - Unique identifier of the business connection on behalf of which the message to be edited was sent.
674    pub fn with_business_connection_id<T>(mut self, value: T) -> Self
675    where
676        T: Into<String>,
677    {
678        self.business_connection_id = Some(value.into());
679        self
680    }
681
682    /// Sets a new horizontal accuracy.
683    ///
684    /// # Arguments
685    ///
686    /// * `value` - A radius of uncertainty for the location; in meters; 0-1500.
687    pub fn with_horizontal_accuracy(mut self, value: Float) -> Self {
688        self.horizontal_accuracy = Some(value);
689        self
690    }
691
692    /// Sets a new heading.
693    ///
694    /// # Arguments
695    ///
696    /// * `value` - A direction in which the user is moving; in degrees; 1-360.
697    pub fn with_heading(mut self, value: Integer) -> Self {
698        self.heading = Some(value);
699        self
700    }
701
702    /// Sets a new live period
703    ///
704    /// # Arguments
705    ///
706    /// * `value` - New period in seconds during which the location can be updated,
707    ///   starting from the message send date.
708    ///   If 0x7FFFFFFF is specified, then the location can be updated forever.
709    ///   Otherwise, the new value must not exceed the current live_period by more than a day,
710    ///   and the live location expiration date must remain within the next 90 days.
711    ///   If not specified, then live_period remains unchanged
712    pub fn with_live_period(mut self, value: Integer) -> Self {
713        self.live_period = Some(value);
714        self
715    }
716
717    /// Sets a new proximity alert radius.
718    ///
719    /// # Arguments
720    ///
721    /// * `value` - A maximum distance for proximity alerts
722    ///   about approaching another chat member; in meters; 1-100000.
723    pub fn with_proximity_alert_radius(mut self, value: Integer) -> Self {
724        self.proximity_alert_radius = Some(value);
725        self
726    }
727
728    /// Sets a new reply markup.
729    ///
730    /// # Arguments
731    ///
732    /// * `value` - Reply markup.
733    pub fn with_reply_markup<T>(mut self, value: T) -> Self
734    where
735        T: Into<InlineKeyboardMarkup>,
736    {
737        self.reply_markup = Some(value.into());
738        self
739    }
740}
741
742impl Method for EditMessageLiveLocation {
743    type Response = EditMessageResult;
744
745    fn into_payload(self) -> Payload {
746        Payload::json("editMessageLiveLocation", self)
747    }
748}
749
750/// Changes animation, audio, document, photo, or video message.
751///
752/// If a message is part of a message album, then it can be edited only
753/// to an audio for audio albums, only to a document for document albums
754/// and to a photo or a video otherwise.
755/// When an inline message is edited, a new file can't be uploaded;
756/// use a previously uploaded file via its file_id or specify a URL.
757#[derive(Debug)]
758pub struct EditMessageMedia {
759    form: Form,
760}
761
762impl EditMessageMedia {
763    /// Creates a new `EditMessageMedia` for a chat message.
764    ///
765    /// # Arguments
766    ///
767    /// * `chat_id` - Unique identifier of the target chat.
768    /// * `message_id` - Identifier of the sent message.
769    /// * `media` - New media content of the message.
770    pub fn for_chat_message<T>(chat_id: T, message_id: Integer, media: InputMedia) -> Self
771    where
772        T: Into<ChatId>,
773    {
774        let mut form: Form = media.into();
775        form.insert_field("chat_id", chat_id.into());
776        form.insert_field("message_id", message_id);
777        Self { form }
778    }
779
780    /// Creates a new `EditMessageMedia` for an inline message.
781    ///
782    /// # Arguments
783    ///
784    /// * `inline_message_id` - Identifier of the inline message.
785    /// * `media` - New media content of the message.
786    pub fn for_inline_message<T>(inline_message_id: T, media: InputMedia) -> Self
787    where
788        T: Into<String>,
789    {
790        let mut form: Form = media.into();
791        form.insert_field("inline_message_id", inline_message_id.into());
792        EditMessageMedia { form }
793    }
794
795    /// Sets a new business connection ID.
796    ///
797    /// # Arguments
798    ///
799    /// * `value` - Unique identifier of the business connection on behalf of which the message to be edited was sent.
800    pub fn with_business_connection_id<T>(mut self, value: T) -> Self
801    where
802        T: Into<String>,
803    {
804        self.form.insert_field("business_connection_id", value.into());
805        self
806    }
807
808    /// Sets a new reply markup.
809    ///
810    /// # Arguments
811    ///
812    /// * `value` - Reply markup.
813    pub fn with_reply_markup<T>(mut self, value: T) -> Result<Self, InlineKeyboardError>
814    where
815        T: Into<InlineKeyboardMarkup>,
816    {
817        let reply_markup = value.into().serialize()?;
818        self.form.insert_field("reply_markup", reply_markup);
819        Ok(self)
820    }
821}
822
823impl Method for EditMessageMedia {
824    type Response = EditMessageResult;
825
826    fn into_payload(self) -> Payload {
827        Payload::form("editMessageMedia", self.form)
828    }
829}
830
831/// Changes the reply markup of a message.
832#[serde_with::skip_serializing_none]
833#[derive(Clone, Debug, Serialize)]
834pub struct EditMessageReplyMarkup {
835    business_connection_id: Option<String>,
836    chat_id: Option<ChatId>,
837    inline_message_id: Option<String>,
838    message_id: Option<Integer>,
839    reply_markup: Option<InlineKeyboardMarkup>,
840}
841
842impl EditMessageReplyMarkup {
843    /// Creates a new `EditMessageReplyMarkup` for a chat message.
844    ///
845    /// # Arguments
846    ///
847    /// * `chat_id` - Unique identifier of the target chat.
848    /// * `message_id` - Identifier of the sent message.
849    pub fn for_chat_message<T>(chat_id: T, message_id: Integer) -> Self
850    where
851        T: Into<ChatId>,
852    {
853        Self {
854            business_connection_id: None,
855            chat_id: Some(chat_id.into()),
856            inline_message_id: None,
857            message_id: Some(message_id),
858            reply_markup: None,
859        }
860    }
861
862    /// Creates a new `EditMessageReplyMarkup` for an inline message.
863    ///
864    /// # Arguments
865    ///
866    /// * `inline_message_id` - Identifier of the inline message.
867    pub fn for_inline_message<T>(inline_message_id: T) -> Self
868    where
869        T: Into<String>,
870    {
871        Self {
872            business_connection_id: None,
873            chat_id: None,
874            inline_message_id: Some(inline_message_id.into()),
875            message_id: None,
876            reply_markup: None,
877        }
878    }
879
880    /// Sets a new business connection ID.
881    ///
882    /// # Arguments
883    ///
884    /// * `value` - Unique identifier of the business connection on behalf of which the message to be edited was sent.
885    pub fn with_business_connection_id<T>(mut self, value: T) -> Self
886    where
887        T: Into<String>,
888    {
889        self.business_connection_id = Some(value.into());
890        self
891    }
892
893    /// Sets a new reply markup.
894    ///
895    /// # Arguments
896    ///
897    /// * `value` - Reply markup.
898    pub fn with_reply_markup<T>(mut self, value: T) -> Self
899    where
900        T: Into<InlineKeyboardMarkup>,
901    {
902        self.reply_markup = Some(value.into());
903        self
904    }
905}
906
907impl Method for EditMessageReplyMarkup {
908    type Response = EditMessageResult;
909
910    fn into_payload(self) -> Payload {
911        Payload::json("editMessageReplyMarkup", self)
912    }
913}
914
915/// Changes a text or a game message.
916#[serde_with::skip_serializing_none]
917#[derive(Clone, Debug, Serialize)]
918pub struct EditMessageText {
919    text: String,
920    business_connection_id: Option<String>,
921    chat_id: Option<ChatId>,
922    entities: Option<TextEntities>,
923    link_preview_options: Option<LinkPreviewOptions>,
924    inline_message_id: Option<String>,
925    message_id: Option<Integer>,
926    parse_mode: Option<ParseMode>,
927    reply_markup: Option<InlineKeyboardMarkup>,
928}
929
930impl EditMessageText {
931    /// Creates a new `EditMessageText` for a chat message.
932    ///
933    /// # Arguments
934    ///
935    /// * `chat_id` - Unique identifier of the target chat.
936    /// * `message_id` - Identifier of the sent message.
937    /// * `text` - New text of the message.
938    pub fn for_chat_message<A, B>(chat_id: A, message_id: Integer, text: B) -> Self
939    where
940        A: Into<ChatId>,
941        B: Into<String>,
942    {
943        Self {
944            text: text.into(),
945            business_connection_id: None,
946            chat_id: Some(chat_id.into()),
947            link_preview_options: None,
948            entities: None,
949            inline_message_id: None,
950            message_id: Some(message_id),
951            parse_mode: None,
952            reply_markup: None,
953        }
954    }
955
956    /// Creates a new `EditMessageText` for an inline message.
957    ///
958    /// # Arguments
959    ///
960    /// * `inline_message_id` - Identifier of the inline message.
961    /// * `text` - New text of the message.
962    pub fn for_inline_message<A, B>(inline_message_id: A, text: B) -> Self
963    where
964        A: Into<String>,
965        B: Into<String>,
966    {
967        Self {
968            text: text.into(),
969            business_connection_id: None,
970            chat_id: None,
971            link_preview_options: None,
972            entities: None,
973            inline_message_id: Some(inline_message_id.into()),
974            message_id: None,
975            parse_mode: None,
976            reply_markup: None,
977        }
978    }
979
980    /// Sets a new business connection ID.
981    ///
982    /// # Arguments
983    ///
984    /// * `value` - Unique identifier of the business connection on behalf of which the message to be edited was sent.
985    pub fn with_business_connection_id<T>(mut self, value: T) -> Self
986    where
987        T: Into<String>,
988    {
989        self.business_connection_id = Some(value.into());
990        self
991    }
992
993    /// Sets a new list of entities
994    ///
995    /// # Arguments
996    ///
997    /// * `value` - List of special entities that appear in the text.
998    ///
999    /// Parse mode will be set to [`None`] when this method is called.
1000    pub fn with_entities<T>(mut self, value: T) -> Self
1001    where
1002        T: IntoIterator<Item = TextEntity>,
1003    {
1004        self.entities = Some(value.into_iter().collect());
1005        self.parse_mode = None;
1006        self
1007    }
1008
1009    /// Sets a new link preview options.
1010    ///
1011    /// # Arguments
1012    ///
1013    /// * `value` - Link preview generation options for the message.
1014    pub fn with_link_preview_options(mut self, value: LinkPreviewOptions) -> Self {
1015        self.link_preview_options = Some(value);
1016        self
1017    }
1018
1019    /// Sets a new parse mode.
1020    ///
1021    /// # Arguments
1022    ///
1023    /// * `value` - Parse mode.
1024    ///
1025    /// Entities will be set to [`None`] when this method is called.
1026    pub fn with_parse_mode(mut self, value: ParseMode) -> Self {
1027        self.parse_mode = Some(value);
1028        self.entities = None;
1029        self
1030    }
1031
1032    /// Sets a new reply markup.
1033    ///
1034    /// # Arguments
1035    ///
1036    /// * `value` - Reply markup.
1037    pub fn with_reply_markup<T>(mut self, value: T) -> Self
1038    where
1039        T: Into<InlineKeyboardMarkup>,
1040    {
1041        self.reply_markup = Some(value.into());
1042        self
1043    }
1044}
1045
1046impl Method for EditMessageText {
1047    type Response = EditMessageResult;
1048
1049    fn into_payload(self) -> Payload {
1050        Payload::json("editMessageText", self)
1051    }
1052}
1053
1054/// Forwards a message.
1055#[serde_with::skip_serializing_none]
1056#[derive(Clone, Debug, Serialize)]
1057pub struct ForwardMessage {
1058    chat_id: ChatId,
1059    from_chat_id: ChatId,
1060    message_id: Integer,
1061    direct_messages_topic_id: Option<Integer>,
1062    disable_notification: Option<bool>,
1063    protect_content: Option<bool>,
1064    message_thread_id: Option<Integer>,
1065    suggested_post_parameters: Option<SuggestedPostParameters>,
1066    video_start_timestamp: Option<Integer>,
1067}
1068
1069impl ForwardMessage {
1070    /// Creates a new `ForwardMessage`.
1071    ///
1072    /// # Arguments
1073    ///
1074    /// * `chat_id` - Unique identifier of the target chat.
1075    /// * `from_chat_id` - Unique identifier for the chat where the original message was sent.
1076    /// * `message_id` - Message identifier in the chat specified in `from_chat_id`.
1077    pub fn new<A, B>(chat_id: A, from_chat_id: B, message_id: Integer) -> Self
1078    where
1079        A: Into<ChatId>,
1080        B: Into<ChatId>,
1081    {
1082        Self {
1083            chat_id: chat_id.into(),
1084            from_chat_id: from_chat_id.into(),
1085            message_id,
1086            direct_messages_topic_id: None,
1087            disable_notification: None,
1088            protect_content: None,
1089            message_thread_id: None,
1090            suggested_post_parameters: None,
1091            video_start_timestamp: None,
1092        }
1093    }
1094
1095    /// Sets a new direct messages topic ID
1096    ///
1097    /// * `value` - Identifier of the direct messages topic to which the message will be sent.
1098    ///
1099    /// Required if the message is sent to a direct messages chat.
1100    pub fn with_direct_messages_topic_id(mut self, value: Integer) -> Self {
1101        self.direct_messages_topic_id = Some(value);
1102        self
1103    }
1104
1105    /// Sets a new value for the `disable_notification` flag.
1106    ///
1107    /// # Arguments
1108    ///
1109    /// * `value` - Indicates whether to send the message silently or not;
1110    ///   a user will receive a notification without sound.
1111    pub fn with_disable_notification(mut self, value: bool) -> Self {
1112        self.disable_notification = Some(value);
1113        self
1114    }
1115
1116    /// Sets a new message thread ID.
1117    ///
1118    /// # Arguments
1119    ///
1120    /// * `value` - Unique identifier of the target message thread;
1121    ///   supergroups only.
1122    pub fn with_message_thread_id(mut self, value: Integer) -> Self {
1123        self.message_thread_id = Some(value);
1124        self
1125    }
1126
1127    /// Sets a new value for the `protect_content` flag.
1128    ///
1129    /// # Arguments
1130    ///
1131    /// * `value` - Indicates whether to protect the contents
1132    ///   of the sent message from forwarding and saving.
1133    pub fn with_protect_content(mut self, value: bool) -> Self {
1134        self.protect_content = Some(value);
1135        self
1136    }
1137
1138    /// Sets a new suggested post parameters.
1139    ///
1140    /// # Arguments
1141    ///
1142    /// * `value` - An object containing the parameters of the suggested post to send.
1143    ///
1144    /// For direct messages chats only.
1145    ///
1146    /// If the message is sent as a reply to another suggested post, then that suggested post is automatically declined.
1147    pub fn with_suggested_post_parameters(mut self, value: SuggestedPostParameters) -> Self {
1148        self.suggested_post_parameters = Some(value);
1149        self
1150    }
1151
1152    /// Sets a new video start timestamp.
1153    ///
1154    /// # Arguments
1155    ///
1156    /// * `value` - New start timestamp for the forwarded video in the message.
1157    pub fn with_video_start_timestamp(mut self, value: Integer) -> Self {
1158        self.video_start_timestamp = Some(value);
1159        self
1160    }
1161}
1162
1163impl Method for ForwardMessage {
1164    type Response = Message;
1165
1166    fn into_payload(self) -> Payload {
1167        Payload::json("forwardMessage", self)
1168    }
1169}
1170
1171/// Forwards multiple messages.
1172///
1173/// If some of the specified messages can't be found or forwarded, they are skipped.
1174/// Service messages and messages with protected content can't be forwarded.
1175/// Album grouping is kept for forwarded messages.
1176#[serde_with::skip_serializing_none]
1177#[derive(Clone, Debug, Serialize)]
1178pub struct ForwardMessages {
1179    chat_id: ChatId,
1180    from_chat_id: ChatId,
1181    message_ids: Vec<Integer>,
1182    direct_messages_topic_id: Option<Integer>,
1183    disable_notification: Option<bool>,
1184    protect_content: Option<bool>,
1185    message_thread_id: Option<Integer>,
1186}
1187
1188impl ForwardMessages {
1189    /// Creates a new `ForwardMessages`.
1190    ///
1191    /// # Arguments
1192    ///
1193    /// * `chat_id` - Unique identifier of the target chat.
1194    /// * `from_chat_id` - Unique identifier for the chat where the original message was sent.
1195    /// * `message_ids` - Identifiers of 1-100 messages in the chat `from_chat_id` to forward;
1196    ///   the identifiers must be specified in a strictly increasing order.
1197    pub fn new<A, B, C>(chat_id: A, from_chat_id: B, message_ids: C) -> Self
1198    where
1199        A: Into<ChatId>,
1200        B: Into<ChatId>,
1201        C: IntoIterator<Item = Integer>,
1202    {
1203        Self {
1204            chat_id: chat_id.into(),
1205            from_chat_id: from_chat_id.into(),
1206            message_ids: message_ids.into_iter().collect(),
1207            direct_messages_topic_id: None,
1208            disable_notification: None,
1209            protect_content: None,
1210            message_thread_id: None,
1211        }
1212    }
1213
1214    /// Sets a new direct messages topic ID
1215    ///
1216    /// * `value` - Identifier of the direct messages topic to which the message will be sent.
1217    ///
1218    /// Required if the message is sent to a direct messages chat.
1219    pub fn with_direct_messages_topic_id(mut self, value: Integer) -> Self {
1220        self.direct_messages_topic_id = Some(value);
1221        self
1222    }
1223
1224    /// Sets a new value for the `disable_notification` flag.
1225    ///
1226    /// # Arguments
1227    ///
1228    /// * `value` - Indicates whether to send the message silently or not;
1229    ///   a user will receive a notification without sound.
1230    pub fn with_disable_notification(mut self, value: bool) -> Self {
1231        self.disable_notification = Some(value);
1232        self
1233    }
1234
1235    /// Sets a new message thread ID.
1236    ///
1237    /// # Arguments
1238    ///
1239    /// * `value` - Unique identifier of the target message thread;
1240    ///   supergroups only.
1241    pub fn with_message_thread_id(mut self, value: Integer) -> Self {
1242        self.message_thread_id = Some(value);
1243        self
1244    }
1245
1246    /// Sets a new value for the `protect_content` flag.
1247    ///
1248    /// # Arguments
1249    ///
1250    /// * `value` - Indicates whether to protect the contents
1251    ///   of the sent message from forwarding and saving.
1252    pub fn with_protect_content(mut self, value: bool) -> Self {
1253        self.protect_content = Some(value);
1254        self
1255    }
1256}
1257
1258impl Method for ForwardMessages {
1259    type Response = Vec<MessageId>;
1260
1261    fn into_payload(self) -> Payload {
1262        Payload::json("forwardMessages", self)
1263    }
1264}
1265
1266/// Sends a text message.
1267#[serde_with::skip_serializing_none]
1268#[derive(Clone, Debug, Serialize)]
1269pub struct SendMessage {
1270    chat_id: ChatId,
1271    text: String,
1272    allow_paid_broadcast: Option<bool>,
1273    business_connection_id: Option<String>,
1274    direct_messages_topic_id: Option<Integer>,
1275    disable_notification: Option<bool>,
1276    entities: Option<TextEntities>,
1277    link_preview_options: Option<LinkPreviewOptions>,
1278    message_effect_id: Option<String>,
1279    message_thread_id: Option<Integer>,
1280    parse_mode: Option<ParseMode>,
1281    protect_content: Option<bool>,
1282    reply_markup: Option<ReplyMarkup>,
1283    reply_parameters: Option<ReplyParameters>,
1284    suggested_post_parameters: Option<SuggestedPostParameters>,
1285}
1286
1287impl SendMessage {
1288    /// Creates a new `SendMessage`.
1289    ///
1290    /// # Arguments
1291    ///
1292    /// * `chat_id` - Unique identifier for the target chat.
1293    /// * `text` - Text of the message to be sent.
1294    pub fn new<A, B>(chat_id: A, text: B) -> Self
1295    where
1296        A: Into<ChatId>,
1297        B: Into<String>,
1298    {
1299        Self {
1300            chat_id: chat_id.into(),
1301            text: text.into(),
1302            allow_paid_broadcast: None,
1303            business_connection_id: None,
1304            direct_messages_topic_id: None,
1305            disable_notification: None,
1306            entities: None,
1307            link_preview_options: None,
1308            message_effect_id: None,
1309            message_thread_id: None,
1310            parse_mode: None,
1311            protect_content: None,
1312            reply_markup: None,
1313            reply_parameters: None,
1314            suggested_post_parameters: None,
1315        }
1316    }
1317
1318    /// Sets a new value for the `allow_paid_broadcast` flag.
1319    ///
1320    /// # Arguments
1321    ///
1322    /// * `value` - Whether to allow up to 1000 messages per second, ignoring broadcasting limits
1323    ///   for a fee of 0.1 Telegram Stars per message.
1324    ///   The relevant Stars will be withdrawn from the bot's balance.
1325    pub fn with_allow_paid_broadcast(mut self, value: bool) -> Self {
1326        self.allow_paid_broadcast = Some(value);
1327        self
1328    }
1329
1330    /// Sets a new business connection ID.
1331    ///
1332    /// # Arguments
1333    ///
1334    /// * `value` - Unique identifier of the business connection.
1335    pub fn with_business_connection_id<T>(mut self, value: T) -> Self
1336    where
1337        T: Into<String>,
1338    {
1339        self.business_connection_id = Some(value.into());
1340        self
1341    }
1342
1343    /// Sets a new direct messages topic ID
1344    ///
1345    /// * `value` - Identifier of the direct messages topic to which the message will be sent.
1346    ///
1347    /// Required if the message is sent to a direct messages chat.
1348    pub fn with_direct_messages_topic_id(mut self, value: Integer) -> Self {
1349        self.direct_messages_topic_id = Some(value);
1350        self
1351    }
1352
1353    /// Sets a new value for the `disable_notification` flag.
1354    ///
1355    /// # Arguments
1356    ///
1357    /// * `value` - Indicates whether to send the message silently or not;
1358    ///   a user will receive a notification without sound.
1359    pub fn with_disable_notification(mut self, value: bool) -> Self {
1360        self.disable_notification = Some(value);
1361        self
1362    }
1363
1364    /// Sets a new list of entities.
1365    ///
1366    /// # Arguments
1367    ///
1368    /// * `value` - List of special entities that appear in the text.
1369    ///
1370    /// Parse mode will be set to [`None`] when this method is called.
1371    pub fn with_entities<T>(mut self, value: T) -> Self
1372    where
1373        T: IntoIterator<Item = TextEntity>,
1374    {
1375        self.entities = Some(value.into_iter().collect());
1376        self.parse_mode = None;
1377        self
1378    }
1379
1380    /// Sets a new link preview options.
1381    ///
1382    /// # Arguments
1383    ///
1384    /// * `value` - Link preview generation options for the message.
1385    pub fn with_link_preview_options(mut self, value: LinkPreviewOptions) -> Self {
1386        self.link_preview_options = Some(value);
1387        self
1388    }
1389
1390    /// Sets a new message effect ID.
1391    ///
1392    /// # Arguments
1393    ///
1394    /// * `value` - Unique identifier of the message effect to be added to the message; for private chats only.
1395    pub fn with_message_effect_id<T>(mut self, value: T) -> Self
1396    where
1397        T: Into<String>,
1398    {
1399        self.message_effect_id = Some(value.into());
1400        self
1401    }
1402
1403    /// Sets a new message thread ID.
1404    ///
1405    /// # Arguments
1406    ///
1407    /// * `value` - Unique identifier of the target message thread;
1408    ///   supergroups only.
1409    pub fn with_message_thread_id(mut self, value: Integer) -> Self {
1410        self.message_thread_id = Some(value);
1411        self
1412    }
1413
1414    /// Sets a new parse mode.
1415    ///
1416    /// # Arguments
1417    ///
1418    /// * `value` - Parse mode.
1419    ///
1420    /// Entities will be set to [`None`] when this method is called.
1421    pub fn with_parse_mode(mut self, value: ParseMode) -> Self {
1422        self.parse_mode = Some(value);
1423        self.entities = None;
1424        self
1425    }
1426
1427    /// Sets a new value for the `protect_content` flag.
1428    ///
1429    /// # Arguments
1430    ///
1431    /// * `value` - Indicates whether to protect the contents
1432    ///   of the sent message from forwarding and saving.
1433    pub fn with_protect_content(mut self, value: bool) -> Self {
1434        self.protect_content = Some(value);
1435        self
1436    }
1437
1438    /// Sets a new reply markup.
1439    ///
1440    /// # Arguments
1441    ///
1442    /// * `value` - Reply markup.
1443    pub fn with_reply_markup<T>(mut self, value: T) -> Self
1444    where
1445        T: Into<ReplyMarkup>,
1446    {
1447        self.reply_markup = Some(value.into());
1448        self
1449    }
1450
1451    /// Sets new reply parameters.
1452    ///
1453    /// # Arguments
1454    ///
1455    /// * `value` - Description of the message to reply to.
1456    pub fn with_reply_parameters(mut self, value: ReplyParameters) -> Self {
1457        self.reply_parameters = Some(value);
1458        self
1459    }
1460
1461    /// Sets a new suggested post parameters.
1462    ///
1463    /// # Arguments
1464    ///
1465    /// * `value` - An object containing the parameters of the suggested post to send.
1466    ///
1467    /// For direct messages chats only.
1468    ///
1469    /// If the message is sent as a reply to another suggested post, then that suggested post is automatically declined.
1470    pub fn with_suggested_post_parameters(mut self, value: SuggestedPostParameters) -> Self {
1471        self.suggested_post_parameters = Some(value);
1472        self
1473    }
1474}
1475
1476impl Method for SendMessage {
1477    type Response = Message;
1478
1479    fn into_payload(self) -> Payload {
1480        Payload::json("sendMessage", self)
1481    }
1482}
1483
1484/// Stops updating a live location message before `live_period` expires.
1485#[serde_with::skip_serializing_none]
1486#[derive(Clone, Debug, Serialize)]
1487pub struct StopMessageLiveLocation {
1488    business_connection_id: Option<String>,
1489    chat_id: Option<ChatId>,
1490    inline_message_id: Option<String>,
1491    message_id: Option<Integer>,
1492    reply_markup: Option<InlineKeyboardMarkup>,
1493}
1494
1495impl StopMessageLiveLocation {
1496    /// Creates a new `StopMessageLiveLocation` for a chat message.
1497    ///
1498    /// # Arguments
1499    ///
1500    /// * `chat_id` - Unique identifier for the target chat.
1501    /// * `message_id` - Identifier of the sent message.
1502    pub fn for_chat_message<T>(chat_id: T, message_id: Integer) -> Self
1503    where
1504        T: Into<ChatId>,
1505    {
1506        Self {
1507            business_connection_id: None,
1508            chat_id: Some(chat_id.into()),
1509            inline_message_id: None,
1510            message_id: Some(message_id),
1511            reply_markup: None,
1512        }
1513    }
1514
1515    /// Creates a new `StopMessageLiveLocation` for an inline message.
1516    ///
1517    /// # Arguments
1518    ///
1519    /// * `inline_message_id` - Identifier of the inline message.
1520    pub fn for_inline_message<T>(inline_message_id: T) -> Self
1521    where
1522        T: Into<String>,
1523    {
1524        Self {
1525            business_connection_id: None,
1526            chat_id: None,
1527            inline_message_id: Some(inline_message_id.into()),
1528            message_id: None,
1529            reply_markup: None,
1530        }
1531    }
1532
1533    /// Sets a new business connection ID.
1534    ///
1535    /// # Arguments
1536    ///
1537    /// * `value` - Unique identifier of the business connection on behalf of which the message to be edited was sent.
1538    pub fn with_business_connection_id<T>(mut self, value: T) -> Self
1539    where
1540        T: Into<String>,
1541    {
1542        self.business_connection_id = Some(value.into());
1543        self
1544    }
1545
1546    /// Sets a new reply markup.
1547    ///
1548    /// # Arguments
1549    ///
1550    /// * `value` - Reply markup.
1551    pub fn with_reply_markup<T>(mut self, value: T) -> Self
1552    where
1553        T: Into<InlineKeyboardMarkup>,
1554    {
1555        self.reply_markup = Some(value.into());
1556        self
1557    }
1558}
1559
1560impl Method for StopMessageLiveLocation {
1561    type Response = EditMessageResult;
1562
1563    fn into_payload(self) -> Payload {
1564        Payload::json("stopMessageLiveLocation", self)
1565    }
1566}