use grammers_mtsender::InvocationError;
use grammers_session::types::PeerRef;
use grammers_tl_types as tl;
use super::messages::parse_mention_entities;
use super::{Client, IterBuffer};
use crate::message::InputMessage;
use crate::utils::generate_random_id;
const MAX_LIMIT: usize = 50;
pub struct InlineResult {
client: Client,
query_id: i64,
pub raw: tl::enums::BotInlineResult,
}
pub type InlineResultIter = IterBuffer<tl::functions::messages::GetInlineBotResults, InlineResult>;
impl InlineResult {
pub async fn send<C: Into<PeerRef>>(&self, peer: C) -> Result<(), InvocationError> {
self.client
.invoke(&tl::functions::messages::SendInlineBotResult {
silent: false,
background: false,
clear_draft: false,
hide_via: false,
peer: peer.into().into(),
reply_to: None,
random_id: generate_random_id(),
query_id: self.query_id,
id: self.id().to_string(),
schedule_date: None,
send_as: None,
quick_reply_shortcut: None,
allow_paid_stars: None,
})
.await
.map(drop)
}
pub fn id(&self) -> &str {
use tl::enums::BotInlineResult::*;
match &self.raw {
Result(r) => &r.id,
BotInlineMediaResult(r) => &r.id,
}
}
pub fn title(&self) -> Option<&String> {
use tl::enums::BotInlineResult::*;
match &self.raw {
Result(r) => r.title.as_ref(),
BotInlineMediaResult(r) => r.title.as_ref(),
}
}
}
impl InlineResultIter {
fn new(client: &Client, bot: PeerRef, query: &str) -> Self {
Self::from_request(
client,
MAX_LIMIT,
tl::functions::messages::GetInlineBotResults {
bot: bot.into(),
peer: tl::enums::InputPeer::Empty,
geo_point: None,
query: query.to_string(),
offset: String::new(),
},
)
}
pub fn peer<C: Into<PeerRef>>(mut self, peer: C) -> Self {
self.request.peer = peer.into().into();
self
}
pub async fn next(&mut self) -> Result<Option<InlineResult>, InvocationError> {
if let Some(result) = self.next_raw() {
return result;
}
let tl::enums::messages::BotResults::Results(tl::types::messages::BotResults {
query_id,
next_offset,
results,
..
}) = self.client.invoke(&self.request).await?;
if let Some(offset) = next_offset {
self.request.offset = offset;
} else {
self.last_chunk = true;
}
let client = self.client.clone();
self.buffer
.extend(results.into_iter().map(|r| InlineResult {
client: client.clone(),
query_id,
raw: r,
}));
Ok(self.pop_item())
}
}
impl Client {
pub fn inline_query<C: Into<PeerRef>>(&self, bot: C, query: &str) -> InlineResultIter {
InlineResultIter::new(self, bot.into(), query)
}
pub(crate) async fn edit_inline_message(
&self,
message_id: tl::enums::InputBotInlineMessageId,
message: InputMessage,
) -> Result<bool, InvocationError> {
let entities = parse_mention_entities(self, message.entities).await;
if message.media.as_ref().is_some_and(|media| {
!matches!(
media,
tl::enums::InputMedia::PhotoExternal(_)
| tl::enums::InputMedia::DocumentExternal(_),
)
}) {
let dc_id = message_id.dc_id();
self.invoke_in_dc(
dc_id,
&tl::functions::messages::EditInlineBotMessage {
id: message_id,
message: Some(message.text),
media: message.media,
entities,
no_webpage: !message.link_preview,
reply_markup: message.reply_markup,
invert_media: message.invert_media,
},
)
.await
} else {
self.invoke(&tl::functions::messages::EditInlineBotMessage {
id: message_id,
message: Some(message.text),
media: message.media,
entities,
no_webpage: !message.link_preview,
reply_markup: message.reply_markup,
invert_media: message.invert_media,
})
.await
}
}
}