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 #[serde(skip_serializing_if = "Option::is_none")]
764 members_only: Option<bool>,
765 #[serde(skip_serializing_if = "Option::is_none")]
766 country_codes: Option<Vec<String>>,
767 #[serde(skip_serializing_if = "Option::is_none")]
768 media: Option<rustigram_types::poll::InputPollMedia>,
769 #[serde(skip_serializing_if = "Option::is_none")]
770 explanation_media: Option<rustigram_types::poll::InputPollMedia>,
771}
772
773pub struct SendPoll {
775 client: BotClient,
776 params: SendPollParams,
777}
778
779impl SendPoll {
780 pub(crate) fn new(
781 client: BotClient,
782 chat_id: impl Into<ChatId>,
783 question: impl Into<String>,
784 options: Vec<InputPollOption>,
785 ) -> Self {
786 Self {
787 client,
788 params: SendPollParams {
789 chat_id: chat_id.into(),
790 question: question.into(),
791 options,
792 question_parse_mode: None,
793 question_entities: None,
794 message_thread_id: None,
795 direct_messages_topic_id: None,
796 poll_type: None,
797 is_anonymous: None,
798 allows_multiple_answers: None,
799 allows_revoting: None,
800 correct_option_ids: None,
801 explanation: None,
802 explanation_parse_mode: None,
803 explanation_entities: None,
804 open_period: None,
805 close_date: None,
806 is_closed: None,
807 shuffle_options: None,
808 allow_adding_options: None,
809 hide_results_until_closes: None,
810 description: None,
811 description_parse_mode: None,
812 description_entities: None,
813 disable_notification: None,
814 protect_content: None,
815 reply_parameters: None,
816 reply_markup: None,
817 suggested_post_parameters: None,
818 members_only: None,
819 country_codes: None,
820 media: None,
821 explanation_media: None,
822 },
823 }
824 }
825 pub fn message_thread_id(mut self, id: i64) -> Self {
827 self.params.message_thread_id = Some(id);
828 self
829 }
830 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
832 self.params.direct_messages_topic_id = Some(id);
833 self
834 }
835 pub fn is_anonymous(mut self, v: bool) -> Self {
837 self.params.is_anonymous = Some(v);
838 self
839 }
840 pub fn allows_multiple_answers(mut self, v: bool) -> Self {
842 self.params.allows_multiple_answers = Some(v);
843 self
844 }
845 pub fn allows_revoting(mut self, v: bool) -> Self {
847 self.params.allows_revoting = Some(v);
848 self
849 }
850 pub fn quiz(mut self, ids: Vec<u8>) -> Self {
852 self.params.poll_type = Some(rustigram_types::poll::PollType::Quiz);
853 self.params.correct_option_ids = Some(ids);
854 self
855 }
856 pub fn quiz_single(self, id: u8) -> Self {
858 self.quiz(vec![id])
859 }
860 pub fn explanation(mut self, text: impl Into<String>) -> Self {
862 self.params.explanation = Some(text.into());
863 self
864 }
865 pub fn explanation_parse_mode(mut self, mode: ParseMode) -> Self {
867 self.params.explanation_parse_mode = Some(mode);
868 self
869 }
870 pub fn explanation_entities(mut self, e: Vec<rustigram_types::message::MessageEntity>) -> Self {
872 self.params.explanation_entities = Some(e);
873 self
874 }
875 pub fn open_period(mut self, secs: u32) -> Self {
877 self.params.open_period = Some(secs);
878 self
879 }
880 pub fn close_date(mut self, ts: i64) -> Self {
882 self.params.close_date = Some(ts);
883 self
884 }
885 pub fn shuffle_options(mut self, v: bool) -> Self {
887 self.params.shuffle_options = Some(v);
888 self
889 }
890 pub fn allow_adding_options(mut self, v: bool) -> Self {
892 self.params.allow_adding_options = Some(v);
893 self
894 }
895 pub fn hide_results_until_closes(mut self, v: bool) -> Self {
897 self.params.hide_results_until_closes = Some(v);
898 self
899 }
900 pub fn description(mut self, d: impl Into<String>) -> Self {
902 self.params.description = Some(d.into());
903 self
904 }
905 pub fn description_parse_mode(mut self, mode: ParseMode) -> Self {
907 self.params.description_parse_mode = Some(mode);
908 self
909 }
910 pub fn description_entities(mut self, e: Vec<rustigram_types::message::MessageEntity>) -> Self {
912 self.params.description_entities = Some(e);
913 self
914 }
915 pub fn question_parse_mode(mut self, mode: ParseMode) -> Self {
917 self.params.question_parse_mode = Some(mode);
918 self
919 }
920 pub fn question_entities(mut self, e: Vec<rustigram_types::message::MessageEntity>) -> Self {
922 self.params.question_entities = Some(e);
923 self
924 }
925 pub fn disable_notification(mut self, v: bool) -> Self {
927 self.params.disable_notification = Some(v);
928 self
929 }
930 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self {
932 self.params.reply_markup = Some(m.into());
933 self
934 }
935 pub fn suggested_post_parameters(mut self, params: SuggestedPostParameters) -> Self {
937 self.params.suggested_post_parameters = Some(params);
938 self
939 }
940 pub fn members_only(mut self, v: bool) -> Self {
943 self.params.members_only = Some(v);
944 self
945 }
946 pub fn country_codes(mut self, codes: Vec<impl Into<String>>) -> Self {
948 self.params.country_codes = Some(codes.into_iter().map(Into::into).collect());
949 self
950 }
951
952 pub fn media(mut self, m: rustigram_types::poll::InputPollMedia) -> Self {
954 self.params.media = Some(m);
955 self
956 }
957
958 pub fn explanation_media(mut self, m: rustigram_types::poll::InputPollMedia) -> Self {
960 self.params.explanation_media = Some(m);
961 self
962 }
963}
964
965impl_into_future!(SendPoll, Message, "sendPoll");
966
967#[derive(Serialize)]
970struct SendMessageDraftParams {
971 chat_id: ChatId,
972 draft_id: i64,
973 text: String,
974 #[serde(skip_serializing_if = "Option::is_none")]
975 message_thread_id: Option<i64>,
976 #[serde(skip_serializing_if = "Option::is_none")]
977 parse_mode: Option<ParseMode>,
978 #[serde(skip_serializing_if = "Option::is_none")]
979 entities: Option<Vec<rustigram_types::message::MessageEntity>>,
980}
981
982pub struct SendMessageDraft {
985 client: BotClient,
986 params: SendMessageDraftParams,
987}
988
989impl SendMessageDraft {
990 pub(crate) fn new(
991 client: BotClient,
992 chat_id: impl Into<ChatId>,
993 draft_id: i64,
994 text: impl Into<String>,
995 ) -> Self {
996 Self {
997 client,
998 params: SendMessageDraftParams {
999 chat_id: chat_id.into(),
1000 draft_id,
1001 text: text.into(),
1002 message_thread_id: None,
1003 parse_mode: None,
1004 entities: None,
1005 },
1006 }
1007 }
1008 pub fn parse_mode(mut self, m: ParseMode) -> Self {
1010 self.params.parse_mode = Some(m);
1011 self
1012 }
1013 pub fn entities(mut self, e: Vec<rustigram_types::message::MessageEntity>) -> Self {
1015 self.params.entities = Some(e);
1016 self
1017 }
1018}
1019
1020impl_into_future!(SendMessageDraft, bool, "sendMessageDraft");
1021
1022#[derive(Default)]
1031pub struct MediaSendOptions {
1032 pub business_connection_id: Option<String>,
1034 pub message_thread_id: Option<i64>,
1036 pub direct_messages_topic_id: Option<i64>,
1038 pub caption: Option<String>,
1040 pub parse_mode: Option<ParseMode>,
1042 pub caption_entities: Option<Vec<rustigram_types::message::MessageEntity>>,
1044 pub show_caption_above_media: Option<bool>,
1046 pub has_spoiler: Option<bool>,
1048 pub disable_notification: Option<bool>,
1050 pub protect_content: Option<bool>,
1052 pub allow_paid_broadcast: Option<bool>,
1054 pub reply_parameters: Option<ReplyParameters>,
1056 pub reply_markup: Option<ReplyMarkup>,
1058 pub suggested_post_parameters: Option<SuggestedPostParameters>,
1060}
1061
1062fn media_json_body(
1064 chat_id: &ChatId,
1065 media_field: &str,
1066 media_value: &str,
1067 opts: &MediaSendOptions,
1068 extra: serde_json::Value,
1069) -> serde_json::Value {
1070 let mut map = serde_json::json!({
1071 "chat_id": chat_id,
1072 media_field: media_value,
1073 });
1074 let obj = map.as_object_mut().unwrap();
1075 if let Some(v) = &opts.business_connection_id {
1076 obj.insert("business_connection_id".to_owned(), serde_json::json!(v));
1077 }
1078 if let Some(v) = &opts.message_thread_id {
1079 obj.insert("message_thread_id".to_owned(), serde_json::json!(v));
1080 }
1081 if let Some(v) = &opts.direct_messages_topic_id {
1082 obj.insert("direct_messages_topic_id".to_owned(), serde_json::json!(v));
1083 }
1084 if let Some(v) = &opts.caption {
1085 obj.insert("caption".to_owned(), serde_json::json!(v));
1086 }
1087 if let Some(v) = &opts.parse_mode {
1088 obj.insert("parse_mode".to_owned(), serde_json::json!(v));
1089 }
1090 if let Some(v) = &opts.caption_entities {
1091 obj.insert("caption_entities".to_owned(), serde_json::json!(v));
1092 }
1093 if let Some(v) = opts.show_caption_above_media {
1094 obj.insert("show_caption_above_media".to_owned(), serde_json::json!(v));
1095 }
1096 if let Some(v) = opts.has_spoiler {
1097 obj.insert("has_spoiler".to_owned(), serde_json::json!(v));
1098 }
1099 if let Some(v) = opts.disable_notification {
1100 obj.insert("disable_notification".to_owned(), serde_json::json!(v));
1101 }
1102 if let Some(v) = opts.protect_content {
1103 obj.insert("protect_content".to_owned(), serde_json::json!(v));
1104 }
1105 if let Some(v) = opts.allow_paid_broadcast {
1106 obj.insert("allow_paid_broadcast".to_owned(), serde_json::json!(v));
1107 }
1108 if let Some(v) = &opts.reply_parameters {
1109 obj.insert("reply_parameters".to_owned(), serde_json::json!(v));
1110 }
1111 if let Some(v) = &opts.reply_markup {
1112 obj.insert("reply_markup".to_owned(), serde_json::json!(v));
1113 }
1114 if let Some(v) = &opts.suggested_post_parameters {
1115 obj.insert("suggested_post_parameters".to_owned(), serde_json::json!(v));
1116 }
1117 if let serde_json::Value::Object(extra_obj) = extra {
1118 for (k, v) in extra_obj {
1119 obj.insert(k, v);
1120 }
1121 }
1122 map
1123}
1124
1125pub struct SendPhoto {
1129 client: BotClient,
1130 chat_id: ChatId,
1131 photo: InputFile,
1132 opts: MediaSendOptions,
1133}
1134
1135impl SendPhoto {
1136 pub(crate) fn new(client: BotClient, chat_id: impl Into<ChatId>, photo: InputFile) -> Self {
1137 Self {
1138 client,
1139 chat_id: chat_id.into(),
1140 photo,
1141 opts: MediaSendOptions::default(),
1142 }
1143 }
1144 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
1146 self.opts.business_connection_id = Some(id.into());
1147 self
1148 }
1149 pub fn message_thread_id(mut self, id: i64) -> Self {
1151 self.opts.message_thread_id = Some(id);
1152 self
1153 }
1154 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
1156 self.opts.direct_messages_topic_id = Some(id);
1157 self
1158 }
1159 pub fn caption(mut self, c: impl Into<String>) -> Self {
1161 self.opts.caption = Some(c.into());
1162 self
1163 }
1164 pub fn parse_mode(mut self, m: ParseMode) -> Self {
1166 self.opts.parse_mode = Some(m);
1167 self
1168 }
1169 pub fn has_spoiler(mut self, v: bool) -> Self {
1171 self.opts.has_spoiler = Some(v);
1172 self
1173 }
1174 pub fn show_caption_above_media(mut self, v: bool) -> Self {
1176 self.opts.show_caption_above_media = Some(v);
1177 self
1178 }
1179 pub fn disable_notification(mut self, v: bool) -> Self {
1181 self.opts.disable_notification = Some(v);
1182 self
1183 }
1184 pub fn protect_content(mut self, v: bool) -> Self {
1186 self.opts.protect_content = Some(v);
1187 self
1188 }
1189 pub fn allow_paid_broadcast(mut self, v: bool) -> Self {
1191 self.opts.allow_paid_broadcast = Some(v);
1192 self
1193 }
1194 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
1196 self.opts.reply_parameters = Some(rp);
1197 self
1198 }
1199 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self {
1201 self.opts.reply_markup = Some(m.into());
1202 self
1203 }
1204 pub fn suggested_post_parameters(mut self, params: SuggestedPostParameters) -> Self {
1206 self.opts.suggested_post_parameters = Some(params);
1207 self
1208 }
1209}
1210
1211impl IntoFuture for SendPhoto {
1212 type Output = Result<Message>;
1213 type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
1214
1215 fn into_future(self) -> Self::IntoFuture {
1216 Box::pin(async move {
1217 match &self.photo {
1218 InputFile::Bytes {
1219 filename,
1220 data,
1221 mime_type,
1222 } => {
1223 let part = Part::bytes(data.clone())
1224 .file_name(filename.clone())
1225 .mime_str(mime_type)
1226 .map_err(|e| crate::error::Error::Decode(e.to_string()))?;
1227 let mut form = Form::new().part("photo", part);
1228 form = form.text("chat_id", self.chat_id.to_string());
1229 if let Some(id) = &self.opts.business_connection_id {
1230 form = form.text("business_connection_id", id.clone());
1231 }
1232 if let Some(id) = self.opts.message_thread_id {
1233 form = form.text("message_thread_id", id.to_string());
1234 }
1235 if let Some(id) = self.opts.direct_messages_topic_id {
1236 form = form.text("direct_messages_topic_id", id.to_string());
1237 }
1238 if let Some(c) = &self.opts.caption {
1239 form = form.text("caption", c.clone());
1240 }
1241 if let Some(m) = &self.opts.parse_mode {
1242 form = form.text("parse_mode", format!("{m:?}"));
1243 }
1244 if let Some(v) = self.opts.disable_notification {
1245 form = form.text("disable_notification", v.to_string());
1246 }
1247 if let Some(v) = self.opts.has_spoiler {
1248 form = form.text("has_spoiler", v.to_string());
1249 }
1250 if let Some(v) = &self.opts.reply_markup {
1251 form = form.text("reply_markup", serde_json::to_string(v).unwrap());
1252 }
1253 if let Some(p) = &self.opts.suggested_post_parameters {
1254 form = form.text(
1255 "suggested_post_parameters",
1256 serde_json::to_string(p).unwrap(),
1257 );
1258 }
1259 self.client.post_multipart("sendPhoto", form).await
1260 }
1261 _ => {
1262 let body = media_json_body(
1263 &self.chat_id,
1264 "photo",
1265 self.photo.as_str(),
1266 &self.opts,
1267 serde_json::Value::Null,
1268 );
1269 self.client.post_json("sendPhoto", &body).await
1270 }
1271 }
1272 })
1273 }
1274}
1275
1276pub struct SendLivePhoto {
1280 client: BotClient,
1281 chat_id: ChatId,
1282 live_photo: InputFile,
1283 photo: InputFile,
1284 opts: MediaSendOptions,
1285 has_spoiler: Option<bool>,
1286 message_effect_id: Option<String>,
1287}
1288
1289impl SendLivePhoto {
1290 pub(crate) fn new(
1291 client: BotClient,
1292 chat_id: impl Into<ChatId>,
1293 live_photo: InputFile,
1294 photo: InputFile,
1295 ) -> Self {
1296 Self {
1297 client,
1298 chat_id: chat_id.into(),
1299 live_photo,
1300 photo,
1301 opts: MediaSendOptions::default(),
1302 has_spoiler: None,
1303 message_effect_id: None,
1304 }
1305 }
1306 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
1308 self.opts.business_connection_id = Some(id.into());
1309 self
1310 }
1311 pub fn message_thread_id(mut self, id: i64) -> Self {
1313 self.opts.message_thread_id = Some(id);
1314 self
1315 }
1316 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
1318 self.opts.direct_messages_topic_id = Some(id);
1319 self
1320 }
1321 pub fn caption(mut self, c: impl Into<String>) -> Self {
1323 self.opts.caption = Some(c.into());
1324 self
1325 }
1326 pub fn parse_mode(mut self, m: ParseMode) -> Self {
1328 self.opts.parse_mode = Some(m);
1329 self
1330 }
1331 pub fn show_caption_above_media(mut self, v: bool) -> Self {
1333 self.opts.show_caption_above_media = Some(v);
1334 self
1335 }
1336 pub fn has_spoiler(mut self, v: bool) -> Self {
1338 self.has_spoiler = Some(v);
1339 self
1340 }
1341 pub fn disable_notification(mut self, v: bool) -> Self {
1343 self.opts.disable_notification = Some(v);
1344 self
1345 }
1346 pub fn protect_content(mut self, v: bool) -> Self {
1348 self.opts.protect_content = Some(v);
1349 self
1350 }
1351 pub fn allow_paid_broadcast(mut self, v: bool) -> Self {
1353 self.opts.allow_paid_broadcast = Some(v);
1354 self
1355 }
1356 pub fn message_effect_id(mut self, id: impl Into<String>) -> Self {
1358 self.message_effect_id = Some(id.into());
1359 self
1360 }
1361 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
1363 self.opts.reply_parameters = Some(rp);
1364 self
1365 }
1366 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self {
1368 self.opts.reply_markup = Some(m.into());
1369 self
1370 }
1371 pub fn suggested_post_parameters(mut self, params: SuggestedPostParameters) -> Self {
1373 self.opts.suggested_post_parameters = Some(params);
1374 self
1375 }
1376}
1377
1378impl IntoFuture for SendLivePhoto {
1379 type Output = Result<Message>;
1380 type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
1381
1382 fn into_future(self) -> Self::IntoFuture {
1383 Box::pin(async move {
1384 let lp_bytes = self.live_photo.requires_multipart();
1385 let ph_bytes = self.photo.requires_multipart();
1386
1387 if lp_bytes || ph_bytes {
1388 let mut form = Form::new();
1389 form = form.text("chat_id", self.chat_id.to_string());
1390
1391 if let InputFile::Bytes {
1392 filename,
1393 data,
1394 mime_type,
1395 } = self.live_photo
1396 {
1397 let part = Part::bytes(data)
1398 .file_name(filename)
1399 .mime_str(&mime_type)
1400 .map_err(|e| crate::error::Error::Decode(e.to_string()))?;
1401 form = form.part("live_photo", part);
1402 } else {
1403 form = form.text("live_photo", self.live_photo.as_str().to_owned());
1404 }
1405
1406 if let InputFile::Bytes {
1407 filename,
1408 data,
1409 mime_type,
1410 } = self.photo
1411 {
1412 let part = Part::bytes(data)
1413 .file_name(filename)
1414 .mime_str(&mime_type)
1415 .map_err(|e| crate::error::Error::Decode(e.to_string()))?;
1416 form = form.part("photo", part);
1417 } else {
1418 form = form.text("photo", self.photo.as_str().to_owned());
1419 }
1420
1421 if let Some(id) = &self.opts.business_connection_id {
1422 form = form.text("business_connection_id", id.clone());
1423 }
1424 if let Some(id) = self.opts.message_thread_id {
1425 form = form.text("message_thread_id", id.to_string());
1426 }
1427 if let Some(id) = self.opts.direct_messages_topic_id {
1428 form = form.text("direct_messages_topic_id", id.to_string());
1429 }
1430 if let Some(c) = &self.opts.caption {
1431 form = form.text("caption", c.clone());
1432 }
1433 if let Some(m) = &self.opts.parse_mode {
1434 form = form.text("parse_mode", format!("{m:?}"));
1435 }
1436 if let Some(v) = self.opts.show_caption_above_media {
1437 form = form.text("show_caption_above_media", v.to_string());
1438 }
1439 if let Some(v) = self.has_spoiler {
1440 form = form.text("has_spoiler", v.to_string());
1441 }
1442 if let Some(v) = self.opts.disable_notification {
1443 form = form.text("disable_notification", v.to_string());
1444 }
1445 if let Some(v) = self.opts.protect_content {
1446 form = form.text("protect_content", v.to_string());
1447 }
1448 if let Some(v) = self.opts.allow_paid_broadcast {
1449 form = form.text("allow_paid_broadcast", v.to_string());
1450 }
1451 if let Some(id) = &self.message_effect_id {
1452 form = form.text("message_effect_id", id.clone());
1453 }
1454 if let Some(v) = &self.opts.reply_parameters {
1455 form = form.text("reply_parameters", serde_json::to_string(v).unwrap());
1456 }
1457 if let Some(v) = &self.opts.reply_markup {
1458 form = form.text("reply_markup", serde_json::to_string(v).unwrap());
1459 }
1460 if let Some(p) = &self.opts.suggested_post_parameters {
1461 form = form.text(
1462 "suggested_post_parameters",
1463 serde_json::to_string(p).unwrap(),
1464 );
1465 }
1466
1467 self.client.post_multipart("sendLivePhoto", form).await
1468 } else {
1469 let extra = {
1470 let mut m = serde_json::json!({});
1471 if let Some(v) = self.has_spoiler {
1472 m["has_spoiler"] = serde_json::json!(v);
1473 }
1474 if let Some(id) = &self.message_effect_id {
1475 m["message_effect_id"] = serde_json::json!(id);
1476 }
1477 m
1478 };
1479 let mut body = media_json_body(
1480 &self.chat_id,
1481 "live_photo",
1482 self.live_photo.as_str(),
1483 &self.opts,
1484 extra,
1485 );
1486 body.as_object_mut()
1487 .unwrap()
1488 .insert("photo".to_owned(), serde_json::json!(self.photo.as_str()));
1489 self.client.post_json("sendLivePhoto", &body).await
1490 }
1491 })
1492 }
1493}
1494
1495macro_rules! media_sender {
1498 ($(#[$doc:meta])* $name:ident, $field:literal, $method:literal, $return_ty:ty, [$($extra_field:ident: $extra_ty:ty),*]) => {
1499 $(#[$doc])*
1500 pub struct $name {
1501 client: BotClient,
1503 chat_id: ChatId,
1505 file: InputFile,
1507 opts: MediaSendOptions,
1509 $($extra_field: Option<$extra_ty>,)*
1511 }
1512
1513 impl $name {
1514 pub(crate) fn new(client: BotClient, chat_id: impl Into<ChatId>, file: InputFile) -> Self {
1515 Self {
1516 client,
1517 chat_id: chat_id.into(),
1518 file,
1519 opts: MediaSendOptions::default(),
1520 $($extra_field: None,)*
1521 }
1522 }
1523 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self { self.opts.business_connection_id = Some(id.into()); self }
1525 pub fn message_thread_id(mut self, id: i64) -> Self { self.opts.message_thread_id = Some(id); self }
1527 pub fn direct_messages_topic_id(mut self, id: i64) -> Self { self.opts.direct_messages_topic_id = Some(id); self }
1529 pub fn caption(mut self, c: impl Into<String>) -> Self { self.opts.caption = Some(c.into()); self }
1531 pub fn parse_mode(mut self, m: ParseMode) -> Self { self.opts.parse_mode = Some(m); self }
1533 pub fn disable_notification(mut self, v: bool) -> Self { self.opts.disable_notification = Some(v); self }
1535 pub fn protect_content(mut self, v: bool) -> Self { self.opts.protect_content = Some(v); self }
1537 pub fn allow_paid_broadcast(mut self, v: bool) -> Self { self.opts.allow_paid_broadcast = Some(v); self }
1539 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self { self.opts.reply_parameters = Some(rp); self }
1541 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self { self.opts.reply_markup = Some(m.into()); self }
1543 pub fn suggested_post_parameters(mut self, params: SuggestedPostParameters) -> Self { self.opts.suggested_post_parameters = Some(params); self }
1545
1546 $(
1547 #[doc = concat!("Sets the ", stringify!($extra_field), " for the media.")]
1548 pub fn $extra_field(mut self, v: $extra_ty) -> Self {
1549 self.$extra_field = Some(v);
1550 self
1551 }
1552 )*
1553 }
1554
1555 impl IntoFuture for $name {
1556 type Output = Result<$return_ty>;
1557 type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
1558
1559 fn into_future(self) -> Self::IntoFuture {
1560 Box::pin(async move {
1561 match &self.file {
1562 InputFile::Bytes { filename, data, mime_type } => {
1563 let part = Part::bytes(data.clone())
1564 .file_name(filename.clone())
1565 .mime_str(mime_type)
1566 .map_err(|e| crate::error::Error::Decode(e.to_string()))?;
1567 let mut form = Form::new().part($field, part);
1568 form = form.text("chat_id", self.chat_id.to_string());
1569 if let Some(id) = &self.opts.business_connection_id { form = form.text("business_connection_id", id.clone()); }
1570 if let Some(id) = self.opts.message_thread_id { form = form.text("message_thread_id", id.to_string()); }
1571 if let Some(id) = self.opts.direct_messages_topic_id { form = form.text("direct_messages_topic_id", id.to_string()); }
1572 if let Some(c) = &self.opts.caption { form = form.text("caption", c.clone()); }
1573 if let Some(v) = self.opts.disable_notification { form = form.text("disable_notification", v.to_string()); }
1574 if let Some(v) = &self.opts.reply_markup { form = form.text("reply_markup", serde_json::to_string(v).unwrap()); }
1575 if let Some(p) = &self.opts.suggested_post_parameters { form = form.text("suggested_post_parameters", serde_json::to_string(p).unwrap()); }
1576
1577 $(
1578 if let Some(ref v) = self.$extra_field {
1579 form = form.text(stringify!($extra_field), v.to_string());
1580 }
1581 )*
1582
1583 self.client.post_multipart($method, form).await
1584 }
1585 _ => {
1586 let mut extra = serde_json::json!({});
1587 $(
1588 if let Some(ref v) = self.$extra_field {
1589 extra[stringify!($extra_field)] = serde_json::json!(v);
1590 }
1591 )*
1592 let body = media_json_body(&self.chat_id, $field, self.file.as_str(), &self.opts, extra);
1593 self.client.post_json($method, &body).await
1594 }
1595 }
1596 })
1597 }
1598 }
1599 };
1600}
1601
1602media_sender!(
1603 SendAudio, "audio", "sendAudio", Message, [duration: u32, performer: String, title: String]);
1605media_sender!(
1606 SendDocument, "document", "sendDocument", Message, [disable_content_type_detection: bool]);
1608media_sender!(
1609 SendVideo, "video", "sendVideo", Message, [duration: u32, width: u32, height: u32, supports_streaming: bool, cover: String, start_timestamp: i64]);
1611media_sender!(
1612 SendAnimation, "animation", "sendAnimation", Message, [duration: u32, width: u32, height: u32]);
1614media_sender!(
1615 SendVoice, "voice", "sendVoice", Message, [duration: u32]);
1617media_sender!(
1618 SendVideoNote, "video_note", "sendVideoNote", Message, [duration: u32, length: u32]);
1620media_sender!(
1621 SendSticker, "sticker", "sendSticker", Message, [emoji: String]);
1623
1624#[derive(Serialize)]
1627struct DeleteMessageParams {
1628 chat_id: ChatId,
1629 message_id: i64,
1630}
1631
1632pub struct DeleteMessage {
1634 client: BotClient,
1635 params: DeleteMessageParams,
1636}
1637impl DeleteMessage {
1638 pub(crate) fn new(client: BotClient, chat_id: impl Into<ChatId>, message_id: i64) -> Self {
1639 Self {
1640 client,
1641 params: DeleteMessageParams {
1642 chat_id: chat_id.into(),
1643 message_id,
1644 },
1645 }
1646 }
1647}
1648impl_into_future!(DeleteMessage, bool, "deleteMessage");
1649
1650#[derive(Serialize)]
1651struct DeleteMessagesParams {
1652 chat_id: ChatId,
1653 message_ids: Vec<i64>,
1654}
1655
1656pub struct DeleteMessages {
1658 client: BotClient,
1659 params: DeleteMessagesParams,
1660}
1661impl DeleteMessages {
1662 pub(crate) fn new(
1663 client: BotClient,
1664 chat_id: impl Into<ChatId>,
1665 message_ids: Vec<i64>,
1666 ) -> Self {
1667 Self {
1668 client,
1669 params: DeleteMessagesParams {
1670 chat_id: chat_id.into(),
1671 message_ids,
1672 },
1673 }
1674 }
1675}
1676impl_into_future!(DeleteMessages, bool, "deleteMessages");
1677
1678#[derive(Serialize)]
1681struct StopPollParams {
1682 chat_id: ChatId,
1683 message_id: i64,
1684 #[serde(skip_serializing_if = "Option::is_none")]
1685 reply_markup: Option<rustigram_types::keyboard::InlineKeyboardMarkup>,
1686}
1687
1688pub struct StopPoll {
1690 client: BotClient,
1691 params: StopPollParams,
1692}
1693impl StopPoll {
1694 pub(crate) fn new(client: BotClient, chat_id: impl Into<ChatId>, message_id: i64) -> Self {
1695 Self {
1696 client,
1697 params: StopPollParams {
1698 chat_id: chat_id.into(),
1699 message_id,
1700 reply_markup: None,
1701 },
1702 }
1703 }
1704 pub fn reply_markup(mut self, m: rustigram_types::keyboard::InlineKeyboardMarkup) -> Self {
1706 self.params.reply_markup = Some(m);
1707 self
1708 }
1709}
1710impl_into_future!(StopPoll, rustigram_types::poll::Poll, "stopPoll");
1711
1712#[derive(Serialize)]
1715struct AnswerCallbackQueryParams {
1716 callback_query_id: String,
1717 #[serde(skip_serializing_if = "Option::is_none")]
1718 text: Option<String>,
1719 #[serde(skip_serializing_if = "Option::is_none")]
1720 show_alert: Option<bool>,
1721 #[serde(skip_serializing_if = "Option::is_none")]
1722 url: Option<String>,
1723 #[serde(skip_serializing_if = "Option::is_none")]
1724 cache_time: Option<u32>,
1725}
1726
1727pub struct AnswerCallbackQuery {
1729 client: BotClient,
1730 params: AnswerCallbackQueryParams,
1731}
1732impl AnswerCallbackQuery {
1733 pub(crate) fn new(client: BotClient, callback_query_id: impl Into<String>) -> Self {
1734 Self {
1735 client,
1736 params: AnswerCallbackQueryParams {
1737 callback_query_id: callback_query_id.into(),
1738 text: None,
1739 show_alert: None,
1740 url: None,
1741 cache_time: None,
1742 },
1743 }
1744 }
1745 pub fn text(mut self, t: impl Into<String>) -> Self {
1747 self.params.text = Some(t.into());
1748 self
1749 }
1750 pub fn show_alert(mut self, v: bool) -> Self {
1752 self.params.show_alert = Some(v);
1753 self
1754 }
1755 pub fn url(mut self, u: impl Into<String>) -> Self {
1757 self.params.url = Some(u.into());
1758 self
1759 }
1760 pub fn cache_time(mut self, secs: u32) -> Self {
1762 self.params.cache_time = Some(secs);
1763 self
1764 }
1765 pub fn alert(self, text: impl Into<String>) -> Self {
1767 self.text(text).show_alert(true)
1768 }
1769}
1770impl_into_future!(AnswerCallbackQuery, bool, "answerCallbackQuery");
1771#[derive(Serialize)]
1774struct ForwardMessagesParams {
1775 chat_id: ChatId,
1776 from_chat_id: ChatId,
1777 message_ids: Vec<i64>,
1778 #[serde(skip_serializing_if = "Option::is_none")]
1779 message_thread_id: Option<i64>,
1780 #[serde(skip_serializing_if = "Option::is_none")]
1781 direct_messages_topic_id: Option<i64>,
1782 #[serde(skip_serializing_if = "Option::is_none")]
1783 disable_notification: Option<bool>,
1784 #[serde(skip_serializing_if = "Option::is_none")]
1785 protect_content: Option<bool>,
1786}
1787
1788pub struct ForwardMessages {
1793 client: BotClient,
1794 params: ForwardMessagesParams,
1795}
1796
1797impl ForwardMessages {
1798 pub(crate) fn new(
1799 client: BotClient,
1800 chat_id: impl Into<ChatId>,
1801 from_chat_id: impl Into<ChatId>,
1802 message_ids: Vec<i64>,
1803 ) -> Self {
1804 Self {
1805 client,
1806 params: ForwardMessagesParams {
1807 chat_id: chat_id.into(),
1808 from_chat_id: from_chat_id.into(),
1809 message_ids,
1810 message_thread_id: None,
1811 direct_messages_topic_id: None,
1812 disable_notification: None,
1813 protect_content: None,
1814 },
1815 }
1816 }
1817 pub fn message_thread_id(mut self, id: i64) -> Self {
1819 self.params.message_thread_id = Some(id);
1820 self
1821 }
1822 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
1824 self.params.direct_messages_topic_id = Some(id);
1825 self
1826 }
1827 pub fn disable_notification(mut self, v: bool) -> Self {
1829 self.params.disable_notification = Some(v);
1830 self
1831 }
1832 pub fn protect_content(mut self, v: bool) -> Self {
1834 self.params.protect_content = Some(v);
1835 self
1836 }
1837}
1838
1839impl_into_future!(
1840 ForwardMessages,
1841 Vec<rustigram_types::message::MessageId>,
1842 "forwardMessages"
1843);
1844
1845#[derive(Serialize)]
1848struct CopyMessagesParams {
1849 chat_id: ChatId,
1850 from_chat_id: ChatId,
1851 message_ids: Vec<i64>,
1852 #[serde(skip_serializing_if = "Option::is_none")]
1853 message_thread_id: Option<i64>,
1854 #[serde(skip_serializing_if = "Option::is_none")]
1855 direct_messages_topic_id: Option<i64>,
1856 #[serde(skip_serializing_if = "Option::is_none")]
1857 disable_notification: Option<bool>,
1858 #[serde(skip_serializing_if = "Option::is_none")]
1859 protect_content: Option<bool>,
1860 #[serde(skip_serializing_if = "Option::is_none")]
1861 remove_caption: Option<bool>,
1862}
1863
1864pub struct CopyMessages {
1869 client: BotClient,
1870 params: CopyMessagesParams,
1871}
1872
1873impl CopyMessages {
1874 pub(crate) fn new(
1875 client: BotClient,
1876 chat_id: impl Into<ChatId>,
1877 from_chat_id: impl Into<ChatId>,
1878 message_ids: Vec<i64>,
1879 ) -> Self {
1880 Self {
1881 client,
1882 params: CopyMessagesParams {
1883 chat_id: chat_id.into(),
1884 from_chat_id: from_chat_id.into(),
1885 message_ids,
1886 message_thread_id: None,
1887 direct_messages_topic_id: None,
1888 disable_notification: None,
1889 protect_content: None,
1890 remove_caption: None,
1891 },
1892 }
1893 }
1894 pub fn message_thread_id(mut self, id: i64) -> Self {
1896 self.params.message_thread_id = Some(id);
1897 self
1898 }
1899 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
1901 self.params.direct_messages_topic_id = Some(id);
1902 self
1903 }
1904 pub fn disable_notification(mut self, v: bool) -> Self {
1906 self.params.disable_notification = Some(v);
1907 self
1908 }
1909 pub fn protect_content(mut self, v: bool) -> Self {
1911 self.params.protect_content = Some(v);
1912 self
1913 }
1914 pub fn remove_caption(mut self, v: bool) -> Self {
1916 self.params.remove_caption = Some(v);
1917 self
1918 }
1919}
1920
1921impl_into_future!(
1922 CopyMessages,
1923 Vec<rustigram_types::message::MessageId>,
1924 "copyMessages"
1925);
1926
1927#[derive(Serialize)]
1930struct SendVenueParams {
1931 chat_id: ChatId,
1932 latitude: f64,
1933 longitude: f64,
1934 title: String,
1935 address: String,
1936 #[serde(skip_serializing_if = "Option::is_none")]
1937 message_thread_id: Option<i64>,
1938 #[serde(skip_serializing_if = "Option::is_none")]
1939 direct_messages_topic_id: Option<i64>,
1940 #[serde(skip_serializing_if = "Option::is_none")]
1941 foursquare_id: Option<String>,
1942 #[serde(skip_serializing_if = "Option::is_none")]
1943 foursquare_type: Option<String>,
1944 #[serde(skip_serializing_if = "Option::is_none")]
1945 google_place_id: Option<String>,
1946 #[serde(skip_serializing_if = "Option::is_none")]
1947 google_place_type: Option<String>,
1948 #[serde(skip_serializing_if = "Option::is_none")]
1949 disable_notification: Option<bool>,
1950 #[serde(skip_serializing_if = "Option::is_none")]
1951 protect_content: Option<bool>,
1952 #[serde(skip_serializing_if = "Option::is_none")]
1953 reply_parameters: Option<ReplyParameters>,
1954 #[serde(skip_serializing_if = "Option::is_none")]
1955 reply_markup: Option<ReplyMarkup>,
1956}
1957
1958pub struct SendVenue {
1960 client: BotClient,
1961 params: SendVenueParams,
1962}
1963
1964impl SendVenue {
1965 pub(crate) fn new(
1966 client: BotClient,
1967 chat_id: impl Into<ChatId>,
1968 latitude: f64,
1969 longitude: f64,
1970 title: impl Into<String>,
1971 address: impl Into<String>,
1972 ) -> Self {
1973 Self {
1974 client,
1975 params: SendVenueParams {
1976 chat_id: chat_id.into(),
1977 latitude,
1978 longitude,
1979 title: title.into(),
1980 address: address.into(),
1981 message_thread_id: None,
1982 direct_messages_topic_id: None,
1983 foursquare_id: None,
1984 foursquare_type: None,
1985 google_place_id: None,
1986 google_place_type: None,
1987 disable_notification: None,
1988 protect_content: None,
1989 reply_parameters: None,
1990 reply_markup: None,
1991 },
1992 }
1993 }
1994 pub fn message_thread_id(mut self, id: i64) -> Self {
1996 self.params.message_thread_id = Some(id);
1997 self
1998 }
1999 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
2001 self.params.direct_messages_topic_id = Some(id);
2002 self
2003 }
2004 pub fn foursquare_id(mut self, id: impl Into<String>) -> Self {
2006 self.params.foursquare_id = Some(id.into());
2007 self
2008 }
2009 pub fn foursquare_type(mut self, t: impl Into<String>) -> Self {
2011 self.params.foursquare_type = Some(t.into());
2012 self
2013 }
2014 pub fn google_place_id(mut self, id: impl Into<String>) -> Self {
2016 self.params.google_place_id = Some(id.into());
2017 self
2018 }
2019 pub fn google_place_type(mut self, t: impl Into<String>) -> Self {
2021 self.params.google_place_type = Some(t.into());
2022 self
2023 }
2024 pub fn disable_notification(mut self, v: bool) -> Self {
2026 self.params.disable_notification = Some(v);
2027 self
2028 }
2029 pub fn protect_content(mut self, v: bool) -> Self {
2031 self.params.protect_content = Some(v);
2032 self
2033 }
2034 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
2036 self.params.reply_parameters = Some(rp);
2037 self
2038 }
2039 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self {
2041 self.params.reply_markup = Some(m.into());
2042 self
2043 }
2044}
2045
2046impl_into_future!(SendVenue, Message, "sendVenue");
2047
2048#[derive(Serialize)]
2051struct SendMediaGroupParams {
2052 chat_id: ChatId,
2053 media: Vec<serde_json::Value>,
2058 #[serde(skip_serializing_if = "Option::is_none")]
2059 message_thread_id: Option<i64>,
2060 #[serde(skip_serializing_if = "Option::is_none")]
2061 direct_messages_topic_id: Option<i64>,
2062 #[serde(skip_serializing_if = "Option::is_none")]
2063 business_connection_id: Option<String>,
2064 #[serde(skip_serializing_if = "Option::is_none")]
2065 disable_notification: Option<bool>,
2066 #[serde(skip_serializing_if = "Option::is_none")]
2067 protect_content: Option<bool>,
2068 #[serde(skip_serializing_if = "Option::is_none")]
2069 reply_parameters: Option<ReplyParameters>,
2070}
2071
2072pub struct SendMediaGroup {
2080 client: BotClient,
2081 params: SendMediaGroupParams,
2082}
2083
2084impl SendMediaGroup {
2085 pub(crate) fn new(
2086 client: BotClient,
2087 chat_id: impl Into<ChatId>,
2088 media: Vec<serde_json::Value>,
2089 ) -> Self {
2090 Self {
2091 client,
2092 params: SendMediaGroupParams {
2093 chat_id: chat_id.into(),
2094 media,
2095 message_thread_id: None,
2096 direct_messages_topic_id: None,
2097 business_connection_id: None,
2098 disable_notification: None,
2099 protect_content: None,
2100 reply_parameters: None,
2101 },
2102 }
2103 }
2104 pub fn message_thread_id(mut self, id: i64) -> Self {
2106 self.params.message_thread_id = Some(id);
2107 self
2108 }
2109 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
2111 self.params.direct_messages_topic_id = Some(id);
2112 self
2113 }
2114 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
2116 self.params.business_connection_id = Some(id.into());
2117 self
2118 }
2119 pub fn disable_notification(mut self, v: bool) -> Self {
2121 self.params.disable_notification = Some(v);
2122 self
2123 }
2124 pub fn protect_content(mut self, v: bool) -> Self {
2126 self.params.protect_content = Some(v);
2127 self
2128 }
2129 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
2131 self.params.reply_parameters = Some(rp);
2132 self
2133 }
2134}
2135
2136impl_into_future!(SendMediaGroup, Vec<Message>, "sendMediaGroup");
2137
2138#[derive(Serialize)]
2141struct SendPaidMediaParams {
2142 chat_id: ChatId,
2143 star_count: u32,
2144 media: Vec<serde_json::Value>,
2149 #[serde(skip_serializing_if = "Option::is_none")]
2150 business_connection_id: Option<String>,
2151 #[serde(skip_serializing_if = "Option::is_none")]
2152 payload: Option<String>,
2153 #[serde(skip_serializing_if = "Option::is_none")]
2154 caption: Option<String>,
2155 #[serde(skip_serializing_if = "Option::is_none")]
2156 parse_mode: Option<ParseMode>,
2157 #[serde(skip_serializing_if = "Option::is_none")]
2158 show_caption_above_media: Option<bool>,
2159 #[serde(skip_serializing_if = "Option::is_none")]
2160 disable_notification: Option<bool>,
2161 #[serde(skip_serializing_if = "Option::is_none")]
2162 protect_content: Option<bool>,
2163 #[serde(skip_serializing_if = "Option::is_none")]
2164 reply_parameters: Option<ReplyParameters>,
2165 #[serde(skip_serializing_if = "Option::is_none")]
2166 reply_markup: Option<ReplyMarkup>,
2167}
2168
2169pub struct SendPaidMedia {
2176 client: BotClient,
2177 params: SendPaidMediaParams,
2178}
2179
2180impl SendPaidMedia {
2181 pub(crate) fn new(
2182 client: BotClient,
2183 chat_id: impl Into<ChatId>,
2184 star_count: u32,
2185 media: Vec<serde_json::Value>,
2186 ) -> Self {
2187 Self {
2188 client,
2189 params: SendPaidMediaParams {
2190 chat_id: chat_id.into(),
2191 star_count,
2192 media,
2193 business_connection_id: None,
2194 payload: None,
2195 caption: None,
2196 parse_mode: None,
2197 show_caption_above_media: None,
2198 disable_notification: None,
2199 protect_content: None,
2200 reply_parameters: None,
2201 reply_markup: None,
2202 },
2203 }
2204 }
2205 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
2207 self.params.business_connection_id = Some(id.into());
2208 self
2209 }
2210 pub fn payload(mut self, p: impl Into<String>) -> Self {
2212 self.params.payload = Some(p.into());
2213 self
2214 }
2215 pub fn caption(mut self, c: impl Into<String>) -> Self {
2217 self.params.caption = Some(c.into());
2218 self
2219 }
2220 pub fn parse_mode(mut self, m: ParseMode) -> Self {
2222 self.params.parse_mode = Some(m);
2223 self
2224 }
2225 pub fn show_caption_above_media(mut self, v: bool) -> Self {
2227 self.params.show_caption_above_media = Some(v);
2228 self
2229 }
2230 pub fn disable_notification(mut self, v: bool) -> Self {
2232 self.params.disable_notification = Some(v);
2233 self
2234 }
2235 pub fn protect_content(mut self, v: bool) -> Self {
2237 self.params.protect_content = Some(v);
2238 self
2239 }
2240 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
2242 self.params.reply_parameters = Some(rp);
2243 self
2244 }
2245 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self {
2247 self.params.reply_markup = Some(m.into());
2248 self
2249 }
2250}
2251
2252impl_into_future!(SendPaidMedia, Message, "sendPaidMedia");
2253
2254#[derive(Serialize)]
2257struct SendGameParams {
2258 chat_id: i64,
2259 game_short_name: String,
2260 #[serde(skip_serializing_if = "Option::is_none")]
2261 business_connection_id: Option<String>,
2262 #[serde(skip_serializing_if = "Option::is_none")]
2263 message_thread_id: Option<i64>,
2264 #[serde(skip_serializing_if = "Option::is_none")]
2265 direct_messages_topic_id: Option<i64>,
2266 #[serde(skip_serializing_if = "Option::is_none")]
2267 disable_notification: Option<bool>,
2268 #[serde(skip_serializing_if = "Option::is_none")]
2269 protect_content: Option<bool>,
2270 #[serde(skip_serializing_if = "Option::is_none")]
2271 reply_parameters: Option<ReplyParameters>,
2272 #[serde(skip_serializing_if = "Option::is_none")]
2273 reply_markup: Option<rustigram_types::keyboard::InlineKeyboardMarkup>,
2274}
2275
2276pub struct SendGame {
2281 client: BotClient,
2282 params: SendGameParams,
2283}
2284
2285impl SendGame {
2286 pub(crate) fn new(client: BotClient, chat_id: i64, game_short_name: impl Into<String>) -> Self {
2287 Self {
2288 client,
2289 params: SendGameParams {
2290 chat_id,
2291 game_short_name: game_short_name.into(),
2292 business_connection_id: None,
2293 message_thread_id: None,
2294 direct_messages_topic_id: None,
2295 disable_notification: None,
2296 protect_content: None,
2297 reply_parameters: None,
2298 reply_markup: None,
2299 },
2300 }
2301 }
2302 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
2304 self.params.business_connection_id = Some(id.into());
2305 self
2306 }
2307 pub fn message_thread_id(mut self, id: i64) -> Self {
2309 self.params.message_thread_id = Some(id);
2310 self
2311 }
2312 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
2314 self.params.direct_messages_topic_id = Some(id);
2315 self
2316 }
2317 pub fn disable_notification(mut self, v: bool) -> Self {
2319 self.params.disable_notification = Some(v);
2320 self
2321 }
2322 pub fn protect_content(mut self, v: bool) -> Self {
2324 self.params.protect_content = Some(v);
2325 self
2326 }
2327 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
2329 self.params.reply_parameters = Some(rp);
2330 self
2331 }
2332 pub fn reply_markup(mut self, m: rustigram_types::keyboard::InlineKeyboardMarkup) -> Self {
2334 self.params.reply_markup = Some(m);
2335 self
2336 }
2337}
2338
2339impl_into_future!(SendGame, Message, "sendGame");
2340
2341#[derive(Serialize)]
2344struct SendChecklistParams {
2345 business_connection_id: String,
2346 chat_id: i64,
2347 checklist: rustigram_types::checklist::InputChecklist,
2348 #[serde(skip_serializing_if = "Option::is_none")]
2349 direct_messages_topic_id: Option<i64>,
2350 #[serde(skip_serializing_if = "Option::is_none")]
2351 disable_notification: Option<bool>,
2352 #[serde(skip_serializing_if = "Option::is_none")]
2353 protect_content: Option<bool>,
2354 #[serde(skip_serializing_if = "Option::is_none")]
2355 message_effect_id: Option<String>,
2356 #[serde(skip_serializing_if = "Option::is_none")]
2357 reply_parameters: Option<ReplyParameters>,
2358 #[serde(skip_serializing_if = "Option::is_none")]
2359 reply_markup: Option<rustigram_types::keyboard::InlineKeyboardMarkup>,
2360 #[serde(skip_serializing_if = "Option::is_none")]
2361 suggested_post_parameters: Option<SuggestedPostParameters>,
2362}
2363
2364pub struct SendChecklist {
2369 client: BotClient,
2370 params: SendChecklistParams,
2371}
2372
2373impl SendChecklist {
2374 pub(crate) fn new(
2375 client: BotClient,
2376 business_connection_id: impl Into<String>,
2377 chat_id: i64,
2378 checklist: rustigram_types::checklist::InputChecklist,
2379 ) -> Self {
2380 Self {
2381 client,
2382 params: SendChecklistParams {
2383 business_connection_id: business_connection_id.into(),
2384 chat_id,
2385 checklist,
2386 direct_messages_topic_id: None,
2387 disable_notification: None,
2388 protect_content: None,
2389 message_effect_id: None,
2390 reply_parameters: None,
2391 reply_markup: None,
2392 suggested_post_parameters: None,
2393 },
2394 }
2395 }
2396 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
2398 self.params.direct_messages_topic_id = Some(id);
2399 self
2400 }
2401 pub fn disable_notification(mut self, v: bool) -> Self {
2403 self.params.disable_notification = Some(v);
2404 self
2405 }
2406 pub fn protect_content(mut self, v: bool) -> Self {
2408 self.params.protect_content = Some(v);
2409 self
2410 }
2411 pub fn message_effect_id(mut self, id: impl Into<String>) -> Self {
2413 self.params.message_effect_id = Some(id.into());
2414 self
2415 }
2416 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
2418 self.params.reply_parameters = Some(rp);
2419 self
2420 }
2421 pub fn reply_markup(mut self, m: rustigram_types::keyboard::InlineKeyboardMarkup) -> Self {
2423 self.params.reply_markup = Some(m);
2424 self
2425 }
2426 pub fn suggested_post_parameters(mut self, params: SuggestedPostParameters) -> Self {
2428 self.params.suggested_post_parameters = Some(params);
2429 self
2430 }
2431}
2432
2433impl_into_future!(SendChecklist, Message, "sendChecklist");