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}
768
769pub struct SendPoll {
771 client: BotClient,
772 params: SendPollParams,
773}
774
775impl SendPoll {
776 pub(crate) fn new(
777 client: BotClient,
778 chat_id: impl Into<ChatId>,
779 question: impl Into<String>,
780 options: Vec<InputPollOption>,
781 ) -> Self {
782 Self {
783 client,
784 params: SendPollParams {
785 chat_id: chat_id.into(),
786 question: question.into(),
787 options,
788 question_parse_mode: None,
789 question_entities: None,
790 message_thread_id: None,
791 direct_messages_topic_id: None,
792 poll_type: None,
793 is_anonymous: None,
794 allows_multiple_answers: None,
795 allows_revoting: None,
796 correct_option_ids: None,
797 explanation: None,
798 explanation_parse_mode: None,
799 explanation_entities: None,
800 open_period: None,
801 close_date: None,
802 is_closed: None,
803 shuffle_options: None,
804 allow_adding_options: None,
805 hide_results_until_closes: None,
806 description: None,
807 description_parse_mode: None,
808 description_entities: None,
809 disable_notification: None,
810 protect_content: None,
811 reply_parameters: None,
812 reply_markup: None,
813 suggested_post_parameters: None,
814 members_only: None,
815 country_codes: None,
816 },
817 }
818 }
819 pub fn message_thread_id(mut self, id: i64) -> Self {
821 self.params.message_thread_id = Some(id);
822 self
823 }
824 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
826 self.params.direct_messages_topic_id = Some(id);
827 self
828 }
829 pub fn is_anonymous(mut self, v: bool) -> Self {
831 self.params.is_anonymous = Some(v);
832 self
833 }
834 pub fn allows_multiple_answers(mut self, v: bool) -> Self {
836 self.params.allows_multiple_answers = Some(v);
837 self
838 }
839 pub fn allows_revoting(mut self, v: bool) -> Self {
841 self.params.allows_revoting = Some(v);
842 self
843 }
844 pub fn quiz(mut self, ids: Vec<u8>) -> Self {
846 self.params.poll_type = Some(rustigram_types::poll::PollType::Quiz);
847 self.params.correct_option_ids = Some(ids);
848 self
849 }
850 pub fn quiz_single(self, id: u8) -> Self {
852 self.quiz(vec![id])
853 }
854 pub fn explanation(mut self, text: impl Into<String>) -> Self {
856 self.params.explanation = Some(text.into());
857 self
858 }
859 pub fn explanation_parse_mode(mut self, mode: ParseMode) -> Self {
861 self.params.explanation_parse_mode = Some(mode);
862 self
863 }
864 pub fn explanation_entities(mut self, e: Vec<rustigram_types::message::MessageEntity>) -> Self {
866 self.params.explanation_entities = Some(e);
867 self
868 }
869 pub fn open_period(mut self, secs: u32) -> Self {
871 self.params.open_period = Some(secs);
872 self
873 }
874 pub fn close_date(mut self, ts: i64) -> Self {
876 self.params.close_date = Some(ts);
877 self
878 }
879 pub fn shuffle_options(mut self, v: bool) -> Self {
881 self.params.shuffle_options = Some(v);
882 self
883 }
884 pub fn allow_adding_options(mut self, v: bool) -> Self {
886 self.params.allow_adding_options = Some(v);
887 self
888 }
889 pub fn hide_results_until_closes(mut self, v: bool) -> Self {
891 self.params.hide_results_until_closes = Some(v);
892 self
893 }
894 pub fn description(mut self, d: impl Into<String>) -> Self {
896 self.params.description = Some(d.into());
897 self
898 }
899 pub fn description_parse_mode(mut self, mode: ParseMode) -> Self {
901 self.params.description_parse_mode = Some(mode);
902 self
903 }
904 pub fn description_entities(mut self, e: Vec<rustigram_types::message::MessageEntity>) -> Self {
906 self.params.description_entities = Some(e);
907 self
908 }
909 pub fn question_parse_mode(mut self, mode: ParseMode) -> Self {
911 self.params.question_parse_mode = Some(mode);
912 self
913 }
914 pub fn question_entities(mut self, e: Vec<rustigram_types::message::MessageEntity>) -> Self {
916 self.params.question_entities = Some(e);
917 self
918 }
919 pub fn disable_notification(mut self, v: bool) -> Self {
921 self.params.disable_notification = Some(v);
922 self
923 }
924 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self {
926 self.params.reply_markup = Some(m.into());
927 self
928 }
929 pub fn suggested_post_parameters(mut self, params: SuggestedPostParameters) -> Self {
931 self.params.suggested_post_parameters = Some(params);
932 self
933 }
934 pub fn members_only(mut self, v: bool) -> Self {
937 self.params.members_only = Some(v);
938 self
939 }
940 pub fn country_codes(mut self, codes: Vec<impl Into<String>>) -> Self {
943 self.params.country_codes = Some(codes.into_iter().map(Into::into).collect());
944 self
945 }
946}
947
948impl_into_future!(SendPoll, Message, "sendPoll");
949
950#[derive(Serialize)]
953struct SendMessageDraftParams {
954 chat_id: ChatId,
955 draft_id: i64,
956 text: String,
957 #[serde(skip_serializing_if = "Option::is_none")]
958 message_thread_id: Option<i64>,
959 #[serde(skip_serializing_if = "Option::is_none")]
960 parse_mode: Option<ParseMode>,
961 #[serde(skip_serializing_if = "Option::is_none")]
962 entities: Option<Vec<rustigram_types::message::MessageEntity>>,
963}
964
965pub struct SendMessageDraft {
968 client: BotClient,
969 params: SendMessageDraftParams,
970}
971
972impl SendMessageDraft {
973 pub(crate) fn new(
974 client: BotClient,
975 chat_id: impl Into<ChatId>,
976 draft_id: i64,
977 text: impl Into<String>,
978 ) -> Self {
979 Self {
980 client,
981 params: SendMessageDraftParams {
982 chat_id: chat_id.into(),
983 draft_id,
984 text: text.into(),
985 message_thread_id: None,
986 parse_mode: None,
987 entities: None,
988 },
989 }
990 }
991 pub fn parse_mode(mut self, m: ParseMode) -> Self {
993 self.params.parse_mode = Some(m);
994 self
995 }
996 pub fn entities(mut self, e: Vec<rustigram_types::message::MessageEntity>) -> Self {
998 self.params.entities = Some(e);
999 self
1000 }
1001}
1002
1003impl_into_future!(SendMessageDraft, bool, "sendMessageDraft");
1004
1005#[derive(Default)]
1014pub struct MediaSendOptions {
1015 pub business_connection_id: Option<String>,
1017 pub message_thread_id: Option<i64>,
1019 pub direct_messages_topic_id: Option<i64>,
1021 pub caption: Option<String>,
1023 pub parse_mode: Option<ParseMode>,
1025 pub caption_entities: Option<Vec<rustigram_types::message::MessageEntity>>,
1027 pub show_caption_above_media: Option<bool>,
1029 pub has_spoiler: Option<bool>,
1031 pub disable_notification: Option<bool>,
1033 pub protect_content: Option<bool>,
1035 pub allow_paid_broadcast: Option<bool>,
1037 pub reply_parameters: Option<ReplyParameters>,
1039 pub reply_markup: Option<ReplyMarkup>,
1041 pub suggested_post_parameters: Option<SuggestedPostParameters>,
1043}
1044
1045fn media_json_body(
1047 chat_id: &ChatId,
1048 media_field: &str,
1049 media_value: &str,
1050 opts: &MediaSendOptions,
1051 extra: serde_json::Value,
1052) -> serde_json::Value {
1053 let mut map = serde_json::json!({
1054 "chat_id": chat_id,
1055 media_field: media_value,
1056 });
1057 let obj = map.as_object_mut().unwrap();
1058 if let Some(v) = &opts.business_connection_id {
1059 obj.insert("business_connection_id".to_owned(), serde_json::json!(v));
1060 }
1061 if let Some(v) = &opts.message_thread_id {
1062 obj.insert("message_thread_id".to_owned(), serde_json::json!(v));
1063 }
1064 if let Some(v) = &opts.direct_messages_topic_id {
1065 obj.insert("direct_messages_topic_id".to_owned(), serde_json::json!(v));
1066 }
1067 if let Some(v) = &opts.caption {
1068 obj.insert("caption".to_owned(), serde_json::json!(v));
1069 }
1070 if let Some(v) = &opts.parse_mode {
1071 obj.insert("parse_mode".to_owned(), serde_json::json!(v));
1072 }
1073 if let Some(v) = &opts.caption_entities {
1074 obj.insert("caption_entities".to_owned(), serde_json::json!(v));
1075 }
1076 if let Some(v) = opts.show_caption_above_media {
1077 obj.insert("show_caption_above_media".to_owned(), serde_json::json!(v));
1078 }
1079 if let Some(v) = opts.has_spoiler {
1080 obj.insert("has_spoiler".to_owned(), serde_json::json!(v));
1081 }
1082 if let Some(v) = opts.disable_notification {
1083 obj.insert("disable_notification".to_owned(), serde_json::json!(v));
1084 }
1085 if let Some(v) = opts.protect_content {
1086 obj.insert("protect_content".to_owned(), serde_json::json!(v));
1087 }
1088 if let Some(v) = opts.allow_paid_broadcast {
1089 obj.insert("allow_paid_broadcast".to_owned(), serde_json::json!(v));
1090 }
1091 if let Some(v) = &opts.reply_parameters {
1092 obj.insert("reply_parameters".to_owned(), serde_json::json!(v));
1093 }
1094 if let Some(v) = &opts.reply_markup {
1095 obj.insert("reply_markup".to_owned(), serde_json::json!(v));
1096 }
1097 if let Some(v) = &opts.suggested_post_parameters {
1098 obj.insert("suggested_post_parameters".to_owned(), serde_json::json!(v));
1099 }
1100 if let serde_json::Value::Object(extra_obj) = extra {
1101 for (k, v) in extra_obj {
1102 obj.insert(k, v);
1103 }
1104 }
1105 map
1106}
1107
1108pub struct SendPhoto {
1112 client: BotClient,
1113 chat_id: ChatId,
1114 photo: InputFile,
1115 opts: MediaSendOptions,
1116}
1117
1118impl SendPhoto {
1119 pub(crate) fn new(client: BotClient, chat_id: impl Into<ChatId>, photo: InputFile) -> Self {
1120 Self {
1121 client,
1122 chat_id: chat_id.into(),
1123 photo,
1124 opts: MediaSendOptions::default(),
1125 }
1126 }
1127 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
1129 self.opts.business_connection_id = Some(id.into());
1130 self
1131 }
1132 pub fn message_thread_id(mut self, id: i64) -> Self {
1134 self.opts.message_thread_id = Some(id);
1135 self
1136 }
1137 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
1139 self.opts.direct_messages_topic_id = Some(id);
1140 self
1141 }
1142 pub fn caption(mut self, c: impl Into<String>) -> Self {
1144 self.opts.caption = Some(c.into());
1145 self
1146 }
1147 pub fn parse_mode(mut self, m: ParseMode) -> Self {
1149 self.opts.parse_mode = Some(m);
1150 self
1151 }
1152 pub fn has_spoiler(mut self, v: bool) -> Self {
1154 self.opts.has_spoiler = Some(v);
1155 self
1156 }
1157 pub fn show_caption_above_media(mut self, v: bool) -> Self {
1159 self.opts.show_caption_above_media = Some(v);
1160 self
1161 }
1162 pub fn disable_notification(mut self, v: bool) -> Self {
1164 self.opts.disable_notification = Some(v);
1165 self
1166 }
1167 pub fn protect_content(mut self, v: bool) -> Self {
1169 self.opts.protect_content = Some(v);
1170 self
1171 }
1172 pub fn allow_paid_broadcast(mut self, v: bool) -> Self {
1174 self.opts.allow_paid_broadcast = Some(v);
1175 self
1176 }
1177 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
1179 self.opts.reply_parameters = Some(rp);
1180 self
1181 }
1182 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self {
1184 self.opts.reply_markup = Some(m.into());
1185 self
1186 }
1187 pub fn suggested_post_parameters(mut self, params: SuggestedPostParameters) -> Self {
1189 self.opts.suggested_post_parameters = Some(params);
1190 self
1191 }
1192}
1193
1194impl IntoFuture for SendPhoto {
1195 type Output = Result<Message>;
1196 type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
1197
1198 fn into_future(self) -> Self::IntoFuture {
1199 Box::pin(async move {
1200 match &self.photo {
1201 InputFile::Bytes {
1202 filename,
1203 data,
1204 mime_type,
1205 } => {
1206 let part = Part::bytes(data.clone())
1207 .file_name(filename.clone())
1208 .mime_str(mime_type)
1209 .map_err(|e| crate::error::Error::Decode(e.to_string()))?;
1210 let mut form = Form::new().part("photo", part);
1211 form = form.text("chat_id", self.chat_id.to_string());
1212 if let Some(id) = &self.opts.business_connection_id {
1213 form = form.text("business_connection_id", id.clone());
1214 }
1215 if let Some(id) = self.opts.message_thread_id {
1216 form = form.text("message_thread_id", id.to_string());
1217 }
1218 if let Some(id) = self.opts.direct_messages_topic_id {
1219 form = form.text("direct_messages_topic_id", id.to_string());
1220 }
1221 if let Some(c) = &self.opts.caption {
1222 form = form.text("caption", c.clone());
1223 }
1224 if let Some(m) = &self.opts.parse_mode {
1225 form = form.text("parse_mode", format!("{m:?}"));
1226 }
1227 if let Some(v) = self.opts.disable_notification {
1228 form = form.text("disable_notification", v.to_string());
1229 }
1230 if let Some(v) = self.opts.has_spoiler {
1231 form = form.text("has_spoiler", v.to_string());
1232 }
1233 if let Some(v) = &self.opts.reply_markup {
1234 form = form.text("reply_markup", serde_json::to_string(v).unwrap());
1235 }
1236 if let Some(p) = &self.opts.suggested_post_parameters {
1237 form = form.text(
1238 "suggested_post_parameters",
1239 serde_json::to_string(p).unwrap(),
1240 );
1241 }
1242 self.client.post_multipart("sendPhoto", form).await
1243 }
1244 _ => {
1245 let body = media_json_body(
1246 &self.chat_id,
1247 "photo",
1248 self.photo.as_str(),
1249 &self.opts,
1250 serde_json::Value::Null,
1251 );
1252 self.client.post_json("sendPhoto", &body).await
1253 }
1254 }
1255 })
1256 }
1257}
1258
1259macro_rules! media_sender {
1262 ($(#[$doc:meta])* $name:ident, $field:literal, $method:literal, $return_ty:ty, [$($extra_field:ident: $extra_ty:ty),*]) => {
1263 $(#[$doc])*
1264 pub struct $name {
1265 client: BotClient,
1267 chat_id: ChatId,
1269 file: InputFile,
1271 opts: MediaSendOptions,
1273 $($extra_field: Option<$extra_ty>,)*
1275 }
1276
1277 impl $name {
1278 pub(crate) fn new(client: BotClient, chat_id: impl Into<ChatId>, file: InputFile) -> Self {
1279 Self {
1280 client,
1281 chat_id: chat_id.into(),
1282 file,
1283 opts: MediaSendOptions::default(),
1284 $($extra_field: None,)*
1285 }
1286 }
1287 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self { self.opts.business_connection_id = Some(id.into()); self }
1289 pub fn message_thread_id(mut self, id: i64) -> Self { self.opts.message_thread_id = Some(id); self }
1291 pub fn direct_messages_topic_id(mut self, id: i64) -> Self { self.opts.direct_messages_topic_id = Some(id); self }
1293 pub fn caption(mut self, c: impl Into<String>) -> Self { self.opts.caption = Some(c.into()); self }
1295 pub fn parse_mode(mut self, m: ParseMode) -> Self { self.opts.parse_mode = Some(m); self }
1297 pub fn disable_notification(mut self, v: bool) -> Self { self.opts.disable_notification = Some(v); self }
1299 pub fn protect_content(mut self, v: bool) -> Self { self.opts.protect_content = Some(v); self }
1301 pub fn allow_paid_broadcast(mut self, v: bool) -> Self { self.opts.allow_paid_broadcast = Some(v); self }
1303 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self { self.opts.reply_parameters = Some(rp); self }
1305 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self { self.opts.reply_markup = Some(m.into()); self }
1307 pub fn suggested_post_parameters(mut self, params: SuggestedPostParameters) -> Self { self.opts.suggested_post_parameters = Some(params); self }
1309
1310 $(
1311 #[doc = concat!("Sets the ", stringify!($extra_field), " for the media.")]
1312 pub fn $extra_field(mut self, v: $extra_ty) -> Self {
1313 self.$extra_field = Some(v);
1314 self
1315 }
1316 )*
1317 }
1318
1319 impl IntoFuture for $name {
1320 type Output = Result<$return_ty>;
1321 type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
1322
1323 fn into_future(self) -> Self::IntoFuture {
1324 Box::pin(async move {
1325 match &self.file {
1326 InputFile::Bytes { filename, data, mime_type } => {
1327 let part = Part::bytes(data.clone())
1328 .file_name(filename.clone())
1329 .mime_str(mime_type)
1330 .map_err(|e| crate::error::Error::Decode(e.to_string()))?;
1331 let mut form = Form::new().part($field, part);
1332 form = form.text("chat_id", self.chat_id.to_string());
1333 if let Some(id) = &self.opts.business_connection_id { form = form.text("business_connection_id", id.clone()); }
1334 if let Some(id) = self.opts.message_thread_id { form = form.text("message_thread_id", id.to_string()); }
1335 if let Some(id) = self.opts.direct_messages_topic_id { form = form.text("direct_messages_topic_id", id.to_string()); }
1336 if let Some(c) = &self.opts.caption { form = form.text("caption", c.clone()); }
1337 if let Some(v) = self.opts.disable_notification { form = form.text("disable_notification", v.to_string()); }
1338 if let Some(v) = &self.opts.reply_markup { form = form.text("reply_markup", serde_json::to_string(v).unwrap()); }
1339 if let Some(p) = &self.opts.suggested_post_parameters { form = form.text("suggested_post_parameters", serde_json::to_string(p).unwrap()); }
1340
1341 $(
1342 if let Some(ref v) = self.$extra_field {
1343 form = form.text(stringify!($extra_field), v.to_string());
1344 }
1345 )*
1346
1347 self.client.post_multipart($method, form).await
1348 }
1349 _ => {
1350 let mut extra = serde_json::json!({});
1351 $(
1352 if let Some(ref v) = self.$extra_field {
1353 extra[stringify!($extra_field)] = serde_json::json!(v);
1354 }
1355 )*
1356 let body = media_json_body(&self.chat_id, $field, self.file.as_str(), &self.opts, extra);
1357 self.client.post_json($method, &body).await
1358 }
1359 }
1360 })
1361 }
1362 }
1363 };
1364}
1365
1366media_sender!(
1367 SendAudio, "audio", "sendAudio", Message, [duration: u32, performer: String, title: String]);
1369media_sender!(
1370 SendDocument, "document", "sendDocument", Message, [disable_content_type_detection: bool]);
1372media_sender!(
1373 SendVideo, "video", "sendVideo", Message, [duration: u32, width: u32, height: u32, supports_streaming: bool, cover: String, start_timestamp: i64]);
1375media_sender!(
1376 SendAnimation, "animation", "sendAnimation", Message, [duration: u32, width: u32, height: u32]);
1378media_sender!(
1379 SendVoice, "voice", "sendVoice", Message, [duration: u32]);
1381media_sender!(
1382 SendVideoNote, "video_note", "sendVideoNote", Message, [duration: u32, length: u32]);
1384media_sender!(
1385 SendSticker, "sticker", "sendSticker", Message, [emoji: String]);
1387
1388#[derive(Serialize)]
1391struct DeleteMessageParams {
1392 chat_id: ChatId,
1393 message_id: i64,
1394}
1395
1396pub struct DeleteMessage {
1398 client: BotClient,
1399 params: DeleteMessageParams,
1400}
1401impl DeleteMessage {
1402 pub(crate) fn new(client: BotClient, chat_id: impl Into<ChatId>, message_id: i64) -> Self {
1403 Self {
1404 client,
1405 params: DeleteMessageParams {
1406 chat_id: chat_id.into(),
1407 message_id,
1408 },
1409 }
1410 }
1411}
1412impl_into_future!(DeleteMessage, bool, "deleteMessage");
1413
1414#[derive(Serialize)]
1415struct DeleteMessagesParams {
1416 chat_id: ChatId,
1417 message_ids: Vec<i64>,
1418}
1419
1420pub struct DeleteMessages {
1422 client: BotClient,
1423 params: DeleteMessagesParams,
1424}
1425impl DeleteMessages {
1426 pub(crate) fn new(
1427 client: BotClient,
1428 chat_id: impl Into<ChatId>,
1429 message_ids: Vec<i64>,
1430 ) -> Self {
1431 Self {
1432 client,
1433 params: DeleteMessagesParams {
1434 chat_id: chat_id.into(),
1435 message_ids,
1436 },
1437 }
1438 }
1439}
1440impl_into_future!(DeleteMessages, bool, "deleteMessages");
1441
1442#[derive(Serialize)]
1445struct StopPollParams {
1446 chat_id: ChatId,
1447 message_id: i64,
1448 #[serde(skip_serializing_if = "Option::is_none")]
1449 reply_markup: Option<rustigram_types::keyboard::InlineKeyboardMarkup>,
1450}
1451
1452pub struct StopPoll {
1454 client: BotClient,
1455 params: StopPollParams,
1456}
1457impl StopPoll {
1458 pub(crate) fn new(client: BotClient, chat_id: impl Into<ChatId>, message_id: i64) -> Self {
1459 Self {
1460 client,
1461 params: StopPollParams {
1462 chat_id: chat_id.into(),
1463 message_id,
1464 reply_markup: None,
1465 },
1466 }
1467 }
1468 pub fn reply_markup(mut self, m: rustigram_types::keyboard::InlineKeyboardMarkup) -> Self {
1470 self.params.reply_markup = Some(m);
1471 self
1472 }
1473}
1474impl_into_future!(StopPoll, rustigram_types::poll::Poll, "stopPoll");
1475
1476#[derive(Serialize)]
1479struct AnswerCallbackQueryParams {
1480 callback_query_id: String,
1481 #[serde(skip_serializing_if = "Option::is_none")]
1482 text: Option<String>,
1483 #[serde(skip_serializing_if = "Option::is_none")]
1484 show_alert: Option<bool>,
1485 #[serde(skip_serializing_if = "Option::is_none")]
1486 url: Option<String>,
1487 #[serde(skip_serializing_if = "Option::is_none")]
1488 cache_time: Option<u32>,
1489}
1490
1491pub struct AnswerCallbackQuery {
1493 client: BotClient,
1494 params: AnswerCallbackQueryParams,
1495}
1496impl AnswerCallbackQuery {
1497 pub(crate) fn new(client: BotClient, callback_query_id: impl Into<String>) -> Self {
1498 Self {
1499 client,
1500 params: AnswerCallbackQueryParams {
1501 callback_query_id: callback_query_id.into(),
1502 text: None,
1503 show_alert: None,
1504 url: None,
1505 cache_time: None,
1506 },
1507 }
1508 }
1509 pub fn text(mut self, t: impl Into<String>) -> Self {
1511 self.params.text = Some(t.into());
1512 self
1513 }
1514 pub fn show_alert(mut self, v: bool) -> Self {
1516 self.params.show_alert = Some(v);
1517 self
1518 }
1519 pub fn url(mut self, u: impl Into<String>) -> Self {
1521 self.params.url = Some(u.into());
1522 self
1523 }
1524 pub fn cache_time(mut self, secs: u32) -> Self {
1526 self.params.cache_time = Some(secs);
1527 self
1528 }
1529 pub fn alert(self, text: impl Into<String>) -> Self {
1531 self.text(text).show_alert(true)
1532 }
1533}
1534impl_into_future!(AnswerCallbackQuery, bool, "answerCallbackQuery");
1535#[derive(Serialize)]
1538struct ForwardMessagesParams {
1539 chat_id: ChatId,
1540 from_chat_id: ChatId,
1541 message_ids: Vec<i64>,
1542 #[serde(skip_serializing_if = "Option::is_none")]
1543 message_thread_id: Option<i64>,
1544 #[serde(skip_serializing_if = "Option::is_none")]
1545 direct_messages_topic_id: Option<i64>,
1546 #[serde(skip_serializing_if = "Option::is_none")]
1547 disable_notification: Option<bool>,
1548 #[serde(skip_serializing_if = "Option::is_none")]
1549 protect_content: Option<bool>,
1550}
1551
1552pub struct ForwardMessages {
1557 client: BotClient,
1558 params: ForwardMessagesParams,
1559}
1560
1561impl ForwardMessages {
1562 pub(crate) fn new(
1563 client: BotClient,
1564 chat_id: impl Into<ChatId>,
1565 from_chat_id: impl Into<ChatId>,
1566 message_ids: Vec<i64>,
1567 ) -> Self {
1568 Self {
1569 client,
1570 params: ForwardMessagesParams {
1571 chat_id: chat_id.into(),
1572 from_chat_id: from_chat_id.into(),
1573 message_ids,
1574 message_thread_id: None,
1575 direct_messages_topic_id: None,
1576 disable_notification: None,
1577 protect_content: None,
1578 },
1579 }
1580 }
1581 pub fn message_thread_id(mut self, id: i64) -> Self {
1583 self.params.message_thread_id = Some(id);
1584 self
1585 }
1586 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
1588 self.params.direct_messages_topic_id = Some(id);
1589 self
1590 }
1591 pub fn disable_notification(mut self, v: bool) -> Self {
1593 self.params.disable_notification = Some(v);
1594 self
1595 }
1596 pub fn protect_content(mut self, v: bool) -> Self {
1598 self.params.protect_content = Some(v);
1599 self
1600 }
1601}
1602
1603impl_into_future!(
1604 ForwardMessages,
1605 Vec<rustigram_types::message::MessageId>,
1606 "forwardMessages"
1607);
1608
1609#[derive(Serialize)]
1612struct CopyMessagesParams {
1613 chat_id: ChatId,
1614 from_chat_id: ChatId,
1615 message_ids: Vec<i64>,
1616 #[serde(skip_serializing_if = "Option::is_none")]
1617 message_thread_id: Option<i64>,
1618 #[serde(skip_serializing_if = "Option::is_none")]
1619 direct_messages_topic_id: Option<i64>,
1620 #[serde(skip_serializing_if = "Option::is_none")]
1621 disable_notification: Option<bool>,
1622 #[serde(skip_serializing_if = "Option::is_none")]
1623 protect_content: Option<bool>,
1624 #[serde(skip_serializing_if = "Option::is_none")]
1625 remove_caption: Option<bool>,
1626}
1627
1628pub struct CopyMessages {
1633 client: BotClient,
1634 params: CopyMessagesParams,
1635}
1636
1637impl CopyMessages {
1638 pub(crate) fn new(
1639 client: BotClient,
1640 chat_id: impl Into<ChatId>,
1641 from_chat_id: impl Into<ChatId>,
1642 message_ids: Vec<i64>,
1643 ) -> Self {
1644 Self {
1645 client,
1646 params: CopyMessagesParams {
1647 chat_id: chat_id.into(),
1648 from_chat_id: from_chat_id.into(),
1649 message_ids,
1650 message_thread_id: None,
1651 direct_messages_topic_id: None,
1652 disable_notification: None,
1653 protect_content: None,
1654 remove_caption: None,
1655 },
1656 }
1657 }
1658 pub fn message_thread_id(mut self, id: i64) -> Self {
1660 self.params.message_thread_id = Some(id);
1661 self
1662 }
1663 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
1665 self.params.direct_messages_topic_id = Some(id);
1666 self
1667 }
1668 pub fn disable_notification(mut self, v: bool) -> Self {
1670 self.params.disable_notification = Some(v);
1671 self
1672 }
1673 pub fn protect_content(mut self, v: bool) -> Self {
1675 self.params.protect_content = Some(v);
1676 self
1677 }
1678 pub fn remove_caption(mut self, v: bool) -> Self {
1680 self.params.remove_caption = Some(v);
1681 self
1682 }
1683}
1684
1685impl_into_future!(
1686 CopyMessages,
1687 Vec<rustigram_types::message::MessageId>,
1688 "copyMessages"
1689);
1690
1691#[derive(Serialize)]
1694struct SendVenueParams {
1695 chat_id: ChatId,
1696 latitude: f64,
1697 longitude: f64,
1698 title: String,
1699 address: String,
1700 #[serde(skip_serializing_if = "Option::is_none")]
1701 message_thread_id: Option<i64>,
1702 #[serde(skip_serializing_if = "Option::is_none")]
1703 direct_messages_topic_id: Option<i64>,
1704 #[serde(skip_serializing_if = "Option::is_none")]
1705 foursquare_id: Option<String>,
1706 #[serde(skip_serializing_if = "Option::is_none")]
1707 foursquare_type: Option<String>,
1708 #[serde(skip_serializing_if = "Option::is_none")]
1709 google_place_id: Option<String>,
1710 #[serde(skip_serializing_if = "Option::is_none")]
1711 google_place_type: Option<String>,
1712 #[serde(skip_serializing_if = "Option::is_none")]
1713 disable_notification: Option<bool>,
1714 #[serde(skip_serializing_if = "Option::is_none")]
1715 protect_content: Option<bool>,
1716 #[serde(skip_serializing_if = "Option::is_none")]
1717 reply_parameters: Option<ReplyParameters>,
1718 #[serde(skip_serializing_if = "Option::is_none")]
1719 reply_markup: Option<ReplyMarkup>,
1720}
1721
1722pub struct SendVenue {
1724 client: BotClient,
1725 params: SendVenueParams,
1726}
1727
1728impl SendVenue {
1729 pub(crate) fn new(
1730 client: BotClient,
1731 chat_id: impl Into<ChatId>,
1732 latitude: f64,
1733 longitude: f64,
1734 title: impl Into<String>,
1735 address: impl Into<String>,
1736 ) -> Self {
1737 Self {
1738 client,
1739 params: SendVenueParams {
1740 chat_id: chat_id.into(),
1741 latitude,
1742 longitude,
1743 title: title.into(),
1744 address: address.into(),
1745 message_thread_id: None,
1746 direct_messages_topic_id: None,
1747 foursquare_id: None,
1748 foursquare_type: None,
1749 google_place_id: None,
1750 google_place_type: None,
1751 disable_notification: None,
1752 protect_content: None,
1753 reply_parameters: None,
1754 reply_markup: None,
1755 },
1756 }
1757 }
1758 pub fn message_thread_id(mut self, id: i64) -> Self {
1760 self.params.message_thread_id = Some(id);
1761 self
1762 }
1763 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
1765 self.params.direct_messages_topic_id = Some(id);
1766 self
1767 }
1768 pub fn foursquare_id(mut self, id: impl Into<String>) -> Self {
1770 self.params.foursquare_id = Some(id.into());
1771 self
1772 }
1773 pub fn foursquare_type(mut self, t: impl Into<String>) -> Self {
1775 self.params.foursquare_type = Some(t.into());
1776 self
1777 }
1778 pub fn google_place_id(mut self, id: impl Into<String>) -> Self {
1780 self.params.google_place_id = Some(id.into());
1781 self
1782 }
1783 pub fn google_place_type(mut self, t: impl Into<String>) -> Self {
1785 self.params.google_place_type = Some(t.into());
1786 self
1787 }
1788 pub fn disable_notification(mut self, v: bool) -> Self {
1790 self.params.disable_notification = Some(v);
1791 self
1792 }
1793 pub fn protect_content(mut self, v: bool) -> Self {
1795 self.params.protect_content = Some(v);
1796 self
1797 }
1798 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
1800 self.params.reply_parameters = Some(rp);
1801 self
1802 }
1803 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self {
1805 self.params.reply_markup = Some(m.into());
1806 self
1807 }
1808}
1809
1810impl_into_future!(SendVenue, Message, "sendVenue");
1811
1812#[derive(Serialize)]
1815struct SendMediaGroupParams {
1816 chat_id: ChatId,
1817 media: Vec<serde_json::Value>,
1822 #[serde(skip_serializing_if = "Option::is_none")]
1823 message_thread_id: Option<i64>,
1824 #[serde(skip_serializing_if = "Option::is_none")]
1825 direct_messages_topic_id: Option<i64>,
1826 #[serde(skip_serializing_if = "Option::is_none")]
1827 business_connection_id: Option<String>,
1828 #[serde(skip_serializing_if = "Option::is_none")]
1829 disable_notification: Option<bool>,
1830 #[serde(skip_serializing_if = "Option::is_none")]
1831 protect_content: Option<bool>,
1832 #[serde(skip_serializing_if = "Option::is_none")]
1833 reply_parameters: Option<ReplyParameters>,
1834}
1835
1836pub struct SendMediaGroup {
1844 client: BotClient,
1845 params: SendMediaGroupParams,
1846}
1847
1848impl SendMediaGroup {
1849 pub(crate) fn new(
1850 client: BotClient,
1851 chat_id: impl Into<ChatId>,
1852 media: Vec<serde_json::Value>,
1853 ) -> Self {
1854 Self {
1855 client,
1856 params: SendMediaGroupParams {
1857 chat_id: chat_id.into(),
1858 media,
1859 message_thread_id: None,
1860 direct_messages_topic_id: None,
1861 business_connection_id: None,
1862 disable_notification: None,
1863 protect_content: None,
1864 reply_parameters: None,
1865 },
1866 }
1867 }
1868 pub fn message_thread_id(mut self, id: i64) -> Self {
1870 self.params.message_thread_id = Some(id);
1871 self
1872 }
1873 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
1875 self.params.direct_messages_topic_id = Some(id);
1876 self
1877 }
1878 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
1880 self.params.business_connection_id = Some(id.into());
1881 self
1882 }
1883 pub fn disable_notification(mut self, v: bool) -> Self {
1885 self.params.disable_notification = Some(v);
1886 self
1887 }
1888 pub fn protect_content(mut self, v: bool) -> Self {
1890 self.params.protect_content = Some(v);
1891 self
1892 }
1893 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
1895 self.params.reply_parameters = Some(rp);
1896 self
1897 }
1898}
1899
1900impl_into_future!(SendMediaGroup, Vec<Message>, "sendMediaGroup");
1901
1902#[derive(Serialize)]
1905struct SendPaidMediaParams {
1906 chat_id: ChatId,
1907 star_count: u32,
1908 media: Vec<serde_json::Value>,
1913 #[serde(skip_serializing_if = "Option::is_none")]
1914 business_connection_id: Option<String>,
1915 #[serde(skip_serializing_if = "Option::is_none")]
1916 payload: Option<String>,
1917 #[serde(skip_serializing_if = "Option::is_none")]
1918 caption: Option<String>,
1919 #[serde(skip_serializing_if = "Option::is_none")]
1920 parse_mode: Option<ParseMode>,
1921 #[serde(skip_serializing_if = "Option::is_none")]
1922 show_caption_above_media: Option<bool>,
1923 #[serde(skip_serializing_if = "Option::is_none")]
1924 disable_notification: Option<bool>,
1925 #[serde(skip_serializing_if = "Option::is_none")]
1926 protect_content: Option<bool>,
1927 #[serde(skip_serializing_if = "Option::is_none")]
1928 reply_parameters: Option<ReplyParameters>,
1929 #[serde(skip_serializing_if = "Option::is_none")]
1930 reply_markup: Option<ReplyMarkup>,
1931}
1932
1933pub struct SendPaidMedia {
1940 client: BotClient,
1941 params: SendPaidMediaParams,
1942}
1943
1944impl SendPaidMedia {
1945 pub(crate) fn new(
1946 client: BotClient,
1947 chat_id: impl Into<ChatId>,
1948 star_count: u32,
1949 media: Vec<serde_json::Value>,
1950 ) -> Self {
1951 Self {
1952 client,
1953 params: SendPaidMediaParams {
1954 chat_id: chat_id.into(),
1955 star_count,
1956 media,
1957 business_connection_id: None,
1958 payload: None,
1959 caption: None,
1960 parse_mode: None,
1961 show_caption_above_media: None,
1962 disable_notification: None,
1963 protect_content: None,
1964 reply_parameters: None,
1965 reply_markup: None,
1966 },
1967 }
1968 }
1969 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
1971 self.params.business_connection_id = Some(id.into());
1972 self
1973 }
1974 pub fn payload(mut self, p: impl Into<String>) -> Self {
1976 self.params.payload = Some(p.into());
1977 self
1978 }
1979 pub fn caption(mut self, c: impl Into<String>) -> Self {
1981 self.params.caption = Some(c.into());
1982 self
1983 }
1984 pub fn parse_mode(mut self, m: ParseMode) -> Self {
1986 self.params.parse_mode = Some(m);
1987 self
1988 }
1989 pub fn show_caption_above_media(mut self, v: bool) -> Self {
1991 self.params.show_caption_above_media = Some(v);
1992 self
1993 }
1994 pub fn disable_notification(mut self, v: bool) -> Self {
1996 self.params.disable_notification = Some(v);
1997 self
1998 }
1999 pub fn protect_content(mut self, v: bool) -> Self {
2001 self.params.protect_content = Some(v);
2002 self
2003 }
2004 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
2006 self.params.reply_parameters = Some(rp);
2007 self
2008 }
2009 pub fn reply_markup(mut self, m: impl Into<ReplyMarkup>) -> Self {
2011 self.params.reply_markup = Some(m.into());
2012 self
2013 }
2014}
2015
2016impl_into_future!(SendPaidMedia, Message, "sendPaidMedia");
2017
2018#[derive(Serialize)]
2021struct SendGameParams {
2022 chat_id: i64,
2023 game_short_name: String,
2024 #[serde(skip_serializing_if = "Option::is_none")]
2025 business_connection_id: Option<String>,
2026 #[serde(skip_serializing_if = "Option::is_none")]
2027 message_thread_id: Option<i64>,
2028 #[serde(skip_serializing_if = "Option::is_none")]
2029 direct_messages_topic_id: Option<i64>,
2030 #[serde(skip_serializing_if = "Option::is_none")]
2031 disable_notification: Option<bool>,
2032 #[serde(skip_serializing_if = "Option::is_none")]
2033 protect_content: Option<bool>,
2034 #[serde(skip_serializing_if = "Option::is_none")]
2035 reply_parameters: Option<ReplyParameters>,
2036 #[serde(skip_serializing_if = "Option::is_none")]
2037 reply_markup: Option<rustigram_types::keyboard::InlineKeyboardMarkup>,
2038}
2039
2040pub struct SendGame {
2045 client: BotClient,
2046 params: SendGameParams,
2047}
2048
2049impl SendGame {
2050 pub(crate) fn new(client: BotClient, chat_id: i64, game_short_name: impl Into<String>) -> Self {
2051 Self {
2052 client,
2053 params: SendGameParams {
2054 chat_id,
2055 game_short_name: game_short_name.into(),
2056 business_connection_id: None,
2057 message_thread_id: None,
2058 direct_messages_topic_id: None,
2059 disable_notification: None,
2060 protect_content: None,
2061 reply_parameters: None,
2062 reply_markup: None,
2063 },
2064 }
2065 }
2066 pub fn business_connection_id(mut self, id: impl Into<String>) -> Self {
2068 self.params.business_connection_id = Some(id.into());
2069 self
2070 }
2071 pub fn message_thread_id(mut self, id: i64) -> Self {
2073 self.params.message_thread_id = Some(id);
2074 self
2075 }
2076 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
2078 self.params.direct_messages_topic_id = Some(id);
2079 self
2080 }
2081 pub fn disable_notification(mut self, v: bool) -> Self {
2083 self.params.disable_notification = Some(v);
2084 self
2085 }
2086 pub fn protect_content(mut self, v: bool) -> Self {
2088 self.params.protect_content = Some(v);
2089 self
2090 }
2091 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
2093 self.params.reply_parameters = Some(rp);
2094 self
2095 }
2096 pub fn reply_markup(mut self, m: rustigram_types::keyboard::InlineKeyboardMarkup) -> Self {
2098 self.params.reply_markup = Some(m);
2099 self
2100 }
2101}
2102
2103impl_into_future!(SendGame, Message, "sendGame");
2104
2105#[derive(Serialize)]
2108struct SendChecklistParams {
2109 business_connection_id: String,
2110 chat_id: i64,
2111 checklist: rustigram_types::checklist::InputChecklist,
2112 #[serde(skip_serializing_if = "Option::is_none")]
2113 direct_messages_topic_id: Option<i64>,
2114 #[serde(skip_serializing_if = "Option::is_none")]
2115 disable_notification: Option<bool>,
2116 #[serde(skip_serializing_if = "Option::is_none")]
2117 protect_content: Option<bool>,
2118 #[serde(skip_serializing_if = "Option::is_none")]
2119 message_effect_id: Option<String>,
2120 #[serde(skip_serializing_if = "Option::is_none")]
2121 reply_parameters: Option<ReplyParameters>,
2122 #[serde(skip_serializing_if = "Option::is_none")]
2123 reply_markup: Option<rustigram_types::keyboard::InlineKeyboardMarkup>,
2124 #[serde(skip_serializing_if = "Option::is_none")]
2125 suggested_post_parameters: Option<SuggestedPostParameters>,
2126}
2127
2128pub struct SendChecklist {
2133 client: BotClient,
2134 params: SendChecklistParams,
2135}
2136
2137impl SendChecklist {
2138 pub(crate) fn new(
2139 client: BotClient,
2140 business_connection_id: impl Into<String>,
2141 chat_id: i64,
2142 checklist: rustigram_types::checklist::InputChecklist,
2143 ) -> Self {
2144 Self {
2145 client,
2146 params: SendChecklistParams {
2147 business_connection_id: business_connection_id.into(),
2148 chat_id,
2149 checklist,
2150 direct_messages_topic_id: None,
2151 disable_notification: None,
2152 protect_content: None,
2153 message_effect_id: None,
2154 reply_parameters: None,
2155 reply_markup: None,
2156 suggested_post_parameters: None,
2157 },
2158 }
2159 }
2160 pub fn direct_messages_topic_id(mut self, id: i64) -> Self {
2162 self.params.direct_messages_topic_id = Some(id);
2163 self
2164 }
2165 pub fn disable_notification(mut self, v: bool) -> Self {
2167 self.params.disable_notification = Some(v);
2168 self
2169 }
2170 pub fn protect_content(mut self, v: bool) -> Self {
2172 self.params.protect_content = Some(v);
2173 self
2174 }
2175 pub fn message_effect_id(mut self, id: impl Into<String>) -> Self {
2177 self.params.message_effect_id = Some(id.into());
2178 self
2179 }
2180 pub fn reply_parameters(mut self, rp: ReplyParameters) -> Self {
2182 self.params.reply_parameters = Some(rp);
2183 self
2184 }
2185 pub fn reply_markup(mut self, m: rustigram_types::keyboard::InlineKeyboardMarkup) -> Self {
2187 self.params.reply_markup = Some(m);
2188 self
2189 }
2190 pub fn suggested_post_parameters(mut self, params: SuggestedPostParameters) -> Self {
2192 self.params.suggested_post_parameters = Some(params);
2193 self
2194 }
2195}
2196
2197impl_into_future!(SendChecklist, Message, "sendChecklist");