Skip to main content

telegram_api_rs/
methods.rs

1//! This module contains all available methods to use the Bot API</br>
2//! To get started, you first have to create a bot
3//! ```ignore
4//! let bot = Bot::new("your_bot_api_key".to_json());
5//! ```
6//! Afterwards you can use the bot, e.g.:
7//! ```ignore
8//! bot.get_me();
9//! ```
10
11extern crate json;
12extern crate rustc_serialize;
13extern crate urlencoding;
14
15use crate::objects::*;
16use crate::*;
17use json::JsonValue;
18use std::sync::mpsc::Sender;
19
20pub struct Bot {
21    key: String,
22    offset: i64,
23}
24
25const BASE_URL: &str = "https://api.telegram.org/bot";
26
27impl Bot {
28    pub fn new(api_key: String) -> Bot {
29        Bot {
30            key: api_key,
31            offset: 0,
32        }
33    }
34
35    /// start_polling is used to get updates from the bot.
36    /// ```ignore
37    /// let (tx, rx) = mpsc::channel();
38    /// bot.start_polling(tx);
39    /// let received = rx.recv().unwrap();
40    /// println!("Got: {}", received);
41    /// ```
42    pub fn start_polling(
43        &mut self,
44        tx: Sender<Update>,
45    ) -> Result<std::thread::JoinHandle<()>, Box<dyn std::error::Error>> {
46        let mut bot = self.clone();
47        let thread_builder = std::thread::Builder::new()
48            .name("telegram-api-rs::start_polling loop thread".into())
49            .stack_size(8 * 1024 * 1024);
50        let handle = thread_builder.spawn(move || loop {
51            if let Some(us) = bot.get_updates(None, None, None) {
52                for u in us {
53                    assert!(tx.send(u).is_ok());
54                }
55            }
56        })?;
57
58        Ok(handle)
59    }
60
61    fn send_request(&self, method: String, parameters: String) -> JsonValue {
62        let request = format!("{}{}/{}?{}", BASE_URL, self.key, method, parameters);
63        // println!("{}", request);
64        let res = reqwest::blocking::get(request);
65        let mut json_response = JsonValue::Null;
66        if let Ok(r) = res {
67            if let Ok(result) = r.text() {
68                if let Ok(parsed) = json::parse(&result) {
69                    json_response = parsed;
70                }
71            }
72        }
73        json_response
74    }
75
76    pub fn get_updates(
77        &mut self,
78        limit: Option<i32>,
79        timeout: Option<i32>,
80        allowed_updates: Option<Vec<String>>,
81    ) -> Option<Vec<Update>> {
82        let mut parameters = "".to_string();
83        parameters.push_str(&format!("offset={}&", self.offset));
84        if let Some(o) = limit {
85            parameters.push_str(&format!("limit={}&", Custom::to_json(o)));
86        }
87        if let Some(o) = timeout {
88            parameters.push_str(&format!("timeout={}&", Custom::to_json(o)));
89        }
90        if let Some(o) = allowed_updates {
91            parameters.push_str(&format!("allowed_updates={}&", Custom::to_json(o)));
92        }
93        parameters.pop();
94        let res = self.send_request("getUpdates".to_string(), parameters);
95        let ret: Vec<Update> = Custom::from_json(res["result"].clone());
96        if !res["ok"].as_bool().unwrap_or(false) || ret.is_empty() {
97            None
98        } else {
99            self.offset = ret[ret.len() - 1].clone().update_id + 1;
100            self.send_request("getUpdates".to_string(), format!("offset={}", self.offset));
101            Some(ret)
102        }
103    }
104
105    pub fn get_me(&mut self) -> User {
106        let res = self.send_request("getMe".to_string(), "".to_string());
107        if !res["ok"].as_bool().unwrap_or(false) {
108            User::empty()
109        } else {
110            let ret: User = Custom::from_json(res["result"].clone());
111            ret
112        }
113    }
114
115    pub fn send_message(
116        &mut self,
117        chat_id: i64,
118        text: String,
119        parse_mode: Option<String>,
120        entities: Option<Vec<MessageEntity>>,
121        disable_web_page_preview: Option<bool>,
122        disable_notification: Option<bool>,
123        reply_to_message_id: Option<i32>,
124        allow_sending_without_reply: Option<bool>,
125        reply_markup_ikm: Option<InlineKeyboardMarkup>,
126        reply_markup_rkm: Option<ReplyKeyboardMarkup>,
127        reply_markup_rkr: Option<ReplyKeyboardRemove>,
128        reply_markup_fr: Option<ForceReply>,
129    ) -> Option<Message> {
130        let mut parameters = "".to_string();
131        expand_parameters_into_string! {
132            parameters, chat_id, text
133        }
134        expand_parameters_opt_into_string! {
135            parameters, parse_mode, entities, disable_web_page_preview, disable_notification, reply_to_message_id,
136            allow_sending_without_reply
137        }
138        expand_parameters_reply_markup_into_string! {
139            parameters, reply_markup_ikm, reply_markup_rkm, reply_markup_rkr, reply_markup_fr
140        }
141        parameters.pop();
142        let res = self.send_request("sendMessage".to_string(), parameters);
143        expand_make_request_to_message! {
144            res
145        }
146    }
147
148    pub fn forward_message(
149        &mut self,
150        chat_id: i64,
151        from_chat_id: i64,
152        message_id: i32,
153        disable_notification: Option<bool>,
154    ) -> Option<Message> {
155        let mut parameters = "".to_string();
156        expand_parameters_into_string! {
157            parameters, chat_id, from_chat_id, message_id
158        }
159        expand_parameters_opt_into_string! {
160            parameters, disable_notification
161        }
162        parameters.pop();
163        let res = self.send_request("ForwardMessage".to_string(), parameters);
164        expand_make_request_to_message! {
165            res
166        }
167    }
168
169    pub fn copy_message(
170        &mut self,
171        chat_id: i64,
172        from_chat_id: i64,
173        message_id: i32,
174        caption: Option<String>,
175        parse_mode: Option<String>,
176        caption_entities: Option<Vec<MessageEntity>>,
177        disable_notification: Option<bool>,
178        reply_to_message_id: Option<i32>,
179        allow_sending_without_reply: Option<bool>,
180        reply_markup_ikm: Option<InlineKeyboardMarkup>,
181        reply_markup_rkm: Option<ReplyKeyboardMarkup>,
182        reply_markup_rkr: Option<ReplyKeyboardRemove>,
183        reply_markup_fr: Option<ForceReply>,
184    ) -> i32 {
185        let mut parameters = "".to_string();
186        expand_parameters_into_string! {
187            parameters, chat_id, from_chat_id, message_id
188        }
189        expand_parameters_opt_into_string! {
190            parameters, caption, parse_mode, caption_entities, disable_notification, reply_to_message_id,
191            allow_sending_without_reply
192        }
193        expand_parameters_reply_markup_into_string! {
194            parameters, reply_markup_ikm, reply_markup_rkm, reply_markup_rkr, reply_markup_fr
195        }
196        parameters.pop();
197        let res = self.send_request("copyMessage".to_string(), parameters);
198        if !res["ok"].as_bool().unwrap_or(false) {
199            0
200        } else {
201            let ret: i32 = Custom::from_json(res["result"].clone());
202            ret
203        }
204    }
205
206    pub fn send_photo(
207        &mut self,
208        chat_id: i64,
209        photo: String,
210        caption: Option<String>,
211        parse_mode: Option<String>,
212        caption_entities: Option<Vec<MessageEntity>>,
213        disable_notification: Option<bool>,
214        reply_to_message_id: Option<i32>,
215        allow_sending_without_reply: Option<bool>,
216        reply_markup_ikm: Option<InlineKeyboardMarkup>,
217        reply_markup_rkm: Option<ReplyKeyboardMarkup>,
218        reply_markup_rkr: Option<ReplyKeyboardRemove>,
219        reply_markup_fr: Option<ForceReply>,
220    ) -> Option<Message> {
221        let mut parameters = "".to_string();
222        expand_parameters_into_string! {
223            parameters, chat_id, photo
224        }
225        expand_parameters_opt_into_string! {
226            parameters, caption, parse_mode, caption_entities, disable_notification, reply_to_message_id,
227            allow_sending_without_reply
228        }
229        expand_parameters_reply_markup_into_string! {
230            parameters, reply_markup_ikm, reply_markup_rkm, reply_markup_rkr, reply_markup_fr
231        }
232        parameters.pop();
233        let res = self.send_request("sendPhoto".to_string(), parameters);
234        expand_make_request_to_message! {
235            res
236        }
237    }
238
239    pub fn send_audio(
240        &mut self,
241        chat_id: i64,
242        audio: String,
243        caption: Option<String>,
244        parse_mode: Option<String>,
245        caption_entities: Option<Vec<MessageEntity>>,
246        duration: Option<i32>,
247        performer: Option<String>,
248        title: Option<String>,
249        thumb: Option<String>,
250        disable_notification: Option<bool>,
251        reply_to_message_id: Option<i32>,
252        allow_sending_without_reply: Option<bool>,
253        reply_markup_ikm: Option<InlineKeyboardMarkup>,
254        reply_markup_rkm: Option<ReplyKeyboardMarkup>,
255        reply_markup_rkr: Option<ReplyKeyboardRemove>,
256        reply_markup_fr: Option<ForceReply>,
257    ) -> Option<Message> {
258        let mut parameters = "".to_string();
259        expand_parameters_into_string! {
260            parameters, chat_id, audio
261        }
262        expand_parameters_opt_into_string! {
263            parameters, caption, parse_mode, caption_entities, duration, performer, title, thumb, disable_notification, reply_to_message_id,
264            allow_sending_without_reply
265        }
266        expand_parameters_reply_markup_into_string! {
267            parameters, reply_markup_ikm, reply_markup_rkm, reply_markup_rkr, reply_markup_fr
268        }
269        parameters.pop();
270        let res = self.send_request("sendAudio".to_string(), parameters);
271        expand_make_request_to_message! {
272            res
273        }
274    }
275
276    pub fn send_document(
277        &mut self,
278        chat_id: i64,
279        document: String,
280        thumb: Option<String>,
281        caption: Option<String>,
282        parse_mode: Option<String>,
283        caption_entities: Option<Vec<MessageEntity>>,
284        disable_content_type_detection: Option<bool>,
285        disable_notification: Option<bool>,
286        reply_to_message_id: Option<i32>,
287        allow_sending_without_reply: Option<bool>,
288        reply_markup_ikm: Option<InlineKeyboardMarkup>,
289        reply_markup_rkm: Option<ReplyKeyboardMarkup>,
290        reply_markup_rkr: Option<ReplyKeyboardRemove>,
291        reply_markup_fr: Option<ForceReply>,
292    ) -> Option<Message> {
293        let mut parameters = "".to_string();
294        expand_parameters_into_string! {
295            parameters, chat_id, document
296        }
297        expand_parameters_opt_into_string! {
298            parameters, thumb, caption, parse_mode, caption_entities, disable_content_type_detection, disable_notification,
299            reply_to_message_id, allow_sending_without_reply
300        }
301        expand_parameters_reply_markup_into_string! {
302            parameters, reply_markup_ikm, reply_markup_rkm, reply_markup_rkr, reply_markup_fr
303        }
304        parameters.pop();
305        let res = self.send_request("sendDocument".to_string(), parameters);
306        expand_make_request_to_message! {
307            res
308        }
309    }
310
311    pub fn send_video(
312        &mut self,
313        chat_id: i64,
314        video: String,
315        duration: Option<i32>,
316        width: Option<i32>,
317        height: Option<i32>,
318        thumb: Option<String>,
319        caption: Option<String>,
320        parse_mode: Option<String>,
321        caption_entities: Option<Vec<MessageEntity>>,
322        supports_streaming: Option<bool>,
323        disable_notification: Option<bool>,
324        reply_to_message_id: Option<i32>,
325        allow_sending_without_reply: Option<bool>,
326        reply_markup_ikm: Option<InlineKeyboardMarkup>,
327        reply_markup_rkm: Option<ReplyKeyboardMarkup>,
328        reply_markup_rkr: Option<ReplyKeyboardRemove>,
329        reply_markup_fr: Option<ForceReply>,
330    ) -> Option<Message> {
331        let mut parameters = "".to_string();
332        expand_parameters_into_string! {
333            parameters, chat_id, video
334        }
335        expand_parameters_opt_into_string! {
336            parameters, duration, width, height, thumb, caption, parse_mode, caption_entities, supports_streaming,
337            disable_notification, reply_to_message_id, allow_sending_without_reply
338        }
339        expand_parameters_reply_markup_into_string! {
340            parameters, reply_markup_ikm, reply_markup_rkm, reply_markup_rkr, reply_markup_fr
341        }
342        parameters.pop();
343        let res = self.send_request("sendVideo".to_string(), parameters);
344        expand_make_request_to_message! {
345            res
346        }
347    }
348
349    pub fn send_animation(
350        &mut self,
351        chat_id: i64,
352        animation: String,
353        duration: Option<i32>,
354        width: Option<i32>,
355        height: Option<i32>,
356        thumb: Option<String>,
357        caption: Option<String>,
358        parse_mode: Option<String>,
359        caption_entities: Option<Vec<MessageEntity>>,
360        disable_notification: Option<bool>,
361        reply_to_message_id: Option<i32>,
362        allow_sending_without_reply: Option<bool>,
363        reply_markup_ikm: Option<InlineKeyboardMarkup>,
364        reply_markup_rkm: Option<ReplyKeyboardMarkup>,
365        reply_markup_rkr: Option<ReplyKeyboardRemove>,
366        reply_markup_fr: Option<ForceReply>,
367    ) -> Option<Message> {
368        let mut parameters = "".to_string();
369        expand_parameters_into_string! {
370            parameters, chat_id, animation
371        }
372        expand_parameters_opt_into_string! {
373            parameters, duration, width, height, thumb, caption, parse_mode, caption_entities,
374            disable_notification, reply_to_message_id, allow_sending_without_reply
375        }
376        expand_parameters_reply_markup_into_string! {
377            parameters, reply_markup_ikm, reply_markup_rkm, reply_markup_rkr, reply_markup_fr
378        }
379        parameters.pop();
380        let res = self.send_request("sendAnimation".to_string(), parameters);
381        expand_make_request_to_message! {
382            res
383        }
384    }
385
386    pub fn send_voice(
387        &mut self,
388        chat_id: i64,
389        voice: String,
390        caption: Option<String>,
391        parse_mode: Option<String>,
392        caption_entities: Option<Vec<MessageEntity>>,
393        duration: Option<i32>,
394        disable_notification: Option<bool>,
395        reply_to_message_id: Option<i32>,
396        allow_sending_without_reply: Option<bool>,
397        reply_markup_ikm: Option<InlineKeyboardMarkup>,
398        reply_markup_rkm: Option<ReplyKeyboardMarkup>,
399        reply_markup_rkr: Option<ReplyKeyboardRemove>,
400        reply_markup_fr: Option<ForceReply>,
401    ) -> Option<Message> {
402        let mut parameters = "".to_string();
403        expand_parameters_into_string! {
404            parameters, chat_id, voice
405        }
406        expand_parameters_opt_into_string! {
407            parameters, caption, parse_mode, caption_entities, duration,
408            disable_notification, reply_to_message_id, allow_sending_without_reply
409        }
410        expand_parameters_reply_markup_into_string! {
411            parameters, reply_markup_ikm, reply_markup_rkm, reply_markup_rkr, reply_markup_fr
412        }
413        parameters.pop();
414        let res = self.send_request("sendVoice".to_string(), parameters);
415        expand_make_request_to_message! {
416            res
417        }
418    }
419
420    pub fn send_video_note(
421        &mut self,
422        chat_id: i64,
423        video_note: String,
424        duration: Option<i32>,
425        length: Option<i32>,
426        thumb: Option<String>,
427        disable_notification: Option<bool>,
428        reply_to_message_id: Option<i32>,
429        allow_sending_without_reply: Option<bool>,
430        reply_markup_ikm: Option<InlineKeyboardMarkup>,
431        reply_markup_rkm: Option<ReplyKeyboardMarkup>,
432        reply_markup_rkr: Option<ReplyKeyboardRemove>,
433        reply_markup_fr: Option<ForceReply>,
434    ) -> Option<Message> {
435        let mut parameters = "".to_string();
436        expand_parameters_into_string! {
437            parameters, chat_id, video_note
438        }
439        expand_parameters_opt_into_string! {
440            parameters, duration, length, thumb, disable_notification, reply_to_message_id, allow_sending_without_reply
441        }
442        expand_parameters_reply_markup_into_string! {
443            parameters, reply_markup_ikm, reply_markup_rkm, reply_markup_rkr, reply_markup_fr
444        }
445        parameters.pop();
446        let res = self.send_request("sendVideoNote".to_string(), parameters);
447        expand_make_request_to_message! {
448            res
449        }
450    }
451
452    pub fn send_media_group(
453        &mut self,
454        chat_id: i64,
455        media: Vec<InputMedia>,
456        disable_notification: Option<bool>,
457        reply_to_message_id: Option<i32>,
458        allow_sending_without_reply: Option<bool>,
459    ) -> Option<Vec<Message>> {
460        let mut parameters = "".to_string();
461        expand_parameters_into_string! {
462            parameters, chat_id, media
463        }
464        expand_parameters_opt_into_string! {
465            parameters, disable_notification, reply_to_message_id, allow_sending_without_reply
466        }
467        parameters.pop();
468        let res = self.send_request("sendMediaGroup".to_string(), parameters);
469        if !res["ok"].as_bool().unwrap_or(false) {
470            None
471        } else {
472            let ret: Vec<Message> = Custom::from_json(res["result"].clone());
473            Some(ret)
474        }
475    }
476
477    pub fn send_location(
478        &mut self,
479        chat_id: i64,
480        latitude: f64,
481        longitude: f64,
482        horizontal_accuracy: Option<f64>,
483        live_period: Option<i32>,
484        heading: Option<i32>,
485        proximity_alert_radius: Option<i32>,
486        disable_notification: Option<bool>,
487        reply_to_message_id: Option<i32>,
488        allow_sending_without_reply: Option<bool>,
489        reply_markup_ikm: Option<InlineKeyboardMarkup>,
490        reply_markup_rkm: Option<ReplyKeyboardMarkup>,
491        reply_markup_rkr: Option<ReplyKeyboardRemove>,
492        reply_markup_fr: Option<ForceReply>,
493    ) -> Option<Message> {
494        let mut parameters = "".to_string();
495        expand_parameters_into_string! {
496            parameters, chat_id, latitude, longitude
497        }
498        expand_parameters_opt_into_string! {
499            parameters, horizontal_accuracy, live_period, heading, proximity_alert_radius, disable_notification,
500            reply_to_message_id, allow_sending_without_reply
501        }
502        expand_parameters_reply_markup_into_string! {
503            parameters, reply_markup_ikm, reply_markup_rkm, reply_markup_rkr, reply_markup_fr
504        }
505        parameters.pop();
506        let res = self.send_request("sendLocation".to_string(), parameters);
507        expand_make_request_to_message! {
508            res
509        }
510    }
511
512    pub fn edit_message_live_location(
513        &mut self,
514        chat_id: Option<i64>,
515        message_id: Option<i32>,
516        inline_message_id: Option<String>,
517        latitude: f64,
518        longitude: f64,
519        horizontal_accuracy: Option<f64>,
520        heading: Option<i32>,
521        proximity_alert_radius: Option<i32>,
522        reply_markup_ikm: Option<InlineKeyboardMarkup>,
523    ) -> Option<Message> {
524        let mut parameters = "".to_string();
525        expand_parameters_into_string! {
526            parameters, latitude, longitude
527        }
528        expand_parameters_opt_into_string! {
529            parameters, chat_id, message_id, inline_message_id, horizontal_accuracy, heading, proximity_alert_radius
530        }
531        expand_parameters_reply_markup_into_string! {
532            parameters, reply_markup_ikm
533        }
534        parameters.pop();
535        let res = self.send_request("editMessageLiveLocation".to_string(), parameters);
536        expand_make_request_to_message! {
537            res
538        }
539    }
540
541    pub fn stop_message_live_location(
542        &mut self,
543        chat_id: Option<i64>,
544        message_id: Option<i32>,
545        inline_message_id: Option<String>,
546        reply_markup_ikm: Option<InlineKeyboardMarkup>,
547    ) -> Option<Message> {
548        let mut parameters = "".to_string();
549        expand_parameters_opt_into_string! {
550            parameters, chat_id, message_id, inline_message_id
551        }
552        expand_parameters_reply_markup_into_string! {
553            parameters, reply_markup_ikm
554        }
555        parameters.pop();
556        let res = self.send_request("stopMessageLiveLocation".to_string(), parameters);
557        expand_make_request_to_message! {
558            res
559        }
560    }
561
562    pub fn send_venue(
563        &mut self,
564        chat_id: i64,
565        latitude: f64,
566        longitude: f64,
567        title: String,
568        address: String,
569        foursquare_id: Option<String>,
570        foursquare_type: Option<String>,
571        google_place_id: Option<String>,
572        google_place_type: Option<String>,
573        disable_notification: Option<bool>,
574        reply_to_message_id: Option<i32>,
575        allow_sending_without_reply: Option<bool>,
576        reply_markup_ikm: Option<InlineKeyboardMarkup>,
577        reply_markup_rkm: Option<ReplyKeyboardMarkup>,
578        reply_markup_rkr: Option<ReplyKeyboardRemove>,
579        reply_markup_fr: Option<ForceReply>,
580    ) -> Option<Message> {
581        let mut parameters = "".to_string();
582        expand_parameters_into_string! {
583            parameters, chat_id, latitude, longitude, title, address
584        }
585        expand_parameters_opt_into_string! {
586            parameters, foursquare_id, foursquare_type, google_place_id, google_place_type, disable_notification,
587            reply_to_message_id, allow_sending_without_reply
588        }
589        expand_parameters_reply_markup_into_string! {
590            parameters, reply_markup_ikm, reply_markup_rkm, reply_markup_rkr, reply_markup_fr
591        }
592        parameters.pop();
593        let res = self.send_request("sendVenue".to_string(), parameters);
594        expand_make_request_to_message! {
595            res
596        }
597    }
598
599    pub fn send_contact(
600        &mut self,
601        chat_id: i64,
602        phone_number: String,
603        first_name: String,
604        last_name: Option<String>,
605        vcard: Option<String>,
606        disable_notification: Option<bool>,
607        reply_to_message_id: Option<i32>,
608        allow_sending_without_reply: Option<bool>,
609        reply_markup_ikm: Option<InlineKeyboardMarkup>,
610        reply_markup_rkm: Option<ReplyKeyboardMarkup>,
611        reply_markup_rkr: Option<ReplyKeyboardRemove>,
612        reply_markup_fr: Option<ForceReply>,
613    ) -> Option<Message> {
614        let mut parameters = "".to_string();
615        expand_parameters_into_string! {
616            parameters, chat_id, phone_number, first_name
617        }
618        expand_parameters_opt_into_string! {
619            parameters, last_name, vcard, disable_notification, reply_to_message_id, allow_sending_without_reply
620        }
621        expand_parameters_reply_markup_into_string! {
622            parameters, reply_markup_ikm, reply_markup_rkm, reply_markup_rkr, reply_markup_fr
623        }
624        parameters.pop();
625        let res = self.send_request("sendContact".to_string(), parameters);
626        expand_make_request_to_message! {
627            res
628        }
629    }
630
631    pub fn send_poll(
632        &mut self,
633        chat_id: i64,
634        question: String,
635        options: Vec<String>,
636        is_anonymous: Option<bool>,
637        typ: Option<String>,
638        allows_multiple_answers: Option<bool>,
639        correct_option_id: Option<i32>,
640        explanation: Option<String>,
641        explanation_parse_mode: Option<String>,
642        explanation_entities: Option<Vec<MessageEntity>>,
643        open_period: Option<i32>,
644        close_date: Option<i32>,
645        is_closed: Option<i32>,
646        disable_notification: Option<bool>,
647        reply_to_message_id: Option<i32>,
648        allow_sending_without_reply: Option<bool>,
649        reply_markup_ikm: Option<InlineKeyboardMarkup>,
650        reply_markup_rkm: Option<ReplyKeyboardMarkup>,
651        reply_markup_rkr: Option<ReplyKeyboardRemove>,
652        reply_markup_fr: Option<ForceReply>,
653    ) -> Option<Message> {
654        let mut parameters = "".to_string();
655        expand_parameters_into_string! {
656            parameters, chat_id, question, options
657        }
658        expand_parameters_opt_into_string! {
659            parameters, is_anonymous, typ, allows_multiple_answers, correct_option_id, explanation,
660            explanation_parse_mode, explanation_entities, open_period, close_date, is_closed,
661            disable_notification, reply_to_message_id, allow_sending_without_reply
662        }
663        expand_parameters_reply_markup_into_string! {
664            parameters, reply_markup_ikm, reply_markup_rkm, reply_markup_rkr, reply_markup_fr
665        }
666        parameters.pop();
667        let res = self.send_request("sendPoll".to_string(), parameters);
668        expand_make_request_to_message! {
669            res
670        }
671    }
672
673    pub fn send_dice(
674        &mut self,
675        chat_id: i64,
676        emoji: Option<String>,
677        disable_notification: Option<bool>,
678        reply_to_message_id: Option<i32>,
679        allow_sending_without_reply: Option<bool>,
680        reply_markup_ikm: Option<InlineKeyboardMarkup>,
681        reply_markup_rkm: Option<ReplyKeyboardMarkup>,
682        reply_markup_rkr: Option<ReplyKeyboardRemove>,
683        reply_markup_fr: Option<ForceReply>,
684    ) -> Option<Message> {
685        let mut parameters = "".to_string();
686        expand_parameters_into_string! {
687            parameters, chat_id
688        }
689        expand_parameters_opt_into_string! {
690            parameters, emoji, disable_notification, reply_to_message_id, allow_sending_without_reply
691        }
692        expand_parameters_reply_markup_into_string! {
693            parameters, reply_markup_ikm, reply_markup_rkm, reply_markup_rkr, reply_markup_fr
694        }
695        parameters.pop();
696        let res = self.send_request("sendDice".to_string(), parameters);
697        expand_make_request_to_message! {
698            res
699        }
700    }
701
702    pub fn send_chat_action(&mut self, chat_id: i64, action: String) -> bool {
703        let mut parameters = "".to_string();
704        expand_parameters_into_string! {
705            parameters, chat_id, action
706        }
707        parameters.pop();
708        let res = self.send_request("sendChatAction".to_string(), parameters);
709        expand_make_request_to_bool! {
710            res
711        }
712    }
713
714    pub fn get_user_profile_photos(
715        &mut self,
716        user_id: i64,
717        offset: Option<i32>,
718        limit: Option<i32>,
719    ) -> Option<UserProfilePhotos> {
720        let mut parameters = "".to_string();
721        expand_parameters_into_string! {
722            parameters, user_id
723        }
724        expand_parameters_opt_into_string! {
725            parameters, offset, limit
726        }
727        parameters.pop();
728        let res = self.send_request("getUserProfilePhotos".to_string(), parameters);
729        if !res["ok"].as_bool().unwrap_or(false) {
730            None
731        } else {
732            let ret: UserProfilePhotos = Custom::from_json(res["result"].clone());
733            Some(ret)
734        }
735    }
736
737    pub fn kick_chat_member(
738        &mut self,
739        chat_id: i64,
740        user_id: i64,
741        until_date: Option<i32>,
742        revoke_messages: Option<bool>,
743    ) -> bool {
744        let mut parameters = "".to_string();
745        expand_parameters_into_string! {
746            parameters, chat_id, user_id
747        }
748        expand_parameters_opt_into_string! {
749            parameters, until_date, revoke_messages
750        }
751        parameters.pop();
752        let res = self.send_request("kickChatMember".to_string(), parameters);
753        expand_make_request_to_bool! {
754            res
755        }
756    }
757
758    pub fn unban_chat_member(
759        &mut self,
760        chat_id: i64,
761        user_id: i64,
762        only_if_banned: Option<bool>,
763    ) -> bool {
764        let mut parameters = "".to_string();
765        expand_parameters_into_string! {
766            parameters, chat_id, user_id
767        }
768        expand_parameters_opt_into_string! {
769            parameters, only_if_banned
770        }
771        parameters.pop();
772        let res = self.send_request("unbanChatMember".to_string(), parameters);
773        expand_make_request_to_bool! {
774            res
775        }
776    }
777
778    pub fn restrict_chat_member(
779        &mut self,
780        chat_id: i64,
781        user_id: i64,
782        permissions: ChatPermissions,
783        until_date: Option<i32>,
784    ) -> bool {
785        let mut parameters = "".to_string();
786        expand_parameters_into_string! {
787            parameters, chat_id, user_id, permissions
788        }
789        expand_parameters_opt_into_string! {
790            parameters, until_date
791        }
792        parameters.pop();
793        let res = self.send_request("restrictChatMember".to_string(), parameters);
794        expand_make_request_to_bool! {
795            res
796        }
797    }
798
799    pub fn promote_chat_member(
800        &mut self,
801        chat_id: i64,
802        user_id: i64,
803        is_anonymous: Option<bool>,
804        can_manage_chat: Option<bool>,
805        can_post_messages: Option<bool>,
806        can_edit_messages: Option<bool>,
807        can_delete_messages: Option<bool>,
808        can_manage_voice_chats: Option<bool>,
809        can_restrict_members: Option<bool>,
810        can_promote_members: Option<bool>,
811        can_change_info: Option<bool>,
812        can_invite_users: Option<bool>,
813        can_pin_messages: Option<bool>,
814    ) -> bool {
815        let mut parameters = "".to_string();
816        expand_parameters_into_string! {
817            parameters, chat_id, user_id
818        }
819        expand_parameters_opt_into_string! {
820            parameters, is_anonymous, can_manage_chat, can_post_messages, can_edit_messages,
821            can_delete_messages, can_manage_voice_chats, can_restrict_members, can_promote_members,
822            can_change_info, can_invite_users, can_pin_messages
823        }
824        parameters.pop();
825        let res = self.send_request("promoteChatMember".to_string(), parameters);
826        expand_make_request_to_bool! {
827            res
828        }
829    }
830
831    pub fn set_chat_administrator_custom_title(
832        &mut self,
833        chat_id: i64,
834        user_id: i64,
835        custom_title: String,
836    ) -> bool {
837        let mut parameters = "".to_string();
838        expand_parameters_into_string! {
839            parameters, chat_id, user_id, custom_title
840        }
841        parameters.pop();
842        let res = self.send_request("setChatAdministratorCustomTitle".to_string(), parameters);
843        expand_make_request_to_bool! {
844            res
845        }
846    }
847
848    pub fn set_chat_permissions(&mut self, chat_id: i64, permissions: ChatPermissions) -> bool {
849        let mut parameters = "".to_string();
850        expand_parameters_into_string! {
851            parameters, chat_id, permissions
852        }
853        parameters.pop();
854        let res = self.send_request("setChatPermissions".to_string(), parameters);
855        expand_make_request_to_bool! {
856            res
857        }
858    }
859
860    pub fn export_chat_invite_link(&mut self, chat_id: i64) -> Option<String> {
861        let mut parameters = "".to_string();
862        expand_parameters_into_string! {
863            parameters, chat_id
864        }
865        parameters.pop();
866        let res = self.send_request("exportChatInviteLink".to_string(), parameters);
867        if !res["ok"].as_bool().unwrap_or(false) {
868            None
869        } else {
870            let ret: String = Custom::from_json(res["result"].clone());
871            Some(ret)
872        }
873    }
874
875    pub fn create_chat_invite_link(
876        &mut self,
877        chat_id: i64,
878        expire_date: Option<i32>,
879        member_limit: Option<i32>,
880    ) -> Option<ChatInviteLink> {
881        let mut parameters = "".to_string();
882        expand_parameters_into_string! {
883            parameters, chat_id
884        }
885        expand_parameters_opt_into_string! {
886            parameters, expire_date, member_limit
887        }
888        parameters.pop();
889        let res = self.send_request("createChatInviteLink".to_string(), parameters);
890        if !res["ok"].as_bool().unwrap_or(false) {
891            None
892        } else {
893            let ret: ChatInviteLink = Custom::from_json(res["result"].clone());
894            Some(ret)
895        }
896    }
897
898    pub fn edit_chat_invite_link(
899        &mut self,
900        chat_id: i64,
901        invite_link: String,
902        expire_date: Option<i32>,
903        member_limit: Option<i32>,
904    ) -> Option<ChatInviteLink> {
905        let mut parameters = "".to_string();
906        expand_parameters_into_string! {
907            parameters, chat_id, invite_link
908        }
909        expand_parameters_opt_into_string! {
910            parameters, expire_date, member_limit
911        }
912        parameters.pop();
913        let res = self.send_request("editChatInviteLink".to_string(), parameters);
914        if !res["ok"].as_bool().unwrap_or(false) {
915            None
916        } else {
917            let ret: ChatInviteLink = Custom::from_json(res["result"].clone());
918            Some(ret)
919        }
920    }
921
922    pub fn revoke_chat_invite_link(
923        &mut self,
924        chat_id: i64,
925        invite_link: String,
926    ) -> Option<ChatInviteLink> {
927        let mut parameters = "".to_string();
928        expand_parameters_into_string! {
929            parameters, chat_id, invite_link
930        }
931        parameters.pop();
932        let res = self.send_request("revokeChatInviteLink".to_string(), parameters);
933        if !res["ok"].as_bool().unwrap_or(false) {
934            None
935        } else {
936            let ret: ChatInviteLink = Custom::from_json(res["result"].clone());
937            Some(ret)
938        }
939    }
940
941    pub fn delete_chat_photo(&mut self, chat_id: i64) -> bool {
942        let mut parameters = "".to_string();
943        expand_parameters_into_string! {
944            parameters, chat_id
945        }
946        parameters.pop();
947        let res = self.send_request("deleteChatPhoto".to_string(), parameters);
948        expand_make_request_to_bool! {
949            res
950        }
951    }
952
953    pub fn set_chat_title(&mut self, chat_id: i64, title: String) -> bool {
954        let mut parameters = "".to_string();
955        expand_parameters_into_string! {
956            parameters, chat_id, title
957        }
958        parameters.pop();
959        let res = self.send_request("setChatTitle".to_string(), parameters);
960        expand_make_request_to_bool! {
961            res
962        }
963    }
964
965    pub fn set_chat_description(&mut self, chat_id: i64, description: String) -> bool {
966        let mut parameters = "".to_string();
967        expand_parameters_into_string! {
968            parameters, chat_id, description
969        }
970        parameters.pop();
971        let res = self.send_request("setChatDescription".to_string(), parameters);
972        expand_make_request_to_bool! {
973            res
974        }
975    }
976
977    pub fn pin_chat_message(
978        &mut self,
979        chat_id: i64,
980        message_id: i32,
981        disable_notification: Option<bool>,
982    ) -> bool {
983        let mut parameters = "".to_string();
984        expand_parameters_into_string! {
985            parameters, chat_id, message_id
986        }
987        expand_parameters_opt_into_string! {
988            parameters, disable_notification
989        }
990        parameters.pop();
991        let res = self.send_request("pinChatMessage".to_string(), parameters);
992        expand_make_request_to_bool! {
993            res
994        }
995    }
996
997    pub fn unpin_chat_message(&mut self, chat_id: i64, message_id: i32) -> bool {
998        let mut parameters = "".to_string();
999        expand_parameters_into_string! {
1000            parameters, chat_id, message_id
1001        }
1002        parameters.pop();
1003        let res = self.send_request("unpinChatMessage".to_string(), parameters);
1004        expand_make_request_to_bool! {
1005            res
1006        }
1007    }
1008
1009    pub fn unpin_all_chat_message(&mut self, chat_id: i64) -> bool {
1010        let mut parameters = "".to_string();
1011        expand_parameters_into_string! {
1012            parameters, chat_id
1013        }
1014        parameters.pop();
1015        let res = self.send_request("unpinAllChatMessages".to_string(), parameters);
1016        expand_make_request_to_bool! {
1017            res
1018        }
1019    }
1020
1021    pub fn leave_chat(&mut self, chat_id: i64) -> bool {
1022        let mut parameters = "".to_string();
1023        expand_parameters_into_string! {
1024            parameters, chat_id
1025        }
1026        parameters.pop();
1027        let res = self.send_request("leaveChat".to_string(), parameters);
1028        expand_make_request_to_bool! {
1029            res
1030        }
1031    }
1032
1033    pub fn get_chat(&mut self, chat_id: i64) -> Option<Chat> {
1034        let mut parameters = "".to_string();
1035        expand_parameters_into_string! {
1036            parameters, chat_id
1037        }
1038        parameters.pop();
1039        let res = self.send_request("getChat".to_string(), parameters);
1040        if !res["ok"].as_bool().unwrap_or(false) {
1041            None
1042        } else {
1043            let ret: Chat = Custom::from_json(res["result"].clone());
1044            Some(ret)
1045        }
1046    }
1047
1048    pub fn get_chat_administrators(&mut self, chat_id: i64) -> Option<Vec<ChatMember>> {
1049        let mut parameters = "".to_string();
1050        expand_parameters_into_string! {
1051            parameters, chat_id
1052        }
1053        parameters.pop();
1054        let res = self.send_request("getChatAdministrators".to_string(), parameters);
1055        if !res["ok"].as_bool().unwrap_or(false) {
1056            None
1057        } else {
1058            let ret: Vec<ChatMember> = Custom::from_json(res["result"].clone());
1059            Some(ret)
1060        }
1061    }
1062
1063    pub fn get_chat_chat_members_count(&mut self, chat_id: i64) -> Option<i32> {
1064        let mut parameters = "".to_string();
1065        expand_parameters_into_string! {
1066            parameters, chat_id
1067        }
1068        parameters.pop();
1069        let res = self.send_request("getChatMembersCount".to_string(), parameters);
1070        if !res["ok"].as_bool().unwrap_or(false) {
1071            None
1072        } else {
1073            let ret: i32 = Custom::from_json(res["result"].clone());
1074            Some(ret)
1075        }
1076    }
1077
1078    pub fn get_chat_chat_member(&mut self, chat_id: i64, user_id: i64) -> Option<ChatMember> {
1079        let mut parameters = "".to_string();
1080        expand_parameters_into_string! {
1081            parameters, chat_id, user_id
1082        }
1083        parameters.pop();
1084        let res = self.send_request("getChatMember".to_string(), parameters);
1085        if !res["ok"].as_bool().unwrap_or(false) {
1086            None
1087        } else {
1088            let ret: ChatMember = Custom::from_json(res["result"].clone());
1089            Some(ret)
1090        }
1091    }
1092
1093    pub fn set_chat_sticker_set(&mut self, chat_id: i64, sticker_set_name: String) -> bool {
1094        let mut parameters = "".to_string();
1095        expand_parameters_into_string! {
1096            parameters, chat_id, sticker_set_name
1097        }
1098        parameters.pop();
1099        let res = self.send_request("setChatStickerSet".to_string(), parameters);
1100        expand_make_request_to_bool! {
1101            res
1102        }
1103    }
1104
1105    pub fn delete_chat_sticker_set(&mut self, chat_id: i64) -> bool {
1106        let mut parameters = "".to_string();
1107        expand_parameters_into_string! {
1108            parameters, chat_id
1109        }
1110        parameters.pop();
1111        let res = self.send_request("deleteChatStickerSet".to_string(), parameters);
1112        expand_make_request_to_bool! {
1113            res
1114        }
1115    }
1116
1117    pub fn answer_callback_query(
1118        &mut self,
1119        callback_query_id: String,
1120        text: String,
1121        show_alert: Option<bool>,
1122        url: Option<String>,
1123        cache_time: Option<i32>,
1124    ) -> bool {
1125        let mut parameters = "".to_string();
1126        expand_parameters_into_string! {
1127            parameters, callback_query_id, text
1128        }
1129        expand_parameters_opt_into_string! {
1130            parameters, show_alert, url, cache_time
1131        }
1132        parameters.pop();
1133        let res = self.send_request("answerCallbackQuery".to_string(), parameters);
1134        expand_make_request_to_bool! {
1135            res
1136        }
1137    }
1138
1139    pub fn set_my_commands(&mut self, commands: Vec<BotCommand>) -> bool {
1140        let mut parameters = "".to_string();
1141        expand_parameters_into_string! {
1142            parameters, commands
1143        }
1144        parameters.pop();
1145        let res = self.send_request("setMyCommands".to_string(), parameters);
1146        expand_make_request_to_bool! {
1147            res
1148        }
1149    }
1150
1151    pub fn get_my_commands(&mut self) -> Option<Vec<BotCommand>> {
1152        let res = self.send_request("getMyCommands".to_string(), "".to_string());
1153        if !res["ok"].as_bool().unwrap_or(false) {
1154            None
1155        } else {
1156            let ret: Vec<BotCommand> = Custom::from_json(res["result"].clone());
1157            Some(ret)
1158        }
1159    }
1160
1161    pub fn edit_message_text(
1162        &mut self,
1163        chat_id: Option<i64>,
1164        message_id: Option<i32>,
1165        inline_message_id: Option<String>,
1166        text: Option<String>,
1167        parse_mode: Option<String>,
1168        entities: Option<Vec<MessageEntity>>,
1169        disable_web_page_preview: Option<bool>,
1170        reply_markup_ikm: Option<InlineKeyboardMarkup>,
1171    ) -> Option<Message> {
1172        let mut parameters = "".to_string();
1173        expand_parameters_opt_into_string! {
1174            parameters, chat_id, message_id, inline_message_id, text, parse_mode, entities, disable_web_page_preview
1175        }
1176        expand_parameters_reply_markup_into_string! {
1177            parameters, reply_markup_ikm
1178        }
1179        parameters.pop();
1180        let res = self.send_request("editMessageText".to_string(), parameters);
1181        expand_make_request_to_message! {
1182            res
1183        }
1184    }
1185
1186    pub fn edit_message_caption(
1187        &mut self,
1188        chat_id: Option<i64>,
1189        message_id: Option<i32>,
1190        inline_message_id: Option<String>,
1191        caption: Option<String>,
1192        parse_mode: Option<String>,
1193        caption_entities: Option<Vec<MessageEntity>>,
1194        reply_markup_ikm: Option<InlineKeyboardMarkup>,
1195    ) -> Option<Message> {
1196        let mut parameters = "".to_string();
1197        expand_parameters_opt_into_string! {
1198            parameters, chat_id, message_id, inline_message_id, caption, parse_mode, caption_entities
1199        }
1200        expand_parameters_reply_markup_into_string! {
1201            parameters, reply_markup_ikm
1202        }
1203        parameters.pop();
1204        let res = self.send_request("editMessageCaption".to_string(), parameters);
1205        expand_make_request_to_message! {
1206            res
1207        }
1208    }
1209
1210    pub fn edit_message_media(
1211        &mut self,
1212        chat_id: Option<i64>,
1213        message_id: Option<i32>,
1214        inline_message_id: Option<String>,
1215        media: Option<InputMedia>,
1216        reply_markup_ikm: Option<InlineKeyboardMarkup>,
1217    ) -> Option<Message> {
1218        let mut parameters = "".to_string();
1219        expand_parameters_opt_into_string! {
1220            parameters, chat_id, message_id, inline_message_id, media
1221        }
1222        expand_parameters_reply_markup_into_string! {
1223            parameters, reply_markup_ikm
1224        }
1225        parameters.pop();
1226        let res = self.send_request("editMessageMedia".to_string(), parameters);
1227        expand_make_request_to_message! {
1228            res
1229        }
1230    }
1231
1232    pub fn edit_message_reply_markup(
1233        &mut self,
1234        chat_id: Option<i64>,
1235        message_id: Option<i32>,
1236        inline_message_id: Option<String>,
1237        reply_markup_ikm: Option<InlineKeyboardMarkup>,
1238    ) -> Option<Message> {
1239        let mut parameters = "".to_string();
1240        expand_parameters_opt_into_string! {
1241            parameters, chat_id, message_id, inline_message_id
1242        }
1243        expand_parameters_reply_markup_into_string! {
1244            parameters, reply_markup_ikm
1245        }
1246        parameters.pop();
1247        let res = self.send_request("editMessageReplyMarkup".to_string(), parameters);
1248        expand_make_request_to_message! {
1249            res
1250        }
1251    }
1252
1253    pub fn stop_poll(
1254        &mut self,
1255        chat_id: i64,
1256        message_id: i32,
1257        reply_markup_ikm: Option<InlineKeyboardMarkup>,
1258    ) -> Option<Poll> {
1259        let mut parameters = "".to_string();
1260        expand_parameters_into_string! {
1261            parameters, chat_id, message_id
1262        }
1263        expand_parameters_reply_markup_into_string! {
1264            parameters, reply_markup_ikm
1265        }
1266        parameters.pop();
1267        let res = self.send_request("stopPoll".to_string(), parameters);
1268        if !res["ok"].as_bool().unwrap_or(false) {
1269            None
1270        } else {
1271            let ret: Poll = Custom::from_json(res["result"].clone());
1272            Some(ret)
1273        }
1274    }
1275
1276    pub fn delete_message(&mut self, chat_id: i64, message_id: i32) -> bool {
1277        let mut parameters = "".to_string();
1278        expand_parameters_into_string! {
1279            parameters, chat_id, message_id
1280        }
1281        parameters.pop();
1282        let res = self.send_request("deleteMessage".to_string(), parameters);
1283        expand_make_request_to_bool! {
1284            res
1285        }
1286    }
1287
1288    pub fn send_sticker(
1289        &mut self,
1290        chat_id: i64,
1291        sticker: String,
1292        disable_notification: Option<bool>,
1293        reply_to_message_id: Option<i32>,
1294        allow_sending_without_reply: Option<bool>,
1295        reply_markup_ikm: Option<InlineKeyboardMarkup>,
1296        reply_markup_rkm: Option<ReplyKeyboardMarkup>,
1297        reply_markup_rkr: Option<ReplyKeyboardRemove>,
1298        reply_markup_fr: Option<ForceReply>,
1299    ) -> Option<Message> {
1300        let mut parameters = "".to_string();
1301        expand_parameters_into_string! {
1302            parameters, chat_id, sticker
1303        }
1304        expand_parameters_opt_into_string! {
1305            parameters, disable_notification, reply_to_message_id, allow_sending_without_reply
1306        }
1307        expand_parameters_reply_markup_into_string! {
1308            parameters, reply_markup_ikm, reply_markup_rkm, reply_markup_rkr, reply_markup_fr
1309        }
1310        parameters.pop();
1311        let res = self.send_request("sendSticker".to_string(), parameters);
1312        expand_make_request_to_message! {
1313            res
1314        }
1315    }
1316
1317    pub fn get_sticker_set(&mut self, name: String) -> Option<StickerSet> {
1318        let mut parameters = "".to_string();
1319        expand_parameters_into_string! {
1320            parameters, name
1321        }
1322        parameters.pop();
1323        let res = self.send_request("getStickerSet".to_string(), parameters);
1324        if !res["ok"].as_bool().unwrap_or(false) {
1325            None
1326        } else {
1327            let ret: StickerSet = Custom::from_json(res["result"].clone());
1328            Some(ret)
1329        }
1330    }
1331
1332    pub fn create_new_sticker_set(
1333        &mut self,
1334        user_id: i64,
1335        name: String,
1336        title: String,
1337        png_sticker: Option<String>,
1338        emojis: String,
1339        contains_masks: Option<bool>,
1340        mask_position: Option<MaskPosition>,
1341    ) -> bool {
1342        let mut parameters = "".to_string();
1343        expand_parameters_into_string! {
1344            parameters, user_id, name, title, emojis
1345        }
1346        expand_parameters_opt_into_string! {
1347            parameters, png_sticker, contains_masks, mask_position
1348        }
1349        parameters.pop();
1350        let res = self.send_request("createNewStickerSet".to_string(), parameters);
1351        expand_make_request_to_bool! {
1352            res
1353        }
1354    }
1355
1356    pub fn add_sticker_to_set(
1357        &mut self,
1358        user_id: i64,
1359        name: String,
1360        png_sticker: Option<String>,
1361        emojis: String,
1362        mask_position: Option<MaskPosition>,
1363    ) -> bool {
1364        let mut parameters = "".to_string();
1365        expand_parameters_into_string! {
1366            parameters, user_id, name, emojis
1367        }
1368        expand_parameters_opt_into_string! {
1369            parameters, png_sticker, mask_position
1370        }
1371        parameters.pop();
1372        let res = self.send_request("addStickerToSet".to_string(), parameters);
1373        expand_make_request_to_bool! {
1374            res
1375        }
1376    }
1377
1378    pub fn add_sticker_position_in_set(&mut self, sticker: String, position: i32) -> bool {
1379        let mut parameters = "".to_string();
1380        expand_parameters_into_string! {
1381            parameters, sticker, position
1382        }
1383        parameters.pop();
1384        let res = self.send_request("setStickerPositionInSet".to_string(), parameters);
1385        expand_make_request_to_bool! {
1386            res
1387        }
1388    }
1389
1390    pub fn delete_sticker_from_chat(&mut self, sticker: String) -> bool {
1391        let mut parameters = "".to_string();
1392        expand_parameters_into_string! {
1393            parameters, sticker
1394        }
1395        parameters.pop();
1396        let res = self.send_request("deleteStickerFromSet".to_string(), parameters);
1397        expand_make_request_to_bool! {
1398            res
1399        }
1400    }
1401
1402    pub fn set_sticker_thumb(&mut self, name: String, user_id: i64, thumb: Option<String>) -> bool {
1403        let mut parameters = "".to_string();
1404        expand_parameters_into_string! {
1405            parameters, name, user_id
1406        }
1407        expand_parameters_opt_into_string! {
1408            parameters, thumb
1409        }
1410        parameters.pop();
1411        let res = self.send_request("setStickerSetThumb".to_string(), parameters);
1412        expand_make_request_to_bool! {
1413            res
1414        }
1415    }
1416}
1417
1418impl Clone for Bot {
1419    fn clone(&self) -> Self {
1420        Bot {
1421            key: self.key.clone(),
1422            offset: self.offset,
1423        }
1424    }
1425}