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