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(&self) -> Option<PeerRef> {
50 self.peers.get_ref(self.sender_id()).await
51 }
52
53 pub fn sender(&self) -> Option<&User> {
55 match self.peers.get(self.sender_id()) {
56 Some(Peer::User(user)) => Some(user),
57 None => None,
58 _ => unreachable!(),
59 }
60 }
61
62 pub fn text(&self) -> &str {
64 self.update().query.as_str()
65 }
66
67 pub fn offset(&self) -> &str {
69 self.update().offset.as_str()
70 }
71
72 pub fn answer<T>(&self, results: impl IntoIterator<Item = T>) -> Answer
75 where
76 T: Into<tl::enums::InputBotInlineResult>,
77 {
78 Answer {
79 request: tl::functions::messages::SetInlineBotResults {
80 gallery: false,
81 private: false,
82 query_id: self.update().query_id,
83 results: results.into_iter().map(Into::into).collect(),
84 cache_time: 0,
85 next_offset: None,
86 switch_pm: None,
87 switch_webview: None,
88 },
89 client: self.client.clone(),
90 }
91 }
92
93 pub fn peer_type(&self) -> Option<tl::enums::InlineQueryPeerType> {
95 self.update().peer_type.clone()
96 }
97
98 pub fn query_id(&self) -> i64 {
100 self.update().query_id
101 }
102}
103
104impl Answer {
105 pub fn gallery(mut self) -> Self {
107 self.request.gallery = true;
108 self
109 }
110
111 pub fn private(mut self) -> Self {
114 self.request.private = true;
115 self
116 }
117
118 pub fn cache_time(mut self, cache_time: i32) -> Self {
121 self.request.cache_time = cache_time;
122 self
123 }
124
125 pub fn next_offset(mut self, next_offset: impl Into<String>) -> Self {
128 self.request.next_offset = Some(next_offset.into());
129 self
130 }
131
132 pub fn switch_pm(mut self, text: impl Into<String>, start_param: impl Into<String>) -> Self {
135 self.request.switch_pm = Some(tl::enums::InlineBotSwitchPm::Pm(
136 tl::types::InlineBotSwitchPm {
137 text: text.into(),
138 start_param: start_param.into(),
139 },
140 ));
141 self
142 }
143
144 pub async fn send(self) -> Result<(), InvocationError> {
146 self.client.invoke(&self.request).await?;
147 Ok(())
148 }
149}
150
151#[derive(Debug)]
155pub struct Article {
156 pub raw: tl::types::InputBotInlineResult,
157}
158
159impl Article {
160 pub fn new<S: Into<String>, M: Into<InputMessage>>(title: S, input_message: M) -> Self {
164 let message = input_message.into();
165 Self {
166 raw: tl::types::InputBotInlineResult {
167 id: utils::generate_random_id().to_string(),
168 r#type: "article".into(),
169 title: Some(title.into()),
170 description: None,
171 url: None,
172 thumb: None,
173 content: None,
174 send_message: tl::enums::InputBotInlineMessage::Text(
176 tl::types::InputBotInlineMessageText {
177 no_webpage: !message.link_preview,
178 invert_media: message.invert_media,
179 message: message.text,
180 entities: Some(message.entities),
181 reply_markup: message.reply_markup,
182 },
183 ),
184 },
185 }
186 }
187
188 pub fn id(mut self, result_id: impl Into<String>) -> Self {
192 self.raw.id = result_id.into();
193 self
194 }
195
196 pub fn description(mut self, description: impl Into<String>) -> Self {
198 self.raw.description = Some(description.into());
199 self
200 }
201
202 pub fn url(mut self, url: impl Into<String>) -> Self {
204 self.raw.url = Some(url.into());
205 self
206 }
207
208 pub fn thumb_url(mut self, thumb_url: impl Into<String>) -> Self {
212 self.raw.thumb = Some(tl::enums::InputWebDocument::Document(
213 tl::types::InputWebDocument {
214 url: thumb_url.into(),
215 size: 0,
216 mime_type: "image/jpeg".into(),
217 attributes: vec![],
218 },
219 ));
220 self
221 }
222}
223
224impl From<Article> for tl::enums::InputBotInlineResult {
225 fn from(article: Article) -> Self {
226 tl::enums::InputBotInlineResult::Result(article.raw)
227 }
228}
229
230impl fmt::Debug for InlineQuery {
231 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
232 f.debug_struct("InlineQuery")
233 .field("text", &self.text())
234 .field("peer_type", &self.peer_type())
235 .field("sender", &self.sender())
236 .field("query_id", &self.query_id())
237 .finish()
238 }
239}