1use std::future::{Future, IntoFuture};
2use std::pin::Pin;
3
4use reqwest::multipart::{Form, Part};
5use serde::Serialize;
6
7use rustigram_types::file::InputFile;
8use rustigram_types::keyboard::ReplyMarkup;
9use rustigram_types::message::{LinkPreviewOptions, Message, ParseMode, ReplyParameters};
10use rustigram_types::poll::InputPollOption;
11use rustigram_types::suggested_post::SuggestedPostParameters;
12use rustigram_types::user::ChatId;
13
14use crate::client::BotClient;
15use crate::error::Result;
16
17macro_rules! impl_into_future {
21 ($builder:ident, $return_ty:ty, $method:literal) => {
22 impl IntoFuture for $builder {
23 type Output = Result<$return_ty>;
24 type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
25
26 fn into_future(self) -> Self::IntoFuture {
27 Box::pin(async move { self.client.post_json($method, &self.params).await })
28 }
29 }
30 };
31}
32
33#[derive(Serialize)]
36struct SendMessageParams {
37 chat_id: ChatId,
38 text: String,
39 #[serde(skip_serializing_if = "Option::is_none")]
40 business_connection_id: Option<String>,
41 #[serde(skip_serializing_if = "Option::is_none")]
42 message_thread_id: Option<i64>,
43 #[serde(skip_serializing_if = "Option::is_none")]
44 direct_messages_topic_id: Option<i64>,
45 #[serde(skip_serializing_if = "Option::is_none")]
46 parse_mode: Option<ParseMode>,
47 #[serde(skip_serializing_if = "Option::is_none")]
48 entities: Option<Vec<rustigram_types::message::MessageEntity>>,
49 #[serde(skip_serializing_if = "Option::is_none")]
50 link_preview_options: Option<LinkPreviewOptions>,
51 #[serde(skip_serializing_if = "Option::is_none")]
52 disable_notification: Option<bool>,
53 #[serde(skip_serializing_if = "Option::is_none")]
54 protect_content: Option<bool>,
55 #[serde(skip_serializing_if = "Option::is_none")]
56 allow_paid_broadcast: Option<bool>,
57 #[serde(skip_serializing_if = "Option::is_none")]
58 message_effect_id: Option<String>,
59 #[serde(skip_serializing_if = "Option::is_none")]
60 reply_parameters: Option<ReplyParameters>,
61 #[serde(skip_serializing_if = "Option::is_none")]
62 reply_markup: Option<ReplyMarkup>,
63 #[serde(skip_serializing_if = "Option::is_none")]
64 suggested_post_parameters: Option<SuggestedPostParameters>,
65}
66
67pub struct SendMessage {
69 client: BotClient,
70 params: SendMessageParams,
71}
72
73impl SendMessage {
74 pub(crate) fn new(
75 client: BotClient,
76 chat_id: impl Into<ChatId>,
77 text: impl Into<String>,
78 ) -> Self {
79 Self {
80 client,
81 params: SendMessageParams {
82 chat_id: chat_id.into(),
83 text: text.into(),
84 business_connection_id: None,
85 message_thread_id: None,
86 direct_messages_topic_id: None,
87 parse_mode: None,
88 entities: None,
89 link_preview_options: None,
90 disable_notification: None,
91 protect_content: None,
92 allow_paid_broadcast: None,
93 message_effect_id: None,
94 reply_parameters: None,
95 reply_markup: None,
96 suggested_post_parameters: None,
97 },
98 }
99 }
100 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
102 self.params.business_connection_id = Some(id.into());
103 self
104 }
105 pub fn message_thread_id(mut self, id: i64) -> Self {
107 self.params.message_thread_id = Some(id);
108 self
109 }
110 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
112 self.params.direct_messages_topic_id = Some(id);
113 self
114 }
115 pub fn parse_mode(mut self, mode: ParseMode) -> Self {
117 self.params.parse_mode = Some(mode);
118 self
119 }
120 pub fn entities(mut self, entities: Vec<rustigram_types::message::MessageEntity>) -> Self {
122 self.params.entities = Some(entities);
123 self
124 }
125 pub fn link_preview_options(mut self, opts: LinkPreviewOptions) -> Self {
127 self.params.link_preview_options = Some(opts);
128 self
129 }
130 pub fn disable_notification(mut self, v: bool) -> Self {
132 self.params.disable_notification = Some(v);
133 self
134 }
135 pub fn protect_content(mut self, v: bool) -> Self {
137 self.params.protect_content = Some(v);
138 self
139 }
140 pub fn allow_paid_broadcast(mut self, v: bool) -> Self {
142 self.params.allow_paid_broadcast = Some(v);
143 self
144 }
145 pub fn message_effect_id(mut self, id: impl Into<String>) -> Self {
147 self.params.message_effect_id = Some(id.into());
148 self
149 }
150 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
152 self.params.reply_parameters = Some(rp);
153 self
154 }
155 pub fn reply_to(mut self, message_id: i64) -> Self {
157 self.params.reply_parameters = Some(ReplyParameters {
158 message_id,
159 chat_id: None,
160 allow_sending_without_reply: None,
161 quote: None,
162 quote_parse_mode: None,
163 quote_entities: None,
164 quote_position: None,
165 poll_option_id: None,
166 checklist_task_id: None,
167 });
168 self
169 }
170 pub fn reply_markup(mut self, markup: impl Into<ReplyMarkup>) -> Self {
172 self.params.reply_markup = Some(markup.into());
173 self
174 }
175 pub fn suggested_post_parameters(mut self, params: SuggestedPostParameters) -> Self {
177 self.params.suggested_post_parameters = Some(params);
178 self
179 }
180}
181
182impl_into_future!(SendMessage, Message, "sendMessage");
183
184#[derive(Serialize)]
187struct ForwardMessageParams {
188 chat_id: ChatId,
189 from_chat_id: ChatId,
190 message_id: i64,
191 #[serde(skip_serializing_if = "Option::is_none")]
192 message_thread_id: Option<i64>,
193 #[serde(skip_serializing_if = "Option::is_none")]
194 direct_messages_topic_id: Option<i64>,
195 #[serde(skip_serializing_if = "Option::is_none")]
196 video_start_timestamp: Option<i64>,
197 #[serde(skip_serializing_if = "Option::is_none")]
198 disable_notification: Option<bool>,
199 #[serde(skip_serializing_if = "Option::is_none")]
200 protect_content: Option<bool>,
201}
202
203pub struct ForwardMessage {
205 client: BotClient,
206 params: ForwardMessageParams,
207}
208
209impl ForwardMessage {
210 pub(crate) fn new(
211 client: BotClient,
212 chat_id: impl Into<ChatId>,
213 from_chat_id: impl Into<ChatId>,
214 message_id: i64,
215 ) -> Self {
216 Self {
217 client,
218 params: ForwardMessageParams {
219 chat_id: chat_id.into(),
220 from_chat_id: from_chat_id.into(),
221 message_id,
222 message_thread_id: None,
223 direct_messages_topic_id: None,
224 video_start_timestamp: None,
225 disable_notification: None,
226 protect_content: None,
227 },
228 }
229 }
230 pub fn message_thread_id(mut self, id: i64) -> Self {
232 self.params.message_thread_id = Some(id);
233 self
234 }
235 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
237 self.params.direct_messages_topic_id = Some(id);
238 self
239 }
240 pub fn video_start_timestamp(mut self, ts: i64) -> Self {
242 self.params.video_start_timestamp = Some(ts);
243 self
244 }
245 pub fn disable_notification(mut self, v: bool) -> Self {
247 self.params.disable_notification = Some(v);
248 self
249 }
250 pub fn protect_content(mut self, v: bool) -> Self {
252 self.params.protect_content = Some(v);
253 self
254 }
255}
256
257impl_into_future!(ForwardMessage, Message, "forwardMessage");
258
259#[derive(Serialize)]
262struct CopyMessageParams {
263 chat_id: ChatId,
264 from_chat_id: ChatId,
265 message_id: i64,
266 #[serde(skip_serializing_if = "Option::is_none")]
267 message_thread_id: Option<i64>,
268 #[serde(skip_serializing_if = "Option::is_none")]
269 direct_messages_topic_id: Option<i64>,
270 #[serde(skip_serializing_if = "Option::is_none")]
271 video_start_timestamp: Option<i64>,
272 #[serde(skip_serializing_if = "Option::is_none")]
273 caption: Option<String>,
274 #[serde(skip_serializing_if = "Option::is_none")]
275 parse_mode: Option<ParseMode>,
276 #[serde(skip_serializing_if = "Option::is_none")]
277 caption_entities: Option<Vec<rustigram_types::message::MessageEntity>>,
278 #[serde(skip_serializing_if = "Option::is_none")]
279 show_caption_above_media: Option<bool>,
280 #[serde(skip_serializing_if = "Option::is_none")]
281 disable_notification: Option<bool>,
282 #[serde(skip_serializing_if = "Option::is_none")]
283 protect_content: Option<bool>,
284 #[serde(skip_serializing_if = "Option::is_none")]
285 reply_parameters: Option<ReplyParameters>,
286 #[serde(skip_serializing_if = "Option::is_none")]
287 reply_markup: Option<ReplyMarkup>,
288}
289
290pub struct CopyMessage {
292 client: BotClient,
293 params: CopyMessageParams,
294}
295
296impl CopyMessage {
297 pub(crate) fn new(
298 client: BotClient,
299 chat_id: impl Into<ChatId>,
300 from_chat_id: impl Into<ChatId>,
301 message_id: i64,
302 ) -> Self {
303 Self {
304 client,
305 params: CopyMessageParams {
306 chat_id: chat_id.into(),
307 from_chat_id: from_chat_id.into(),
308 message_id,
309 message_thread_id: None,
310 direct_messages_topic_id: None,
311 video_start_timestamp: None,
312 caption: None,
313 parse_mode: None,
314 caption_entities: None,
315 show_caption_above_media: None,
316 disable_notification: None,
317 protect_content: None,
318 reply_parameters: None,
319 reply_markup: None,
320 },
321 }
322 }
323 pub fn message_thread_id(mut self, id: i64) -> Self {
325 self.params.message_thread_id = Some(id);
326 self
327 }
328 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
330 self.params.direct_messages_topic_id = Some(id);
331 self
332 }
333 pub fn video_start_timestamp(mut self, ts: i64) -> Self {
335 self.params.video_start_timestamp = Some(ts);
336 self
337 }
338 pub fn caption(mut self, c: impl Into<String>) -> Self {
340 self.params.caption = Some(c.into());
341 self
342 }
343 pub fn parse_mode(mut self, m: ParseMode) -> Self {
345 self.params.parse_mode = Some(m);
346 self
347 }
348 pub fn disable_notification(mut self, v: bool) -> Self {
350 self.params.disable_notification = Some(v);
351 self
352 }
353 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self {
355 self.params.reply_markup = Some(m.into());
356 self
357 }
358}
359
360impl_into_future!(
361 CopyMessage,
362 rustigram_types::message::MessageId,
363 "copyMessage"
364);
365
366#[derive(Serialize)]
369struct SendChatActionParams {
370 chat_id: ChatId,
371 action: ChatAction,
372 #[serde(skip_serializing_if = "Option::is_none")]
373 business_connection_id: Option<String>,
374 #[serde(skip_serializing_if = "Option::is_none")]
375 message_thread_id: Option<i64>,
376}
377
378#[derive(Serialize, Clone, Copy)]
379#[serde(rename_all = "snake_case")]
381pub enum ChatAction {
382 Typing,
384 UploadPhoto,
386 RecordVideo,
388 UploadVideo,
390 RecordVoice,
392 UploadVoice,
394 UploadDocument,
396 ChooseSticker,
398 FindLocation,
400 RecordVideoNote,
402 UploadVideoNote,
404}
405
406pub struct SendChatAction {
408 client: BotClient,
409 params: SendChatActionParams,
410}
411
412impl SendChatAction {
413 pub(crate) fn new(client: BotClient, chat_id: impl Into<ChatId>, action: ChatAction) -> Self {
414 Self {
415 client,
416 params: SendChatActionParams {
417 chat_id: chat_id.into(),
418 action,
419 business_connection_id: None,
420 message_thread_id: None,
421 },
422 }
423 }
424 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
426 self.params.business_connection_id = Some(id.into());
427 self
428 }
429 pub fn message_thread_id(mut self, id: i64) -> Self {
431 self.params.message_thread_id = Some(id);
432 self
433 }
434}
435
436impl_into_future!(SendChatAction, bool, "sendChatAction");
437
438#[derive(Serialize)]
441struct SendDiceParams {
442 chat_id: ChatId,
443 #[serde(skip_serializing_if = "Option::is_none")]
444 emoji: Option<String>,
445 #[serde(skip_serializing_if = "Option::is_none")]
446 message_thread_id: Option<i64>,
447 #[serde(skip_serializing_if = "Option::is_none")]
448 direct_messages_topic_id: Option<i64>,
449 #[serde(skip_serializing_if = "Option::is_none")]
450 disable_notification: Option<bool>,
451 #[serde(skip_serializing_if = "Option::is_none")]
452 protect_content: Option<bool>,
453 #[serde(skip_serializing_if = "Option::is_none")]
454 reply_parameters: Option<ReplyParameters>,
455 #[serde(skip_serializing_if = "Option::is_none")]
456 reply_markup: Option<ReplyMarkup>,
457}
458
459pub struct SendDice {
461 client: BotClient,
462 params: SendDiceParams,
463}
464
465impl SendDice {
466 pub(crate) fn new(client: BotClient, chat_id: impl Into<ChatId>) -> Self {
467 Self {
468 client,
469 params: SendDiceParams {
470 chat_id: chat_id.into(),
471 emoji: None,
472 message_thread_id: None,
473 direct_messages_topic_id: None,
474 disable_notification: None,
475 protect_content: None,
476 reply_parameters: None,
477 reply_markup: None,
478 },
479 }
480 }
481 pub fn emoji(mut self, e: impl Into<String>) -> Self {
483 self.params.emoji = Some(e.into());
484 self
485 }
486 pub fn message_thread_id(mut self, id: i64) -> Self {
488 self.params.message_thread_id = Some(id);
489 self
490 }
491 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
493 self.params.direct_messages_topic_id = Some(id);
494 self
495 }
496 pub fn disable_notification(mut self, v: bool) -> Self {
498 self.params.disable_notification = Some(v);
499 self
500 }
501 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self {
503 self.params.reply_markup = Some(m.into());
504 self
505 }
506}
507
508impl_into_future!(SendDice, Message, "sendDice");
509
510#[derive(Serialize)]
513struct SendLocationParams {
514 chat_id: ChatId,
515 latitude: f64,
516 longitude: f64,
517 #[serde(skip_serializing_if = "Option::is_none")]
518 message_thread_id: Option<i64>,
519 #[serde(skip_serializing_if = "Option::is_none")]
520 direct_messages_topic_id: Option<i64>,
521 #[serde(skip_serializing_if = "Option::is_none")]
522 horizontal_accuracy: Option<f64>,
523 #[serde(skip_serializing_if = "Option::is_none")]
524 live_period: Option<u32>,
525 #[serde(skip_serializing_if = "Option::is_none")]
526 heading: Option<u16>,
527 #[serde(skip_serializing_if = "Option::is_none")]
528 proximity_alert_radius: Option<u32>,
529 #[serde(skip_serializing_if = "Option::is_none")]
530 disable_notification: Option<bool>,
531 #[serde(skip_serializing_if = "Option::is_none")]
532 protect_content: Option<bool>,
533 #[serde(skip_serializing_if = "Option::is_none")]
534 reply_parameters: Option<ReplyParameters>,
535 #[serde(skip_serializing_if = "Option::is_none")]
536 reply_markup: Option<ReplyMarkup>,
537}
538
539pub struct SendLocation {
541 client: BotClient,
542 params: SendLocationParams,
543}
544
545impl SendLocation {
546 pub(crate) fn new(
547 client: BotClient,
548 chat_id: impl Into<ChatId>,
549 latitude: f64,
550 longitude: f64,
551 ) -> Self {
552 Self {
553 client,
554 params: SendLocationParams {
555 chat_id: chat_id.into(),
556 latitude,
557 longitude,
558 message_thread_id: None,
559 direct_messages_topic_id: None,
560 horizontal_accuracy: None,
561 live_period: None,
562 heading: None,
563 proximity_alert_radius: None,
564 disable_notification: None,
565 protect_content: None,
566 reply_parameters: None,
567 reply_markup: None,
568 },
569 }
570 }
571 pub fn message_thread_id(mut self, id: i64) -> Self {
573 self.params.message_thread_id = Some(id);
574 self
575 }
576 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
578 self.params.direct_messages_topic_id = Some(id);
579 self
580 }
581 pub fn horizontal_accuracy(mut self, v: f64) -> Self {
583 self.params.horizontal_accuracy = Some(v);
584 self
585 }
586 pub fn live_period(mut self, v: u32) -> Self {
588 self.params.live_period = Some(v);
589 self
590 }
591 pub fn heading(mut self, v: u16) -> Self {
593 self.params.heading = Some(v);
594 self
595 }
596 pub fn proximity_alert_radius(mut self, v: u32) -> Self {
598 self.params.proximity_alert_radius = Some(v);
599 self
600 }
601 pub fn disable_notification(mut self, v: bool) -> Self {
603 self.params.disable_notification = Some(v);
604 self
605 }
606 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self {
608 self.params.reply_markup = Some(m.into());
609 self
610 }
611}
612
613impl_into_future!(SendLocation, Message, "sendLocation");
614
615#[derive(Serialize)]
618struct SendContactParams {
619 chat_id: ChatId,
620 phone_number: String,
621 first_name: String,
622 #[serde(skip_serializing_if = "Option::is_none")]
623 last_name: Option<String>,
624 #[serde(skip_serializing_if = "Option::is_none")]
625 vcard: Option<String>,
626 #[serde(skip_serializing_if = "Option::is_none")]
627 message_thread_id: Option<i64>,
628 #[serde(skip_serializing_if = "Option::is_none")]
629 direct_messages_topic_id: Option<i64>,
630 #[serde(skip_serializing_if = "Option::is_none")]
631 disable_notification: Option<bool>,
632 #[serde(skip_serializing_if = "Option::is_none")]
633 protect_content: Option<bool>,
634 #[serde(skip_serializing_if = "Option::is_none")]
635 reply_parameters: Option<ReplyParameters>,
636 #[serde(skip_serializing_if = "Option::is_none")]
637 reply_markup: Option<ReplyMarkup>,
638}
639
640pub struct SendContact {
642 client: BotClient,
643 params: SendContactParams,
644}
645
646impl SendContact {
647 pub(crate) fn new(
648 client: BotClient,
649 chat_id: impl Into<ChatId>,
650 phone_number: impl Into<String>,
651 first_name: impl Into<String>,
652 ) -> Self {
653 Self {
654 client,
655 params: SendContactParams {
656 chat_id: chat_id.into(),
657 phone_number: phone_number.into(),
658 first_name: first_name.into(),
659 last_name: None,
660 vcard: None,
661 message_thread_id: None,
662 direct_messages_topic_id: None,
663 disable_notification: None,
664 protect_content: None,
665 reply_parameters: None,
666 reply_markup: None,
667 },
668 }
669 }
670 pub fn message_thread_id(mut self, id: i64) -> Self {
672 self.params.message_thread_id = Some(id);
673 self
674 }
675 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
677 self.params.direct_messages_topic_id = Some(id);
678 self
679 }
680 pub fn last_name(mut self, v: impl Into<String>) -> Self {
682 self.params.last_name = Some(v.into());
683 self
684 }
685 pub fn vcard(mut self, v: impl Into<String>) -> Self {
687 self.params.vcard = Some(v.into());
688 self
689 }
690 pub fn disable_notification(mut self, v: bool) -> Self {
692 self.params.disable_notification = Some(v);
693 self
694 }
695 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self {
697 self.params.reply_markup = Some(m.into());
698 self
699 }
700}
701
702impl_into_future!(SendContact, Message, "sendContact");
703
704#[derive(Serialize)]
707struct SendPollParams {
708 chat_id: ChatId,
709 question: String,
710 options: Vec<InputPollOption>,
711 #[serde(skip_serializing_if = "Option::is_none")]
712 question_parse_mode: Option<ParseMode>,
713 #[serde(skip_serializing_if = "Option::is_none")]
714 question_entities: Option<Vec<rustigram_types::message::MessageEntity>>,
715 #[serde(skip_serializing_if = "Option::is_none")]
716 message_thread_id: Option<i64>,
717 #[serde(skip_serializing_if = "Option::is_none")]
718 direct_messages_topic_id: Option<i64>,
719 #[serde(skip_serializing_if = "Option::is_none", rename = "type")]
720 poll_type: Option<rustigram_types::poll::PollType>,
721 #[serde(skip_serializing_if = "Option::is_none")]
722 is_anonymous: Option<bool>,
723 #[serde(skip_serializing_if = "Option::is_none")]
724 allows_multiple_answers: Option<bool>,
725 #[serde(skip_serializing_if = "Option::is_none")]
726 allows_revoting: Option<bool>,
727 #[serde(skip_serializing_if = "Option::is_none")]
728 correct_option_ids: Option<Vec<u8>>,
729 #[serde(skip_serializing_if = "Option::is_none")]
730 explanation: Option<String>,
731 #[serde(skip_serializing_if = "Option::is_none")]
732 explanation_parse_mode: Option<ParseMode>,
733 #[serde(skip_serializing_if = "Option::is_none")]
734 explanation_entities: Option<Vec<rustigram_types::message::MessageEntity>>,
735 #[serde(skip_serializing_if = "Option::is_none")]
736 open_period: Option<u32>,
737 #[serde(skip_serializing_if = "Option::is_none")]
738 close_date: Option<i64>,
739 #[serde(skip_serializing_if = "Option::is_none")]
740 is_closed: Option<bool>,
741 #[serde(skip_serializing_if = "Option::is_none")]
742 shuffle_options: Option<bool>,
743 #[serde(skip_serializing_if = "Option::is_none")]
744 allow_adding_options: Option<bool>,
745 #[serde(skip_serializing_if = "Option::is_none")]
746 hide_results_until_closes: Option<bool>,
747 #[serde(skip_serializing_if = "Option::is_none")]
748 description: Option<String>,
749 #[serde(skip_serializing_if = "Option::is_none")]
750 description_parse_mode: Option<ParseMode>,
751 #[serde(skip_serializing_if = "Option::is_none")]
752 description_entities: Option<Vec<rustigram_types::message::MessageEntity>>,
753 #[serde(skip_serializing_if = "Option::is_none")]
754 disable_notification: Option<bool>,
755 #[serde(skip_serializing_if = "Option::is_none")]
756 protect_content: Option<bool>,
757 #[serde(skip_serializing_if = "Option::is_none")]
758 reply_parameters: Option<ReplyParameters>,
759 #[serde(skip_serializing_if = "Option::is_none")]
760 reply_markup: Option<ReplyMarkup>,
761 #[serde(skip_serializing_if = "Option::is_none")]
762 suggested_post_parameters: Option<SuggestedPostParameters>,
763}
764
765pub struct SendPoll {
767 client: BotClient,
768 params: SendPollParams,
769}
770
771impl SendPoll {
772 pub(crate) fn new(
773 client: BotClient,
774 chat_id: impl Into<ChatId>,
775 question: impl Into<String>,
776 options: Vec<InputPollOption>,
777 ) -> Self {
778 Self {
779 client,
780 params: SendPollParams {
781 chat_id: chat_id.into(),
782 question: question.into(),
783 options,
784 question_parse_mode: None,
785 question_entities: None,
786 message_thread_id: None,
787 direct_messages_topic_id: None,
788 poll_type: None,
789 is_anonymous: None,
790 allows_multiple_answers: None,
791 allows_revoting: None,
792 correct_option_ids: None,
793 explanation: None,
794 explanation_parse_mode: None,
795 explanation_entities: None,
796 open_period: None,
797 close_date: None,
798 is_closed: None,
799 shuffle_options: None,
800 allow_adding_options: None,
801 hide_results_until_closes: None,
802 description: None,
803 description_parse_mode: None,
804 description_entities: None,
805 disable_notification: None,
806 protect_content: None,
807 reply_parameters: None,
808 reply_markup: None,
809 suggested_post_parameters: None,
810 },
811 }
812 }
813 pub fn message_thread_id(mut self, id: i64) -> Self {
815 self.params.message_thread_id = Some(id);
816 self
817 }
818 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
820 self.params.direct_messages_topic_id = Some(id);
821 self
822 }
823 pub fn is_anonymous(mut self, v: bool) -> Self {
825 self.params.is_anonymous = Some(v);
826 self
827 }
828 pub fn allows_multiple_answers(mut self, v: bool) -> Self {
830 self.params.allows_multiple_answers = Some(v);
831 self
832 }
833 pub fn allows_revoting(mut self, v: bool) -> Self {
835 self.params.allows_revoting = Some(v);
836 self
837 }
838 pub fn quiz(mut self, ids: Vec<u8>) -> Self {
840 self.params.poll_type = Some(rustigram_types::poll::PollType::Quiz);
841 self.params.correct_option_ids = Some(ids);
842 self
843 }
844 pub fn quiz_single(self, id: u8) -> Self {
846 self.quiz(vec![id])
847 }
848 pub fn explanation(mut self, text: impl Into<String>) -> Self {
850 self.params.explanation = Some(text.into());
851 self
852 }
853 pub fn explanation_parse_mode(mut self, mode: ParseMode) -> Self {
855 self.params.explanation_parse_mode = Some(mode);
856 self
857 }
858 pub fn explanation_entities(mut self, e: Vec<rustigram_types::message::MessageEntity>) -> Self {
860 self.params.explanation_entities = Some(e);
861 self
862 }
863 pub fn open_period(mut self, secs: u32) -> Self {
865 self.params.open_period = Some(secs);
866 self
867 }
868 pub fn close_date(mut self, ts: i64) -> Self {
870 self.params.close_date = Some(ts);
871 self
872 }
873 pub fn shuffle_options(mut self, v: bool) -> Self {
875 self.params.shuffle_options = Some(v);
876 self
877 }
878 pub fn allow_adding_options(mut self, v: bool) -> Self {
880 self.params.allow_adding_options = Some(v);
881 self
882 }
883 pub fn hide_results_until_closes(mut self, v: bool) -> Self {
885 self.params.hide_results_until_closes = Some(v);
886 self
887 }
888 pub fn description(mut self, d: impl Into<String>) -> Self {
890 self.params.description = Some(d.into());
891 self
892 }
893 pub fn description_parse_mode(mut self, mode: ParseMode) -> Self {
895 self.params.description_parse_mode = Some(mode);
896 self
897 }
898 pub fn description_entities(mut self, e: Vec<rustigram_types::message::MessageEntity>) -> Self {
900 self.params.description_entities = Some(e);
901 self
902 }
903 pub fn question_parse_mode(mut self, mode: ParseMode) -> Self {
905 self.params.question_parse_mode = Some(mode);
906 self
907 }
908 pub fn question_entities(mut self, e: Vec<rustigram_types::message::MessageEntity>) -> Self {
910 self.params.question_entities = Some(e);
911 self
912 }
913 pub fn disable_notification(mut self, v: bool) -> Self {
915 self.params.disable_notification = Some(v);
916 self
917 }
918 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self {
920 self.params.reply_markup = Some(m.into());
921 self
922 }
923 pub fn suggested_post_parameters(mut self, params: SuggestedPostParameters) -> Self {
925 self.params.suggested_post_parameters = Some(params);
926 self
927 }
928}
929
930impl_into_future!(SendPoll, Message, "sendPoll");
931
932#[derive(Serialize)]
935struct SendMessageDraftParams {
936 chat_id: ChatId,
937 draft_id: i64,
938 text: String,
939 #[serde(skip_serializing_if = "Option::is_none")]
940 message_thread_id: Option<i64>,
941 #[serde(skip_serializing_if = "Option::is_none")]
942 parse_mode: Option<ParseMode>,
943 #[serde(skip_serializing_if = "Option::is_none")]
944 entities: Option<Vec<rustigram_types::message::MessageEntity>>,
945}
946
947pub struct SendMessageDraft {
950 client: BotClient,
951 params: SendMessageDraftParams,
952}
953
954impl SendMessageDraft {
955 pub(crate) fn new(
956 client: BotClient,
957 chat_id: impl Into<ChatId>,
958 draft_id: i64,
959 text: impl Into<String>,
960 ) -> Self {
961 Self {
962 client,
963 params: SendMessageDraftParams {
964 chat_id: chat_id.into(),
965 draft_id,
966 text: text.into(),
967 message_thread_id: None,
968 parse_mode: None,
969 entities: None,
970 },
971 }
972 }
973 pub fn parse_mode(mut self, m: ParseMode) -> Self {
975 self.params.parse_mode = Some(m);
976 self
977 }
978 pub fn entities(mut self, e: Vec<rustigram_types::message::MessageEntity>) -> Self {
980 self.params.entities = Some(e);
981 self
982 }
983}
984
985impl_into_future!(SendMessageDraft, bool, "sendMessageDraft");
986
987#[derive(Default)]
996pub struct MediaSendOptions {
997 pub business_connection_id: Option<String>,
999 pub message_thread_id: Option<i64>,
1001 pub direct_messages_topic_id: Option<i64>,
1003 pub caption: Option<String>,
1005 pub parse_mode: Option<ParseMode>,
1007 pub caption_entities: Option<Vec<rustigram_types::message::MessageEntity>>,
1009 pub show_caption_above_media: Option<bool>,
1011 pub has_spoiler: Option<bool>,
1013 pub disable_notification: Option<bool>,
1015 pub protect_content: Option<bool>,
1017 pub allow_paid_broadcast: Option<bool>,
1019 pub reply_parameters: Option<ReplyParameters>,
1021 pub reply_markup: Option<ReplyMarkup>,
1023 pub suggested_post_parameters: Option<SuggestedPostParameters>,
1025}
1026
1027fn media_json_body(
1029 chat_id: &ChatId,
1030 media_field: &str,
1031 media_value: &str,
1032 opts: &MediaSendOptions,
1033 extra: serde_json::Value,
1034) -> serde_json::Value {
1035 let mut map = serde_json::json!({
1036 "chat_id": chat_id,
1037 media_field: media_value,
1038 });
1039 let obj = map.as_object_mut().unwrap();
1040 if let Some(v) = &opts.business_connection_id {
1041 obj.insert("business_connection_id".to_owned(), serde_json::json!(v));
1042 }
1043 if let Some(v) = &opts.message_thread_id {
1044 obj.insert("message_thread_id".to_owned(), serde_json::json!(v));
1045 }
1046 if let Some(v) = &opts.direct_messages_topic_id {
1047 obj.insert("direct_messages_topic_id".to_owned(), serde_json::json!(v));
1048 }
1049 if let Some(v) = &opts.caption {
1050 obj.insert("caption".to_owned(), serde_json::json!(v));
1051 }
1052 if let Some(v) = &opts.parse_mode {
1053 obj.insert("parse_mode".to_owned(), serde_json::json!(v));
1054 }
1055 if let Some(v) = &opts.caption_entities {
1056 obj.insert("caption_entities".to_owned(), serde_json::json!(v));
1057 }
1058 if let Some(v) = opts.show_caption_above_media {
1059 obj.insert("show_caption_above_media".to_owned(), serde_json::json!(v));
1060 }
1061 if let Some(v) = opts.has_spoiler {
1062 obj.insert("has_spoiler".to_owned(), serde_json::json!(v));
1063 }
1064 if let Some(v) = opts.disable_notification {
1065 obj.insert("disable_notification".to_owned(), serde_json::json!(v));
1066 }
1067 if let Some(v) = opts.protect_content {
1068 obj.insert("protect_content".to_owned(), serde_json::json!(v));
1069 }
1070 if let Some(v) = opts.allow_paid_broadcast {
1071 obj.insert("allow_paid_broadcast".to_owned(), serde_json::json!(v));
1072 }
1073 if let Some(v) = &opts.reply_parameters {
1074 obj.insert("reply_parameters".to_owned(), serde_json::json!(v));
1075 }
1076 if let Some(v) = &opts.reply_markup {
1077 obj.insert("reply_markup".to_owned(), serde_json::json!(v));
1078 }
1079 if let Some(v) = &opts.suggested_post_parameters {
1080 obj.insert("suggested_post_parameters".to_owned(), serde_json::json!(v));
1081 }
1082 if let serde_json::Value::Object(extra_obj) = extra {
1083 for (k, v) in extra_obj {
1084 obj.insert(k, v);
1085 }
1086 }
1087 map
1088}
1089
1090pub struct SendPhoto {
1094 client: BotClient,
1095 chat_id: ChatId,
1096 photo: InputFile,
1097 opts: MediaSendOptions,
1098}
1099
1100impl SendPhoto {
1101 pub(crate) fn new(client: BotClient, chat_id: impl Into<ChatId>, photo: InputFile) -> Self {
1102 Self {
1103 client,
1104 chat_id: chat_id.into(),
1105 photo,
1106 opts: MediaSendOptions::default(),
1107 }
1108 }
1109 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
1111 self.opts.business_connection_id = Some(id.into());
1112 self
1113 }
1114 pub fn message_thread_id(mut self, id: i64) -> Self {
1116 self.opts.message_thread_id = Some(id);
1117 self
1118 }
1119 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
1121 self.opts.direct_messages_topic_id = Some(id);
1122 self
1123 }
1124 pub fn caption(mut self, c: impl Into<String>) -> Self {
1126 self.opts.caption = Some(c.into());
1127 self
1128 }
1129 pub fn parse_mode(mut self, m: ParseMode) -> Self {
1131 self.opts.parse_mode = Some(m);
1132 self
1133 }
1134 pub fn has_spoiler(mut self, v: bool) -> Self {
1136 self.opts.has_spoiler = Some(v);
1137 self
1138 }
1139 pub fn show_caption_above_media(mut self, v: bool) -> Self {
1141 self.opts.show_caption_above_media = Some(v);
1142 self
1143 }
1144 pub fn disable_notification(mut self, v: bool) -> Self {
1146 self.opts.disable_notification = Some(v);
1147 self
1148 }
1149 pub fn protect_content(mut self, v: bool) -> Self {
1151 self.opts.protect_content = Some(v);
1152 self
1153 }
1154 pub fn allow_paid_broadcast(mut self, v: bool) -> Self {
1156 self.opts.allow_paid_broadcast = Some(v);
1157 self
1158 }
1159 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
1161 self.opts.reply_parameters = Some(rp);
1162 self
1163 }
1164 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self {
1166 self.opts.reply_markup = Some(m.into());
1167 self
1168 }
1169 pub fn suggested_post_parameters(mut self, params: SuggestedPostParameters) -> Self {
1171 self.opts.suggested_post_parameters = Some(params);
1172 self
1173 }
1174}
1175
1176impl IntoFuture for SendPhoto {
1177 type Output = Result<Message>;
1178 type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
1179
1180 fn into_future(self) -> Self::IntoFuture {
1181 Box::pin(async move {
1182 match &self.photo {
1183 InputFile::Bytes {
1184 filename,
1185 data,
1186 mime_type,
1187 } => {
1188 let part = Part::bytes(data.clone())
1189 .file_name(filename.clone())
1190 .mime_str(mime_type)
1191 .map_err(|e| crate::error::Error::Decode(e.to_string()))?;
1192 let mut form = Form::new().part("photo", part);
1193 form = form.text("chat_id", self.chat_id.to_string());
1194 if let Some(id) = &self.opts.business_connection_id {
1195 form = form.text("business_connection_id", id.clone());
1196 }
1197 if let Some(id) = self.opts.message_thread_id {
1198 form = form.text("message_thread_id", id.to_string());
1199 }
1200 if let Some(id) = self.opts.direct_messages_topic_id {
1201 form = form.text("direct_messages_topic_id", id.to_string());
1202 }
1203 if let Some(c) = &self.opts.caption {
1204 form = form.text("caption", c.clone());
1205 }
1206 if let Some(m) = &self.opts.parse_mode {
1207 form = form.text("parse_mode", format!("{m:?}"));
1208 }
1209 if let Some(v) = self.opts.disable_notification {
1210 form = form.text("disable_notification", v.to_string());
1211 }
1212 if let Some(v) = self.opts.has_spoiler {
1213 form = form.text("has_spoiler", v.to_string());
1214 }
1215 if let Some(v) = &self.opts.reply_markup {
1216 form = form.text("reply_markup", serde_json::to_string(v).unwrap());
1217 }
1218 if let Some(p) = &self.opts.suggested_post_parameters {
1219 form = form.text(
1220 "suggested_post_parameters",
1221 serde_json::to_string(p).unwrap(),
1222 );
1223 }
1224 self.client.post_multipart("sendPhoto", form).await
1225 }
1226 _ => {
1227 let body = media_json_body(
1228 &self.chat_id,
1229 "photo",
1230 self.photo.as_str(),
1231 &self.opts,
1232 serde_json::Value::Null,
1233 );
1234 self.client.post_json("sendPhoto", &body).await
1235 }
1236 }
1237 })
1238 }
1239}
1240
1241macro_rules! media_sender {
1244 ($(#[$doc:meta])* $name:ident, $field:literal, $method:literal, $return_ty:ty, [$($extra_field:ident: $extra_ty:ty),*]) => {
1245 $(#[$doc])*
1246 pub struct $name {
1247 client: BotClient,
1249 chat_id: ChatId,
1251 file: InputFile,
1253 opts: MediaSendOptions,
1255 $($extra_field: Option<$extra_ty>,)*
1257 }
1258
1259 impl $name {
1260 pub(crate) fn new(client: BotClient, chat_id: impl Into<ChatId>, file: InputFile) -> Self {
1261 Self {
1262 client,
1263 chat_id: chat_id.into(),
1264 file,
1265 opts: MediaSendOptions::default(),
1266 $($extra_field: None,)*
1267 }
1268 }
1269 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self { self.opts.business_connection_id = Some(id.into()); self }
1271 pub fn message_thread_id(mut self, id: i64) -> Self { self.opts.message_thread_id = Some(id); self }
1273 pub fn direct_messages_topic_id(mut self, id: i64) -> Self { self.opts.direct_messages_topic_id = Some(id); self }
1275 pub fn caption(mut self, c: impl Into<String>) -> Self { self.opts.caption = Some(c.into()); self }
1277 pub fn parse_mode(mut self, m: ParseMode) -> Self { self.opts.parse_mode = Some(m); self }
1279 pub fn disable_notification(mut self, v: bool) -> Self { self.opts.disable_notification = Some(v); self }
1281 pub fn protect_content(mut self, v: bool) -> Self { self.opts.protect_content = Some(v); self }
1283 pub fn allow_paid_broadcast(mut self, v: bool) -> Self { self.opts.allow_paid_broadcast = Some(v); self }
1285 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self { self.opts.reply_parameters = Some(rp); self }
1287 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self { self.opts.reply_markup = Some(m.into()); self }
1289 pub fn suggested_post_parameters(mut self, params: SuggestedPostParameters) -> Self { self.opts.suggested_post_parameters = Some(params); self }
1291
1292 $(
1293 #[doc = concat!("Sets the ", stringify!($extra_field), " for the media.")]
1294 pub fn $extra_field(mut self, v: $extra_ty) -> Self {
1295 self.$extra_field = Some(v);
1296 self
1297 }
1298 )*
1299 }
1300
1301 impl IntoFuture for $name {
1302 type Output = Result<$return_ty>;
1303 type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
1304
1305 fn into_future(self) -> Self::IntoFuture {
1306 Box::pin(async move {
1307 match &self.file {
1308 InputFile::Bytes { filename, data, mime_type } => {
1309 let part = Part::bytes(data.clone())
1310 .file_name(filename.clone())
1311 .mime_str(mime_type)
1312 .map_err(|e| crate::error::Error::Decode(e.to_string()))?;
1313 let mut form = Form::new().part($field, part);
1314 form = form.text("chat_id", self.chat_id.to_string());
1315 if let Some(id) = &self.opts.business_connection_id { form = form.text("business_connection_id", id.clone()); }
1316 if let Some(id) = self.opts.message_thread_id { form = form.text("message_thread_id", id.to_string()); }
1317 if let Some(id) = self.opts.direct_messages_topic_id { form = form.text("direct_messages_topic_id", id.to_string()); }
1318 if let Some(c) = &self.opts.caption { form = form.text("caption", c.clone()); }
1319 if let Some(v) = self.opts.disable_notification { form = form.text("disable_notification", v.to_string()); }
1320 if let Some(v) = &self.opts.reply_markup { form = form.text("reply_markup", serde_json::to_string(v).unwrap()); }
1321 if let Some(p) = &self.opts.suggested_post_parameters { form = form.text("suggested_post_parameters", serde_json::to_string(p).unwrap()); }
1322
1323 $(
1324 if let Some(ref v) = self.$extra_field {
1325 form = form.text(stringify!($extra_field), v.to_string());
1326 }
1327 )*
1328
1329 self.client.post_multipart($method, form).await
1330 }
1331 _ => {
1332 let mut extra = serde_json::json!({});
1333 $(
1334 if let Some(ref v) = self.$extra_field {
1335 extra[stringify!($extra_field)] = serde_json::json!(v);
1336 }
1337 )*
1338 let body = media_json_body(&self.chat_id, $field, self.file.as_str(), &self.opts, extra);
1339 self.client.post_json($method, &body).await
1340 }
1341 }
1342 })
1343 }
1344 }
1345 };
1346}
1347
1348media_sender!(
1349 SendAudio, "audio", "sendAudio", Message, [duration: u32, performer: String, title: String]);
1351media_sender!(
1352 SendDocument, "document", "sendDocument", Message, [disable_content_type_detection: bool]);
1354media_sender!(
1355 SendVideo, "video", "sendVideo", Message, [duration: u32, width: u32, height: u32, supports_streaming: bool, cover: String, start_timestamp: i64]);
1357media_sender!(
1358 SendAnimation, "animation", "sendAnimation", Message, [duration: u32, width: u32, height: u32]);
1360media_sender!(
1361 SendVoice, "voice", "sendVoice", Message, [duration: u32]);
1363media_sender!(
1364 SendVideoNote, "video_note", "sendVideoNote", Message, [duration: u32, length: u32]);
1366media_sender!(
1367 SendSticker, "sticker", "sendSticker", Message, [emoji: String]);
1369
1370#[derive(Serialize)]
1373struct DeleteMessageParams {
1374 chat_id: ChatId,
1375 message_id: i64,
1376}
1377
1378pub struct DeleteMessage {
1380 client: BotClient,
1381 params: DeleteMessageParams,
1382}
1383impl DeleteMessage {
1384 pub(crate) fn new(client: BotClient, chat_id: impl Into<ChatId>, message_id: i64) -> Self {
1385 Self {
1386 client,
1387 params: DeleteMessageParams {
1388 chat_id: chat_id.into(),
1389 message_id,
1390 },
1391 }
1392 }
1393}
1394impl_into_future!(DeleteMessage, bool, "deleteMessage");
1395
1396#[derive(Serialize)]
1397struct DeleteMessagesParams {
1398 chat_id: ChatId,
1399 message_ids: Vec<i64>,
1400}
1401
1402pub struct DeleteMessages {
1404 client: BotClient,
1405 params: DeleteMessagesParams,
1406}
1407impl DeleteMessages {
1408 pub(crate) fn new(
1409 client: BotClient,
1410 chat_id: impl Into<ChatId>,
1411 message_ids: Vec<i64>,
1412 ) -> Self {
1413 Self {
1414 client,
1415 params: DeleteMessagesParams {
1416 chat_id: chat_id.into(),
1417 message_ids,
1418 },
1419 }
1420 }
1421}
1422impl_into_future!(DeleteMessages, bool, "deleteMessages");
1423
1424#[derive(Serialize)]
1427struct StopPollParams {
1428 chat_id: ChatId,
1429 message_id: i64,
1430 #[serde(skip_serializing_if = "Option::is_none")]
1431 reply_markup: Option<rustigram_types::keyboard::InlineKeyboardMarkup>,
1432}
1433
1434pub struct StopPoll {
1436 client: BotClient,
1437 params: StopPollParams,
1438}
1439impl StopPoll {
1440 pub(crate) fn new(client: BotClient, chat_id: impl Into<ChatId>, message_id: i64) -> Self {
1441 Self {
1442 client,
1443 params: StopPollParams {
1444 chat_id: chat_id.into(),
1445 message_id,
1446 reply_markup: None,
1447 },
1448 }
1449 }
1450 pub fn reply_markup(mut self, m: rustigram_types::keyboard::InlineKeyboardMarkup) -> Self {
1452 self.params.reply_markup = Some(m);
1453 self
1454 }
1455}
1456impl_into_future!(StopPoll, rustigram_types::poll::Poll, "stopPoll");
1457
1458#[derive(Serialize)]
1461struct AnswerCallbackQueryParams {
1462 callback_query_id: String,
1463 #[serde(skip_serializing_if = "Option::is_none")]
1464 text: Option<String>,
1465 #[serde(skip_serializing_if = "Option::is_none")]
1466 show_alert: Option<bool>,
1467 #[serde(skip_serializing_if = "Option::is_none")]
1468 url: Option<String>,
1469 #[serde(skip_serializing_if = "Option::is_none")]
1470 cache_time: Option<u32>,
1471}
1472
1473pub struct AnswerCallbackQuery {
1475 client: BotClient,
1476 params: AnswerCallbackQueryParams,
1477}
1478impl AnswerCallbackQuery {
1479 pub(crate) fn new(client: BotClient, callback_query_id: impl Into<String>) -> Self {
1480 Self {
1481 client,
1482 params: AnswerCallbackQueryParams {
1483 callback_query_id: callback_query_id.into(),
1484 text: None,
1485 show_alert: None,
1486 url: None,
1487 cache_time: None,
1488 },
1489 }
1490 }
1491 pub fn text(mut self, t: impl Into<String>) -> Self {
1493 self.params.text = Some(t.into());
1494 self
1495 }
1496 pub fn show_alert(mut self, v: bool) -> Self {
1498 self.params.show_alert = Some(v);
1499 self
1500 }
1501 pub fn url(mut self, u: impl Into<String>) -> Self {
1503 self.params.url = Some(u.into());
1504 self
1505 }
1506 pub fn cache_time(mut self, secs: u32) -> Self {
1508 self.params.cache_time = Some(secs);
1509 self
1510 }
1511 pub fn alert(self, text: impl Into<String>) -> Self {
1513 self.text(text).show_alert(true)
1514 }
1515}
1516impl_into_future!(AnswerCallbackQuery, bool, "answerCallbackQuery");
1517#[derive(Serialize)]
1520struct ForwardMessagesParams {
1521 chat_id: ChatId,
1522 from_chat_id: ChatId,
1523 message_ids: Vec<i64>,
1524 #[serde(skip_serializing_if = "Option::is_none")]
1525 message_thread_id: Option<i64>,
1526 #[serde(skip_serializing_if = "Option::is_none")]
1527 direct_messages_topic_id: Option<i64>,
1528 #[serde(skip_serializing_if = "Option::is_none")]
1529 disable_notification: Option<bool>,
1530 #[serde(skip_serializing_if = "Option::is_none")]
1531 protect_content: Option<bool>,
1532}
1533
1534pub struct ForwardMessages {
1539 client: BotClient,
1540 params: ForwardMessagesParams,
1541}
1542
1543impl ForwardMessages {
1544 pub(crate) fn new(
1545 client: BotClient,
1546 chat_id: impl Into<ChatId>,
1547 from_chat_id: impl Into<ChatId>,
1548 message_ids: Vec<i64>,
1549 ) -> Self {
1550 Self {
1551 client,
1552 params: ForwardMessagesParams {
1553 chat_id: chat_id.into(),
1554 from_chat_id: from_chat_id.into(),
1555 message_ids,
1556 message_thread_id: None,
1557 direct_messages_topic_id: None,
1558 disable_notification: None,
1559 protect_content: None,
1560 },
1561 }
1562 }
1563 pub fn message_thread_id(mut self, id: i64) -> Self {
1565 self.params.message_thread_id = Some(id);
1566 self
1567 }
1568 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
1570 self.params.direct_messages_topic_id = Some(id);
1571 self
1572 }
1573 pub fn disable_notification(mut self, v: bool) -> Self {
1575 self.params.disable_notification = Some(v);
1576 self
1577 }
1578 pub fn protect_content(mut self, v: bool) -> Self {
1580 self.params.protect_content = Some(v);
1581 self
1582 }
1583}
1584
1585impl_into_future!(
1586 ForwardMessages,
1587 Vec<rustigram_types::message::MessageId>,
1588 "forwardMessages"
1589);
1590
1591#[derive(Serialize)]
1594struct CopyMessagesParams {
1595 chat_id: ChatId,
1596 from_chat_id: ChatId,
1597 message_ids: Vec<i64>,
1598 #[serde(skip_serializing_if = "Option::is_none")]
1599 message_thread_id: Option<i64>,
1600 #[serde(skip_serializing_if = "Option::is_none")]
1601 direct_messages_topic_id: Option<i64>,
1602 #[serde(skip_serializing_if = "Option::is_none")]
1603 disable_notification: Option<bool>,
1604 #[serde(skip_serializing_if = "Option::is_none")]
1605 protect_content: Option<bool>,
1606 #[serde(skip_serializing_if = "Option::is_none")]
1607 remove_caption: Option<bool>,
1608}
1609
1610pub struct CopyMessages {
1615 client: BotClient,
1616 params: CopyMessagesParams,
1617}
1618
1619impl CopyMessages {
1620 pub(crate) fn new(
1621 client: BotClient,
1622 chat_id: impl Into<ChatId>,
1623 from_chat_id: impl Into<ChatId>,
1624 message_ids: Vec<i64>,
1625 ) -> Self {
1626 Self {
1627 client,
1628 params: CopyMessagesParams {
1629 chat_id: chat_id.into(),
1630 from_chat_id: from_chat_id.into(),
1631 message_ids,
1632 message_thread_id: None,
1633 direct_messages_topic_id: None,
1634 disable_notification: None,
1635 protect_content: None,
1636 remove_caption: None,
1637 },
1638 }
1639 }
1640 pub fn message_thread_id(mut self, id: i64) -> Self {
1642 self.params.message_thread_id = Some(id);
1643 self
1644 }
1645 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
1647 self.params.direct_messages_topic_id = Some(id);
1648 self
1649 }
1650 pub fn disable_notification(mut self, v: bool) -> Self {
1652 self.params.disable_notification = Some(v);
1653 self
1654 }
1655 pub fn protect_content(mut self, v: bool) -> Self {
1657 self.params.protect_content = Some(v);
1658 self
1659 }
1660 pub fn remove_caption(mut self, v: bool) -> Self {
1662 self.params.remove_caption = Some(v);
1663 self
1664 }
1665}
1666
1667impl_into_future!(
1668 CopyMessages,
1669 Vec<rustigram_types::message::MessageId>,
1670 "copyMessages"
1671);
1672
1673#[derive(Serialize)]
1676struct SendVenueParams {
1677 chat_id: ChatId,
1678 latitude: f64,
1679 longitude: f64,
1680 title: String,
1681 address: String,
1682 #[serde(skip_serializing_if = "Option::is_none")]
1683 message_thread_id: Option<i64>,
1684 #[serde(skip_serializing_if = "Option::is_none")]
1685 direct_messages_topic_id: Option<i64>,
1686 #[serde(skip_serializing_if = "Option::is_none")]
1687 foursquare_id: Option<String>,
1688 #[serde(skip_serializing_if = "Option::is_none")]
1689 foursquare_type: Option<String>,
1690 #[serde(skip_serializing_if = "Option::is_none")]
1691 google_place_id: Option<String>,
1692 #[serde(skip_serializing_if = "Option::is_none")]
1693 google_place_type: Option<String>,
1694 #[serde(skip_serializing_if = "Option::is_none")]
1695 disable_notification: Option<bool>,
1696 #[serde(skip_serializing_if = "Option::is_none")]
1697 protect_content: Option<bool>,
1698 #[serde(skip_serializing_if = "Option::is_none")]
1699 reply_parameters: Option<ReplyParameters>,
1700 #[serde(skip_serializing_if = "Option::is_none")]
1701 reply_markup: Option<ReplyMarkup>,
1702}
1703
1704pub struct SendVenue {
1706 client: BotClient,
1707 params: SendVenueParams,
1708}
1709
1710impl SendVenue {
1711 pub(crate) fn new(
1712 client: BotClient,
1713 chat_id: impl Into<ChatId>,
1714 latitude: f64,
1715 longitude: f64,
1716 title: impl Into<String>,
1717 address: impl Into<String>,
1718 ) -> Self {
1719 Self {
1720 client,
1721 params: SendVenueParams {
1722 chat_id: chat_id.into(),
1723 latitude,
1724 longitude,
1725 title: title.into(),
1726 address: address.into(),
1727 message_thread_id: None,
1728 direct_messages_topic_id: None,
1729 foursquare_id: None,
1730 foursquare_type: None,
1731 google_place_id: None,
1732 google_place_type: None,
1733 disable_notification: None,
1734 protect_content: None,
1735 reply_parameters: None,
1736 reply_markup: None,
1737 },
1738 }
1739 }
1740 pub fn message_thread_id(mut self, id: i64) -> Self {
1742 self.params.message_thread_id = Some(id);
1743 self
1744 }
1745 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
1747 self.params.direct_messages_topic_id = Some(id);
1748 self
1749 }
1750 pub fn foursquare_id(mut self, id: impl Into<String>) -> Self {
1752 self.params.foursquare_id = Some(id.into());
1753 self
1754 }
1755 pub fn foursquare_type(mut self, t: impl Into<String>) -> Self {
1757 self.params.foursquare_type = Some(t.into());
1758 self
1759 }
1760 pub fn google_place_id(mut self, id: impl Into<String>) -> Self {
1762 self.params.google_place_id = Some(id.into());
1763 self
1764 }
1765 pub fn google_place_type(mut self, t: impl Into<String>) -> Self {
1767 self.params.google_place_type = Some(t.into());
1768 self
1769 }
1770 pub fn disable_notification(mut self, v: bool) -> Self {
1772 self.params.disable_notification = Some(v);
1773 self
1774 }
1775 pub fn protect_content(mut self, v: bool) -> Self {
1777 self.params.protect_content = Some(v);
1778 self
1779 }
1780 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
1782 self.params.reply_parameters = Some(rp);
1783 self
1784 }
1785 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self {
1787 self.params.reply_markup = Some(m.into());
1788 self
1789 }
1790}
1791
1792impl_into_future!(SendVenue, Message, "sendVenue");
1793
1794#[derive(Serialize)]
1797struct SendMediaGroupParams {
1798 chat_id: ChatId,
1799 media: Vec<serde_json::Value>,
1804 #[serde(skip_serializing_if = "Option::is_none")]
1805 message_thread_id: Option<i64>,
1806 #[serde(skip_serializing_if = "Option::is_none")]
1807 direct_messages_topic_id: Option<i64>,
1808 #[serde(skip_serializing_if = "Option::is_none")]
1809 business_connection_id: Option<String>,
1810 #[serde(skip_serializing_if = "Option::is_none")]
1811 disable_notification: Option<bool>,
1812 #[serde(skip_serializing_if = "Option::is_none")]
1813 protect_content: Option<bool>,
1814 #[serde(skip_serializing_if = "Option::is_none")]
1815 reply_parameters: Option<ReplyParameters>,
1816}
1817
1818pub struct SendMediaGroup {
1826 client: BotClient,
1827 params: SendMediaGroupParams,
1828}
1829
1830impl SendMediaGroup {
1831 pub(crate) fn new(
1832 client: BotClient,
1833 chat_id: impl Into<ChatId>,
1834 media: Vec<serde_json::Value>,
1835 ) -> Self {
1836 Self {
1837 client,
1838 params: SendMediaGroupParams {
1839 chat_id: chat_id.into(),
1840 media,
1841 message_thread_id: None,
1842 direct_messages_topic_id: None,
1843 business_connection_id: None,
1844 disable_notification: None,
1845 protect_content: None,
1846 reply_parameters: None,
1847 },
1848 }
1849 }
1850 pub fn message_thread_id(mut self, id: i64) -> Self {
1852 self.params.message_thread_id = Some(id);
1853 self
1854 }
1855 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
1857 self.params.direct_messages_topic_id = Some(id);
1858 self
1859 }
1860 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
1862 self.params.business_connection_id = Some(id.into());
1863 self
1864 }
1865 pub fn disable_notification(mut self, v: bool) -> Self {
1867 self.params.disable_notification = Some(v);
1868 self
1869 }
1870 pub fn protect_content(mut self, v: bool) -> Self {
1872 self.params.protect_content = Some(v);
1873 self
1874 }
1875 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
1877 self.params.reply_parameters = Some(rp);
1878 self
1879 }
1880}
1881
1882impl_into_future!(SendMediaGroup, Vec<Message>, "sendMediaGroup");
1883
1884#[derive(Serialize)]
1887struct SendPaidMediaParams {
1888 chat_id: ChatId,
1889 star_count: u32,
1890 media: Vec<serde_json::Value>,
1895 #[serde(skip_serializing_if = "Option::is_none")]
1896 business_connection_id: Option<String>,
1897 #[serde(skip_serializing_if = "Option::is_none")]
1898 payload: Option<String>,
1899 #[serde(skip_serializing_if = "Option::is_none")]
1900 caption: Option<String>,
1901 #[serde(skip_serializing_if = "Option::is_none")]
1902 parse_mode: Option<ParseMode>,
1903 #[serde(skip_serializing_if = "Option::is_none")]
1904 show_caption_above_media: Option<bool>,
1905 #[serde(skip_serializing_if = "Option::is_none")]
1906 disable_notification: Option<bool>,
1907 #[serde(skip_serializing_if = "Option::is_none")]
1908 protect_content: Option<bool>,
1909 #[serde(skip_serializing_if = "Option::is_none")]
1910 reply_parameters: Option<ReplyParameters>,
1911 #[serde(skip_serializing_if = "Option::is_none")]
1912 reply_markup: Option<ReplyMarkup>,
1913}
1914
1915pub struct SendPaidMedia {
1922 client: BotClient,
1923 params: SendPaidMediaParams,
1924}
1925
1926impl SendPaidMedia {
1927 pub(crate) fn new(
1928 client: BotClient,
1929 chat_id: impl Into<ChatId>,
1930 star_count: u32,
1931 media: Vec<serde_json::Value>,
1932 ) -> Self {
1933 Self {
1934 client,
1935 params: SendPaidMediaParams {
1936 chat_id: chat_id.into(),
1937 star_count,
1938 media,
1939 business_connection_id: None,
1940 payload: None,
1941 caption: None,
1942 parse_mode: None,
1943 show_caption_above_media: None,
1944 disable_notification: None,
1945 protect_content: None,
1946 reply_parameters: None,
1947 reply_markup: None,
1948 },
1949 }
1950 }
1951 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
1953 self.params.business_connection_id = Some(id.into());
1954 self
1955 }
1956 pub fn payload(mut self, p: impl Into<String>) -> Self {
1958 self.params.payload = Some(p.into());
1959 self
1960 }
1961 pub fn caption(mut self, c: impl Into<String>) -> Self {
1963 self.params.caption = Some(c.into());
1964 self
1965 }
1966 pub fn parse_mode(mut self, m: ParseMode) -> Self {
1968 self.params.parse_mode = Some(m);
1969 self
1970 }
1971 pub fn show_caption_above_media(mut self, v: bool) -> Self {
1973 self.params.show_caption_above_media = Some(v);
1974 self
1975 }
1976 pub fn disable_notification(mut self, v: bool) -> Self {
1978 self.params.disable_notification = Some(v);
1979 self
1980 }
1981 pub fn protect_content(mut self, v: bool) -> Self {
1983 self.params.protect_content = Some(v);
1984 self
1985 }
1986 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
1988 self.params.reply_parameters = Some(rp);
1989 self
1990 }
1991 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self {
1993 self.params.reply_markup = Some(m.into());
1994 self
1995 }
1996}
1997
1998impl_into_future!(SendPaidMedia, Message, "sendPaidMedia");
1999
2000#[derive(Serialize)]
2003struct SendGameParams {
2004 chat_id: i64,
2005 game_short_name: String,
2006 #[serde(skip_serializing_if = "Option::is_none")]
2007 business_connection_id: Option<String>,
2008 #[serde(skip_serializing_if = "Option::is_none")]
2009 message_thread_id: Option<i64>,
2010 #[serde(skip_serializing_if = "Option::is_none")]
2011 direct_messages_topic_id: Option<i64>,
2012 #[serde(skip_serializing_if = "Option::is_none")]
2013 disable_notification: Option<bool>,
2014 #[serde(skip_serializing_if = "Option::is_none")]
2015 protect_content: Option<bool>,
2016 #[serde(skip_serializing_if = "Option::is_none")]
2017 reply_parameters: Option<ReplyParameters>,
2018 #[serde(skip_serializing_if = "Option::is_none")]
2019 reply_markup: Option<rustigram_types::keyboard::InlineKeyboardMarkup>,
2020}
2021
2022pub struct SendGame {
2027 client: BotClient,
2028 params: SendGameParams,
2029}
2030
2031impl SendGame {
2032 pub(crate) fn new(client: BotClient, chat_id: i64, game_short_name: impl Into<String>) -> Self {
2033 Self {
2034 client,
2035 params: SendGameParams {
2036 chat_id,
2037 game_short_name: game_short_name.into(),
2038 business_connection_id: None,
2039 message_thread_id: None,
2040 direct_messages_topic_id: None,
2041 disable_notification: None,
2042 protect_content: None,
2043 reply_parameters: None,
2044 reply_markup: None,
2045 },
2046 }
2047 }
2048 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
2050 self.params.business_connection_id = Some(id.into());
2051 self
2052 }
2053 pub fn message_thread_id(mut self, id: i64) -> Self {
2055 self.params.message_thread_id = Some(id);
2056 self
2057 }
2058 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
2060 self.params.direct_messages_topic_id = Some(id);
2061 self
2062 }
2063 pub fn disable_notification(mut self, v: bool) -> Self {
2065 self.params.disable_notification = Some(v);
2066 self
2067 }
2068 pub fn protect_content(mut self, v: bool) -> Self {
2070 self.params.protect_content = Some(v);
2071 self
2072 }
2073 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
2075 self.params.reply_parameters = Some(rp);
2076 self
2077 }
2078 pub fn reply_markup(mut self, m: rustigram_types::keyboard::InlineKeyboardMarkup) -> Self {
2080 self.params.reply_markup = Some(m);
2081 self
2082 }
2083}
2084
2085impl_into_future!(SendGame, Message, "sendGame");
2086
2087#[derive(Serialize)]
2090struct SendChecklistParams {
2091 business_connection_id: String,
2092 chat_id: i64,
2093 checklist: rustigram_types::checklist::InputChecklist,
2094 #[serde(skip_serializing_if = "Option::is_none")]
2095 direct_messages_topic_id: Option<i64>,
2096 #[serde(skip_serializing_if = "Option::is_none")]
2097 disable_notification: Option<bool>,
2098 #[serde(skip_serializing_if = "Option::is_none")]
2099 protect_content: Option<bool>,
2100 #[serde(skip_serializing_if = "Option::is_none")]
2101 message_effect_id: Option<String>,
2102 #[serde(skip_serializing_if = "Option::is_none")]
2103 reply_parameters: Option<ReplyParameters>,
2104 #[serde(skip_serializing_if = "Option::is_none")]
2105 reply_markup: Option<rustigram_types::keyboard::InlineKeyboardMarkup>,
2106 #[serde(skip_serializing_if = "Option::is_none")]
2107 suggested_post_parameters: Option<SuggestedPostParameters>,
2108}
2109
2110pub struct SendChecklist {
2115 client: BotClient,
2116 params: SendChecklistParams,
2117}
2118
2119impl SendChecklist {
2120 pub(crate) fn new(
2121 client: BotClient,
2122 business_connection_id: impl Into<String>,
2123 chat_id: i64,
2124 checklist: rustigram_types::checklist::InputChecklist,
2125 ) -> Self {
2126 Self {
2127 client,
2128 params: SendChecklistParams {
2129 business_connection_id: business_connection_id.into(),
2130 chat_id,
2131 checklist,
2132 direct_messages_topic_id: None,
2133 disable_notification: None,
2134 protect_content: None,
2135 message_effect_id: None,
2136 reply_parameters: None,
2137 reply_markup: None,
2138 suggested_post_parameters: None,
2139 },
2140 }
2141 }
2142 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
2144 self.params.direct_messages_topic_id = Some(id);
2145 self
2146 }
2147 pub fn disable_notification(mut self, v: bool) -> Self {
2149 self.params.disable_notification = Some(v);
2150 self
2151 }
2152 pub fn protect_content(mut self, v: bool) -> Self {
2154 self.params.protect_content = Some(v);
2155 self
2156 }
2157 pub fn message_effect_id(mut self, id: impl Into<String>) -> Self {
2159 self.params.message_effect_id = Some(id.into());
2160 self
2161 }
2162 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
2164 self.params.reply_parameters = Some(rp);
2165 self
2166 }
2167 pub fn reply_markup(mut self, m: rustigram_types::keyboard::InlineKeyboardMarkup) -> Self {
2169 self.params.reply_markup = Some(m);
2170 self
2171 }
2172 pub fn suggested_post_parameters(mut self, params: SuggestedPostParameters) -> Self {
2174 self.params.suggested_post_parameters = Some(params);
2175 self
2176 }
2177}
2178
2179impl_into_future!(SendChecklist, Message, "sendChecklist");