1use std::{error::Error, fmt};
2
3use serde::{Deserialize, Serialize};
4
5use crate::{
6 api::{Form, Method, Payload},
7 types::{ChatAdministratorRights, ChatId, InputProfilePhoto, InputProfilePhotoError, Integer, StarAmount, User},
8};
9
10#[serde_with::skip_serializing_none]
12#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
13pub struct Bot {
14 pub first_name: String,
16 pub id: Integer,
18 pub username: String,
20 pub allows_users_to_create_topics: bool,
22 pub can_connect_to_business: bool,
24 pub can_join_groups: bool,
26 pub can_manage_bots: bool,
28 pub can_read_all_group_messages: bool,
30 pub has_main_web_app: bool,
32 pub has_topics_enabled: bool,
34 pub last_name: Option<String>,
36 pub supports_guest_queries: bool,
38 pub supports_inline_queries: bool,
40 pub supports_join_request_queries: bool,
42}
43
44impl Bot {
45 pub fn new<A, B>(id: Integer, username: A, first_name: B) -> Self
53 where
54 A: Into<String>,
55 B: Into<String>,
56 {
57 Self {
58 first_name: first_name.into(),
59 id,
60 username: username.into(),
61 allows_users_to_create_topics: false,
62 can_connect_to_business: false,
63 can_join_groups: false,
64 can_manage_bots: false,
65 can_read_all_group_messages: false,
66 has_main_web_app: false,
67 has_topics_enabled: false,
68 last_name: None,
69 supports_guest_queries: false,
70 supports_inline_queries: false,
71 supports_join_request_queries: false,
72 }
73 }
74
75 pub fn with_allows_users_to_create_topics(mut self, value: bool) -> Self {
81 self.allows_users_to_create_topics = value;
82 self
83 }
84
85 pub fn with_can_connect_to_business(mut self, value: bool) -> Self {
91 self.can_connect_to_business = value;
92 self
93 }
94
95 pub fn with_can_join_groups(mut self, value: bool) -> Self {
101 self.can_join_groups = value;
102 self
103 }
104
105 pub fn with_can_manage_bots(mut self, value: bool) -> Self {
111 self.can_manage_bots = value;
112 self
113 }
114
115 pub fn with_can_read_all_group_messages(mut self, value: bool) -> Self {
121 self.can_read_all_group_messages = value;
122 self
123 }
124
125 pub fn with_has_main_web_app(mut self, value: bool) -> Self {
131 self.has_main_web_app = value;
132 self
133 }
134
135 pub fn with_has_topics_enabled(mut self, value: bool) -> Self {
141 self.has_topics_enabled = value;
142 self
143 }
144
145 pub fn with_last_name<T>(mut self, value: T) -> Self
151 where
152 T: Into<String>,
153 {
154 self.last_name = Some(value.into());
155 self
156 }
157
158 pub fn with_supports_guest_queries(mut self, value: bool) -> Self {
164 self.supports_guest_queries = value;
165 self
166 }
167
168 pub fn with_supports_inline_queries(mut self, value: bool) -> Self {
174 self.supports_inline_queries = value;
175 self
176 }
177
178 pub fn with_supports_join_request_queries(mut self, value: bool) -> Self {
184 self.supports_join_request_queries = value;
185 self
186 }
187}
188
189#[serde_with::skip_serializing_none]
191#[derive(Clone, Debug, Default, Deserialize, Serialize)]
192pub struct BotAccessSettings {
193 pub is_access_restricted: bool,
197 pub added_users: Option<Vec<User>>,
199}
200
201impl BotAccessSettings {
202 pub fn with_added_users<T>(mut self, value: T) -> Self
208 where
209 T: IntoIterator<Item = User>,
210 {
211 self.added_users = Some(value.into_iter().collect());
212 self
213 }
214
215 pub fn with_is_access_restricted(mut self, value: bool) -> Self {
221 self.is_access_restricted = value;
222 self
223 }
224}
225
226#[derive(Clone, Debug, Deserialize, Serialize)]
228pub struct BotCommand {
229 #[serde(rename = "command")]
230 name: String,
231 description: String,
232}
233
234impl BotCommand {
235 const MIN_NAME_LEN: usize = 1;
236 const MAX_NAME_LEN: usize = 32;
237 const MIN_DESCRIPTION_LEN: usize = 3;
238 const MAX_DESCRIPTION_LEN: usize = 256;
239
240 pub fn new<C, D>(name: C, description: D) -> Result<Self, BotCommandError>
248 where
249 C: Into<String>,
250 D: Into<String>,
251 {
252 let name = name.into();
253 let description = description.into();
254 let name_len = name.len();
255 let description_len = description.len();
256 if !(Self::MIN_NAME_LEN..=Self::MAX_NAME_LEN).contains(&name_len) {
257 Err(BotCommandError::BadNameLen(name_len))
258 } else if !(Self::MIN_DESCRIPTION_LEN..=Self::MAX_DESCRIPTION_LEN).contains(&description_len) {
259 Err(BotCommandError::BadDescriptionLen(description_len))
260 } else {
261 Ok(Self { name, description })
262 }
263 }
264
265 pub fn name(&self) -> &str {
267 &self.name
268 }
269
270 pub fn with_name<T>(mut self, value: T) -> Self
276 where
277 T: Into<String>,
278 {
279 self.name = value.into();
280 self
281 }
282
283 pub fn description(&self) -> &str {
285 &self.description
286 }
287
288 pub fn with_description<T>(mut self, value: T) -> Self
294 where
295 T: Into<String>,
296 {
297 self.description = value.into();
298 self
299 }
300}
301
302#[derive(Debug)]
304pub enum BotCommandError {
305 BadNameLen(usize),
307 BadDescriptionLen(usize),
309}
310
311impl Error for BotCommandError {}
312
313impl fmt::Display for BotCommandError {
314 fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {
315 use self::BotCommandError::*;
316 match self {
317 BadNameLen(len) => write!(
318 out,
319 "command name can have a length of {} up to {} characters, got {}",
320 BotCommand::MIN_NAME_LEN,
321 BotCommand::MAX_NAME_LEN,
322 len
323 ),
324 BadDescriptionLen(len) => write!(
325 out,
326 "command description can have a length of {} up to {} characters, got {}",
327 BotCommand::MIN_DESCRIPTION_LEN,
328 BotCommand::MAX_DESCRIPTION_LEN,
329 len
330 ),
331 }
332 }
333}
334
335#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
337#[serde(tag = "type")]
338#[serde(rename_all = "snake_case")]
339pub enum BotCommandScope {
340 AllChatAdministrators,
342 AllGroupChats,
344 AllPrivateChats,
346 Chat {
348 chat_id: ChatId,
350 },
351 ChatAdministrators {
353 chat_id: ChatId,
355 },
356 ChatMember {
358 chat_id: ChatId,
360 user_id: Integer,
362 },
363 Default,
367}
368
369impl BotCommandScope {
370 pub fn chat<T>(value: T) -> Self
376 where
377 T: Into<ChatId>,
378 {
379 Self::Chat { chat_id: value.into() }
380 }
381
382 pub fn chat_administrators<T>(value: T) -> Self
389 where
390 T: Into<ChatId>,
391 {
392 Self::ChatAdministrators { chat_id: value.into() }
393 }
394
395 pub fn chat_member<A>(chat_id: A, user_id: Integer) -> Self
402 where
403 A: Into<ChatId>,
404 {
405 Self::ChatMember {
406 chat_id: chat_id.into(),
407 user_id,
408 }
409 }
410}
411
412#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
414pub struct BotDescription {
415 pub description: String,
417}
418
419impl BotDescription {
420 pub fn new<T>(value: T) -> Self
426 where
427 T: Into<String>,
428 {
429 Self {
430 description: value.into(),
431 }
432 }
433}
434
435#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
437pub struct BotName {
438 pub name: String,
440}
441
442impl BotName {
443 pub fn new<T>(value: T) -> Self
449 where
450 T: Into<String>,
451 {
452 Self { name: value.into() }
453 }
454}
455
456#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
458pub struct BotShortDescription {
459 pub short_description: String,
461}
462
463impl BotShortDescription {
464 pub fn new<T>(value: T) -> Self
470 where
471 T: Into<String>,
472 {
473 Self {
474 short_description: value.into(),
475 }
476 }
477}
478
479#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
482pub struct ManagedBotUpdated {
483 pub bot: User,
485 pub user: User,
487}
488
489#[derive(Clone, Copy, Debug)]
496pub struct Close;
497
498impl Method for Close {
499 type Response = bool;
500
501 fn into_payload(self) -> Payload {
502 Payload::empty("close")
503 }
504}
505
506#[serde_with::skip_serializing_none]
510#[derive(Clone, Debug, Default, Serialize)]
511pub struct DeleteBotCommands {
512 language_code: Option<String>,
513 scope: Option<BotCommandScope>,
514}
515
516impl DeleteBotCommands {
517 pub fn with_language_code<T>(mut self, value: T) -> Self
523 where
524 T: Into<String>,
525 {
526 self.language_code = Some(value.into());
527 self
528 }
529
530 pub fn with_scope(mut self, value: BotCommandScope) -> Self {
536 self.scope = Some(value);
537 self
538 }
539}
540
541impl Method for DeleteBotCommands {
542 type Response = bool;
543
544 fn into_payload(self) -> Payload {
545 Payload::json("deleteMyCommands", self)
546 }
547}
548
549#[derive(Clone, Copy, Debug)]
551pub struct GetBot;
552
553impl Method for GetBot {
554 type Response = Bot;
555
556 fn into_payload(self) -> Payload {
557 Payload::empty("getMe")
558 }
559}
560
561#[serde_with::skip_serializing_none]
563#[derive(Clone, Debug, Default, Serialize)]
564pub struct GetBotCommands {
565 language_code: Option<String>,
566 scope: Option<BotCommandScope>,
567}
568
569impl GetBotCommands {
570 pub fn with_language_code<T>(mut self, value: T) -> Self
576 where
577 T: Into<String>,
578 {
579 self.language_code = Some(value.into());
580 self
581 }
582
583 pub fn with_scope(mut self, value: BotCommandScope) -> Self {
589 self.scope = Some(value);
590 self
591 }
592}
593
594impl Method for GetBotCommands {
595 type Response = Vec<BotCommand>;
596
597 fn into_payload(self) -> Payload {
598 Payload::json("getMyCommands", self)
599 }
600}
601
602#[serde_with::skip_serializing_none]
604#[derive(Clone, Copy, Debug, Default, Serialize)]
605pub struct GetBotDefaultAdministratorRights {
606 for_channels: Option<bool>,
607}
608
609impl GetBotDefaultAdministratorRights {
610 pub fn with_for_channels(mut self, value: bool) -> Self {
616 self.for_channels = Some(value);
617 self
618 }
619}
620
621impl Method for GetBotDefaultAdministratorRights {
622 type Response = ChatAdministratorRights;
623
624 fn into_payload(self) -> Payload {
625 Payload::json("getMyDefaultAdministratorRights", self)
626 }
627}
628
629#[serde_with::skip_serializing_none]
631#[derive(Clone, Debug, Default, Serialize)]
632pub struct GetBotDescription {
633 language_code: Option<String>,
634}
635
636impl GetBotDescription {
637 pub fn with_language_code<T>(mut self, value: T) -> Self
643 where
644 T: Into<String>,
645 {
646 self.language_code = Some(value.into());
647 self
648 }
649}
650
651impl Method for GetBotDescription {
652 type Response = BotDescription;
653
654 fn into_payload(self) -> Payload {
655 Payload::json("getMyDescription", self)
656 }
657}
658
659#[serde_with::skip_serializing_none]
661#[derive(Clone, Debug, Default, Serialize)]
662pub struct GetBotName {
663 language_code: Option<String>,
664}
665
666impl GetBotName {
667 pub fn with_language_code<T>(mut self, value: T) -> Self
673 where
674 T: Into<String>,
675 {
676 self.language_code = Some(value.into());
677 self
678 }
679}
680
681impl Method for GetBotName {
682 type Response = BotName;
683
684 fn into_payload(self) -> Payload {
685 Payload::json("getMyName", self)
686 }
687}
688
689#[serde_with::skip_serializing_none]
691#[derive(Clone, Debug, Default, Serialize)]
692pub struct GetBotShortDescription {
693 language_code: Option<String>,
694}
695
696impl GetBotShortDescription {
697 pub fn with_language_code<T>(mut self, value: T) -> Self
703 where
704 T: Into<String>,
705 {
706 self.language_code = Some(value.into());
707 self
708 }
709}
710
711impl Method for GetBotShortDescription {
712 type Response = BotShortDescription;
713
714 fn into_payload(self) -> Payload {
715 Payload::json("getMyShortDescription", self)
716 }
717}
718
719#[derive(Clone, Copy, Debug)]
721pub struct GetBotStarBalance;
722
723impl Method for GetBotStarBalance {
724 type Response = StarAmount;
725
726 fn into_payload(self) -> Payload {
727 Payload::empty("getMyStarBalance")
728 }
729}
730
731#[derive(Clone, Copy, Debug, Serialize)]
733pub struct GetManagedBotAccessSettings {
734 user_id: Integer,
735}
736
737impl From<Integer> for GetManagedBotAccessSettings {
738 fn from(value: Integer) -> Self {
739 Self { user_id: value }
740 }
741}
742
743impl Method for GetManagedBotAccessSettings {
744 type Response = BotAccessSettings;
745
746 fn into_payload(self) -> Payload {
747 Payload::json("getManagedBotAccessSettings", self)
748 }
749}
750
751#[derive(Clone, Copy, Debug, Serialize)]
753pub struct GetManagedBotToken {
754 user_id: Integer,
755}
756
757impl From<Integer> for GetManagedBotToken {
758 fn from(value: Integer) -> Self {
759 Self { user_id: value }
760 }
761}
762
763impl Method for GetManagedBotToken {
764 type Response = String;
765
766 fn into_payload(self) -> Payload {
767 Payload::json("getManagedBotToken", self)
768 }
769}
770
771#[derive(Clone, Copy, Debug)]
779pub struct LogOut;
780
781impl Method for LogOut {
782 type Response = bool;
783
784 fn into_payload(self) -> Payload {
785 Payload::empty("logOut")
786 }
787}
788
789#[derive(Clone, Copy, Debug, Serialize)]
791pub struct ReplaceManagedBotToken {
792 user_id: Integer,
793}
794
795impl From<Integer> for ReplaceManagedBotToken {
796 fn from(value: Integer) -> Self {
797 Self { user_id: value }
798 }
799}
800
801impl Method for ReplaceManagedBotToken {
802 type Response = String;
803
804 fn into_payload(self) -> Payload {
805 Payload::json("replaceManagedBotToken", self)
806 }
807}
808
809#[serde_with::skip_serializing_none]
811#[derive(Clone, Debug, Serialize)]
812pub struct SetBotCommands {
813 commands: Vec<BotCommand>,
814 language_code: Option<String>,
815 scope: Option<BotCommandScope>,
816}
817
818impl SetBotCommands {
819 pub fn new(commands: impl IntoIterator<Item = BotCommand>) -> Self {
825 Self {
826 commands: commands.into_iter().collect(),
827 language_code: None,
828 scope: None,
829 }
830 }
831
832 pub fn with_language_code<T>(mut self, value: T) -> Self
840 where
841 T: Into<String>,
842 {
843 self.language_code = Some(value.into());
844 self
845 }
846
847 pub fn with_scope(mut self, value: BotCommandScope) -> Self {
854 self.scope = Some(value);
855 self
856 }
857}
858
859impl Method for SetBotCommands {
860 type Response = bool;
861
862 fn into_payload(self) -> Payload {
863 Payload::json("setMyCommands", self)
864 }
865}
866
867#[serde_with::skip_serializing_none]
873#[derive(Clone, Copy, Debug, Default, Serialize)]
874pub struct SetBotDefaultAdministratorRights {
875 for_channels: Option<bool>,
876 rights: Option<ChatAdministratorRights>,
877}
878
879impl SetBotDefaultAdministratorRights {
880 pub fn with_for_channels(mut self, value: bool) -> Self {
886 self.for_channels = Some(value);
887 self
888 }
889
890 pub fn with_rights(mut self, value: ChatAdministratorRights) -> Self {
897 self.rights = Some(value);
898 self
899 }
900}
901
902impl Method for SetBotDefaultAdministratorRights {
903 type Response = bool;
904
905 fn into_payload(self) -> Payload {
906 Payload::json("setMyDefaultAdministratorRights", self)
907 }
908}
909
910#[serde_with::skip_serializing_none]
912#[derive(Clone, Debug, Default, Serialize)]
913pub struct SetBotDescription {
914 description: Option<String>,
915 language_code: Option<String>,
916}
917
918impl SetBotDescription {
919 pub fn with_description<T>(mut self, value: T) -> Self
927 where
928 T: Into<String>,
929 {
930 self.description = Some(value.into());
931 self
932 }
933
934 pub fn with_language_code<T>(mut self, value: T) -> Self
942 where
943 T: Into<String>,
944 {
945 self.language_code = Some(value.into());
946 self
947 }
948}
949
950impl Method for SetBotDescription {
951 type Response = bool;
952
953 fn into_payload(self) -> Payload {
954 Payload::json("setMyDescription", self)
955 }
956}
957
958#[serde_with::skip_serializing_none]
960#[derive(Clone, Debug, Default, Serialize)]
961pub struct SetBotName {
962 language_code: Option<String>,
963 name: Option<String>,
964}
965
966impl SetBotName {
967 pub fn with_language_code<T>(mut self, value: T) -> Self
975 where
976 T: Into<String>,
977 {
978 self.language_code = Some(value.into());
979 self
980 }
981
982 pub fn with_name<T>(mut self, value: T) -> Self
990 where
991 T: Into<String>,
992 {
993 self.name = Some(value.into());
994 self
995 }
996}
997
998impl Method for SetBotName {
999 type Response = bool;
1000
1001 fn into_payload(self) -> Payload {
1002 Payload::json("setMyName", self)
1003 }
1004}
1005
1006#[derive(Debug)]
1008pub struct SetBotProfilePhoto {
1009 form: Form,
1010}
1011
1012impl SetBotProfilePhoto {
1013 pub fn new<T>(photo: T) -> Result<Self, InputProfilePhotoError>
1019 where
1020 T: Into<InputProfilePhoto>,
1021 {
1022 let form = Form::try_from(photo.into())?;
1023 Ok(Self { form })
1024 }
1025}
1026
1027impl Method for SetBotProfilePhoto {
1028 type Response = bool;
1029
1030 fn into_payload(self) -> Payload {
1031 Payload::form("setMyProfilePhoto", self.form)
1032 }
1033}
1034
1035#[serde_with::skip_serializing_none]
1038#[derive(Clone, Debug, Default, Serialize)]
1039pub struct SetBotShortDescription {
1040 language_code: Option<String>,
1041 short_description: Option<String>,
1042}
1043
1044impl SetBotShortDescription {
1045 pub fn with_language_code<T>(mut self, value: T) -> Self
1053 where
1054 T: Into<String>,
1055 {
1056 self.language_code = Some(value.into());
1057 self
1058 }
1059
1060 pub fn with_short_description<T>(mut self, value: T) -> Self
1068 where
1069 T: Into<String>,
1070 {
1071 self.short_description = Some(value.into());
1072 self
1073 }
1074}
1075
1076impl Method for SetBotShortDescription {
1077 type Response = bool;
1078
1079 fn into_payload(self) -> Payload {
1080 Payload::json("setMyShortDescription", self)
1081 }
1082}
1083
1084#[serde_with::skip_serializing_none]
1086#[derive(Clone, Debug, Serialize)]
1087pub struct SetManagedBotAccessSettings {
1088 user_id: Integer,
1089 is_access_restricted: bool,
1090 added_user_ids: Option<Vec<Integer>>,
1091}
1092
1093impl SetManagedBotAccessSettings {
1094 pub fn new(user_id: Integer, is_access_restricted: bool) -> Self {
1102 Self {
1103 user_id,
1104 is_access_restricted,
1105 added_user_ids: None,
1106 }
1107 }
1108
1109 pub fn with_added_user_ids<T>(mut self, value: T) -> Self
1117 where
1118 T: IntoIterator<Item = Integer>,
1119 {
1120 self.added_user_ids = Some(value.into_iter().collect());
1121 self
1122 }
1123}
1124
1125impl Method for SetManagedBotAccessSettings {
1126 type Response = bool;
1127
1128 fn into_payload(self) -> Payload {
1129 Payload::json("setManagedBotAccessSettings", self)
1130 }
1131}
1132
1133#[derive(Clone, Copy, Debug, Serialize)]
1135pub struct RemoveBotProfilePhoto;
1136
1137impl Method for RemoveBotProfilePhoto {
1138 type Response = bool;
1139
1140 fn into_payload(self) -> Payload {
1141 Payload::empty("removeMyProfilePhoto")
1142 }
1143}