Skip to main content

rustigram_api/methods/
bot_settings.rs

1use rustigram_types::file::InputProfilePhoto;
2
3use crate::client::BotClient;
4use crate::error::Result;
5use reqwest::multipart::{Form, Part};
6use rustigram_types::keyboard::MenuButton;
7use rustigram_types::user::{
8    BotCommand, BotCommandScope, BotDescription, BotName, BotShortDescription,
9    ChatAdministratorRights, ChatId,
10};
11use serde::Serialize;
12use std::future::{Future, IntoFuture};
13use std::pin::Pin;
14
15// ─── Helper macro ─────────────────────────────────────────────────────────────
16
17/// Generates an `IntoFuture` impl that calls `BotClient::post_json`.
18macro_rules! impl_into_future {
19    ($builder:ident, $return_ty:ty, $method:literal) => {
20        impl IntoFuture for $builder {
21            type Output = Result<$return_ty>;
22            type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
23
24            fn into_future(self) -> Self::IntoFuture {
25                Box::pin(async move { self.client.post_json($method, &self.params).await })
26            }
27        }
28    };
29}
30
31// ─── setMyCommands ────────────────────────────────────────────────────────────
32
33#[derive(Serialize)]
34struct SetMyCommandsParams {
35    commands: Vec<BotCommand>,
36    #[serde(skip_serializing_if = "Option::is_none")]
37    scope: Option<BotCommandScope>,
38    #[serde(skip_serializing_if = "Option::is_none")]
39    language_code: Option<String>,
40}
41
42/// Builder for the [`setMyCommands`](https://core.telegram.org/bots/api#setmycommands) method.
43pub struct SetMyCommands {
44    client: BotClient,
45    params: SetMyCommandsParams,
46}
47
48impl SetMyCommands {
49    pub(crate) fn new(client: BotClient, commands: Vec<BotCommand>) -> Self {
50        Self {
51            client,
52            params: SetMyCommandsParams {
53                commands,
54                scope: None,
55                language_code: None,
56            },
57        }
58    }
59    /// Restricts these commands to a specific scope (chat type or individual chat).
60    pub fn scope(mut self, s: BotCommandScope) -> Self {
61        self.params.scope = Some(s);
62        self
63    }
64    /// Sets the language code for localised command lists (IETF tag, e.g. `"en"`).
65    pub fn language_code(mut self, lc: impl Into<String>) -> Self {
66        self.params.language_code = Some(lc.into());
67        self
68    }
69}
70
71impl_into_future!(SetMyCommands, bool, "setMyCommands");
72
73// ─── deleteMyCommands ─────────────────────────────────────────────────────────
74
75#[derive(Serialize, Default)]
76struct DeleteMyCommandsParams {
77    #[serde(skip_serializing_if = "Option::is_none")]
78    scope: Option<BotCommandScope>,
79    #[serde(skip_serializing_if = "Option::is_none")]
80    language_code: Option<String>,
81}
82
83/// Builder for the [`deleteMyCommands`](https://core.telegram.org/bots/api#deletemycommands) method.
84///
85/// Deletes the bot's command list for the given scope and language.
86/// After deletion, higher-level commands will be shown to affected users.
87pub struct DeleteMyCommands {
88    client: BotClient,
89    params: DeleteMyCommandsParams,
90}
91
92impl DeleteMyCommands {
93    pub(crate) fn new(client: BotClient) -> Self {
94        Self {
95            client,
96            params: Default::default(),
97        }
98    }
99    /// Restricts deletion to a specific scope.
100    pub fn scope(mut self, s: BotCommandScope) -> Self {
101        self.params.scope = Some(s);
102        self
103    }
104    /// Restricts deletion to a specific language code (IETF tag, e.g. `"en"`).
105    pub fn language_code(mut self, lc: impl Into<String>) -> Self {
106        self.params.language_code = Some(lc.into());
107        self
108    }
109}
110
111impl_into_future!(DeleteMyCommands, bool, "deleteMyCommands");
112
113// ─── getMyCommands ────────────────────────────────────────────────────────────
114
115#[derive(Serialize, Default)]
116struct GetMyCommandsParams {
117    #[serde(skip_serializing_if = "Option::is_none")]
118    scope: Option<BotCommandScope>,
119    #[serde(skip_serializing_if = "Option::is_none")]
120    language_code: Option<String>,
121}
122
123/// Builder for the [`getMyCommands`](https://core.telegram.org/bots/api#getmycommands) method.
124pub struct GetMyCommands {
125    client: BotClient,
126    params: GetMyCommandsParams,
127}
128
129impl GetMyCommands {
130    pub(crate) fn new(client: BotClient) -> Self {
131        Self {
132            client,
133            params: Default::default(),
134        }
135    }
136    /// Restricts the list of retrieved commands to a specific scope (chat type or individual chat).
137    pub fn scope(mut self, s: BotCommandScope) -> Self {
138        self.params.scope = Some(s);
139        self
140    }
141    /// The language code for localised command lists (IETF tag, e.g. `"en"`).
142    pub fn language_code(mut self, lc: impl Into<String>) -> Self {
143        self.params.language_code = Some(lc.into());
144        self
145    }
146}
147
148impl_into_future!(GetMyCommands, Vec<BotCommand>, "getMyCommands");
149
150// ─── setMyName ────────────────────────────────────────────────────────────────
151
152#[derive(Serialize, Default)]
153struct SetMyNameParams {
154    #[serde(skip_serializing_if = "Option::is_none")]
155    name: Option<String>,
156    #[serde(skip_serializing_if = "Option::is_none")]
157    language_code: Option<String>,
158}
159
160/// Builder for the [`setMyName`](https://core.telegram.org/bots/api#setmyname) method.
161pub struct SetMyName {
162    client: BotClient,
163    params: SetMyNameParams,
164}
165
166impl SetMyName {
167    pub(crate) fn new(client: BotClient) -> Self {
168        Self {
169            client,
170            params: Default::default(),
171        }
172    }
173    /// Sets the new bot name (up to 64 characters).
174    pub fn name(mut self, n: impl Into<String>) -> Self {
175        self.params.name = Some(n.into());
176        self
177    }
178    /// Sets the language code for localised bot names (IETF tag, e.g. `"en"`).
179    pub fn language_code(mut self, lc: impl Into<String>) -> Self {
180        self.params.language_code = Some(lc.into());
181        self
182    }
183}
184
185impl_into_future!(SetMyName, bool, "setMyName");
186
187// ─── getMyName ────────────────────────────────────────────────────────────────
188
189#[derive(Serialize, Default)]
190struct GetMyNameParams {
191    #[serde(skip_serializing_if = "Option::is_none")]
192    language_code: Option<String>,
193}
194
195/// Builder for the [`getMyName`](https://core.telegram.org/bots/api#getmyname) method.
196pub struct GetMyName {
197    client: BotClient,
198    params: GetMyNameParams,
199}
200
201impl GetMyName {
202    pub(crate) fn new(client: BotClient) -> Self {
203        Self {
204            client,
205            params: Default::default(),
206        }
207    }
208    /// The language code for the localised bot name to retrieve (IETF tag, e.g. `"en"`).
209    pub fn language_code(mut self, lc: impl Into<String>) -> Self {
210        self.params.language_code = Some(lc.into());
211        self
212    }
213}
214
215impl_into_future!(GetMyName, BotName, "getMyName");
216
217// ─── setMyDescription ─────────────────────────────────────────────────────────
218
219#[derive(Serialize, Default)]
220struct SetMyDescriptionParams {
221    #[serde(skip_serializing_if = "Option::is_none")]
222    description: Option<String>,
223    #[serde(skip_serializing_if = "Option::is_none")]
224    language_code: Option<String>,
225}
226
227/// Builder for the [`setMyDescription`](https://core.telegram.org/bots/api#setmydescription) method.
228pub struct SetMyDescription {
229    client: BotClient,
230    params: SetMyDescriptionParams,
231}
232
233impl SetMyDescription {
234    pub(crate) fn new(client: BotClient) -> Self {
235        Self {
236            client,
237            params: Default::default(),
238        }
239    }
240    /// Sets the new bot description shown on the profile page (up to 512 characters).
241    pub fn description(mut self, d: impl Into<String>) -> Self {
242        self.params.description = Some(d.into());
243        self
244    }
245    /// Sets the language code for localised bot descriptions (IETF tag, e.g. `"en"`).
246    pub fn language_code(mut self, lc: impl Into<String>) -> Self {
247        self.params.language_code = Some(lc.into());
248        self
249    }
250}
251
252impl_into_future!(SetMyDescription, bool, "setMyDescription");
253
254// ─── getMyDescription ─────────────────────────────────────────────────────────
255
256#[derive(Serialize, Default)]
257struct GetMyDescriptionParams {
258    #[serde(skip_serializing_if = "Option::is_none")]
259    language_code: Option<String>,
260}
261
262/// Builder for the [`getMyDescription`](https://core.telegram.org/bots/api#getmydescription) method.
263pub struct GetMyDescription {
264    client: BotClient,
265    params: GetMyDescriptionParams,
266}
267
268impl GetMyDescription {
269    pub(crate) fn new(client: BotClient) -> Self {
270        Self {
271            client,
272            params: Default::default(),
273        }
274    }
275    /// The language code for the localised bot description to retrieve (IETF tag, e.g. `"en"`).
276    pub fn language_code(mut self, lc: impl Into<String>) -> Self {
277        self.params.language_code = Some(lc.into());
278        self
279    }
280}
281
282impl_into_future!(GetMyDescription, BotDescription, "getMyDescription");
283
284// ─── setMyShortDescription ────────────────────────────────────────────────────
285
286#[derive(Serialize, Default)]
287struct SetMyShortDescriptionParams {
288    #[serde(skip_serializing_if = "Option::is_none")]
289    short_description: Option<String>,
290    #[serde(skip_serializing_if = "Option::is_none")]
291    language_code: Option<String>,
292}
293
294/// Builder for the [`setMyShortDescription`](https://core.telegram.org/bots/api#setmyshortdescription) method.
295///
296/// The short description is shown on the bot's profile page and sent with
297/// sharing links. Up to 120 characters; omit to remove the localised value.
298pub struct SetMyShortDescription {
299    client: BotClient,
300    params: SetMyShortDescriptionParams,
301}
302
303impl SetMyShortDescription {
304    pub(crate) fn new(client: BotClient) -> Self {
305        Self {
306            client,
307            params: Default::default(),
308        }
309    }
310    /// Sets the short description (0–120 characters). Omit to remove the dedicated value.
311    pub fn short_description(mut self, d: impl Into<String>) -> Self {
312        self.params.short_description = Some(d.into());
313        self
314    }
315    /// Sets the language code for the localised short description (IETF tag, e.g. `"en"`).
316    pub fn language_code(mut self, lc: impl Into<String>) -> Self {
317        self.params.language_code = Some(lc.into());
318        self
319    }
320}
321
322impl_into_future!(SetMyShortDescription, bool, "setMyShortDescription");
323
324// ─── getMyShortDescription ────────────────────────────────────────────────────
325
326#[derive(Serialize, Default)]
327struct GetMyShortDescriptionParams {
328    #[serde(skip_serializing_if = "Option::is_none")]
329    language_code: Option<String>,
330}
331
332/// Builder for the [`getMyShortDescription`](https://core.telegram.org/bots/api#getmyshortdescription) method.
333pub struct GetMyShortDescription {
334    client: BotClient,
335    params: GetMyShortDescriptionParams,
336}
337
338impl GetMyShortDescription {
339    pub(crate) fn new(client: BotClient) -> Self {
340        Self {
341            client,
342            params: Default::default(),
343        }
344    }
345    /// The language code for the localised short description to retrieve (IETF tag, e.g. `"en"`).
346    pub fn language_code(mut self, lc: impl Into<String>) -> Self {
347        self.params.language_code = Some(lc.into());
348        self
349    }
350}
351
352impl_into_future!(
353    GetMyShortDescription,
354    BotShortDescription,
355    "getMyShortDescription"
356);
357
358// ─── setMyDefaultAdministratorRights ─────────────────────────────────────────
359
360#[derive(Serialize, Default)]
361struct SetMyDefaultAdministratorRightsParams {
362    #[serde(skip_serializing_if = "Option::is_none")]
363    rights: Option<ChatAdministratorRights>,
364    #[serde(skip_serializing_if = "Option::is_none")]
365    for_channels: Option<bool>,
366}
367
368/// Builder for the [`setMyDefaultAdministratorRights`](https://core.telegram.org/bots/api#setmydefaultadministratorrights) method.
369///
370/// Sets the default administrator rights suggested to users when the bot is
371/// added as an administrator. Pass `None` rights to clear the defaults.
372pub struct SetMyDefaultAdministratorRights {
373    client: BotClient,
374    params: SetMyDefaultAdministratorRightsParams,
375}
376
377impl SetMyDefaultAdministratorRights {
378    pub(crate) fn new(client: BotClient) -> Self {
379        Self {
380            client,
381            params: Default::default(),
382        }
383    }
384    /// Sets the new default administrator rights. Omit to clear the current defaults.
385    pub fn rights(mut self, r: ChatAdministratorRights) -> Self {
386        self.params.rights = Some(r);
387        self
388    }
389    /// Pass `true` to change defaults for channels; otherwise changes group/supergroup defaults.
390    pub fn for_channels(mut self, v: bool) -> Self {
391        self.params.for_channels = Some(v);
392        self
393    }
394}
395
396impl_into_future!(
397    SetMyDefaultAdministratorRights,
398    bool,
399    "setMyDefaultAdministratorRights"
400);
401
402// ─── getMyDefaultAdministratorRights ─────────────────────────────────────────
403
404#[derive(Serialize, Default)]
405struct GetMyDefaultAdministratorRightsParams {
406    #[serde(skip_serializing_if = "Option::is_none")]
407    for_channels: Option<bool>,
408}
409
410/// Builder for the [`getMyDefaultAdministratorRights`](https://core.telegram.org/bots/api#getmydefaultadministratorrights) method.
411pub struct GetMyDefaultAdministratorRights {
412    client: BotClient,
413    params: GetMyDefaultAdministratorRightsParams,
414}
415
416impl GetMyDefaultAdministratorRights {
417    pub(crate) fn new(client: BotClient) -> Self {
418        Self {
419            client,
420            params: Default::default(),
421        }
422    }
423    /// Pass `true` to get default administrator rights for channels;
424    /// otherwise returns defaults for groups and supergroups.
425    pub fn for_channels(mut self, v: bool) -> Self {
426        self.params.for_channels = Some(v);
427        self
428    }
429}
430
431impl_into_future!(
432    GetMyDefaultAdministratorRights,
433    ChatAdministratorRights,
434    "getMyDefaultAdministratorRights"
435);
436
437// ─── getChatMenuButton ────────────────────────────────────────────────────────
438
439#[derive(Serialize, Default)]
440struct GetChatMenuButtonParams {
441    #[serde(skip_serializing_if = "Option::is_none")]
442    chat_id: Option<ChatId>,
443}
444
445/// Builder for the [`getChatMenuButton`](https://core.telegram.org/bots/api#getchatmenubutton) method.
446pub struct GetChatMenuButton {
447    client: BotClient,
448    params: GetChatMenuButtonParams,
449}
450
451impl GetChatMenuButton {
452    pub(crate) fn new(client: BotClient) -> Self {
453        Self {
454            client,
455            params: Default::default(),
456        }
457    }
458    /// Restricts the menu button query to a specific private chat.
459    pub fn chat_id(mut self, id: impl Into<ChatId>) -> Self {
460        self.params.chat_id = Some(id.into());
461        self
462    }
463}
464
465impl_into_future!(GetChatMenuButton, MenuButton, "getChatMenuButton");
466
467// ─── setChatMenuButton ────────────────────────────────────────────────────────
468
469#[derive(Serialize, Default)]
470struct SetChatMenuButtonParams {
471    #[serde(skip_serializing_if = "Option::is_none")]
472    chat_id: Option<i64>,
473    #[serde(skip_serializing_if = "Option::is_none")]
474    menu_button: Option<MenuButton>,
475}
476
477/// Builder for the [`setChatMenuButton`](https://core.telegram.org/bots/api#setchatmenubutton) method.
478///
479/// Changes the bot's menu button in a private chat, or the default menu button.
480/// Omit `chat_id` to change the default; omit `menu_button` to reset to `MenuButtonDefault`.
481pub struct SetChatMenuButton {
482    client: BotClient,
483    params: SetChatMenuButtonParams,
484}
485
486impl SetChatMenuButton {
487    pub(crate) fn new(client: BotClient) -> Self {
488        Self {
489            client,
490            params: Default::default(),
491        }
492    }
493    /// Targets a specific private chat. Omit to change the default menu button.
494    pub fn chat_id(mut self, id: i64) -> Self {
495        self.params.chat_id = Some(id);
496        self
497    }
498    /// Sets the new menu button. Omit to reset to `MenuButtonDefault`.
499    pub fn menu_button(mut self, btn: MenuButton) -> Self {
500        self.params.menu_button = Some(btn);
501        self
502    }
503}
504
505impl_into_future!(SetChatMenuButton, bool, "setChatMenuButton");
506
507// ─── logOut ───────────────────────────────────────────────────────────────────
508
509/// Builder for the [`logOut`](https://core.telegram.org/bots/api#logout) method.
510///
511/// Logs out from the cloud Bot API server. Must be called before running the
512/// bot locally. After a successful call the bot cannot log back in to the cloud
513/// server for 10 minutes.
514pub struct LogOut {
515    client: BotClient,
516}
517
518impl LogOut {
519    pub(crate) fn new(client: BotClient) -> Self {
520        Self { client }
521    }
522}
523
524impl IntoFuture for LogOut {
525    type Output = Result<bool>;
526    type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
527
528    fn into_future(self) -> Self::IntoFuture {
529        Box::pin(async move {
530            self.client
531                .post_json("logOut", &serde_json::json!({}))
532                .await
533        })
534    }
535}
536
537// ─── close ────────────────────────────────────────────────────────────────────
538
539/// Builder for the [`close`](https://core.telegram.org/bots/api#close) method.
540///
541/// Closes the bot instance before moving it to another local server. Delete
542/// the webhook before calling this to prevent the bot from restarting.
543/// Returns error 429 in the first 10 minutes after launch.
544pub struct Close {
545    client: BotClient,
546}
547
548impl Close {
549    pub(crate) fn new(client: BotClient) -> Self {
550        Self { client }
551    }
552}
553
554impl IntoFuture for Close {
555    type Output = Result<bool>;
556    type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
557
558    fn into_future(self) -> Self::IntoFuture {
559        Box::pin(async move { self.client.post_json("close", &serde_json::json!({})).await })
560    }
561}
562
563// ─── setMyProfilePhoto ────────────────────────────────────────────────────────
564
565/// Builder for the [`setMyProfilePhoto`](https://core.telegram.org/bots/api#setmyprofilephoto) method (Bot API 9.4).
566///
567/// Changes the profile photo of the bot. The photo must be uploaded via
568/// multipart/form-data as an `InputProfilePhoto`.
569pub struct SetMyProfilePhoto {
570    client: BotClient,
571    photo: InputProfilePhoto,
572}
573
574impl SetMyProfilePhoto {
575    pub(crate) fn new(client: BotClient, photo: InputProfilePhoto) -> Self {
576        Self { client, photo }
577    }
578}
579
580impl IntoFuture for SetMyProfilePhoto {
581    type Output = Result<bool>;
582    type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
583
584    fn into_future(self) -> Self::IntoFuture {
585        Box::pin(async move {
586            let photo =
587                serde_json::to_string(&self.photo).map_err(crate::error::Error::Serialization)?;
588            let part = Part::text(photo)
589                .mime_str("application/json")
590                .map_err(|e| crate::error::Error::Decode(e.to_string()))?;
591            let form = Form::new().part("photo", part);
592            self.client.post_multipart("setMyProfilePhoto", form).await
593        })
594    }
595}
596
597// ─── removeMyProfilePhoto ─────────────────────────────────────────────────────
598
599/// Builder for the [`removeMyProfilePhoto`](https://core.telegram.org/bots/api#removemyprofilephoto) method (Bot API 9.4).
600///
601/// Removes the current profile photo of the bot. Requires no parameters.
602pub struct RemoveMyProfilePhoto {
603    client: BotClient,
604}
605
606impl RemoveMyProfilePhoto {
607    pub(crate) fn new(client: BotClient) -> Self {
608        Self { client }
609    }
610}
611
612impl IntoFuture for RemoveMyProfilePhoto {
613    type Output = Result<bool>;
614    type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
615
616    fn into_future(self) -> Self::IntoFuture {
617        Box::pin(async move {
618            self.client
619                .post_json("removeMyProfilePhoto", &serde_json::json!({}))
620                .await
621        })
622    }
623}
624
625// ─── replaceManagedBotToken ───────────────────────────────────────────────────
626
627#[derive(Serialize)]
628struct ReplaceManagedBotTokenParams {
629    user_id: i64,
630}
631
632/// Builder for the [`replaceManagedBotToken`](https://core.telegram.org/bots/api#replacemanagedbottoken) method (Bot API 9.6).
633///
634/// Revokes the current token of a managed bot and generates a new one.
635/// Returns the new token as a `String`.
636pub struct ReplaceManagedBotToken {
637    client: BotClient,
638    params: ReplaceManagedBotTokenParams,
639}
640
641impl ReplaceManagedBotToken {
642    pub(crate) fn new(client: BotClient, user_id: i64) -> Self {
643        Self {
644            client,
645            params: ReplaceManagedBotTokenParams { user_id },
646        }
647    }
648}
649
650impl_into_future!(ReplaceManagedBotToken, String, "replaceManagedBotToken");
651
652// ─── getManagedBotToken ───────────────────────────────────────────────────────
653
654#[derive(Serialize)]
655struct GetManagedBotTokenParams {
656    user_id: i64,
657}
658
659/// Builder for the [`getManagedBotToken`](https://core.telegram.org/bots/api#getmanagedbottoken) method (Bot API 9.6).
660pub struct GetManagedBotToken {
661    client: BotClient,
662    params: GetManagedBotTokenParams,
663}
664
665impl GetManagedBotToken {
666    pub(crate) fn new(client: BotClient, user_id: i64) -> Self {
667        Self {
668            client,
669            params: GetManagedBotTokenParams { user_id },
670        }
671    }
672}
673
674impl_into_future!(GetManagedBotToken, String, "getManagedBotToken");
675
676// ─── getManagedBotAccessSettings ─────────────────────────────────────────────
677
678#[derive(serde::Serialize)]
679struct GetManagedBotAccessSettingsParams {
680    user_id: i64,
681}
682
683/// Builder for the [`getManagedBotAccessSettings`](https://core.telegram.org/bots/api#getmanagedbotaccesssettings) method (Bot API 9.7).
684///
685/// Returns the access settings of a managed bot.
686pub struct GetManagedBotAccessSettings {
687    client: BotClient,
688    params: GetManagedBotAccessSettingsParams,
689}
690
691impl GetManagedBotAccessSettings {
692    pub(crate) fn new(client: BotClient, user_id: i64) -> Self {
693        Self {
694            client,
695            params: GetManagedBotAccessSettingsParams { user_id },
696        }
697    }
698}
699
700impl IntoFuture for GetManagedBotAccessSettings {
701    type Output = crate::error::Result<rustigram_types::user::BotAccessSettings>;
702    type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
703    fn into_future(self) -> Self::IntoFuture {
704        Box::pin(async move {
705            self.client
706                .post_json("getManagedBotAccessSettings", &self.params)
707                .await
708        })
709    }
710}
711
712// ─── setManagedBotAccessSettings ─────────────────────────────────────────────
713
714#[derive(serde::Serialize)]
715struct SetManagedBotAccessSettingsParams {
716    user_id: i64,
717    is_access_restricted: bool,
718    #[serde(skip_serializing_if = "Option::is_none")]
719    added_user_ids: Option<Vec<i64>>,
720}
721
722/// Builder for the [`setManagedBotAccessSettings`](https://core.telegram.org/bots/api#setmanagedbotaccesssettings) method (Bot API 9.7).
723///
724/// Changes the access settings of a managed bot.
725pub struct SetManagedBotAccessSettings {
726    client: BotClient,
727    params: SetManagedBotAccessSettingsParams,
728}
729
730impl SetManagedBotAccessSettings {
731    pub(crate) fn new(client: BotClient, user_id: i64, is_access_restricted: bool) -> Self {
732        Self {
733            client,
734            params: SetManagedBotAccessSettingsParams {
735                user_id,
736                is_access_restricted,
737                added_user_ids: None,
738            },
739        }
740    }
741
742    /// Up to 10 user IDs who will have access to the bot in addition to its owner.
743    /// Ignored if `is_access_restricted` is `false`.
744    pub fn added_user_ids(mut self, ids: Vec<i64>) -> Self {
745        self.params.added_user_ids = Some(ids);
746        self
747    }
748}
749
750impl IntoFuture for SetManagedBotAccessSettings {
751    type Output = crate::error::Result<bool>;
752    type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send>>;
753    fn into_future(self) -> Self::IntoFuture {
754        Box::pin(async move {
755            self.client
756                .post_json("setManagedBotAccessSettings", &self.params)
757                .await
758        })
759    }
760}