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 #[serde(skip_serializing_if = "Option::is_none")]
66 receiver_user_id: Option<i64>,
67 #[serde(skip_serializing_if = "Option::is_none")]
68 callback_query_id: Option<String>,
69}
70
71pub struct SendMessage {
73 client: BotClient,
74 params: SendMessageParams,
75}
76
77impl SendMessage {
78 pub(crate) fn new(
79 client: BotClient,
80 chat_id: impl Into<ChatId>,
81 text: impl Into<String>,
82 ) -> Self {
83 Self {
84 client,
85 params: SendMessageParams {
86 chat_id: chat_id.into(),
87 text: text.into(),
88 business_connection_id: None,
89 message_thread_id: None,
90 direct_messages_topic_id: None,
91 parse_mode: None,
92 entities: None,
93 link_preview_options: None,
94 disable_notification: None,
95 protect_content: None,
96 allow_paid_broadcast: None,
97 message_effect_id: None,
98 reply_parameters: None,
99 reply_markup: None,
100 suggested_post_parameters: None,
101 receiver_user_id: None,
102 callback_query_id: None,
103 },
104 }
105 }
106 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
108 self.params.business_connection_id = Some(id.into());
109 self
110 }
111 pub fn message_thread_id(mut self, id: i64) -> Self {
113 self.params.message_thread_id = Some(id);
114 self
115 }
116 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
118 self.params.direct_messages_topic_id = Some(id);
119 self
120 }
121 pub fn parse_mode(mut self, mode: ParseMode) -> Self {
123 self.params.parse_mode = Some(mode);
124 self
125 }
126 pub fn entities(mut self, entities: Vec<rustigram_types::message::MessageEntity>) -> Self {
128 self.params.entities = Some(entities);
129 self
130 }
131 pub fn link_preview_options(mut self, opts: LinkPreviewOptions) -> Self {
133 self.params.link_preview_options = Some(opts);
134 self
135 }
136 pub fn disable_notification(mut self, v: bool) -> Self {
138 self.params.disable_notification = Some(v);
139 self
140 }
141 pub fn protect_content(mut self, v: bool) -> Self {
143 self.params.protect_content = Some(v);
144 self
145 }
146 pub fn allow_paid_broadcast(mut self, v: bool) -> Self {
148 self.params.allow_paid_broadcast = Some(v);
149 self
150 }
151 pub fn message_effect_id(mut self, id: impl Into<String>) -> Self {
153 self.params.message_effect_id = Some(id.into());
154 self
155 }
156 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
158 self.params.reply_parameters = Some(rp);
159 self
160 }
161 pub fn reply_to(mut self, message_id: i64) -> Self {
163 self.params.reply_parameters = Some(ReplyParameters {
164 message_id: Some(message_id),
165 ephemeral_message_id: None,
166 chat_id: None,
167 allow_sending_without_reply: None,
168 quote: None,
169 quote_parse_mode: None,
170 quote_entities: None,
171 quote_position: None,
172 poll_option_id: None,
173 checklist_task_id: None,
174 });
175 self
176 }
177 pub fn reply_to_ephemeral(mut self, ephemeral_message_id: i64) -> Self {
182 self.params.reply_parameters = Some(ReplyParameters {
183 message_id: None,
184 ephemeral_message_id: Some(ephemeral_message_id),
185 chat_id: None,
186 allow_sending_without_reply: None,
187 quote: None,
188 quote_parse_mode: None,
189 quote_entities: None,
190 quote_position: None,
191 poll_option_id: None,
192 checklist_task_id: None,
193 });
194 self
195 }
196 pub fn reply_markup(mut self, markup: impl Into<ReplyMarkup>) -> Self {
198 self.params.reply_markup = Some(markup.into());
199 self
200 }
201 pub fn suggested_post_parameters(mut self, params: SuggestedPostParameters) -> Self {
203 self.params.suggested_post_parameters = Some(params);
204 self
205 }
206 pub fn receiver_user_id(mut self, id: i64) -> Self {
212 self.params.receiver_user_id = Some(id);
213 self
214 }
215 pub fn callback_query_id(mut self, id: impl Into<String>) -> Self {
217 self.params.callback_query_id = Some(id.into());
218 self
219 }
220}
221
222impl_into_future!(SendMessage, Message, "sendMessage");
223
224#[derive(Serialize)]
227struct ForwardMessageParams {
228 chat_id: ChatId,
229 from_chat_id: ChatId,
230 message_id: i64,
231 #[serde(skip_serializing_if = "Option::is_none")]
232 message_thread_id: Option<i64>,
233 #[serde(skip_serializing_if = "Option::is_none")]
234 direct_messages_topic_id: Option<i64>,
235 #[serde(skip_serializing_if = "Option::is_none")]
236 video_start_timestamp: Option<i64>,
237 #[serde(skip_serializing_if = "Option::is_none")]
238 disable_notification: Option<bool>,
239 #[serde(skip_serializing_if = "Option::is_none")]
240 protect_content: Option<bool>,
241}
242
243pub struct ForwardMessage {
245 client: BotClient,
246 params: ForwardMessageParams,
247}
248
249impl ForwardMessage {
250 pub(crate) fn new(
251 client: BotClient,
252 chat_id: impl Into<ChatId>,
253 from_chat_id: impl Into<ChatId>,
254 message_id: i64,
255 ) -> Self {
256 Self {
257 client,
258 params: ForwardMessageParams {
259 chat_id: chat_id.into(),
260 from_chat_id: from_chat_id.into(),
261 message_id,
262 message_thread_id: None,
263 direct_messages_topic_id: None,
264 video_start_timestamp: None,
265 disable_notification: None,
266 protect_content: None,
267 },
268 }
269 }
270 pub fn message_thread_id(mut self, id: i64) -> Self {
272 self.params.message_thread_id = Some(id);
273 self
274 }
275 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
277 self.params.direct_messages_topic_id = Some(id);
278 self
279 }
280 pub fn video_start_timestamp(mut self, ts: i64) -> Self {
282 self.params.video_start_timestamp = Some(ts);
283 self
284 }
285 pub fn disable_notification(mut self, v: bool) -> Self {
287 self.params.disable_notification = Some(v);
288 self
289 }
290 pub fn protect_content(mut self, v: bool) -> Self {
292 self.params.protect_content = Some(v);
293 self
294 }
295}
296
297impl_into_future!(ForwardMessage, Message, "forwardMessage");
298
299#[derive(Serialize)]
302struct CopyMessageParams {
303 chat_id: ChatId,
304 from_chat_id: ChatId,
305 message_id: i64,
306 #[serde(skip_serializing_if = "Option::is_none")]
307 message_thread_id: Option<i64>,
308 #[serde(skip_serializing_if = "Option::is_none")]
309 direct_messages_topic_id: Option<i64>,
310 #[serde(skip_serializing_if = "Option::is_none")]
311 video_start_timestamp: Option<i64>,
312 #[serde(skip_serializing_if = "Option::is_none")]
313 caption: Option<String>,
314 #[serde(skip_serializing_if = "Option::is_none")]
315 parse_mode: Option<ParseMode>,
316 #[serde(skip_serializing_if = "Option::is_none")]
317 caption_entities: Option<Vec<rustigram_types::message::MessageEntity>>,
318 #[serde(skip_serializing_if = "Option::is_none")]
319 show_caption_above_media: Option<bool>,
320 #[serde(skip_serializing_if = "Option::is_none")]
321 disable_notification: Option<bool>,
322 #[serde(skip_serializing_if = "Option::is_none")]
323 protect_content: Option<bool>,
324 #[serde(skip_serializing_if = "Option::is_none")]
325 reply_parameters: Option<ReplyParameters>,
326 #[serde(skip_serializing_if = "Option::is_none")]
327 reply_markup: Option<ReplyMarkup>,
328}
329
330pub struct CopyMessage {
332 client: BotClient,
333 params: CopyMessageParams,
334}
335
336impl CopyMessage {
337 pub(crate) fn new(
338 client: BotClient,
339 chat_id: impl Into<ChatId>,
340 from_chat_id: impl Into<ChatId>,
341 message_id: i64,
342 ) -> Self {
343 Self {
344 client,
345 params: CopyMessageParams {
346 chat_id: chat_id.into(),
347 from_chat_id: from_chat_id.into(),
348 message_id,
349 message_thread_id: None,
350 direct_messages_topic_id: None,
351 video_start_timestamp: None,
352 caption: None,
353 parse_mode: None,
354 caption_entities: None,
355 show_caption_above_media: None,
356 disable_notification: None,
357 protect_content: None,
358 reply_parameters: None,
359 reply_markup: None,
360 },
361 }
362 }
363 pub fn message_thread_id(mut self, id: i64) -> Self {
365 self.params.message_thread_id = Some(id);
366 self
367 }
368 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
370 self.params.direct_messages_topic_id = Some(id);
371 self
372 }
373 pub fn video_start_timestamp(mut self, ts: i64) -> Self {
375 self.params.video_start_timestamp = Some(ts);
376 self
377 }
378 pub fn caption(mut self, c: impl Into<String>) -> Self {
380 self.params.caption = Some(c.into());
381 self
382 }
383 pub fn parse_mode(mut self, m: ParseMode) -> Self {
385 self.params.parse_mode = Some(m);
386 self
387 }
388 pub fn disable_notification(mut self, v: bool) -> Self {
390 self.params.disable_notification = Some(v);
391 self
392 }
393 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self {
395 self.params.reply_markup = Some(m.into());
396 self
397 }
398}
399
400impl_into_future!(
401 CopyMessage,
402 rustigram_types::message::MessageId,
403 "copyMessage"
404);
405
406#[derive(Serialize)]
409struct SendChatActionParams {
410 chat_id: ChatId,
411 action: ChatAction,
412 #[serde(skip_serializing_if = "Option::is_none")]
413 business_connection_id: Option<String>,
414 #[serde(skip_serializing_if = "Option::is_none")]
415 message_thread_id: Option<i64>,
416}
417
418#[derive(Serialize, Clone, Copy)]
419#[serde(rename_all = "snake_case")]
421pub enum ChatAction {
422 Typing,
424 UploadPhoto,
426 RecordVideo,
428 UploadVideo,
430 RecordVoice,
432 UploadVoice,
434 UploadDocument,
436 ChooseSticker,
438 FindLocation,
440 RecordVideoNote,
442 UploadVideoNote,
444}
445
446pub struct SendChatAction {
448 client: BotClient,
449 params: SendChatActionParams,
450}
451
452impl SendChatAction {
453 pub(crate) fn new(client: BotClient, chat_id: impl Into<ChatId>, action: ChatAction) -> Self {
454 Self {
455 client,
456 params: SendChatActionParams {
457 chat_id: chat_id.into(),
458 action,
459 business_connection_id: None,
460 message_thread_id: None,
461 },
462 }
463 }
464 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
466 self.params.business_connection_id = Some(id.into());
467 self
468 }
469 pub fn message_thread_id(mut self, id: i64) -> Self {
471 self.params.message_thread_id = Some(id);
472 self
473 }
474}
475
476impl_into_future!(SendChatAction, bool, "sendChatAction");
477
478#[derive(Serialize)]
481struct SendDiceParams {
482 chat_id: ChatId,
483 #[serde(skip_serializing_if = "Option::is_none")]
484 emoji: Option<String>,
485 #[serde(skip_serializing_if = "Option::is_none")]
486 message_thread_id: Option<i64>,
487 #[serde(skip_serializing_if = "Option::is_none")]
488 direct_messages_topic_id: Option<i64>,
489 #[serde(skip_serializing_if = "Option::is_none")]
490 disable_notification: Option<bool>,
491 #[serde(skip_serializing_if = "Option::is_none")]
492 protect_content: Option<bool>,
493 #[serde(skip_serializing_if = "Option::is_none")]
494 reply_parameters: Option<ReplyParameters>,
495 #[serde(skip_serializing_if = "Option::is_none")]
496 reply_markup: Option<ReplyMarkup>,
497}
498
499pub struct SendDice {
501 client: BotClient,
502 params: SendDiceParams,
503}
504
505impl SendDice {
506 pub(crate) fn new(client: BotClient, chat_id: impl Into<ChatId>) -> Self {
507 Self {
508 client,
509 params: SendDiceParams {
510 chat_id: chat_id.into(),
511 emoji: None,
512 message_thread_id: None,
513 direct_messages_topic_id: None,
514 disable_notification: None,
515 protect_content: None,
516 reply_parameters: None,
517 reply_markup: None,
518 },
519 }
520 }
521 pub fn emoji(mut self, e: impl Into<String>) -> Self {
523 self.params.emoji = Some(e.into());
524 self
525 }
526 pub fn message_thread_id(mut self, id: i64) -> Self {
528 self.params.message_thread_id = Some(id);
529 self
530 }
531 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
533 self.params.direct_messages_topic_id = Some(id);
534 self
535 }
536 pub fn disable_notification(mut self, v: bool) -> Self {
538 self.params.disable_notification = Some(v);
539 self
540 }
541 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self {
543 self.params.reply_markup = Some(m.into());
544 self
545 }
546}
547
548impl_into_future!(SendDice, Message, "sendDice");
549
550#[derive(Serialize)]
553struct SendLocationParams {
554 chat_id: ChatId,
555 latitude: f64,
556 longitude: f64,
557 #[serde(skip_serializing_if = "Option::is_none")]
558 message_thread_id: Option<i64>,
559 #[serde(skip_serializing_if = "Option::is_none")]
560 direct_messages_topic_id: Option<i64>,
561 #[serde(skip_serializing_if = "Option::is_none")]
562 horizontal_accuracy: Option<f64>,
563 #[serde(skip_serializing_if = "Option::is_none")]
564 live_period: Option<u32>,
565 #[serde(skip_serializing_if = "Option::is_none")]
566 heading: Option<u16>,
567 #[serde(skip_serializing_if = "Option::is_none")]
568 proximity_alert_radius: Option<u32>,
569 #[serde(skip_serializing_if = "Option::is_none")]
570 disable_notification: Option<bool>,
571 #[serde(skip_serializing_if = "Option::is_none")]
572 protect_content: Option<bool>,
573 #[serde(skip_serializing_if = "Option::is_none")]
574 reply_parameters: Option<ReplyParameters>,
575 #[serde(skip_serializing_if = "Option::is_none")]
576 reply_markup: Option<ReplyMarkup>,
577 #[serde(skip_serializing_if = "Option::is_none")]
578 receiver_user_id: Option<i64>,
579 #[serde(skip_serializing_if = "Option::is_none")]
580 callback_query_id: Option<String>,
581}
582
583pub struct SendLocation {
585 client: BotClient,
586 params: SendLocationParams,
587}
588
589impl SendLocation {
590 pub(crate) fn new(
591 client: BotClient,
592 chat_id: impl Into<ChatId>,
593 latitude: f64,
594 longitude: f64,
595 ) -> Self {
596 Self {
597 client,
598 params: SendLocationParams {
599 chat_id: chat_id.into(),
600 latitude,
601 longitude,
602 message_thread_id: None,
603 direct_messages_topic_id: None,
604 horizontal_accuracy: None,
605 live_period: None,
606 heading: None,
607 proximity_alert_radius: None,
608 disable_notification: None,
609 protect_content: None,
610 reply_parameters: None,
611 reply_markup: None,
612 receiver_user_id: None,
613 callback_query_id: None,
614 },
615 }
616 }
617 pub fn message_thread_id(mut self, id: i64) -> Self {
619 self.params.message_thread_id = Some(id);
620 self
621 }
622 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
624 self.params.direct_messages_topic_id = Some(id);
625 self
626 }
627 pub fn horizontal_accuracy(mut self, v: f64) -> Self {
629 self.params.horizontal_accuracy = Some(v);
630 self
631 }
632 pub fn live_period(mut self, v: u32) -> Self {
636 self.params.live_period = Some(v);
637 self
638 }
639 pub fn heading(mut self, v: u16) -> Self {
641 self.params.heading = Some(v);
642 self
643 }
644 pub fn proximity_alert_radius(mut self, v: u32) -> Self {
646 self.params.proximity_alert_radius = Some(v);
647 self
648 }
649 pub fn disable_notification(mut self, v: bool) -> Self {
651 self.params.disable_notification = Some(v);
652 self
653 }
654 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self {
656 self.params.reply_markup = Some(m.into());
657 self
658 }
659 pub fn receiver_user_id(mut self, id: i64) -> Self {
661 self.params.receiver_user_id = Some(id);
662 self
663 }
664 pub fn callback_query_id(mut self, id: impl Into<String>) -> Self {
666 self.params.callback_query_id = Some(id.into());
667 self
668 }
669}
670
671impl_into_future!(SendLocation, Message, "sendLocation");
672
673#[derive(Serialize)]
676struct SendContactParams {
677 chat_id: ChatId,
678 phone_number: String,
679 first_name: String,
680 #[serde(skip_serializing_if = "Option::is_none")]
681 last_name: Option<String>,
682 #[serde(skip_serializing_if = "Option::is_none")]
683 vcard: Option<String>,
684 #[serde(skip_serializing_if = "Option::is_none")]
685 message_thread_id: Option<i64>,
686 #[serde(skip_serializing_if = "Option::is_none")]
687 direct_messages_topic_id: Option<i64>,
688 #[serde(skip_serializing_if = "Option::is_none")]
689 disable_notification: Option<bool>,
690 #[serde(skip_serializing_if = "Option::is_none")]
691 protect_content: Option<bool>,
692 #[serde(skip_serializing_if = "Option::is_none")]
693 reply_parameters: Option<ReplyParameters>,
694 #[serde(skip_serializing_if = "Option::is_none")]
695 reply_markup: Option<ReplyMarkup>,
696 #[serde(skip_serializing_if = "Option::is_none")]
697 receiver_user_id: Option<i64>,
698 #[serde(skip_serializing_if = "Option::is_none")]
699 callback_query_id: Option<String>,
700}
701
702pub struct SendContact {
704 client: BotClient,
705 params: SendContactParams,
706}
707
708impl SendContact {
709 pub(crate) fn new(
710 client: BotClient,
711 chat_id: impl Into<ChatId>,
712 phone_number: impl Into<String>,
713 first_name: impl Into<String>,
714 ) -> Self {
715 Self {
716 client,
717 params: SendContactParams {
718 chat_id: chat_id.into(),
719 phone_number: phone_number.into(),
720 first_name: first_name.into(),
721 last_name: None,
722 vcard: None,
723 message_thread_id: None,
724 direct_messages_topic_id: None,
725 disable_notification: None,
726 protect_content: None,
727 reply_parameters: None,
728 reply_markup: None,
729 receiver_user_id: None,
730 callback_query_id: None,
731 },
732 }
733 }
734 pub fn message_thread_id(mut self, id: i64) -> Self {
736 self.params.message_thread_id = Some(id);
737 self
738 }
739 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
741 self.params.direct_messages_topic_id = Some(id);
742 self
743 }
744 pub fn last_name(mut self, v: impl Into<String>) -> Self {
746 self.params.last_name = Some(v.into());
747 self
748 }
749 pub fn vcard(mut self, v: impl Into<String>) -> Self {
751 self.params.vcard = Some(v.into());
752 self
753 }
754 pub fn disable_notification(mut self, v: bool) -> Self {
756 self.params.disable_notification = Some(v);
757 self
758 }
759 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self {
761 self.params.reply_markup = Some(m.into());
762 self
763 }
764 pub fn receiver_user_id(mut self, id: i64) -> Self {
766 self.params.receiver_user_id = Some(id);
767 self
768 }
769 pub fn callback_query_id(mut self, id: impl Into<String>) -> Self {
771 self.params.callback_query_id = Some(id.into());
772 self
773 }
774}
775
776impl_into_future!(SendContact, Message, "sendContact");
777
778#[derive(Serialize)]
781struct SendPollParams {
782 chat_id: ChatId,
783 question: String,
784 options: Vec<InputPollOption>,
785 #[serde(skip_serializing_if = "Option::is_none")]
786 question_parse_mode: Option<ParseMode>,
787 #[serde(skip_serializing_if = "Option::is_none")]
788 question_entities: Option<Vec<rustigram_types::message::MessageEntity>>,
789 #[serde(skip_serializing_if = "Option::is_none")]
790 message_thread_id: Option<i64>,
791 #[serde(skip_serializing_if = "Option::is_none")]
792 direct_messages_topic_id: Option<i64>,
793 #[serde(skip_serializing_if = "Option::is_none", rename = "type")]
794 poll_type: Option<rustigram_types::poll::PollType>,
795 #[serde(skip_serializing_if = "Option::is_none")]
796 is_anonymous: Option<bool>,
797 #[serde(skip_serializing_if = "Option::is_none")]
798 allows_multiple_answers: Option<bool>,
799 #[serde(skip_serializing_if = "Option::is_none")]
800 allows_revoting: Option<bool>,
801 #[serde(skip_serializing_if = "Option::is_none")]
802 correct_option_ids: Option<Vec<u8>>,
803 #[serde(skip_serializing_if = "Option::is_none")]
804 explanation: Option<String>,
805 #[serde(skip_serializing_if = "Option::is_none")]
806 explanation_parse_mode: Option<ParseMode>,
807 #[serde(skip_serializing_if = "Option::is_none")]
808 explanation_entities: Option<Vec<rustigram_types::message::MessageEntity>>,
809 #[serde(skip_serializing_if = "Option::is_none")]
810 open_period: Option<u32>,
811 #[serde(skip_serializing_if = "Option::is_none")]
812 close_date: Option<i64>,
813 #[serde(skip_serializing_if = "Option::is_none")]
814 is_closed: Option<bool>,
815 #[serde(skip_serializing_if = "Option::is_none")]
816 shuffle_options: Option<bool>,
817 #[serde(skip_serializing_if = "Option::is_none")]
818 allow_adding_options: Option<bool>,
819 #[serde(skip_serializing_if = "Option::is_none")]
820 hide_results_until_closes: Option<bool>,
821 #[serde(skip_serializing_if = "Option::is_none")]
822 description: Option<String>,
823 #[serde(skip_serializing_if = "Option::is_none")]
824 description_parse_mode: Option<ParseMode>,
825 #[serde(skip_serializing_if = "Option::is_none")]
826 description_entities: Option<Vec<rustigram_types::message::MessageEntity>>,
827 #[serde(skip_serializing_if = "Option::is_none")]
828 disable_notification: Option<bool>,
829 #[serde(skip_serializing_if = "Option::is_none")]
830 protect_content: Option<bool>,
831 #[serde(skip_serializing_if = "Option::is_none")]
832 reply_parameters: Option<ReplyParameters>,
833 #[serde(skip_serializing_if = "Option::is_none")]
834 reply_markup: Option<ReplyMarkup>,
835 #[serde(skip_serializing_if = "Option::is_none")]
836 suggested_post_parameters: Option<SuggestedPostParameters>,
837 #[serde(skip_serializing_if = "Option::is_none")]
838 members_only: Option<bool>,
839 #[serde(skip_serializing_if = "Option::is_none")]
840 country_codes: Option<Vec<String>>,
841 #[serde(skip_serializing_if = "Option::is_none")]
842 media: Option<rustigram_types::poll::InputPollMedia>,
843 #[serde(skip_serializing_if = "Option::is_none")]
844 explanation_media: Option<rustigram_types::poll::InputPollMedia>,
845}
846
847pub struct SendPoll {
849 client: BotClient,
850 params: SendPollParams,
851}
852
853impl SendPoll {
854 pub(crate) fn new(
855 client: BotClient,
856 chat_id: impl Into<ChatId>,
857 question: impl Into<String>,
858 options: Vec<InputPollOption>,
859 ) -> Self {
860 Self {
861 client,
862 params: SendPollParams {
863 chat_id: chat_id.into(),
864 question: question.into(),
865 options,
866 question_parse_mode: None,
867 question_entities: None,
868 message_thread_id: None,
869 direct_messages_topic_id: None,
870 poll_type: None,
871 is_anonymous: None,
872 allows_multiple_answers: None,
873 allows_revoting: None,
874 correct_option_ids: None,
875 explanation: None,
876 explanation_parse_mode: None,
877 explanation_entities: None,
878 open_period: None,
879 close_date: None,
880 is_closed: None,
881 shuffle_options: None,
882 allow_adding_options: None,
883 hide_results_until_closes: None,
884 description: None,
885 description_parse_mode: None,
886 description_entities: None,
887 disable_notification: None,
888 protect_content: None,
889 reply_parameters: None,
890 reply_markup: None,
891 suggested_post_parameters: None,
892 members_only: None,
893 country_codes: None,
894 media: None,
895 explanation_media: None,
896 },
897 }
898 }
899 pub fn message_thread_id(mut self, id: i64) -> Self {
901 self.params.message_thread_id = Some(id);
902 self
903 }
904 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
906 self.params.direct_messages_topic_id = Some(id);
907 self
908 }
909 pub fn is_anonymous(mut self, v: bool) -> Self {
911 self.params.is_anonymous = Some(v);
912 self
913 }
914 pub fn allows_multiple_answers(mut self, v: bool) -> Self {
916 self.params.allows_multiple_answers = Some(v);
917 self
918 }
919 pub fn allows_revoting(mut self, v: bool) -> Self {
921 self.params.allows_revoting = Some(v);
922 self
923 }
924 pub fn quiz(mut self, ids: Vec<u8>) -> Self {
926 self.params.poll_type = Some(rustigram_types::poll::PollType::Quiz);
927 self.params.correct_option_ids = Some(ids);
928 self
929 }
930 pub fn quiz_single(self, id: u8) -> Self {
932 self.quiz(vec![id])
933 }
934 pub fn explanation(mut self, text: impl Into<String>) -> Self {
936 self.params.explanation = Some(text.into());
937 self
938 }
939 pub fn explanation_parse_mode(mut self, mode: ParseMode) -> Self {
941 self.params.explanation_parse_mode = Some(mode);
942 self
943 }
944 pub fn explanation_entities(mut self, e: Vec<rustigram_types::message::MessageEntity>) -> Self {
946 self.params.explanation_entities = Some(e);
947 self
948 }
949 pub fn open_period(mut self, secs: u32) -> Self {
951 self.params.open_period = Some(secs);
952 self
953 }
954 pub fn close_date(mut self, ts: i64) -> Self {
956 self.params.close_date = Some(ts);
957 self
958 }
959 pub fn shuffle_options(mut self, v: bool) -> Self {
961 self.params.shuffle_options = Some(v);
962 self
963 }
964 pub fn allow_adding_options(mut self, v: bool) -> Self {
966 self.params.allow_adding_options = Some(v);
967 self
968 }
969 pub fn hide_results_until_closes(mut self, v: bool) -> Self {
971 self.params.hide_results_until_closes = Some(v);
972 self
973 }
974 pub fn description(mut self, d: impl Into<String>) -> Self {
976 self.params.description = Some(d.into());
977 self
978 }
979 pub fn description_parse_mode(mut self, mode: ParseMode) -> Self {
981 self.params.description_parse_mode = Some(mode);
982 self
983 }
984 pub fn description_entities(mut self, e: Vec<rustigram_types::message::MessageEntity>) -> Self {
986 self.params.description_entities = Some(e);
987 self
988 }
989 pub fn question_parse_mode(mut self, mode: ParseMode) -> Self {
991 self.params.question_parse_mode = Some(mode);
992 self
993 }
994 pub fn question_entities(mut self, e: Vec<rustigram_types::message::MessageEntity>) -> Self {
996 self.params.question_entities = Some(e);
997 self
998 }
999 pub fn disable_notification(mut self, v: bool) -> Self {
1001 self.params.disable_notification = Some(v);
1002 self
1003 }
1004 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self {
1006 self.params.reply_markup = Some(m.into());
1007 self
1008 }
1009 pub fn suggested_post_parameters(mut self, params: SuggestedPostParameters) -> Self {
1011 self.params.suggested_post_parameters = Some(params);
1012 self
1013 }
1014 pub fn members_only(mut self, v: bool) -> Self {
1017 self.params.members_only = Some(v);
1018 self
1019 }
1020 pub fn country_codes(mut self, codes: Vec<impl Into<String>>) -> Self {
1022 self.params.country_codes = Some(codes.into_iter().map(Into::into).collect());
1023 self
1024 }
1025
1026 pub fn media(mut self, m: rustigram_types::poll::InputPollMedia) -> Self {
1028 self.params.media = Some(m);
1029 self
1030 }
1031
1032 pub fn explanation_media(mut self, m: rustigram_types::poll::InputPollMedia) -> Self {
1034 self.params.explanation_media = Some(m);
1035 self
1036 }
1037}
1038
1039impl_into_future!(SendPoll, Message, "sendPoll");
1040
1041#[derive(Serialize)]
1044struct SendMessageDraftParams {
1045 chat_id: ChatId,
1046 draft_id: i64,
1047 text: String,
1048 #[serde(skip_serializing_if = "Option::is_none")]
1049 message_thread_id: Option<i64>,
1050 #[serde(skip_serializing_if = "Option::is_none")]
1051 parse_mode: Option<ParseMode>,
1052 #[serde(skip_serializing_if = "Option::is_none")]
1053 entities: Option<Vec<rustigram_types::message::MessageEntity>>,
1054}
1055
1056pub struct SendMessageDraft {
1059 client: BotClient,
1060 params: SendMessageDraftParams,
1061}
1062
1063impl SendMessageDraft {
1064 pub(crate) fn new(
1065 client: BotClient,
1066 chat_id: impl Into<ChatId>,
1067 draft_id: i64,
1068 text: impl Into<String>,
1069 ) -> Self {
1070 Self {
1071 client,
1072 params: SendMessageDraftParams {
1073 chat_id: chat_id.into(),
1074 draft_id,
1075 text: text.into(),
1076 message_thread_id: None,
1077 parse_mode: None,
1078 entities: None,
1079 },
1080 }
1081 }
1082 pub fn parse_mode(mut self, m: ParseMode) -> Self {
1084 self.params.parse_mode = Some(m);
1085 self
1086 }
1087 pub fn entities(mut self, e: Vec<rustigram_types::message::MessageEntity>) -> Self {
1089 self.params.entities = Some(e);
1090 self
1091 }
1092}
1093
1094impl_into_future!(SendMessageDraft, bool, "sendMessageDraft");
1095
1096#[derive(Default)]
1105pub struct MediaSendOptions {
1106 pub business_connection_id: Option<String>,
1108 pub message_thread_id: Option<i64>,
1110 pub direct_messages_topic_id: Option<i64>,
1112 pub caption: Option<String>,
1114 pub parse_mode: Option<ParseMode>,
1116 pub caption_entities: Option<Vec<rustigram_types::message::MessageEntity>>,
1118 pub show_caption_above_media: Option<bool>,
1120 pub has_spoiler: Option<bool>,
1122 pub disable_notification: Option<bool>,
1124 pub protect_content: Option<bool>,
1126 pub allow_paid_broadcast: Option<bool>,
1128 pub reply_parameters: Option<ReplyParameters>,
1130 pub reply_markup: Option<ReplyMarkup>,
1132 pub suggested_post_parameters: Option<SuggestedPostParameters>,
1134 pub receiver_user_id: Option<i64>,
1138 pub callback_query_id: Option<String>,
1141}
1142
1143fn media_json_body(
1145 chat_id: &ChatId,
1146 media_field: &str,
1147 media_value: &str,
1148 opts: &MediaSendOptions,
1149 extra: serde_json::Value,
1150) -> serde_json::Value {
1151 let mut map = serde_json::json!({
1152 "chat_id": chat_id,
1153 media_field: media_value,
1154 });
1155 let obj = map.as_object_mut().unwrap();
1156 if let Some(v) = &opts.business_connection_id {
1157 obj.insert("business_connection_id".to_owned(), serde_json::json!(v));
1158 }
1159 if let Some(v) = &opts.message_thread_id {
1160 obj.insert("message_thread_id".to_owned(), serde_json::json!(v));
1161 }
1162 if let Some(v) = &opts.direct_messages_topic_id {
1163 obj.insert("direct_messages_topic_id".to_owned(), serde_json::json!(v));
1164 }
1165 if let Some(v) = &opts.caption {
1166 obj.insert("caption".to_owned(), serde_json::json!(v));
1167 }
1168 if let Some(v) = &opts.parse_mode {
1169 obj.insert("parse_mode".to_owned(), serde_json::json!(v));
1170 }
1171 if let Some(v) = &opts.caption_entities {
1172 obj.insert("caption_entities".to_owned(), serde_json::json!(v));
1173 }
1174 if let Some(v) = opts.show_caption_above_media {
1175 obj.insert("show_caption_above_media".to_owned(), serde_json::json!(v));
1176 }
1177 if let Some(v) = opts.has_spoiler {
1178 obj.insert("has_spoiler".to_owned(), serde_json::json!(v));
1179 }
1180 if let Some(v) = opts.disable_notification {
1181 obj.insert("disable_notification".to_owned(), serde_json::json!(v));
1182 }
1183 if let Some(v) = opts.protect_content {
1184 obj.insert("protect_content".to_owned(), serde_json::json!(v));
1185 }
1186 if let Some(v) = opts.allow_paid_broadcast {
1187 obj.insert("allow_paid_broadcast".to_owned(), serde_json::json!(v));
1188 }
1189 if let Some(v) = &opts.reply_parameters {
1190 obj.insert("reply_parameters".to_owned(), serde_json::json!(v));
1191 }
1192 if let Some(v) = &opts.reply_markup {
1193 obj.insert("reply_markup".to_owned(), serde_json::json!(v));
1194 }
1195 if let Some(v) = &opts.suggested_post_parameters {
1196 obj.insert("suggested_post_parameters".to_owned(), serde_json::json!(v));
1197 }
1198 if let Some(v) = opts.receiver_user_id {
1199 obj.insert("receiver_user_id".to_owned(), serde_json::json!(v));
1200 }
1201 if let Some(v) = &opts.callback_query_id {
1202 obj.insert("callback_query_id".to_owned(), serde_json::json!(v));
1203 }
1204 if let serde_json::Value::Object(extra_obj) = extra {
1205 for (k, v) in extra_obj {
1206 obj.insert(k, v);
1207 }
1208 }
1209 map
1210}
1211
1212pub struct SendPhoto {
1216 client: BotClient,
1217 chat_id: ChatId,
1218 photo: InputFile,
1219 opts: MediaSendOptions,
1220}
1221
1222impl SendPhoto {
1223 pub(crate) fn new(client: BotClient, chat_id: impl Into<ChatId>, photo: InputFile) -> Self {
1224 Self {
1225 client,
1226 chat_id: chat_id.into(),
1227 photo,
1228 opts: MediaSendOptions::default(),
1229 }
1230 }
1231 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
1233 self.opts.business_connection_id = Some(id.into());
1234 self
1235 }
1236 pub fn message_thread_id(mut self, id: i64) -> Self {
1238 self.opts.message_thread_id = Some(id);
1239 self
1240 }
1241 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
1243 self.opts.direct_messages_topic_id = Some(id);
1244 self
1245 }
1246 pub fn caption(mut self, c: impl Into<String>) -> Self {
1248 self.opts.caption = Some(c.into());
1249 self
1250 }
1251 pub fn parse_mode(mut self, m: ParseMode) -> Self {
1253 self.opts.parse_mode = Some(m);
1254 self
1255 }
1256 pub fn has_spoiler(mut self, v: bool) -> Self {
1258 self.opts.has_spoiler = Some(v);
1259 self
1260 }
1261 pub fn show_caption_above_media(mut self, v: bool) -> Self {
1263 self.opts.show_caption_above_media = Some(v);
1264 self
1265 }
1266 pub fn disable_notification(mut self, v: bool) -> Self {
1268 self.opts.disable_notification = Some(v);
1269 self
1270 }
1271 pub fn protect_content(mut self, v: bool) -> Self {
1273 self.opts.protect_content = Some(v);
1274 self
1275 }
1276 pub fn allow_paid_broadcast(mut self, v: bool) -> Self {
1278 self.opts.allow_paid_broadcast = Some(v);
1279 self
1280 }
1281 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
1283 self.opts.reply_parameters = Some(rp);
1284 self
1285 }
1286 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self {
1288 self.opts.reply_markup = Some(m.into());
1289 self
1290 }
1291 pub fn suggested_post_parameters(mut self, params: SuggestedPostParameters) -> Self {
1293 self.opts.suggested_post_parameters = Some(params);
1294 self
1295 }
1296 pub fn receiver_user_id(mut self, id: i64) -> Self {
1298 self.opts.receiver_user_id = Some(id);
1299 self
1300 }
1301 pub fn callback_query_id(mut self, id: impl Into<String>) -> Self {
1303 self.opts.callback_query_id = Some(id.into());
1304 self
1305 }
1306}
1307
1308impl IntoFuture for SendPhoto {
1309 type Output = Result<Message>;
1310 type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
1311
1312 fn into_future(self) -> Self::IntoFuture {
1313 Box::pin(async move {
1314 match &self.photo {
1315 InputFile::Bytes {
1316 filename,
1317 data,
1318 mime_type,
1319 } => {
1320 let part = Part::bytes(data.clone())
1321 .file_name(filename.clone())
1322 .mime_str(mime_type)
1323 .map_err(|e| crate::error::Error::Decode(e.to_string()))?;
1324 let mut form = Form::new().part("photo", part);
1325 form = form.text("chat_id", self.chat_id.to_string());
1326 if let Some(id) = &self.opts.business_connection_id {
1327 form = form.text("business_connection_id", id.clone());
1328 }
1329 if let Some(id) = self.opts.message_thread_id {
1330 form = form.text("message_thread_id", id.to_string());
1331 }
1332 if let Some(id) = self.opts.direct_messages_topic_id {
1333 form = form.text("direct_messages_topic_id", id.to_string());
1334 }
1335 if let Some(c) = &self.opts.caption {
1336 form = form.text("caption", c.clone());
1337 }
1338 if let Some(m) = &self.opts.parse_mode {
1339 form = form.text("parse_mode", format!("{m:?}"));
1340 }
1341 if let Some(v) = self.opts.disable_notification {
1342 form = form.text("disable_notification", v.to_string());
1343 }
1344 if let Some(v) = self.opts.has_spoiler {
1345 form = form.text("has_spoiler", v.to_string());
1346 }
1347 if let Some(v) = &self.opts.reply_markup {
1348 form = form.text("reply_markup", serde_json::to_string(v).unwrap());
1349 }
1350 if let Some(p) = &self.opts.suggested_post_parameters {
1351 form = form.text(
1352 "suggested_post_parameters",
1353 serde_json::to_string(p).unwrap(),
1354 );
1355 }
1356 if let Some(id) = self.opts.receiver_user_id {
1357 form = form.text("receiver_user_id", id.to_string());
1358 }
1359 if let Some(id) = &self.opts.callback_query_id {
1360 form = form.text("callback_query_id", id.clone());
1361 }
1362 self.client.post_multipart("sendPhoto", form).await
1363 }
1364 _ => {
1365 let body = media_json_body(
1366 &self.chat_id,
1367 "photo",
1368 self.photo.as_str(),
1369 &self.opts,
1370 serde_json::Value::Null,
1371 );
1372 self.client.post_json("sendPhoto", &body).await
1373 }
1374 }
1375 })
1376 }
1377}
1378
1379pub struct SendLivePhoto {
1383 client: BotClient,
1384 chat_id: ChatId,
1385 live_photo: InputFile,
1386 photo: InputFile,
1387 opts: MediaSendOptions,
1388 has_spoiler: Option<bool>,
1389 message_effect_id: Option<String>,
1390}
1391
1392impl SendLivePhoto {
1393 pub(crate) fn new(
1394 client: BotClient,
1395 chat_id: impl Into<ChatId>,
1396 live_photo: InputFile,
1397 photo: InputFile,
1398 ) -> Self {
1399 Self {
1400 client,
1401 chat_id: chat_id.into(),
1402 live_photo,
1403 photo,
1404 opts: MediaSendOptions::default(),
1405 has_spoiler: None,
1406 message_effect_id: None,
1407 }
1408 }
1409 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
1411 self.opts.business_connection_id = Some(id.into());
1412 self
1413 }
1414 pub fn message_thread_id(mut self, id: i64) -> Self {
1416 self.opts.message_thread_id = Some(id);
1417 self
1418 }
1419 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
1421 self.opts.direct_messages_topic_id = Some(id);
1422 self
1423 }
1424 pub fn caption(mut self, c: impl Into<String>) -> Self {
1426 self.opts.caption = Some(c.into());
1427 self
1428 }
1429 pub fn parse_mode(mut self, m: ParseMode) -> Self {
1431 self.opts.parse_mode = Some(m);
1432 self
1433 }
1434 pub fn show_caption_above_media(mut self, v: bool) -> Self {
1436 self.opts.show_caption_above_media = Some(v);
1437 self
1438 }
1439 pub fn has_spoiler(mut self, v: bool) -> Self {
1441 self.has_spoiler = Some(v);
1442 self
1443 }
1444 pub fn disable_notification(mut self, v: bool) -> Self {
1446 self.opts.disable_notification = Some(v);
1447 self
1448 }
1449 pub fn protect_content(mut self, v: bool) -> Self {
1451 self.opts.protect_content = Some(v);
1452 self
1453 }
1454 pub fn allow_paid_broadcast(mut self, v: bool) -> Self {
1456 self.opts.allow_paid_broadcast = Some(v);
1457 self
1458 }
1459 pub fn message_effect_id(mut self, id: impl Into<String>) -> Self {
1461 self.message_effect_id = Some(id.into());
1462 self
1463 }
1464 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
1466 self.opts.reply_parameters = Some(rp);
1467 self
1468 }
1469 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self {
1471 self.opts.reply_markup = Some(m.into());
1472 self
1473 }
1474 pub fn suggested_post_parameters(mut self, params: SuggestedPostParameters) -> Self {
1476 self.opts.suggested_post_parameters = Some(params);
1477 self
1478 }
1479}
1480
1481impl IntoFuture for SendLivePhoto {
1482 type Output = Result<Message>;
1483 type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
1484
1485 fn into_future(self) -> Self::IntoFuture {
1486 Box::pin(async move {
1487 let lp_bytes = self.live_photo.requires_multipart();
1488 let ph_bytes = self.photo.requires_multipart();
1489
1490 if lp_bytes || ph_bytes {
1491 let mut form = Form::new();
1492 form = form.text("chat_id", self.chat_id.to_string());
1493
1494 if let InputFile::Bytes {
1495 filename,
1496 data,
1497 mime_type,
1498 } = self.live_photo
1499 {
1500 let part = Part::bytes(data)
1501 .file_name(filename)
1502 .mime_str(&mime_type)
1503 .map_err(|e| crate::error::Error::Decode(e.to_string()))?;
1504 form = form.part("live_photo", part);
1505 } else {
1506 form = form.text("live_photo", self.live_photo.as_str().to_owned());
1507 }
1508
1509 if let InputFile::Bytes {
1510 filename,
1511 data,
1512 mime_type,
1513 } = self.photo
1514 {
1515 let part = Part::bytes(data)
1516 .file_name(filename)
1517 .mime_str(&mime_type)
1518 .map_err(|e| crate::error::Error::Decode(e.to_string()))?;
1519 form = form.part("photo", part);
1520 } else {
1521 form = form.text("photo", self.photo.as_str().to_owned());
1522 }
1523
1524 if let Some(id) = &self.opts.business_connection_id {
1525 form = form.text("business_connection_id", id.clone());
1526 }
1527 if let Some(id) = self.opts.message_thread_id {
1528 form = form.text("message_thread_id", id.to_string());
1529 }
1530 if let Some(id) = self.opts.direct_messages_topic_id {
1531 form = form.text("direct_messages_topic_id", id.to_string());
1532 }
1533 if let Some(c) = &self.opts.caption {
1534 form = form.text("caption", c.clone());
1535 }
1536 if let Some(m) = &self.opts.parse_mode {
1537 form = form.text("parse_mode", format!("{m:?}"));
1538 }
1539 if let Some(v) = self.opts.show_caption_above_media {
1540 form = form.text("show_caption_above_media", v.to_string());
1541 }
1542 if let Some(v) = self.has_spoiler {
1543 form = form.text("has_spoiler", v.to_string());
1544 }
1545 if let Some(v) = self.opts.disable_notification {
1546 form = form.text("disable_notification", v.to_string());
1547 }
1548 if let Some(v) = self.opts.protect_content {
1549 form = form.text("protect_content", v.to_string());
1550 }
1551 if let Some(v) = self.opts.allow_paid_broadcast {
1552 form = form.text("allow_paid_broadcast", v.to_string());
1553 }
1554 if let Some(id) = &self.message_effect_id {
1555 form = form.text("message_effect_id", id.clone());
1556 }
1557 if let Some(v) = &self.opts.reply_parameters {
1558 form = form.text("reply_parameters", serde_json::to_string(v).unwrap());
1559 }
1560 if let Some(v) = &self.opts.reply_markup {
1561 form = form.text("reply_markup", serde_json::to_string(v).unwrap());
1562 }
1563 if let Some(p) = &self.opts.suggested_post_parameters {
1564 form = form.text(
1565 "suggested_post_parameters",
1566 serde_json::to_string(p).unwrap(),
1567 );
1568 }
1569
1570 self.client.post_multipart("sendLivePhoto", form).await
1571 } else {
1572 let extra = {
1573 let mut m = serde_json::json!({});
1574 if let Some(v) = self.has_spoiler {
1575 m["has_spoiler"] = serde_json::json!(v);
1576 }
1577 if let Some(id) = &self.message_effect_id {
1578 m["message_effect_id"] = serde_json::json!(id);
1579 }
1580 m
1581 };
1582 let mut body = media_json_body(
1583 &self.chat_id,
1584 "live_photo",
1585 self.live_photo.as_str(),
1586 &self.opts,
1587 extra,
1588 );
1589 body.as_object_mut()
1590 .unwrap()
1591 .insert("photo".to_owned(), serde_json::json!(self.photo.as_str()));
1592 self.client.post_json("sendLivePhoto", &body).await
1593 }
1594 })
1595 }
1596}
1597
1598macro_rules! media_sender {
1601 ($(#[$doc:meta])* $name:ident, $field:literal, $method:literal, $return_ty:ty, [$($extra_field:ident: $extra_ty:ty),*]) => {
1602 $(#[$doc])*
1603 pub struct $name {
1604 client: BotClient,
1606 chat_id: ChatId,
1608 file: InputFile,
1610 opts: MediaSendOptions,
1612 $($extra_field: Option<$extra_ty>,)*
1614 }
1615
1616 impl $name {
1617 pub(crate) fn new(client: BotClient, chat_id: impl Into<ChatId>, file: InputFile) -> Self {
1618 Self {
1619 client,
1620 chat_id: chat_id.into(),
1621 file,
1622 opts: MediaSendOptions::default(),
1623 $($extra_field: None,)*
1624 }
1625 }
1626 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self { self.opts.business_connection_id = Some(id.into()); self }
1628 pub fn message_thread_id(mut self, id: i64) -> Self { self.opts.message_thread_id = Some(id); self }
1630 pub fn direct_messages_topic_id(mut self, id: i64) -> Self { self.opts.direct_messages_topic_id = Some(id); self }
1632 pub fn caption(mut self, c: impl Into<String>) -> Self { self.opts.caption = Some(c.into()); self }
1634 pub fn parse_mode(mut self, m: ParseMode) -> Self { self.opts.parse_mode = Some(m); self }
1636 pub fn disable_notification(mut self, v: bool) -> Self { self.opts.disable_notification = Some(v); self }
1638 pub fn protect_content(mut self, v: bool) -> Self { self.opts.protect_content = Some(v); self }
1640 pub fn allow_paid_broadcast(mut self, v: bool) -> Self { self.opts.allow_paid_broadcast = Some(v); self }
1642 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self { self.opts.reply_parameters = Some(rp); self }
1644 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self { self.opts.reply_markup = Some(m.into()); self }
1646 pub fn suggested_post_parameters(mut self, params: SuggestedPostParameters) -> Self { self.opts.suggested_post_parameters = Some(params); self }
1648 pub fn receiver_user_id(mut self, id: i64) -> Self { self.opts.receiver_user_id = Some(id); self }
1650 pub fn callback_query_id(mut self, id: impl Into<String>) -> Self { self.opts.callback_query_id = Some(id.into()); self }
1652
1653 $(
1654 #[doc = concat!("Sets the ", stringify!($extra_field), " for the media.")]
1655 pub fn $extra_field(mut self, v: $extra_ty) -> Self {
1656 self.$extra_field = Some(v);
1657 self
1658 }
1659 )*
1660 }
1661
1662 impl IntoFuture for $name {
1663 type Output = Result<$return_ty>;
1664 type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
1665
1666 fn into_future(self) -> Self::IntoFuture {
1667 Box::pin(async move {
1668 match &self.file {
1669 InputFile::Bytes { filename, data, mime_type } => {
1670 let part = Part::bytes(data.clone())
1671 .file_name(filename.clone())
1672 .mime_str(mime_type)
1673 .map_err(|e| crate::error::Error::Decode(e.to_string()))?;
1674 let mut form = Form::new().part($field, part);
1675 form = form.text("chat_id", self.chat_id.to_string());
1676 if let Some(id) = &self.opts.business_connection_id { form = form.text("business_connection_id", id.clone()); }
1677 if let Some(id) = self.opts.message_thread_id { form = form.text("message_thread_id", id.to_string()); }
1678 if let Some(id) = self.opts.direct_messages_topic_id { form = form.text("direct_messages_topic_id", id.to_string()); }
1679 if let Some(c) = &self.opts.caption { form = form.text("caption", c.clone()); }
1680 if let Some(m) = &self.opts.parse_mode { form = form.text("parse_mode", format!("{m:?}")); }
1681 if let Some(v) = self.opts.disable_notification { form = form.text("disable_notification", v.to_string()); }
1682 if let Some(v) = &self.opts.reply_markup { form = form.text("reply_markup", serde_json::to_string(v).unwrap()); }
1683 if let Some(p) = &self.opts.suggested_post_parameters { form = form.text("suggested_post_parameters", serde_json::to_string(p).unwrap()); }
1684 if let Some(id) = self.opts.receiver_user_id { form = form.text("receiver_user_id", id.to_string()); }
1685 if let Some(id) = &self.opts.callback_query_id { form = form.text("callback_query_id", id.clone()); }
1686
1687 $(
1688 if let Some(ref v) = self.$extra_field {
1689 form = form.text(stringify!($extra_field), v.to_string());
1690 }
1691 )*
1692
1693 self.client.post_multipart($method, form).await
1694 }
1695 _ => {
1696 let mut extra = serde_json::json!({});
1697 $(
1698 if let Some(ref v) = self.$extra_field {
1699 extra[stringify!($extra_field)] = serde_json::json!(v);
1700 }
1701 )*
1702 let body = media_json_body(&self.chat_id, $field, self.file.as_str(), &self.opts, extra);
1703 self.client.post_json($method, &body).await
1704 }
1705 }
1706 })
1707 }
1708 }
1709 };
1710}
1711
1712media_sender!(
1713 SendAudio, "audio", "sendAudio", Message, [duration: u32, performer: String, title: String]);
1715media_sender!(
1716 SendDocument, "document", "sendDocument", Message, [disable_content_type_detection: bool]);
1718media_sender!(
1719 SendVideo, "video", "sendVideo", Message, [duration: u32, width: u32, height: u32, supports_streaming: bool, cover: String, start_timestamp: i64]);
1721media_sender!(
1722 SendAnimation, "animation", "sendAnimation", Message, [duration: u32, width: u32, height: u32]);
1724media_sender!(
1725 SendVoice, "voice", "sendVoice", Message, [duration: u32]);
1727media_sender!(
1728 SendVideoNote, "video_note", "sendVideoNote", Message, [duration: u32, length: u32]);
1730media_sender!(
1731 SendSticker, "sticker", "sendSticker", Message, [emoji: String]);
1733
1734#[derive(Serialize)]
1737struct DeleteMessageParams {
1738 chat_id: ChatId,
1739 message_id: i64,
1740}
1741
1742pub struct DeleteMessage {
1744 client: BotClient,
1745 params: DeleteMessageParams,
1746}
1747impl DeleteMessage {
1748 pub(crate) fn new(client: BotClient, chat_id: impl Into<ChatId>, message_id: i64) -> Self {
1749 Self {
1750 client,
1751 params: DeleteMessageParams {
1752 chat_id: chat_id.into(),
1753 message_id,
1754 },
1755 }
1756 }
1757}
1758impl_into_future!(DeleteMessage, bool, "deleteMessage");
1759
1760#[derive(Serialize)]
1761struct DeleteMessagesParams {
1762 chat_id: ChatId,
1763 message_ids: Vec<i64>,
1764}
1765
1766pub struct DeleteMessages {
1768 client: BotClient,
1769 params: DeleteMessagesParams,
1770}
1771impl DeleteMessages {
1772 pub(crate) fn new(
1773 client: BotClient,
1774 chat_id: impl Into<ChatId>,
1775 message_ids: Vec<i64>,
1776 ) -> Self {
1777 Self {
1778 client,
1779 params: DeleteMessagesParams {
1780 chat_id: chat_id.into(),
1781 message_ids,
1782 },
1783 }
1784 }
1785}
1786impl_into_future!(DeleteMessages, bool, "deleteMessages");
1787
1788#[derive(Serialize)]
1791struct DeleteEphemeralMessageParams {
1792 chat_id: ChatId,
1793 receiver_user_id: i64,
1794 ephemeral_message_id: i64,
1795}
1796
1797pub struct DeleteEphemeralMessage {
1802 client: BotClient,
1803 params: DeleteEphemeralMessageParams,
1804}
1805impl DeleteEphemeralMessage {
1806 pub(crate) fn new(
1807 client: BotClient,
1808 chat_id: impl Into<ChatId>,
1809 receiver_user_id: i64,
1810 ephemeral_message_id: i64,
1811 ) -> Self {
1812 Self {
1813 client,
1814 params: DeleteEphemeralMessageParams {
1815 chat_id: chat_id.into(),
1816 receiver_user_id,
1817 ephemeral_message_id,
1818 },
1819 }
1820 }
1821}
1822impl_into_future!(DeleteEphemeralMessage, bool, "deleteEphemeralMessage");
1823
1824#[derive(Serialize)]
1827struct StopPollParams {
1828 chat_id: ChatId,
1829 message_id: i64,
1830 #[serde(skip_serializing_if = "Option::is_none")]
1831 reply_markup: Option<rustigram_types::keyboard::InlineKeyboardMarkup>,
1832}
1833
1834pub struct StopPoll {
1836 client: BotClient,
1837 params: StopPollParams,
1838}
1839impl StopPoll {
1840 pub(crate) fn new(client: BotClient, chat_id: impl Into<ChatId>, message_id: i64) -> Self {
1841 Self {
1842 client,
1843 params: StopPollParams {
1844 chat_id: chat_id.into(),
1845 message_id,
1846 reply_markup: None,
1847 },
1848 }
1849 }
1850 pub fn reply_markup(mut self, m: rustigram_types::keyboard::InlineKeyboardMarkup) -> Self {
1852 self.params.reply_markup = Some(m);
1853 self
1854 }
1855}
1856impl_into_future!(StopPoll, rustigram_types::poll::Poll, "stopPoll");
1857
1858#[derive(Serialize)]
1861struct AnswerCallbackQueryParams {
1862 callback_query_id: String,
1863 #[serde(skip_serializing_if = "Option::is_none")]
1864 text: Option<String>,
1865 #[serde(skip_serializing_if = "Option::is_none")]
1866 show_alert: Option<bool>,
1867 #[serde(skip_serializing_if = "Option::is_none")]
1868 url: Option<String>,
1869 #[serde(skip_serializing_if = "Option::is_none")]
1870 cache_time: Option<u32>,
1871}
1872
1873pub struct AnswerCallbackQuery {
1875 client: BotClient,
1876 params: AnswerCallbackQueryParams,
1877}
1878impl AnswerCallbackQuery {
1879 pub(crate) fn new(client: BotClient, callback_query_id: impl Into<String>) -> Self {
1880 Self {
1881 client,
1882 params: AnswerCallbackQueryParams {
1883 callback_query_id: callback_query_id.into(),
1884 text: None,
1885 show_alert: None,
1886 url: None,
1887 cache_time: None,
1888 },
1889 }
1890 }
1891 pub fn text(mut self, t: impl Into<String>) -> Self {
1893 self.params.text = Some(t.into());
1894 self
1895 }
1896 pub fn show_alert(mut self, v: bool) -> Self {
1898 self.params.show_alert = Some(v);
1899 self
1900 }
1901 pub fn url(mut self, u: impl Into<String>) -> Self {
1903 self.params.url = Some(u.into());
1904 self
1905 }
1906 pub fn cache_time(mut self, secs: u32) -> Self {
1908 self.params.cache_time = Some(secs);
1909 self
1910 }
1911 pub fn alert(self, text: impl Into<String>) -> Self {
1913 self.text(text).show_alert(true)
1914 }
1915}
1916impl_into_future!(AnswerCallbackQuery, bool, "answerCallbackQuery");
1917#[derive(Serialize)]
1920struct ForwardMessagesParams {
1921 chat_id: ChatId,
1922 from_chat_id: ChatId,
1923 message_ids: Vec<i64>,
1924 #[serde(skip_serializing_if = "Option::is_none")]
1925 message_thread_id: Option<i64>,
1926 #[serde(skip_serializing_if = "Option::is_none")]
1927 direct_messages_topic_id: Option<i64>,
1928 #[serde(skip_serializing_if = "Option::is_none")]
1929 disable_notification: Option<bool>,
1930 #[serde(skip_serializing_if = "Option::is_none")]
1931 protect_content: Option<bool>,
1932}
1933
1934pub struct ForwardMessages {
1939 client: BotClient,
1940 params: ForwardMessagesParams,
1941}
1942
1943impl ForwardMessages {
1944 pub(crate) fn new(
1945 client: BotClient,
1946 chat_id: impl Into<ChatId>,
1947 from_chat_id: impl Into<ChatId>,
1948 message_ids: Vec<i64>,
1949 ) -> Self {
1950 Self {
1951 client,
1952 params: ForwardMessagesParams {
1953 chat_id: chat_id.into(),
1954 from_chat_id: from_chat_id.into(),
1955 message_ids,
1956 message_thread_id: None,
1957 direct_messages_topic_id: None,
1958 disable_notification: None,
1959 protect_content: None,
1960 },
1961 }
1962 }
1963 pub fn message_thread_id(mut self, id: i64) -> Self {
1965 self.params.message_thread_id = Some(id);
1966 self
1967 }
1968 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
1970 self.params.direct_messages_topic_id = Some(id);
1971 self
1972 }
1973 pub fn disable_notification(mut self, v: bool) -> Self {
1975 self.params.disable_notification = Some(v);
1976 self
1977 }
1978 pub fn protect_content(mut self, v: bool) -> Self {
1980 self.params.protect_content = Some(v);
1981 self
1982 }
1983}
1984
1985impl_into_future!(
1986 ForwardMessages,
1987 Vec<rustigram_types::message::MessageId>,
1988 "forwardMessages"
1989);
1990
1991#[derive(Serialize)]
1994struct CopyMessagesParams {
1995 chat_id: ChatId,
1996 from_chat_id: ChatId,
1997 message_ids: Vec<i64>,
1998 #[serde(skip_serializing_if = "Option::is_none")]
1999 message_thread_id: Option<i64>,
2000 #[serde(skip_serializing_if = "Option::is_none")]
2001 direct_messages_topic_id: Option<i64>,
2002 #[serde(skip_serializing_if = "Option::is_none")]
2003 disable_notification: Option<bool>,
2004 #[serde(skip_serializing_if = "Option::is_none")]
2005 protect_content: Option<bool>,
2006 #[serde(skip_serializing_if = "Option::is_none")]
2007 remove_caption: Option<bool>,
2008}
2009
2010pub struct CopyMessages {
2015 client: BotClient,
2016 params: CopyMessagesParams,
2017}
2018
2019impl CopyMessages {
2020 pub(crate) fn new(
2021 client: BotClient,
2022 chat_id: impl Into<ChatId>,
2023 from_chat_id: impl Into<ChatId>,
2024 message_ids: Vec<i64>,
2025 ) -> Self {
2026 Self {
2027 client,
2028 params: CopyMessagesParams {
2029 chat_id: chat_id.into(),
2030 from_chat_id: from_chat_id.into(),
2031 message_ids,
2032 message_thread_id: None,
2033 direct_messages_topic_id: None,
2034 disable_notification: None,
2035 protect_content: None,
2036 remove_caption: None,
2037 },
2038 }
2039 }
2040 pub fn message_thread_id(mut self, id: i64) -> Self {
2042 self.params.message_thread_id = Some(id);
2043 self
2044 }
2045 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
2047 self.params.direct_messages_topic_id = Some(id);
2048 self
2049 }
2050 pub fn disable_notification(mut self, v: bool) -> Self {
2052 self.params.disable_notification = Some(v);
2053 self
2054 }
2055 pub fn protect_content(mut self, v: bool) -> Self {
2057 self.params.protect_content = Some(v);
2058 self
2059 }
2060 pub fn remove_caption(mut self, v: bool) -> Self {
2062 self.params.remove_caption = Some(v);
2063 self
2064 }
2065}
2066
2067impl_into_future!(
2068 CopyMessages,
2069 Vec<rustigram_types::message::MessageId>,
2070 "copyMessages"
2071);
2072
2073#[derive(Serialize)]
2076struct SendVenueParams {
2077 chat_id: ChatId,
2078 latitude: f64,
2079 longitude: f64,
2080 title: String,
2081 address: String,
2082 #[serde(skip_serializing_if = "Option::is_none")]
2083 message_thread_id: Option<i64>,
2084 #[serde(skip_serializing_if = "Option::is_none")]
2085 direct_messages_topic_id: Option<i64>,
2086 #[serde(skip_serializing_if = "Option::is_none")]
2087 foursquare_id: Option<String>,
2088 #[serde(skip_serializing_if = "Option::is_none")]
2089 foursquare_type: Option<String>,
2090 #[serde(skip_serializing_if = "Option::is_none")]
2091 google_place_id: Option<String>,
2092 #[serde(skip_serializing_if = "Option::is_none")]
2093 google_place_type: Option<String>,
2094 #[serde(skip_serializing_if = "Option::is_none")]
2095 disable_notification: Option<bool>,
2096 #[serde(skip_serializing_if = "Option::is_none")]
2097 protect_content: Option<bool>,
2098 #[serde(skip_serializing_if = "Option::is_none")]
2099 reply_parameters: Option<ReplyParameters>,
2100 #[serde(skip_serializing_if = "Option::is_none")]
2101 reply_markup: Option<ReplyMarkup>,
2102 #[serde(skip_serializing_if = "Option::is_none")]
2103 receiver_user_id: Option<i64>,
2104 #[serde(skip_serializing_if = "Option::is_none")]
2105 callback_query_id: Option<String>,
2106}
2107
2108pub struct SendVenue {
2110 client: BotClient,
2111 params: SendVenueParams,
2112}
2113
2114impl SendVenue {
2115 pub(crate) fn new(
2116 client: BotClient,
2117 chat_id: impl Into<ChatId>,
2118 latitude: f64,
2119 longitude: f64,
2120 title: impl Into<String>,
2121 address: impl Into<String>,
2122 ) -> Self {
2123 Self {
2124 client,
2125 params: SendVenueParams {
2126 chat_id: chat_id.into(),
2127 latitude,
2128 longitude,
2129 title: title.into(),
2130 address: address.into(),
2131 message_thread_id: None,
2132 direct_messages_topic_id: None,
2133 foursquare_id: None,
2134 foursquare_type: None,
2135 google_place_id: None,
2136 google_place_type: None,
2137 disable_notification: None,
2138 protect_content: None,
2139 reply_parameters: None,
2140 reply_markup: None,
2141 receiver_user_id: None,
2142 callback_query_id: None,
2143 },
2144 }
2145 }
2146 pub fn message_thread_id(mut self, id: i64) -> Self {
2148 self.params.message_thread_id = Some(id);
2149 self
2150 }
2151 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
2153 self.params.direct_messages_topic_id = Some(id);
2154 self
2155 }
2156 pub fn foursquare_id(mut self, id: impl Into<String>) -> Self {
2158 self.params.foursquare_id = Some(id.into());
2159 self
2160 }
2161 pub fn foursquare_type(mut self, t: impl Into<String>) -> Self {
2163 self.params.foursquare_type = Some(t.into());
2164 self
2165 }
2166 pub fn google_place_id(mut self, id: impl Into<String>) -> Self {
2168 self.params.google_place_id = Some(id.into());
2169 self
2170 }
2171 pub fn google_place_type(mut self, t: impl Into<String>) -> Self {
2173 self.params.google_place_type = Some(t.into());
2174 self
2175 }
2176 pub fn disable_notification(mut self, v: bool) -> Self {
2178 self.params.disable_notification = Some(v);
2179 self
2180 }
2181 pub fn protect_content(mut self, v: bool) -> Self {
2183 self.params.protect_content = Some(v);
2184 self
2185 }
2186 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
2188 self.params.reply_parameters = Some(rp);
2189 self
2190 }
2191 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self {
2193 self.params.reply_markup = Some(m.into());
2194 self
2195 }
2196 pub fn receiver_user_id(mut self, id: i64) -> Self {
2198 self.params.receiver_user_id = Some(id);
2199 self
2200 }
2201 pub fn callback_query_id(mut self, id: impl Into<String>) -> Self {
2203 self.params.callback_query_id = Some(id.into());
2204 self
2205 }
2206}
2207
2208impl_into_future!(SendVenue, Message, "sendVenue");
2209
2210#[derive(Serialize)]
2213struct SendMediaGroupParams {
2214 chat_id: ChatId,
2215 media: Vec<serde_json::Value>,
2220 #[serde(skip_serializing_if = "Option::is_none")]
2221 message_thread_id: Option<i64>,
2222 #[serde(skip_serializing_if = "Option::is_none")]
2223 direct_messages_topic_id: Option<i64>,
2224 #[serde(skip_serializing_if = "Option::is_none")]
2225 business_connection_id: Option<String>,
2226 #[serde(skip_serializing_if = "Option::is_none")]
2227 disable_notification: Option<bool>,
2228 #[serde(skip_serializing_if = "Option::is_none")]
2229 protect_content: Option<bool>,
2230 #[serde(skip_serializing_if = "Option::is_none")]
2231 reply_parameters: Option<ReplyParameters>,
2232}
2233
2234pub struct SendMediaGroup {
2242 client: BotClient,
2243 params: SendMediaGroupParams,
2244}
2245
2246impl SendMediaGroup {
2247 pub(crate) fn new(
2248 client: BotClient,
2249 chat_id: impl Into<ChatId>,
2250 media: Vec<serde_json::Value>,
2251 ) -> Self {
2252 Self {
2253 client,
2254 params: SendMediaGroupParams {
2255 chat_id: chat_id.into(),
2256 media,
2257 message_thread_id: None,
2258 direct_messages_topic_id: None,
2259 business_connection_id: None,
2260 disable_notification: None,
2261 protect_content: None,
2262 reply_parameters: None,
2263 },
2264 }
2265 }
2266 pub fn message_thread_id(mut self, id: i64) -> Self {
2268 self.params.message_thread_id = Some(id);
2269 self
2270 }
2271 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
2273 self.params.direct_messages_topic_id = Some(id);
2274 self
2275 }
2276 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
2278 self.params.business_connection_id = Some(id.into());
2279 self
2280 }
2281 pub fn disable_notification(mut self, v: bool) -> Self {
2283 self.params.disable_notification = Some(v);
2284 self
2285 }
2286 pub fn protect_content(mut self, v: bool) -> Self {
2288 self.params.protect_content = Some(v);
2289 self
2290 }
2291 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
2293 self.params.reply_parameters = Some(rp);
2294 self
2295 }
2296}
2297
2298impl_into_future!(SendMediaGroup, Vec<Message>, "sendMediaGroup");
2299
2300#[derive(Serialize)]
2303struct SendPaidMediaParams {
2304 chat_id: ChatId,
2305 star_count: u32,
2306 media: Vec<serde_json::Value>,
2311 #[serde(skip_serializing_if = "Option::is_none")]
2312 business_connection_id: Option<String>,
2313 #[serde(skip_serializing_if = "Option::is_none")]
2314 payload: Option<String>,
2315 #[serde(skip_serializing_if = "Option::is_none")]
2316 caption: Option<String>,
2317 #[serde(skip_serializing_if = "Option::is_none")]
2318 parse_mode: Option<ParseMode>,
2319 #[serde(skip_serializing_if = "Option::is_none")]
2320 show_caption_above_media: Option<bool>,
2321 #[serde(skip_serializing_if = "Option::is_none")]
2322 disable_notification: Option<bool>,
2323 #[serde(skip_serializing_if = "Option::is_none")]
2324 protect_content: Option<bool>,
2325 #[serde(skip_serializing_if = "Option::is_none")]
2326 reply_parameters: Option<ReplyParameters>,
2327 #[serde(skip_serializing_if = "Option::is_none")]
2328 reply_markup: Option<ReplyMarkup>,
2329}
2330
2331pub struct SendPaidMedia {
2338 client: BotClient,
2339 params: SendPaidMediaParams,
2340}
2341
2342impl SendPaidMedia {
2343 pub(crate) fn new(
2344 client: BotClient,
2345 chat_id: impl Into<ChatId>,
2346 star_count: u32,
2347 media: Vec<serde_json::Value>,
2348 ) -> Self {
2349 Self {
2350 client,
2351 params: SendPaidMediaParams {
2352 chat_id: chat_id.into(),
2353 star_count,
2354 media,
2355 business_connection_id: None,
2356 payload: None,
2357 caption: None,
2358 parse_mode: None,
2359 show_caption_above_media: None,
2360 disable_notification: None,
2361 protect_content: None,
2362 reply_parameters: None,
2363 reply_markup: None,
2364 },
2365 }
2366 }
2367 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
2369 self.params.business_connection_id = Some(id.into());
2370 self
2371 }
2372 pub fn payload(mut self, p: impl Into<String>) -> Self {
2374 self.params.payload = Some(p.into());
2375 self
2376 }
2377 pub fn caption(mut self, c: impl Into<String>) -> Self {
2379 self.params.caption = Some(c.into());
2380 self
2381 }
2382 pub fn parse_mode(mut self, m: ParseMode) -> Self {
2384 self.params.parse_mode = Some(m);
2385 self
2386 }
2387 pub fn show_caption_above_media(mut self, v: bool) -> Self {
2389 self.params.show_caption_above_media = Some(v);
2390 self
2391 }
2392 pub fn disable_notification(mut self, v: bool) -> Self {
2394 self.params.disable_notification = Some(v);
2395 self
2396 }
2397 pub fn protect_content(mut self, v: bool) -> Self {
2399 self.params.protect_content = Some(v);
2400 self
2401 }
2402 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
2404 self.params.reply_parameters = Some(rp);
2405 self
2406 }
2407 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self {
2409 self.params.reply_markup = Some(m.into());
2410 self
2411 }
2412}
2413
2414impl_into_future!(SendPaidMedia, Message, "sendPaidMedia");
2415
2416#[derive(Serialize)]
2419struct SendGameParams {
2420 chat_id: i64,
2421 game_short_name: String,
2422 #[serde(skip_serializing_if = "Option::is_none")]
2423 business_connection_id: Option<String>,
2424 #[serde(skip_serializing_if = "Option::is_none")]
2425 message_thread_id: Option<i64>,
2426 #[serde(skip_serializing_if = "Option::is_none")]
2427 direct_messages_topic_id: Option<i64>,
2428 #[serde(skip_serializing_if = "Option::is_none")]
2429 disable_notification: Option<bool>,
2430 #[serde(skip_serializing_if = "Option::is_none")]
2431 protect_content: Option<bool>,
2432 #[serde(skip_serializing_if = "Option::is_none")]
2433 reply_parameters: Option<ReplyParameters>,
2434 #[serde(skip_serializing_if = "Option::is_none")]
2435 reply_markup: Option<rustigram_types::keyboard::InlineKeyboardMarkup>,
2436}
2437
2438pub struct SendGame {
2443 client: BotClient,
2444 params: SendGameParams,
2445}
2446
2447impl SendGame {
2448 pub(crate) fn new(client: BotClient, chat_id: i64, game_short_name: impl Into<String>) -> Self {
2449 Self {
2450 client,
2451 params: SendGameParams {
2452 chat_id,
2453 game_short_name: game_short_name.into(),
2454 business_connection_id: None,
2455 message_thread_id: None,
2456 direct_messages_topic_id: None,
2457 disable_notification: None,
2458 protect_content: None,
2459 reply_parameters: None,
2460 reply_markup: None,
2461 },
2462 }
2463 }
2464 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
2466 self.params.business_connection_id = Some(id.into());
2467 self
2468 }
2469 pub fn message_thread_id(mut self, id: i64) -> Self {
2471 self.params.message_thread_id = Some(id);
2472 self
2473 }
2474 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
2476 self.params.direct_messages_topic_id = Some(id);
2477 self
2478 }
2479 pub fn disable_notification(mut self, v: bool) -> Self {
2481 self.params.disable_notification = Some(v);
2482 self
2483 }
2484 pub fn protect_content(mut self, v: bool) -> Self {
2486 self.params.protect_content = Some(v);
2487 self
2488 }
2489 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
2491 self.params.reply_parameters = Some(rp);
2492 self
2493 }
2494 pub fn reply_markup(mut self, m: rustigram_types::keyboard::InlineKeyboardMarkup) -> Self {
2496 self.params.reply_markup = Some(m);
2497 self
2498 }
2499}
2500
2501impl_into_future!(SendGame, Message, "sendGame");
2502
2503#[derive(Serialize)]
2506struct SendChecklistParams {
2507 business_connection_id: String,
2508 chat_id: i64,
2509 checklist: rustigram_types::checklist::InputChecklist,
2510 #[serde(skip_serializing_if = "Option::is_none")]
2511 direct_messages_topic_id: Option<i64>,
2512 #[serde(skip_serializing_if = "Option::is_none")]
2513 disable_notification: Option<bool>,
2514 #[serde(skip_serializing_if = "Option::is_none")]
2515 protect_content: Option<bool>,
2516 #[serde(skip_serializing_if = "Option::is_none")]
2517 message_effect_id: Option<String>,
2518 #[serde(skip_serializing_if = "Option::is_none")]
2519 reply_parameters: Option<ReplyParameters>,
2520 #[serde(skip_serializing_if = "Option::is_none")]
2521 reply_markup: Option<rustigram_types::keyboard::InlineKeyboardMarkup>,
2522 #[serde(skip_serializing_if = "Option::is_none")]
2523 suggested_post_parameters: Option<SuggestedPostParameters>,
2524}
2525
2526pub struct SendChecklist {
2531 client: BotClient,
2532 params: SendChecklistParams,
2533}
2534
2535impl SendChecklist {
2536 pub(crate) fn new(
2537 client: BotClient,
2538 business_connection_id: impl Into<String>,
2539 chat_id: i64,
2540 checklist: rustigram_types::checklist::InputChecklist,
2541 ) -> Self {
2542 Self {
2543 client,
2544 params: SendChecklistParams {
2545 business_connection_id: business_connection_id.into(),
2546 chat_id,
2547 checklist,
2548 direct_messages_topic_id: None,
2549 disable_notification: None,
2550 protect_content: None,
2551 message_effect_id: None,
2552 reply_parameters: None,
2553 reply_markup: None,
2554 suggested_post_parameters: None,
2555 },
2556 }
2557 }
2558 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
2560 self.params.direct_messages_topic_id = Some(id);
2561 self
2562 }
2563 pub fn disable_notification(mut self, v: bool) -> Self {
2565 self.params.disable_notification = Some(v);
2566 self
2567 }
2568 pub fn protect_content(mut self, v: bool) -> Self {
2570 self.params.protect_content = Some(v);
2571 self
2572 }
2573 pub fn message_effect_id(mut self, id: impl Into<String>) -> Self {
2575 self.params.message_effect_id = Some(id.into());
2576 self
2577 }
2578 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
2580 self.params.reply_parameters = Some(rp);
2581 self
2582 }
2583 pub fn reply_markup(mut self, m: rustigram_types::keyboard::InlineKeyboardMarkup) -> Self {
2585 self.params.reply_markup = Some(m);
2586 self
2587 }
2588 pub fn suggested_post_parameters(mut self, params: SuggestedPostParameters) -> Self {
2590 self.params.suggested_post_parameters = Some(params);
2591 self
2592 }
2593}
2594
2595impl_into_future!(SendChecklist, Message, "sendChecklist");
2596
2597#[derive(Serialize)]
2600struct SendRichMessageParams {
2601 chat_id: ChatId,
2602 rich_message: rustigram_types::rich_message::InputRichMessage,
2603 #[serde(skip_serializing_if = "Option::is_none")]
2604 business_connection_id: Option<String>,
2605 #[serde(skip_serializing_if = "Option::is_none")]
2606 message_thread_id: Option<i64>,
2607 #[serde(skip_serializing_if = "Option::is_none")]
2608 direct_messages_topic_id: Option<i64>,
2609 #[serde(skip_serializing_if = "Option::is_none")]
2610 disable_notification: Option<bool>,
2611 #[serde(skip_serializing_if = "Option::is_none")]
2612 protect_content: Option<bool>,
2613 #[serde(skip_serializing_if = "Option::is_none")]
2614 allow_paid_broadcast: Option<bool>,
2615 #[serde(skip_serializing_if = "Option::is_none")]
2616 message_effect_id: Option<String>,
2617 #[serde(skip_serializing_if = "Option::is_none")]
2618 suggested_post_parameters: Option<SuggestedPostParameters>,
2619 #[serde(skip_serializing_if = "Option::is_none")]
2620 reply_parameters: Option<ReplyParameters>,
2621 #[serde(skip_serializing_if = "Option::is_none")]
2622 reply_markup: Option<rustigram_types::keyboard::ReplyMarkup>,
2623}
2624
2625pub struct SendRichMessage {
2627 client: BotClient,
2628 params: SendRichMessageParams,
2629}
2630
2631impl SendRichMessage {
2632 pub(crate) fn new(
2633 client: BotClient,
2634 chat_id: impl Into<ChatId>,
2635 rich_message: rustigram_types::rich_message::InputRichMessage,
2636 ) -> Self {
2637 Self {
2638 client,
2639 params: SendRichMessageParams {
2640 chat_id: chat_id.into(),
2641 rich_message,
2642 business_connection_id: None,
2643 message_thread_id: None,
2644 direct_messages_topic_id: None,
2645 disable_notification: None,
2646 protect_content: None,
2647 allow_paid_broadcast: None,
2648 message_effect_id: None,
2649 suggested_post_parameters: None,
2650 reply_parameters: None,
2651 reply_markup: None,
2652 },
2653 }
2654 }
2655
2656 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
2658 self.params.business_connection_id = Some(id.into());
2659 self
2660 }
2661 pub fn message_thread_id(mut self, id: i64) -> Self {
2663 self.params.message_thread_id = Some(id);
2664 self
2665 }
2666 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
2668 self.params.direct_messages_topic_id = Some(id);
2669 self
2670 }
2671 pub fn disable_notification(mut self, v: bool) -> Self {
2673 self.params.disable_notification = Some(v);
2674 self
2675 }
2676 pub fn protect_content(mut self, v: bool) -> Self {
2678 self.params.protect_content = Some(v);
2679 self
2680 }
2681 pub fn allow_paid_broadcast(mut self, v: bool) -> Self {
2683 self.params.allow_paid_broadcast = Some(v);
2684 self
2685 }
2686 pub fn message_effect_id(mut self, id: impl Into<String>) -> Self {
2688 self.params.message_effect_id = Some(id.into());
2689 self
2690 }
2691 pub fn suggested_post_parameters(mut self, p: SuggestedPostParameters) -> Self {
2693 self.params.suggested_post_parameters = Some(p);
2694 self
2695 }
2696 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
2698 self.params.reply_parameters = Some(rp);
2699 self
2700 }
2701 pub fn reply_markup(mut self, m: rustigram_types::keyboard::ReplyMarkup) -> Self {
2703 self.params.reply_markup = Some(m);
2704 self
2705 }
2706}
2707
2708impl_into_future!(SendRichMessage, Message, "sendRichMessage");
2709
2710#[derive(Serialize)]
2713struct SendRichMessageDraftParams {
2714 chat_id: i64,
2715 draft_id: i64,
2716 rich_message: rustigram_types::rich_message::InputRichMessage,
2717 #[serde(skip_serializing_if = "Option::is_none")]
2718 message_thread_id: Option<i64>,
2719}
2720
2721pub struct SendRichMessageDraft {
2726 client: BotClient,
2727 params: SendRichMessageDraftParams,
2728}
2729
2730impl SendRichMessageDraft {
2731 pub(crate) fn new(
2732 client: BotClient,
2733 chat_id: i64,
2734 draft_id: i64,
2735 rich_message: rustigram_types::rich_message::InputRichMessage,
2736 ) -> Self {
2737 Self {
2738 client,
2739 params: SendRichMessageDraftParams {
2740 chat_id,
2741 draft_id,
2742 rich_message,
2743 message_thread_id: None,
2744 },
2745 }
2746 }
2747
2748 pub fn message_thread_id(mut self, id: i64) -> Self {
2750 self.params.message_thread_id = Some(id);
2751 self
2752 }
2753}
2754
2755impl_into_future!(SendRichMessageDraft, bool, "sendRichMessageDraft");