grammers_client/update/
inline_query.rs1use 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::message::InputMessage;
17use crate::peer::{Peer, PeerMap, User};
18use crate::{Client, utils};
19
20#[derive(Clone)]
22pub struct InlineQuery {
23 pub raw: tl::enums::Update,
24 pub state: State,
25 pub(crate) client: Client,
26 pub(crate) peers: PeerMap,
27}
28
29pub struct Answer {
31 request: tl::functions::messages::SetInlineBotResults,
32 client: Client,
33}
34
35impl InlineQuery {
36 fn update(&self) -> &tl::types::UpdateBotInlineQuery {
37 match &self.raw {
38 tl::enums::Update::BotInlineQuery(update) => update,
39 _ => unreachable!(),
40 }
41 }
42
43 pub fn sender_id(&self) -> PeerId {
45 PeerId::user_unchecked(self.update().user_id)
46 }
47
48 pub async fn sender_ref(
50 &self,
51 ) -> Result<Option<PeerRef>, Box<dyn std::error::Error + Send + Sync>> {
52 self.peers.get_ref(self.sender_id()).await
53 }
54
55 pub fn sender(&self) -> Option<&User> {
57 match self.peers.get(self.sender_id()) {
58 Some(Peer::User(user)) => Some(user),
59 None => None,
60 _ => unreachable!(),
61 }
62 }
63
64 pub fn text(&self) -> &str {
66 self.update().query.as_str()
67 }
68
69 pub fn offset(&self) -> &str {
71 self.update().offset.as_str()
72 }
73
74 pub fn answer<T>(&self, results: impl IntoIterator<Item = T>) -> Answer
77 where
78 T: Into<tl::enums::InputBotInlineResult>,
79 {
80 Answer {
81 request: tl::functions::messages::SetInlineBotResults {
82 gallery: false,
83 private: false,
84 query_id: self.update().query_id,
85 results: results.into_iter().map(Into::into).collect(),
86 cache_time: 0,
87 next_offset: None,
88 switch_pm: None,
89 switch_webview: None,
90 },
91 client: self.client.clone(),
92 }
93 }
94
95 pub fn peer_type(&self) -> Option<tl::enums::InlineQueryPeerType> {
97 self.update().peer_type.clone()
98 }
99
100 pub fn query_id(&self) -> i64 {
102 self.update().query_id
103 }
104}
105
106impl Answer {
107 pub fn gallery(mut self) -> Self {
109 self.request.gallery = true;
110 self
111 }
112
113 pub fn private(mut self) -> Self {
116 self.request.private = true;
117 self
118 }
119
120 pub fn cache_time(mut self, cache_time: i32) -> Self {
123 self.request.cache_time = cache_time;
124 self
125 }
126
127 pub fn next_offset(mut self, next_offset: impl Into<String>) -> Self {
130 self.request.next_offset = Some(next_offset.into());
131 self
132 }
133
134 pub fn switch_pm(mut self, text: impl Into<String>, start_param: impl Into<String>) -> Self {
137 self.request.switch_pm = Some(tl::enums::InlineBotSwitchPm::Pm(
138 tl::types::InlineBotSwitchPm {
139 text: text.into(),
140 start_param: start_param.into(),
141 },
142 ));
143 self
144 }
145
146 pub async fn send(self) -> Result<(), InvocationError> {
148 self.client.invoke(&self.request).await?;
149 Ok(())
150 }
151}
152
153#[derive(Debug)]
157pub struct Article {
158 pub raw: tl::types::InputBotInlineResult,
159}
160
161impl Article {
162 pub fn new<S: Into<String>, M: Into<InputMessage>>(title: S, input_message: M) -> Self {
166 let message = input_message.into();
167 Self {
168 raw: tl::types::InputBotInlineResult {
169 id: utils::generate_random_id().to_string(),
170 r#type: "article".into(),
171 title: Some(title.into()),
172 description: None,
173 url: None,
174 thumb: None,
175 content: None,
176 send_message: tl::enums::InputBotInlineMessage::Text(
178 tl::types::InputBotInlineMessageText {
179 no_webpage: !message.link_preview,
180 invert_media: message.invert_media,
181 message: message.text,
182 entities: Some(message.entities),
183 reply_markup: message.reply_markup,
184 },
185 ),
186 },
187 }
188 }
189
190 pub fn id(mut self, result_id: impl Into<String>) -> Self {
194 self.raw.id = result_id.into();
195 self
196 }
197
198 pub fn description(mut self, description: impl Into<String>) -> Self {
200 self.raw.description = Some(description.into());
201 self
202 }
203
204 pub fn url(mut self, url: impl Into<String>) -> Self {
206 self.raw.url = Some(url.into());
207 self
208 }
209
210 pub fn thumb_url(mut self, thumb_url: impl Into<String>) -> Self {
214 self.raw.thumb = Some(tl::enums::InputWebDocument::Document(
215 tl::types::InputWebDocument {
216 url: thumb_url.into(),
217 size: 0,
218 mime_type: "image/jpeg".into(),
219 attributes: vec![],
220 },
221 ));
222 self
223 }
224}
225
226impl From<Article> for tl::enums::InputBotInlineResult {
227 fn from(article: Article) -> Self {
228 tl::enums::InputBotInlineResult::Result(article.raw)
229 }
230}
231
232impl fmt::Debug for InlineQuery {
233 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
234 f.debug_struct("InlineQuery")
235 .field("text", &self.text())
236 .field("peer_type", &self.peer_type())
237 .field("sender", &self.sender())
238 .field("query_id", &self.query_id())
239 .finish()
240 }
241}