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