Skip to main content

grammers_client/update/
inline_send.rs

1// Copyright 2020 - developers of the `grammers` project.
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9use std::fmt;
10
11use grammers_mtsender::InvocationError;
12use grammers_session::types::{PeerId, PeerRef};
13use grammers_session::updates::State;
14use grammers_tl_types as tl;
15
16use crate::Client;
17use crate::message::InputMessage;
18use crate::peer::{Peer, PeerMap, User};
19
20/// Update that bots receive when a user chooses an inline query result.
21///
22/// To receive this update, "Inline Feedback" under "Bot Settings" must be enabled via [@BotFather](https://t.me/BotFather).
23#[derive(Clone)]
24pub struct InlineSend {
25    pub raw: tl::enums::Update,
26    pub state: State,
27    pub(crate) client: Client,
28    pub(crate) peers: PeerMap,
29}
30
31impl InlineSend {
32    fn update(&self) -> &tl::types::UpdateBotInlineSend {
33        match &self.raw {
34            tl::enums::Update::BotInlineSend(update) => update,
35            _ => unreachable!(),
36        }
37    }
38
39    /// The query that was used to obtain the result.
40    pub fn text(&self) -> &str {
41        self.update().query.as_str()
42    }
43
44    /// The [`Self::sender`]'s identifier.
45    pub fn sender_id(&self) -> PeerId {
46        PeerId::user_unchecked(self.update().user_id)
47    }
48
49    /// Cached reference to the [`Self::sender`], if it is in cache.
50    pub async fn sender_ref(&self) -> Option<PeerRef> {
51        self.peers.get_ref(self.sender_id()).await
52    }
53
54    /// The user that chose the result, if it is in cache.
55    pub fn sender(&self) -> Option<&User> {
56        match self.peers.get(self.sender_id()) {
57            Some(Peer::User(user)) => Some(user),
58            None => None,
59            _ => unreachable!(),
60        }
61    }
62
63    /// The unique identifier for the result that was chosen
64    pub fn result_id(&self) -> &str {
65        self.update().id.as_str()
66    }
67
68    /// Identifier of sent inline message.
69    /// Available only if there is an inline keyboard attached.
70    /// Will be also received in callback queries and can be used to edit the message.
71    pub fn message_id(&self) -> Option<tl::enums::InputBotInlineMessageId> {
72        self.update().msg_id.clone()
73    }
74
75    /// Edits this inline message.
76    ///
77    /// **This method will return Ok(None) if message id is None (e.g. if an inline keyboard is not attached)**
78    pub async fn edit_message(
79        &self,
80        input_message: impl Into<InputMessage>,
81    ) -> Result<Option<bool>, InvocationError> {
82        let msg_id = match self.update().msg_id.clone() {
83            None => return Ok(None),
84            Some(msg_id) => msg_id,
85        };
86
87        Ok(Some(
88            self.client
89                .edit_inline_message(msg_id, input_message.into())
90                .await?,
91        ))
92    }
93}
94
95impl fmt::Debug for InlineSend {
96    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
97        f.debug_struct("InlineSend")
98            .field("text", &self.text())
99            .field("sender", &self.sender())
100            .field("result_id", &self.result_id())
101            .field("message_id", &self.message_id())
102            .finish()
103    }
104}