Skip to main content

ferogram/client/
polls.rs

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