Skip to main content

ferogram/client/
polls.rs

1/*
2 * Copyright (c) 2026 Ankit Chaubey <ankitchaubey.dev@gmail.com>
3 * https://github.com/ankit-chaubey
4 *
5 * Project: ferogram
6 * Website: https://ferogram.dev
7 *
8 * Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
9 * https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
10 * <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
11 * This file may not be copied, modified, or distributed except according
12 * to those terms.
13 */
14
15#[allow(unused_imports)]
16use super::random_i64;
17use crate::*;
18#[allow(unused_imports)]
19use crate::{
20    InputMessage, InvocationError, PeerRef,
21    dialog::{Dialog, DialogIter, MessageIter},
22    inline_iter, media, participants, search, update,
23};
24#[allow(unused_imports)]
25use ferogram_tl_types::{Cursor, Deserializable};
26
27impl Client {
28    /// Send a poll, built with [`crate::poll::PollBuilder`].
29    pub async fn send_poll(
30        &self,
31        peer: impl Into<PeerRef>,
32        poll: crate::poll::PollBuilder,
33    ) -> Result<(), InvocationError> {
34        let peer = peer.into().resolve(self).await?;
35        let input_peer = self.inner.peer_cache.read().await.peer_to_input(&peer)?;
36        let media = poll.into_input_media();
37        let req = tl::functions::messages::SendMedia {
38            silent: false,
39            background: false,
40            clear_draft: false,
41            noforwards: false,
42            update_stickersets_order: false,
43            invert_media: false,
44            allow_paid_floodskip: false,
45            peer: input_peer,
46            reply_to: None,
47            media,
48            message: String::new(),
49            random_id: random_i64(),
50            reply_markup: None,
51            entities: None,
52            schedule_date: None,
53            schedule_repeat_period: None,
54            send_as: None,
55            quick_reply_shortcut: None,
56            effect: None,
57            allow_paid_stars: None,
58            suggested_post: None,
59        };
60        self.rpc_call_raw(&req).await?;
61        Ok(())
62    }
63
64    /// Vote on a poll. `options` are the option byte identifiers from the
65    /// poll's own answer list, not their text or index - pass more than one
66    /// only if the poll allows multiple choice.
67    pub async fn send_vote(
68        &self,
69        peer: impl Into<PeerRef>,
70        msg_id: i32,
71        options: Vec<Vec<u8>>,
72    ) -> Result<(), InvocationError> {
73        let peer = peer.into().resolve(self).await?;
74        let input_peer = self.inner.peer_cache.read().await.peer_to_input(&peer)?;
75        let req = tl::functions::messages::SendVote {
76            peer: input_peer,
77            msg_id,
78            options,
79        };
80        self.rpc_write(&req).await
81    }
82
83    /// Get statistics for a poll message.
84    pub async fn poll_results(
85        &self,
86        peer: impl Into<PeerRef>,
87        msg_id: i32,
88    ) -> Result<tl::types::stats::PollStats, InvocationError> {
89        let peer = peer.into().resolve(self).await?;
90        let input_peer = self.inner.peer_cache.read().await.peer_to_input(&peer)?;
91        let req = tl::functions::stats::GetPollStats {
92            dark: false,
93            peer: input_peer,
94            msg_id,
95        };
96        let body = self.rpc_call_raw(&req).await?;
97        let mut cur = Cursor::from_slice(&body);
98        let tl::enums::stats::PollStats::PollStats(result) =
99            tl::enums::stats::PollStats::deserialize(&mut cur)?;
100        Ok(result)
101    }
102
103    /// List who voted for what on a poll. Pass `option` to filter to one
104    /// specific answer, or `None` for everyone; `offset`/`limit` page
105    /// through results.
106    pub async fn get_poll_votes(
107        &self,
108        peer: impl Into<PeerRef>,
109        msg_id: i32,
110        option: Option<Vec<u8>>,
111        limit: i32,
112        offset: Option<String>,
113    ) -> Result<tl::types::messages::VotesList, InvocationError> {
114        let peer = peer.into().resolve(self).await?;
115        let input_peer = self.inner.peer_cache.read().await.peer_to_input(&peer)?;
116        let req = tl::functions::messages::GetPollVotes {
117            peer: input_peer,
118            id: msg_id,
119            option,
120            offset,
121            limit,
122        };
123        let body = self.rpc_call_raw(&req).await?;
124        let mut cur = Cursor::from_slice(&body);
125        let tl::enums::messages::VotesList::VotesList(result) =
126            tl::enums::messages::VotesList::deserialize(&mut cur)?;
127        self.cache_users_slice(&result.users).await;
128        self.cache_chats_slice(&result.chats).await;
129        Ok(result)
130    }
131}