Skip to main content

telers/methods/
send_poll.rs

1use crate::client::Bot;
2use serde::Serialize;
3/// Use this method to send a native poll. On success, the sent Message is returned.
4/// # Documentation
5/// <https://core.telegram.org/bots/api#sendpoll>
6/// # Returns
7/// - `crate::types::Message`
8#[derive(Clone, Debug, Serialize)]
9pub struct SendPoll {
10    /// Unique identifier of the business connection on behalf of which the message will be sent
11    #[serde(skip_serializing_if = "Option::is_none")]
12    pub business_connection_id: Option<Box<str>>,
13    /// Unique identifier for the target chat or username of the target channel (in the format @channelusername). Polls can't be sent to channel direct messages chats.
14    pub chat_id: crate::types::ChatIdKind,
15    /// Unique identifier for the target message thread (topic) of a forum; for forum supergroups and private chats of bots with forum topic mode enabled only
16    #[serde(skip_serializing_if = "Option::is_none")]
17    pub message_thread_id: Option<i64>,
18    /// Poll question, 1-300 characters
19    pub question: Box<str>,
20    /// Mode for parsing entities in the question. See formatting options for more details. Currently, only custom emoji entities are allowed
21    #[serde(skip_serializing_if = "Option::is_none")]
22    pub question_parse_mode: Option<Box<str>>,
23    /// A JSON-serialized list of special entities that appear in the poll question. It can be specified instead of `question_parse_mode`
24    #[serde(skip_serializing_if = "Option::is_none")]
25    pub question_entities: Option<Box<[crate::types::MessageEntity]>>,
26    /// A JSON-serialized list of 2-12 answer options
27    pub options: Box<[crate::types::InputPollOption]>,
28    /// `true`, if the poll needs to be anonymous, defaults to `true`
29    #[serde(skip_serializing_if = "Option::is_none")]
30    pub is_anonymous: Option<bool>,
31    /// Poll type, `quiz` or `regular`, defaults to `regular`
32    #[serde(skip_serializing_if = "Option::is_none")]
33    pub r#type: Option<Box<str>>,
34    /// `true`, if the poll allows multiple answers, ignored for polls in quiz mode, defaults to `false`
35    #[serde(skip_serializing_if = "Option::is_none")]
36    pub allows_multiple_answers: Option<bool>,
37    /// 0-based identifier of the correct answer option, required for polls in quiz mode
38    #[serde(skip_serializing_if = "Option::is_none")]
39    pub correct_option_id: Option<i64>,
40    /// Text that is shown when a user chooses an incorrect answer or taps on the lamp icon in a quiz-style poll, 0-200 characters with at most 2 line feeds after entities parsing
41    #[serde(skip_serializing_if = "Option::is_none")]
42    pub explanation: Option<Box<str>>,
43    /// Mode for parsing entities in the explanation. See formatting options for more details.
44    #[serde(skip_serializing_if = "Option::is_none")]
45    pub explanation_parse_mode: Option<Box<str>>,
46    /// A JSON-serialized list of special entities that appear in the poll explanation. It can be specified instead of `explanation_parse_mode`
47    #[serde(skip_serializing_if = "Option::is_none")]
48    pub explanation_entities: Option<Box<[crate::types::MessageEntity]>>,
49    /// Amount of time in seconds the poll will be active after creation, 5-600. Can't be used together with `close_date`.
50    #[serde(skip_serializing_if = "Option::is_none")]
51    pub open_period: Option<u16>,
52    /// Point in time (Unix timestamp) when the poll will be automatically closed. Must be at least 5 and no more than 600 seconds in the future. Can't be used together with `open_period`.
53    #[serde(skip_serializing_if = "Option::is_none")]
54    pub close_date: Option<i64>,
55    /// Pass `true` if the poll needs to be immediately closed. This can be useful for poll preview.
56    #[serde(skip_serializing_if = "Option::is_none")]
57    pub is_closed: Option<bool>,
58    /// Sends the message silently. Users will receive a notification with no sound.
59    #[serde(skip_serializing_if = "Option::is_none")]
60    pub disable_notification: Option<bool>,
61    /// Protects the contents of the sent message from forwarding and saving
62    #[serde(skip_serializing_if = "Option::is_none")]
63    pub protect_content: Option<bool>,
64    /// Pass `true` to allow up to 1000 messages per second, ignoring broadcasting limits for a fee of 0.1 Telegram Stars per message. The relevant Stars will be withdrawn from the bot's balance
65    #[serde(skip_serializing_if = "Option::is_none")]
66    pub allow_paid_broadcast: Option<bool>,
67    /// Unique identifier of the message effect to be added to the message; for private chats only
68    #[serde(skip_serializing_if = "Option::is_none")]
69    pub message_effect_id: Option<Box<str>>,
70    /// Description of the message to reply to
71    #[serde(skip_serializing_if = "Option::is_none")]
72    pub reply_parameters: Option<crate::types::ReplyParameters>,
73    /// Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove a reply keyboard or to force a reply from the user
74    #[serde(skip_serializing_if = "Option::is_none")]
75    pub reply_markup: Option<crate::types::ReplyMarkup>,
76}
77impl SendPoll {
78    /// Creates a new `SendPoll`.
79    ///
80    /// # Arguments
81    /// * `chat_id` - Unique identifier for the target chat or username of the target channel (in the format @channelusername). Polls can't be sent to channel direct messages chats.
82    /// * `question` - Poll question, 1-300 characters
83    /// * `options` - A JSON-serialized list of 2-12 answer options
84    ///
85    /// # Notes
86    /// Use builder methods to set optional fields.
87    #[must_use]
88    pub fn new<
89        T0: Into<crate::types::ChatIdKind>,
90        T1: Into<Box<str>>,
91        T2Item: Into<crate::types::InputPollOption>,
92        T2: IntoIterator<Item = T2Item>,
93    >(
94        chat_id: T0,
95        question: T1,
96        options: T2,
97    ) -> Self {
98        Self {
99            business_connection_id: None,
100            chat_id: chat_id.into(),
101            message_thread_id: None,
102            question: question.into(),
103            question_parse_mode: None,
104            question_entities: None,
105            options: options.into_iter().map(Into::into).collect(),
106            is_anonymous: None,
107            r#type: None,
108            allows_multiple_answers: None,
109            correct_option_id: None,
110            explanation: None,
111            explanation_parse_mode: None,
112            explanation_entities: None,
113            open_period: None,
114            close_date: None,
115            is_closed: None,
116            disable_notification: None,
117            protect_content: None,
118            allow_paid_broadcast: None,
119            message_effect_id: None,
120            reply_parameters: None,
121            reply_markup: None,
122        }
123    }
124
125    /// Unique identifier of the business connection on behalf of which the message will be sent
126    #[must_use]
127    pub fn business_connection_id<T: Into<Box<str>>>(self, val: T) -> Self {
128        let mut this = self;
129        this.business_connection_id = Some(val.into());
130        this
131    }
132
133    /// Unique identifier of the business connection on behalf of which the message will be sent
134    #[must_use]
135    pub fn business_connection_id_option<T: Into<Box<str>>>(self, val: Option<T>) -> Self {
136        let mut this = self;
137        this.business_connection_id = val.map(Into::into);
138        this
139    }
140
141    /// Unique identifier for the target chat or username of the target channel (in the format @channelusername). Polls can't be sent to channel direct messages chats.
142    #[must_use]
143    pub fn chat_id<T: Into<crate::types::ChatIdKind>>(self, val: T) -> Self {
144        let mut this = self;
145        this.chat_id = val.into();
146        this
147    }
148
149    /// Unique identifier for the target message thread (topic) of a forum; for forum supergroups and private chats of bots with forum topic mode enabled only
150    #[must_use]
151    pub fn message_thread_id<T: Into<i64>>(self, val: T) -> Self {
152        let mut this = self;
153        this.message_thread_id = Some(val.into());
154        this
155    }
156
157    /// Unique identifier for the target message thread (topic) of a forum; for forum supergroups and private chats of bots with forum topic mode enabled only
158    #[must_use]
159    pub fn message_thread_id_option<T: Into<i64>>(self, val: Option<T>) -> Self {
160        let mut this = self;
161        this.message_thread_id = val.map(Into::into);
162        this
163    }
164
165    /// Poll question, 1-300 characters
166    #[must_use]
167    pub fn question<T: Into<Box<str>>>(self, val: T) -> Self {
168        let mut this = self;
169        this.question = val.into();
170        this
171    }
172
173    /// Mode for parsing entities in the question. See formatting options for more details. Currently, only custom emoji entities are allowed
174    #[must_use]
175    pub fn question_parse_mode<T: Into<Box<str>>>(self, val: T) -> Self {
176        let mut this = self;
177        this.question_parse_mode = Some(val.into());
178        this
179    }
180
181    /// Mode for parsing entities in the question. See formatting options for more details. Currently, only custom emoji entities are allowed
182    #[must_use]
183    pub fn question_parse_mode_option<T: Into<Box<str>>>(self, val: Option<T>) -> Self {
184        let mut this = self;
185        this.question_parse_mode = val.map(Into::into);
186        this
187    }
188
189    /// A JSON-serialized list of special entities that appear in the poll question. It can be specified instead of `question_parse_mode`
190    ///
191    /// # Notes
192    /// Adds multiple elements.
193    #[must_use]
194    pub fn question_entities<
195        TItem: Into<crate::types::MessageEntity>,
196        T: IntoIterator<Item = TItem>,
197    >(
198        self,
199        val: T,
200    ) -> Self {
201        let mut this = self;
202        this.question_entities = Some(
203            this.question_entities
204                .unwrap_or_default()
205                .into_vec()
206                .into_iter()
207                .chain(val.into_iter().map(Into::into))
208                .collect(),
209        );
210        this
211    }
212
213    /// A JSON-serialized list of special entities that appear in the poll question. It can be specified instead of `question_parse_mode`
214    ///
215    /// # Notes
216    /// Adds a single element.
217    #[must_use]
218    pub fn question_entity<T: Into<crate::types::MessageEntity>>(self, val: T) -> Self {
219        let mut this = self;
220        this.question_entities = Some(
221            this.question_entities
222                .unwrap_or_default()
223                .into_vec()
224                .into_iter()
225                .chain(Some(val.into()))
226                .collect(),
227        );
228        this
229    }
230
231    /// A JSON-serialized list of special entities that appear in the poll question. It can be specified instead of `question_parse_mode`
232    ///
233    /// # Notes
234    /// Adds multiple elements.
235    #[must_use]
236    pub fn question_entities_option<
237        TItem: Into<crate::types::MessageEntity>,
238        T: IntoIterator<Item = TItem>,
239    >(
240        self,
241        val: Option<T>,
242    ) -> Self {
243        let mut this = self;
244        this.question_entities = val.map(|v| v.into_iter().map(Into::into).collect());
245        this
246    }
247
248    /// A JSON-serialized list of 2-12 answer options
249    ///
250    /// # Notes
251    /// Adds multiple elements.
252    #[must_use]
253    pub fn options<TItem: Into<crate::types::InputPollOption>, T: IntoIterator<Item = TItem>>(
254        self,
255        val: T,
256    ) -> Self {
257        let mut this = self;
258        this.options = this
259            .options
260            .into_vec()
261            .into_iter()
262            .chain(val.into_iter().map(Into::into))
263            .collect();
264        this
265    }
266
267    /// A JSON-serialized list of 2-12 answer options
268    ///
269    /// # Notes
270    /// Adds a single element.
271    #[must_use]
272    pub fn option<T: Into<crate::types::InputPollOption>>(self, val: T) -> Self {
273        let mut this = self;
274        this.options = this
275            .options
276            .into_vec()
277            .into_iter()
278            .chain(Some(val.into()))
279            .collect();
280        this
281    }
282
283    /// `true`, if the poll needs to be anonymous, defaults to `true`
284    #[must_use]
285    pub fn is_anonymous<T: Into<bool>>(self, val: T) -> Self {
286        let mut this = self;
287        this.is_anonymous = Some(val.into());
288        this
289    }
290
291    /// `true`, if the poll needs to be anonymous, defaults to `true`
292    #[must_use]
293    pub fn is_anonymous_option<T: Into<bool>>(self, val: Option<T>) -> Self {
294        let mut this = self;
295        this.is_anonymous = val.map(Into::into);
296        this
297    }
298
299    /// Poll type, `quiz` or `regular`, defaults to `regular`
300    #[must_use]
301    pub fn r#type<T: Into<Box<str>>>(self, val: T) -> Self {
302        let mut this = self;
303        this.r#type = Some(val.into());
304        this
305    }
306
307    /// Poll type, `quiz` or `regular`, defaults to `regular`
308    #[must_use]
309    pub fn type_option<T: Into<Box<str>>>(self, val: Option<T>) -> Self {
310        let mut this = self;
311        this.r#type = val.map(Into::into);
312        this
313    }
314
315    /// `true`, if the poll allows multiple answers, ignored for polls in quiz mode, defaults to `false`
316    #[must_use]
317    pub fn allows_multiple_answers<T: Into<bool>>(self, val: T) -> Self {
318        let mut this = self;
319        this.allows_multiple_answers = Some(val.into());
320        this
321    }
322
323    /// `true`, if the poll allows multiple answers, ignored for polls in quiz mode, defaults to `false`
324    #[must_use]
325    pub fn allows_multiple_answers_option<T: Into<bool>>(self, val: Option<T>) -> Self {
326        let mut this = self;
327        this.allows_multiple_answers = val.map(Into::into);
328        this
329    }
330
331    /// 0-based identifier of the correct answer option, required for polls in quiz mode
332    #[must_use]
333    pub fn correct_option_id<T: Into<i64>>(self, val: T) -> Self {
334        let mut this = self;
335        this.correct_option_id = Some(val.into());
336        this
337    }
338
339    /// 0-based identifier of the correct answer option, required for polls in quiz mode
340    #[must_use]
341    pub fn correct_option_id_option<T: Into<i64>>(self, val: Option<T>) -> Self {
342        let mut this = self;
343        this.correct_option_id = val.map(Into::into);
344        this
345    }
346
347    /// Text that is shown when a user chooses an incorrect answer or taps on the lamp icon in a quiz-style poll, 0-200 characters with at most 2 line feeds after entities parsing
348    #[must_use]
349    pub fn explanation<T: Into<Box<str>>>(self, val: T) -> Self {
350        let mut this = self;
351        this.explanation = Some(val.into());
352        this
353    }
354
355    /// Text that is shown when a user chooses an incorrect answer or taps on the lamp icon in a quiz-style poll, 0-200 characters with at most 2 line feeds after entities parsing
356    #[must_use]
357    pub fn explanation_option<T: Into<Box<str>>>(self, val: Option<T>) -> Self {
358        let mut this = self;
359        this.explanation = val.map(Into::into);
360        this
361    }
362
363    /// Mode for parsing entities in the explanation. See formatting options for more details.
364    #[must_use]
365    pub fn explanation_parse_mode<T: Into<Box<str>>>(self, val: T) -> Self {
366        let mut this = self;
367        this.explanation_parse_mode = Some(val.into());
368        this
369    }
370
371    /// Mode for parsing entities in the explanation. See formatting options for more details.
372    #[must_use]
373    pub fn explanation_parse_mode_option<T: Into<Box<str>>>(self, val: Option<T>) -> Self {
374        let mut this = self;
375        this.explanation_parse_mode = val.map(Into::into);
376        this
377    }
378
379    /// A JSON-serialized list of special entities that appear in the poll explanation. It can be specified instead of `explanation_parse_mode`
380    ///
381    /// # Notes
382    /// Adds multiple elements.
383    #[must_use]
384    pub fn explanation_entities<
385        TItem: Into<crate::types::MessageEntity>,
386        T: IntoIterator<Item = TItem>,
387    >(
388        self,
389        val: T,
390    ) -> Self {
391        let mut this = self;
392        this.explanation_entities = Some(
393            this.explanation_entities
394                .unwrap_or_default()
395                .into_vec()
396                .into_iter()
397                .chain(val.into_iter().map(Into::into))
398                .collect(),
399        );
400        this
401    }
402
403    /// A JSON-serialized list of special entities that appear in the poll explanation. It can be specified instead of `explanation_parse_mode`
404    ///
405    /// # Notes
406    /// Adds a single element.
407    #[must_use]
408    pub fn explanation_entity<T: Into<crate::types::MessageEntity>>(self, val: T) -> Self {
409        let mut this = self;
410        this.explanation_entities = Some(
411            this.explanation_entities
412                .unwrap_or_default()
413                .into_vec()
414                .into_iter()
415                .chain(Some(val.into()))
416                .collect(),
417        );
418        this
419    }
420
421    /// A JSON-serialized list of special entities that appear in the poll explanation. It can be specified instead of `explanation_parse_mode`
422    ///
423    /// # Notes
424    /// Adds multiple elements.
425    #[must_use]
426    pub fn explanation_entities_option<
427        TItem: Into<crate::types::MessageEntity>,
428        T: IntoIterator<Item = TItem>,
429    >(
430        self,
431        val: Option<T>,
432    ) -> Self {
433        let mut this = self;
434        this.explanation_entities = val.map(|v| v.into_iter().map(Into::into).collect());
435        this
436    }
437
438    /// Amount of time in seconds the poll will be active after creation, 5-600. Can't be used together with `close_date`.
439    #[must_use]
440    pub fn open_period<T: Into<u16>>(self, val: T) -> Self {
441        let mut this = self;
442        this.open_period = Some(val.into());
443        this
444    }
445
446    /// Amount of time in seconds the poll will be active after creation, 5-600. Can't be used together with `close_date`.
447    #[must_use]
448    pub fn open_period_option<T: Into<u16>>(self, val: Option<T>) -> Self {
449        let mut this = self;
450        this.open_period = val.map(Into::into);
451        this
452    }
453
454    /// Point in time (Unix timestamp) when the poll will be automatically closed. Must be at least 5 and no more than 600 seconds in the future. Can't be used together with `open_period`.
455    #[must_use]
456    pub fn close_date<T: Into<i64>>(self, val: T) -> Self {
457        let mut this = self;
458        this.close_date = Some(val.into());
459        this
460    }
461
462    /// Point in time (Unix timestamp) when the poll will be automatically closed. Must be at least 5 and no more than 600 seconds in the future. Can't be used together with `open_period`.
463    #[must_use]
464    pub fn close_date_option<T: Into<i64>>(self, val: Option<T>) -> Self {
465        let mut this = self;
466        this.close_date = val.map(Into::into);
467        this
468    }
469
470    /// Pass `true` if the poll needs to be immediately closed. This can be useful for poll preview.
471    #[must_use]
472    pub fn is_closed<T: Into<bool>>(self, val: T) -> Self {
473        let mut this = self;
474        this.is_closed = Some(val.into());
475        this
476    }
477
478    /// Pass `true` if the poll needs to be immediately closed. This can be useful for poll preview.
479    #[must_use]
480    pub fn is_closed_option<T: Into<bool>>(self, val: Option<T>) -> Self {
481        let mut this = self;
482        this.is_closed = val.map(Into::into);
483        this
484    }
485
486    /// Sends the message silently. Users will receive a notification with no sound.
487    #[must_use]
488    pub fn disable_notification<T: Into<bool>>(self, val: T) -> Self {
489        let mut this = self;
490        this.disable_notification = Some(val.into());
491        this
492    }
493
494    /// Sends the message silently. Users will receive a notification with no sound.
495    #[must_use]
496    pub fn disable_notification_option<T: Into<bool>>(self, val: Option<T>) -> Self {
497        let mut this = self;
498        this.disable_notification = val.map(Into::into);
499        this
500    }
501
502    /// Protects the contents of the sent message from forwarding and saving
503    #[must_use]
504    pub fn protect_content<T: Into<bool>>(self, val: T) -> Self {
505        let mut this = self;
506        this.protect_content = Some(val.into());
507        this
508    }
509
510    /// Protects the contents of the sent message from forwarding and saving
511    #[must_use]
512    pub fn protect_content_option<T: Into<bool>>(self, val: Option<T>) -> Self {
513        let mut this = self;
514        this.protect_content = val.map(Into::into);
515        this
516    }
517
518    /// Pass `true` to allow up to 1000 messages per second, ignoring broadcasting limits for a fee of 0.1 Telegram Stars per message. The relevant Stars will be withdrawn from the bot's balance
519    #[must_use]
520    pub fn allow_paid_broadcast<T: Into<bool>>(self, val: T) -> Self {
521        let mut this = self;
522        this.allow_paid_broadcast = Some(val.into());
523        this
524    }
525
526    /// Pass `true` to allow up to 1000 messages per second, ignoring broadcasting limits for a fee of 0.1 Telegram Stars per message. The relevant Stars will be withdrawn from the bot's balance
527    #[must_use]
528    pub fn allow_paid_broadcast_option<T: Into<bool>>(self, val: Option<T>) -> Self {
529        let mut this = self;
530        this.allow_paid_broadcast = val.map(Into::into);
531        this
532    }
533
534    /// Unique identifier of the message effect to be added to the message; for private chats only
535    #[must_use]
536    pub fn message_effect_id<T: Into<Box<str>>>(self, val: T) -> Self {
537        let mut this = self;
538        this.message_effect_id = Some(val.into());
539        this
540    }
541
542    /// Unique identifier of the message effect to be added to the message; for private chats only
543    #[must_use]
544    pub fn message_effect_id_option<T: Into<Box<str>>>(self, val: Option<T>) -> Self {
545        let mut this = self;
546        this.message_effect_id = val.map(Into::into);
547        this
548    }
549
550    /// Description of the message to reply to
551    #[must_use]
552    pub fn reply_parameters<T: Into<crate::types::ReplyParameters>>(self, val: T) -> Self {
553        let mut this = self;
554        this.reply_parameters = Some(val.into());
555        this
556    }
557
558    /// Description of the message to reply to
559    #[must_use]
560    pub fn reply_parameters_option<T: Into<crate::types::ReplyParameters>>(
561        self,
562        val: Option<T>,
563    ) -> Self {
564        let mut this = self;
565        this.reply_parameters = val.map(Into::into);
566        this
567    }
568
569    /// Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove a reply keyboard or to force a reply from the user
570    #[must_use]
571    pub fn reply_markup<T: Into<crate::types::ReplyMarkup>>(self, val: T) -> Self {
572        let mut this = self;
573        this.reply_markup = Some(val.into());
574        this
575    }
576
577    /// Additional interface options. A JSON-serialized object for an inline keyboard, custom reply keyboard, instructions to remove a reply keyboard or to force a reply from the user
578    #[must_use]
579    pub fn reply_markup_option<T: Into<crate::types::ReplyMarkup>>(self, val: Option<T>) -> Self {
580        let mut this = self;
581        this.reply_markup = val.map(Into::into);
582        this
583    }
584}
585impl super::TelegramMethod for SendPoll {
586    type Method = Self;
587    type Return = crate::types::Message;
588
589    fn build_request<Client>(self, _bot: &Bot<Client>) -> super::Request<Self::Method> {
590        super::Request::new("sendPoll", self, None)
591    }
592}