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}