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(m) = &self.opts.parse_mode { form = form.text("parse_mode", format!("{m:?}")); }
1574 if let Some(v) = self.opts.disable_notification { form = form.text("disable_notification", v.to_string()); }
1575 if let Some(v) = &self.opts.reply_markup { form = form.text("reply_markup", serde_json::to_string(v).unwrap()); }
1576 if let Some(p) = &self.opts.suggested_post_parameters { form = form.text("suggested_post_parameters", serde_json::to_string(p).unwrap()); }
1577
1578 $(
1579 if let Some(ref v) = self.$extra_field {
1580 form = form.text(stringify!($extra_field), v.to_string());
1581 }
1582 )*
1583
1584 self.client.post_multipart($method, form).await
1585 }
1586 _ => {
1587 let mut extra = serde_json::json!({});
1588 $(
1589 if let Some(ref v) = self.$extra_field {
1590 extra[stringify!($extra_field)] = serde_json::json!(v);
1591 }
1592 )*
1593 let body = media_json_body(&self.chat_id, $field, self.file.as_str(), &self.opts, extra);
1594 self.client.post_json($method, &body).await
1595 }
1596 }
1597 })
1598 }
1599 }
1600 };
1601}
1602
1603media_sender!(
1604 SendAudio, "audio", "sendAudio", Message, [duration: u32, performer: String, title: String]);
1606media_sender!(
1607 SendDocument, "document", "sendDocument", Message, [disable_content_type_detection: bool]);
1609media_sender!(
1610 SendVideo, "video", "sendVideo", Message, [duration: u32, width: u32, height: u32, supports_streaming: bool, cover: String, start_timestamp: i64]);
1612media_sender!(
1613 SendAnimation, "animation", "sendAnimation", Message, [duration: u32, width: u32, height: u32]);
1615media_sender!(
1616 SendVoice, "voice", "sendVoice", Message, [duration: u32]);
1618media_sender!(
1619 SendVideoNote, "video_note", "sendVideoNote", Message, [duration: u32, length: u32]);
1621media_sender!(
1622 SendSticker, "sticker", "sendSticker", Message, [emoji: String]);
1624
1625#[derive(Serialize)]
1628struct DeleteMessageParams {
1629 chat_id: ChatId,
1630 message_id: i64,
1631}
1632
1633pub struct DeleteMessage {
1635 client: BotClient,
1636 params: DeleteMessageParams,
1637}
1638impl DeleteMessage {
1639 pub(crate) fn new(client: BotClient, chat_id: impl Into<ChatId>, message_id: i64) -> Self {
1640 Self {
1641 client,
1642 params: DeleteMessageParams {
1643 chat_id: chat_id.into(),
1644 message_id,
1645 },
1646 }
1647 }
1648}
1649impl_into_future!(DeleteMessage, bool, "deleteMessage");
1650
1651#[derive(Serialize)]
1652struct DeleteMessagesParams {
1653 chat_id: ChatId,
1654 message_ids: Vec<i64>,
1655}
1656
1657pub struct DeleteMessages {
1659 client: BotClient,
1660 params: DeleteMessagesParams,
1661}
1662impl DeleteMessages {
1663 pub(crate) fn new(
1664 client: BotClient,
1665 chat_id: impl Into<ChatId>,
1666 message_ids: Vec<i64>,
1667 ) -> Self {
1668 Self {
1669 client,
1670 params: DeleteMessagesParams {
1671 chat_id: chat_id.into(),
1672 message_ids,
1673 },
1674 }
1675 }
1676}
1677impl_into_future!(DeleteMessages, bool, "deleteMessages");
1678
1679#[derive(Serialize)]
1682struct StopPollParams {
1683 chat_id: ChatId,
1684 message_id: i64,
1685 #[serde(skip_serializing_if = "Option::is_none")]
1686 reply_markup: Option<rustigram_types::keyboard::InlineKeyboardMarkup>,
1687}
1688
1689pub struct StopPoll {
1691 client: BotClient,
1692 params: StopPollParams,
1693}
1694impl StopPoll {
1695 pub(crate) fn new(client: BotClient, chat_id: impl Into<ChatId>, message_id: i64) -> Self {
1696 Self {
1697 client,
1698 params: StopPollParams {
1699 chat_id: chat_id.into(),
1700 message_id,
1701 reply_markup: None,
1702 },
1703 }
1704 }
1705 pub fn reply_markup(mut self, m: rustigram_types::keyboard::InlineKeyboardMarkup) -> Self {
1707 self.params.reply_markup = Some(m);
1708 self
1709 }
1710}
1711impl_into_future!(StopPoll, rustigram_types::poll::Poll, "stopPoll");
1712
1713#[derive(Serialize)]
1716struct AnswerCallbackQueryParams {
1717 callback_query_id: String,
1718 #[serde(skip_serializing_if = "Option::is_none")]
1719 text: Option<String>,
1720 #[serde(skip_serializing_if = "Option::is_none")]
1721 show_alert: Option<bool>,
1722 #[serde(skip_serializing_if = "Option::is_none")]
1723 url: Option<String>,
1724 #[serde(skip_serializing_if = "Option::is_none")]
1725 cache_time: Option<u32>,
1726}
1727
1728pub struct AnswerCallbackQuery {
1730 client: BotClient,
1731 params: AnswerCallbackQueryParams,
1732}
1733impl AnswerCallbackQuery {
1734 pub(crate) fn new(client: BotClient, callback_query_id: impl Into<String>) -> Self {
1735 Self {
1736 client,
1737 params: AnswerCallbackQueryParams {
1738 callback_query_id: callback_query_id.into(),
1739 text: None,
1740 show_alert: None,
1741 url: None,
1742 cache_time: None,
1743 },
1744 }
1745 }
1746 pub fn text(mut self, t: impl Into<String>) -> Self {
1748 self.params.text = Some(t.into());
1749 self
1750 }
1751 pub fn show_alert(mut self, v: bool) -> Self {
1753 self.params.show_alert = Some(v);
1754 self
1755 }
1756 pub fn url(mut self, u: impl Into<String>) -> Self {
1758 self.params.url = Some(u.into());
1759 self
1760 }
1761 pub fn cache_time(mut self, secs: u32) -> Self {
1763 self.params.cache_time = Some(secs);
1764 self
1765 }
1766 pub fn alert(self, text: impl Into<String>) -> Self {
1768 self.text(text).show_alert(true)
1769 }
1770}
1771impl_into_future!(AnswerCallbackQuery, bool, "answerCallbackQuery");
1772#[derive(Serialize)]
1775struct ForwardMessagesParams {
1776 chat_id: ChatId,
1777 from_chat_id: ChatId,
1778 message_ids: Vec<i64>,
1779 #[serde(skip_serializing_if = "Option::is_none")]
1780 message_thread_id: Option<i64>,
1781 #[serde(skip_serializing_if = "Option::is_none")]
1782 direct_messages_topic_id: Option<i64>,
1783 #[serde(skip_serializing_if = "Option::is_none")]
1784 disable_notification: Option<bool>,
1785 #[serde(skip_serializing_if = "Option::is_none")]
1786 protect_content: Option<bool>,
1787}
1788
1789pub struct ForwardMessages {
1794 client: BotClient,
1795 params: ForwardMessagesParams,
1796}
1797
1798impl ForwardMessages {
1799 pub(crate) fn new(
1800 client: BotClient,
1801 chat_id: impl Into<ChatId>,
1802 from_chat_id: impl Into<ChatId>,
1803 message_ids: Vec<i64>,
1804 ) -> Self {
1805 Self {
1806 client,
1807 params: ForwardMessagesParams {
1808 chat_id: chat_id.into(),
1809 from_chat_id: from_chat_id.into(),
1810 message_ids,
1811 message_thread_id: None,
1812 direct_messages_topic_id: None,
1813 disable_notification: None,
1814 protect_content: None,
1815 },
1816 }
1817 }
1818 pub fn message_thread_id(mut self, id: i64) -> Self {
1820 self.params.message_thread_id = Some(id);
1821 self
1822 }
1823 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
1825 self.params.direct_messages_topic_id = Some(id);
1826 self
1827 }
1828 pub fn disable_notification(mut self, v: bool) -> Self {
1830 self.params.disable_notification = Some(v);
1831 self
1832 }
1833 pub fn protect_content(mut self, v: bool) -> Self {
1835 self.params.protect_content = Some(v);
1836 self
1837 }
1838}
1839
1840impl_into_future!(
1841 ForwardMessages,
1842 Vec<rustigram_types::message::MessageId>,
1843 "forwardMessages"
1844);
1845
1846#[derive(Serialize)]
1849struct CopyMessagesParams {
1850 chat_id: ChatId,
1851 from_chat_id: ChatId,
1852 message_ids: Vec<i64>,
1853 #[serde(skip_serializing_if = "Option::is_none")]
1854 message_thread_id: Option<i64>,
1855 #[serde(skip_serializing_if = "Option::is_none")]
1856 direct_messages_topic_id: Option<i64>,
1857 #[serde(skip_serializing_if = "Option::is_none")]
1858 disable_notification: Option<bool>,
1859 #[serde(skip_serializing_if = "Option::is_none")]
1860 protect_content: Option<bool>,
1861 #[serde(skip_serializing_if = "Option::is_none")]
1862 remove_caption: Option<bool>,
1863}
1864
1865pub struct CopyMessages {
1870 client: BotClient,
1871 params: CopyMessagesParams,
1872}
1873
1874impl CopyMessages {
1875 pub(crate) fn new(
1876 client: BotClient,
1877 chat_id: impl Into<ChatId>,
1878 from_chat_id: impl Into<ChatId>,
1879 message_ids: Vec<i64>,
1880 ) -> Self {
1881 Self {
1882 client,
1883 params: CopyMessagesParams {
1884 chat_id: chat_id.into(),
1885 from_chat_id: from_chat_id.into(),
1886 message_ids,
1887 message_thread_id: None,
1888 direct_messages_topic_id: None,
1889 disable_notification: None,
1890 protect_content: None,
1891 remove_caption: None,
1892 },
1893 }
1894 }
1895 pub fn message_thread_id(mut self, id: i64) -> Self {
1897 self.params.message_thread_id = Some(id);
1898 self
1899 }
1900 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
1902 self.params.direct_messages_topic_id = Some(id);
1903 self
1904 }
1905 pub fn disable_notification(mut self, v: bool) -> Self {
1907 self.params.disable_notification = Some(v);
1908 self
1909 }
1910 pub fn protect_content(mut self, v: bool) -> Self {
1912 self.params.protect_content = Some(v);
1913 self
1914 }
1915 pub fn remove_caption(mut self, v: bool) -> Self {
1917 self.params.remove_caption = Some(v);
1918 self
1919 }
1920}
1921
1922impl_into_future!(
1923 CopyMessages,
1924 Vec<rustigram_types::message::MessageId>,
1925 "copyMessages"
1926);
1927
1928#[derive(Serialize)]
1931struct SendVenueParams {
1932 chat_id: ChatId,
1933 latitude: f64,
1934 longitude: f64,
1935 title: String,
1936 address: String,
1937 #[serde(skip_serializing_if = "Option::is_none")]
1938 message_thread_id: Option<i64>,
1939 #[serde(skip_serializing_if = "Option::is_none")]
1940 direct_messages_topic_id: Option<i64>,
1941 #[serde(skip_serializing_if = "Option::is_none")]
1942 foursquare_id: Option<String>,
1943 #[serde(skip_serializing_if = "Option::is_none")]
1944 foursquare_type: Option<String>,
1945 #[serde(skip_serializing_if = "Option::is_none")]
1946 google_place_id: Option<String>,
1947 #[serde(skip_serializing_if = "Option::is_none")]
1948 google_place_type: Option<String>,
1949 #[serde(skip_serializing_if = "Option::is_none")]
1950 disable_notification: Option<bool>,
1951 #[serde(skip_serializing_if = "Option::is_none")]
1952 protect_content: Option<bool>,
1953 #[serde(skip_serializing_if = "Option::is_none")]
1954 reply_parameters: Option<ReplyParameters>,
1955 #[serde(skip_serializing_if = "Option::is_none")]
1956 reply_markup: Option<ReplyMarkup>,
1957}
1958
1959pub struct SendVenue {
1961 client: BotClient,
1962 params: SendVenueParams,
1963}
1964
1965impl SendVenue {
1966 pub(crate) fn new(
1967 client: BotClient,
1968 chat_id: impl Into<ChatId>,
1969 latitude: f64,
1970 longitude: f64,
1971 title: impl Into<String>,
1972 address: impl Into<String>,
1973 ) -> Self {
1974 Self {
1975 client,
1976 params: SendVenueParams {
1977 chat_id: chat_id.into(),
1978 latitude,
1979 longitude,
1980 title: title.into(),
1981 address: address.into(),
1982 message_thread_id: None,
1983 direct_messages_topic_id: None,
1984 foursquare_id: None,
1985 foursquare_type: None,
1986 google_place_id: None,
1987 google_place_type: None,
1988 disable_notification: None,
1989 protect_content: None,
1990 reply_parameters: None,
1991 reply_markup: None,
1992 },
1993 }
1994 }
1995 pub fn message_thread_id(mut self, id: i64) -> Self {
1997 self.params.message_thread_id = Some(id);
1998 self
1999 }
2000 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
2002 self.params.direct_messages_topic_id = Some(id);
2003 self
2004 }
2005 pub fn foursquare_id(mut self, id: impl Into<String>) -> Self {
2007 self.params.foursquare_id = Some(id.into());
2008 self
2009 }
2010 pub fn foursquare_type(mut self, t: impl Into<String>) -> Self {
2012 self.params.foursquare_type = Some(t.into());
2013 self
2014 }
2015 pub fn google_place_id(mut self, id: impl Into<String>) -> Self {
2017 self.params.google_place_id = Some(id.into());
2018 self
2019 }
2020 pub fn google_place_type(mut self, t: impl Into<String>) -> Self {
2022 self.params.google_place_type = Some(t.into());
2023 self
2024 }
2025 pub fn disable_notification(mut self, v: bool) -> Self {
2027 self.params.disable_notification = Some(v);
2028 self
2029 }
2030 pub fn protect_content(mut self, v: bool) -> Self {
2032 self.params.protect_content = Some(v);
2033 self
2034 }
2035 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
2037 self.params.reply_parameters = Some(rp);
2038 self
2039 }
2040 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self {
2042 self.params.reply_markup = Some(m.into());
2043 self
2044 }
2045}
2046
2047impl_into_future!(SendVenue, Message, "sendVenue");
2048
2049#[derive(Serialize)]
2052struct SendMediaGroupParams {
2053 chat_id: ChatId,
2054 media: Vec<serde_json::Value>,
2059 #[serde(skip_serializing_if = "Option::is_none")]
2060 message_thread_id: Option<i64>,
2061 #[serde(skip_serializing_if = "Option::is_none")]
2062 direct_messages_topic_id: Option<i64>,
2063 #[serde(skip_serializing_if = "Option::is_none")]
2064 business_connection_id: Option<String>,
2065 #[serde(skip_serializing_if = "Option::is_none")]
2066 disable_notification: Option<bool>,
2067 #[serde(skip_serializing_if = "Option::is_none")]
2068 protect_content: Option<bool>,
2069 #[serde(skip_serializing_if = "Option::is_none")]
2070 reply_parameters: Option<ReplyParameters>,
2071}
2072
2073pub struct SendMediaGroup {
2081 client: BotClient,
2082 params: SendMediaGroupParams,
2083}
2084
2085impl SendMediaGroup {
2086 pub(crate) fn new(
2087 client: BotClient,
2088 chat_id: impl Into<ChatId>,
2089 media: Vec<serde_json::Value>,
2090 ) -> Self {
2091 Self {
2092 client,
2093 params: SendMediaGroupParams {
2094 chat_id: chat_id.into(),
2095 media,
2096 message_thread_id: None,
2097 direct_messages_topic_id: None,
2098 business_connection_id: None,
2099 disable_notification: None,
2100 protect_content: None,
2101 reply_parameters: None,
2102 },
2103 }
2104 }
2105 pub fn message_thread_id(mut self, id: i64) -> Self {
2107 self.params.message_thread_id = Some(id);
2108 self
2109 }
2110 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
2112 self.params.direct_messages_topic_id = Some(id);
2113 self
2114 }
2115 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
2117 self.params.business_connection_id = Some(id.into());
2118 self
2119 }
2120 pub fn disable_notification(mut self, v: bool) -> Self {
2122 self.params.disable_notification = Some(v);
2123 self
2124 }
2125 pub fn protect_content(mut self, v: bool) -> Self {
2127 self.params.protect_content = Some(v);
2128 self
2129 }
2130 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
2132 self.params.reply_parameters = Some(rp);
2133 self
2134 }
2135}
2136
2137impl_into_future!(SendMediaGroup, Vec<Message>, "sendMediaGroup");
2138
2139#[derive(Serialize)]
2142struct SendPaidMediaParams {
2143 chat_id: ChatId,
2144 star_count: u32,
2145 media: Vec<serde_json::Value>,
2150 #[serde(skip_serializing_if = "Option::is_none")]
2151 business_connection_id: Option<String>,
2152 #[serde(skip_serializing_if = "Option::is_none")]
2153 payload: Option<String>,
2154 #[serde(skip_serializing_if = "Option::is_none")]
2155 caption: Option<String>,
2156 #[serde(skip_serializing_if = "Option::is_none")]
2157 parse_mode: Option<ParseMode>,
2158 #[serde(skip_serializing_if = "Option::is_none")]
2159 show_caption_above_media: Option<bool>,
2160 #[serde(skip_serializing_if = "Option::is_none")]
2161 disable_notification: Option<bool>,
2162 #[serde(skip_serializing_if = "Option::is_none")]
2163 protect_content: Option<bool>,
2164 #[serde(skip_serializing_if = "Option::is_none")]
2165 reply_parameters: Option<ReplyParameters>,
2166 #[serde(skip_serializing_if = "Option::is_none")]
2167 reply_markup: Option<ReplyMarkup>,
2168}
2169
2170pub struct SendPaidMedia {
2177 client: BotClient,
2178 params: SendPaidMediaParams,
2179}
2180
2181impl SendPaidMedia {
2182 pub(crate) fn new(
2183 client: BotClient,
2184 chat_id: impl Into<ChatId>,
2185 star_count: u32,
2186 media: Vec<serde_json::Value>,
2187 ) -> Self {
2188 Self {
2189 client,
2190 params: SendPaidMediaParams {
2191 chat_id: chat_id.into(),
2192 star_count,
2193 media,
2194 business_connection_id: None,
2195 payload: None,
2196 caption: None,
2197 parse_mode: None,
2198 show_caption_above_media: None,
2199 disable_notification: None,
2200 protect_content: None,
2201 reply_parameters: None,
2202 reply_markup: None,
2203 },
2204 }
2205 }
2206 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
2208 self.params.business_connection_id = Some(id.into());
2209 self
2210 }
2211 pub fn payload(mut self, p: impl Into<String>) -> Self {
2213 self.params.payload = Some(p.into());
2214 self
2215 }
2216 pub fn caption(mut self, c: impl Into<String>) -> Self {
2218 self.params.caption = Some(c.into());
2219 self
2220 }
2221 pub fn parse_mode(mut self, m: ParseMode) -> Self {
2223 self.params.parse_mode = Some(m);
2224 self
2225 }
2226 pub fn show_caption_above_media(mut self, v: bool) -> Self {
2228 self.params.show_caption_above_media = Some(v);
2229 self
2230 }
2231 pub fn disable_notification(mut self, v: bool) -> Self {
2233 self.params.disable_notification = Some(v);
2234 self
2235 }
2236 pub fn protect_content(mut self, v: bool) -> Self {
2238 self.params.protect_content = Some(v);
2239 self
2240 }
2241 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
2243 self.params.reply_parameters = Some(rp);
2244 self
2245 }
2246 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self {
2248 self.params.reply_markup = Some(m.into());
2249 self
2250 }
2251}
2252
2253impl_into_future!(SendPaidMedia, Message, "sendPaidMedia");
2254
2255#[derive(Serialize)]
2258struct SendGameParams {
2259 chat_id: i64,
2260 game_short_name: String,
2261 #[serde(skip_serializing_if = "Option::is_none")]
2262 business_connection_id: Option<String>,
2263 #[serde(skip_serializing_if = "Option::is_none")]
2264 message_thread_id: Option<i64>,
2265 #[serde(skip_serializing_if = "Option::is_none")]
2266 direct_messages_topic_id: Option<i64>,
2267 #[serde(skip_serializing_if = "Option::is_none")]
2268 disable_notification: Option<bool>,
2269 #[serde(skip_serializing_if = "Option::is_none")]
2270 protect_content: Option<bool>,
2271 #[serde(skip_serializing_if = "Option::is_none")]
2272 reply_parameters: Option<ReplyParameters>,
2273 #[serde(skip_serializing_if = "Option::is_none")]
2274 reply_markup: Option<rustigram_types::keyboard::InlineKeyboardMarkup>,
2275}
2276
2277pub struct SendGame {
2282 client: BotClient,
2283 params: SendGameParams,
2284}
2285
2286impl SendGame {
2287 pub(crate) fn new(client: BotClient, chat_id: i64, game_short_name: impl Into<String>) -> Self {
2288 Self {
2289 client,
2290 params: SendGameParams {
2291 chat_id,
2292 game_short_name: game_short_name.into(),
2293 business_connection_id: None,
2294 message_thread_id: None,
2295 direct_messages_topic_id: None,
2296 disable_notification: None,
2297 protect_content: None,
2298 reply_parameters: None,
2299 reply_markup: None,
2300 },
2301 }
2302 }
2303 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
2305 self.params.business_connection_id = Some(id.into());
2306 self
2307 }
2308 pub fn message_thread_id(mut self, id: i64) -> Self {
2310 self.params.message_thread_id = Some(id);
2311 self
2312 }
2313 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
2315 self.params.direct_messages_topic_id = Some(id);
2316 self
2317 }
2318 pub fn disable_notification(mut self, v: bool) -> Self {
2320 self.params.disable_notification = Some(v);
2321 self
2322 }
2323 pub fn protect_content(mut self, v: bool) -> Self {
2325 self.params.protect_content = Some(v);
2326 self
2327 }
2328 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
2330 self.params.reply_parameters = Some(rp);
2331 self
2332 }
2333 pub fn reply_markup(mut self, m: rustigram_types::keyboard::InlineKeyboardMarkup) -> Self {
2335 self.params.reply_markup = Some(m);
2336 self
2337 }
2338}
2339
2340impl_into_future!(SendGame, Message, "sendGame");
2341
2342#[derive(Serialize)]
2345struct SendChecklistParams {
2346 business_connection_id: String,
2347 chat_id: i64,
2348 checklist: rustigram_types::checklist::InputChecklist,
2349 #[serde(skip_serializing_if = "Option::is_none")]
2350 direct_messages_topic_id: Option<i64>,
2351 #[serde(skip_serializing_if = "Option::is_none")]
2352 disable_notification: Option<bool>,
2353 #[serde(skip_serializing_if = "Option::is_none")]
2354 protect_content: Option<bool>,
2355 #[serde(skip_serializing_if = "Option::is_none")]
2356 message_effect_id: Option<String>,
2357 #[serde(skip_serializing_if = "Option::is_none")]
2358 reply_parameters: Option<ReplyParameters>,
2359 #[serde(skip_serializing_if = "Option::is_none")]
2360 reply_markup: Option<rustigram_types::keyboard::InlineKeyboardMarkup>,
2361 #[serde(skip_serializing_if = "Option::is_none")]
2362 suggested_post_parameters: Option<SuggestedPostParameters>,
2363}
2364
2365pub struct SendChecklist {
2370 client: BotClient,
2371 params: SendChecklistParams,
2372}
2373
2374impl SendChecklist {
2375 pub(crate) fn new(
2376 client: BotClient,
2377 business_connection_id: impl Into<String>,
2378 chat_id: i64,
2379 checklist: rustigram_types::checklist::InputChecklist,
2380 ) -> Self {
2381 Self {
2382 client,
2383 params: SendChecklistParams {
2384 business_connection_id: business_connection_id.into(),
2385 chat_id,
2386 checklist,
2387 direct_messages_topic_id: None,
2388 disable_notification: None,
2389 protect_content: None,
2390 message_effect_id: None,
2391 reply_parameters: None,
2392 reply_markup: None,
2393 suggested_post_parameters: None,
2394 },
2395 }
2396 }
2397 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
2399 self.params.direct_messages_topic_id = Some(id);
2400 self
2401 }
2402 pub fn disable_notification(mut self, v: bool) -> Self {
2404 self.params.disable_notification = Some(v);
2405 self
2406 }
2407 pub fn protect_content(mut self, v: bool) -> Self {
2409 self.params.protect_content = Some(v);
2410 self
2411 }
2412 pub fn message_effect_id(mut self, id: impl Into<String>) -> Self {
2414 self.params.message_effect_id = Some(id.into());
2415 self
2416 }
2417 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
2419 self.params.reply_parameters = Some(rp);
2420 self
2421 }
2422 pub fn reply_markup(mut self, m: rustigram_types::keyboard::InlineKeyboardMarkup) -> Self {
2424 self.params.reply_markup = Some(m);
2425 self
2426 }
2427 pub fn suggested_post_parameters(mut self, params: SuggestedPostParameters) -> Self {
2429 self.params.suggested_post_parameters = Some(params);
2430 self
2431 }
2432}
2433
2434impl_into_future!(SendChecklist, Message, "sendChecklist");
2435
2436#[derive(Serialize)]
2439struct SendRichMessageParams {
2440 chat_id: ChatId,
2441 rich_message: rustigram_types::rich_message::InputRichMessage,
2442 #[serde(skip_serializing_if = "Option::is_none")]
2443 business_connection_id: Option<String>,
2444 #[serde(skip_serializing_if = "Option::is_none")]
2445 message_thread_id: Option<i64>,
2446 #[serde(skip_serializing_if = "Option::is_none")]
2447 direct_messages_topic_id: Option<i64>,
2448 #[serde(skip_serializing_if = "Option::is_none")]
2449 disable_notification: Option<bool>,
2450 #[serde(skip_serializing_if = "Option::is_none")]
2451 protect_content: Option<bool>,
2452 #[serde(skip_serializing_if = "Option::is_none")]
2453 allow_paid_broadcast: Option<bool>,
2454 #[serde(skip_serializing_if = "Option::is_none")]
2455 message_effect_id: Option<String>,
2456 #[serde(skip_serializing_if = "Option::is_none")]
2457 suggested_post_parameters: Option<SuggestedPostParameters>,
2458 #[serde(skip_serializing_if = "Option::is_none")]
2459 reply_parameters: Option<ReplyParameters>,
2460 #[serde(skip_serializing_if = "Option::is_none")]
2461 reply_markup: Option<rustigram_types::keyboard::ReplyMarkup>,
2462}
2463
2464pub struct SendRichMessage {
2466 client: BotClient,
2467 params: SendRichMessageParams,
2468}
2469
2470impl SendRichMessage {
2471 pub(crate) fn new(
2472 client: BotClient,
2473 chat_id: impl Into<ChatId>,
2474 rich_message: rustigram_types::rich_message::InputRichMessage,
2475 ) -> Self {
2476 Self {
2477 client,
2478 params: SendRichMessageParams {
2479 chat_id: chat_id.into(),
2480 rich_message,
2481 business_connection_id: None,
2482 message_thread_id: None,
2483 direct_messages_topic_id: None,
2484 disable_notification: None,
2485 protect_content: None,
2486 allow_paid_broadcast: None,
2487 message_effect_id: None,
2488 suggested_post_parameters: None,
2489 reply_parameters: None,
2490 reply_markup: None,
2491 },
2492 }
2493 }
2494
2495 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
2497 self.params.business_connection_id = Some(id.into());
2498 self
2499 }
2500 pub fn message_thread_id(mut self, id: i64) -> Self {
2502 self.params.message_thread_id = Some(id);
2503 self
2504 }
2505 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
2507 self.params.direct_messages_topic_id = Some(id);
2508 self
2509 }
2510 pub fn disable_notification(mut self, v: bool) -> Self {
2512 self.params.disable_notification = Some(v);
2513 self
2514 }
2515 pub fn protect_content(mut self, v: bool) -> Self {
2517 self.params.protect_content = Some(v);
2518 self
2519 }
2520 pub fn allow_paid_broadcast(mut self, v: bool) -> Self {
2522 self.params.allow_paid_broadcast = Some(v);
2523 self
2524 }
2525 pub fn message_effect_id(mut self, id: impl Into<String>) -> Self {
2527 self.params.message_effect_id = Some(id.into());
2528 self
2529 }
2530 pub fn suggested_post_parameters(mut self, p: SuggestedPostParameters) -> Self {
2532 self.params.suggested_post_parameters = Some(p);
2533 self
2534 }
2535 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
2537 self.params.reply_parameters = Some(rp);
2538 self
2539 }
2540 pub fn reply_markup(mut self, m: rustigram_types::keyboard::ReplyMarkup) -> Self {
2542 self.params.reply_markup = Some(m);
2543 self
2544 }
2545}
2546
2547impl_into_future!(SendRichMessage, Message, "sendRichMessage");
2548
2549#[derive(Serialize)]
2552struct SendRichMessageDraftParams {
2553 chat_id: i64,
2554 draft_id: i64,
2555 rich_message: rustigram_types::rich_message::InputRichMessage,
2556 #[serde(skip_serializing_if = "Option::is_none")]
2557 message_thread_id: Option<i64>,
2558}
2559
2560pub struct SendRichMessageDraft {
2565 client: BotClient,
2566 params: SendRichMessageDraftParams,
2567}
2568
2569impl SendRichMessageDraft {
2570 pub(crate) fn new(
2571 client: BotClient,
2572 chat_id: i64,
2573 draft_id: i64,
2574 rich_message: rustigram_types::rich_message::InputRichMessage,
2575 ) -> Self {
2576 Self {
2577 client,
2578 params: SendRichMessageDraftParams {
2579 chat_id,
2580 draft_id,
2581 rich_message,
2582 message_thread_id: None,
2583 },
2584 }
2585 }
2586
2587 pub fn message_thread_id(mut self, id: i64) -> Self {
2589 self.params.message_thread_id = Some(id);
2590 self
2591 }
2592}
2593
2594impl_into_future!(SendRichMessageDraft, bool, "sendRichMessageDraft");