grammers_client/client/
bots.rs1use crate::client::messages::parse_mention_entities;
9use crate::utils::generate_random_id;
10use crate::Client;
11use crate::{types::IterBuffer, InputMessage};
12pub use grammers_mtsender::{AuthorizationError, InvocationError};
13use grammers_session::PackedChat;
14use grammers_tl_types as tl;
15
16const MAX_LIMIT: usize = 50;
17
18pub struct InlineResult {
19 client: Client,
20 query_id: i64,
21 result: tl::enums::BotInlineResult,
22}
23
24pub type InlineResultIter = IterBuffer<tl::functions::messages::GetInlineBotResults, InlineResult>;
25
26impl InlineResult {
27 pub async fn send<C: Into<PackedChat>>(&self, chat: C) -> Result<(), InvocationError> {
30 self.client
31 .invoke(&tl::functions::messages::SendInlineBotResult {
32 silent: false,
33 background: false,
34 clear_draft: false,
35 hide_via: false,
36 peer: chat.into().to_input_peer(),
37 reply_to: None,
38 random_id: generate_random_id(),
39 query_id: self.query_id,
40 id: self.id().to_string(),
41 schedule_date: None,
42 send_as: None,
43 quick_reply_shortcut: None,
44 })
45 .await
46 .map(drop)
47 }
48
49 pub fn id(&self) -> &str {
51 use tl::enums::BotInlineResult::*;
52
53 match &self.result {
54 Result(r) => &r.id,
55 BotInlineMediaResult(r) => &r.id,
56 }
57 }
58
59 pub fn title(&self) -> Option<&String> {
61 use tl::enums::BotInlineResult::*;
62
63 match &self.result {
64 Result(r) => r.title.as_ref(),
65 BotInlineMediaResult(r) => r.title.as_ref(),
66 }
67 }
68}
69
70impl InlineResultIter {
71 fn new(client: &Client, bot: PackedChat, query: &str) -> Self {
72 Self::from_request(
73 client,
74 MAX_LIMIT,
75 tl::functions::messages::GetInlineBotResults {
76 bot: bot.to_input_user_lossy(),
77 peer: tl::enums::InputPeer::Empty,
78 geo_point: None,
79 query: query.to_string(),
80 offset: String::new(),
81 },
82 )
83 }
84
85 pub fn chat<C: Into<PackedChat>>(mut self, chat: C) -> Self {
90 self.request.peer = chat.into().to_input_peer();
91 self
92 }
93
94 pub async fn next(&mut self) -> Result<Option<InlineResult>, InvocationError> {
99 if let Some(result) = self.next_raw() {
100 return result;
101 }
102
103 let tl::enums::messages::BotResults::Results(tl::types::messages::BotResults {
104 query_id,
105 next_offset,
106 results,
107 ..
108 }) = self.client.invoke(&self.request).await?;
109
110 if let Some(offset) = next_offset {
111 self.request.offset = offset;
112 } else {
113 self.last_chunk = true;
114 }
115
116 let client = self.client.clone();
117 self.buffer
118 .extend(results.into_iter().map(|r| InlineResult {
119 client: client.clone(),
120 query_id,
121 result: r,
122 }));
123
124 Ok(self.pop_item())
125 }
126}
127
128impl Client {
130 pub fn inline_query<C: Into<PackedChat>>(&self, bot: C, query: &str) -> InlineResultIter {
153 InlineResultIter::new(self, bot.into(), query)
154 }
155
156 pub async fn edit_inline_message<M: Into<InputMessage>>(
157 &self,
158 message_id: tl::enums::InputBotInlineMessageId,
159 input_message: M,
160 ) -> Result<bool, InvocationError> {
161 let message: InputMessage = input_message.into();
162 let entities = parse_mention_entities(self, message.entities);
163 let dc_id = message_id.dc_id();
164 let result = self
165 .invoke_in_dc(
166 &tl::functions::messages::EditInlineBotMessage {
167 id: message_id,
168 message: Some(message.text),
169 media: message.media,
170 entities,
171 no_webpage: !message.link_preview,
172 reply_markup: message.reply_markup,
173 invert_media: message.invert_media,
174 },
175 dc_id,
176 )
177 .await?;
178 Ok(result)
179 }
180}