mirror of
https://github.com/TheFunny/TelegramTwitterMediaBot.git
synced 2026-10-05 01:12:06 +00:00
fix: always answer inline query
This commit is contained in:
@@ -114,16 +114,10 @@ static INLINE_DEBOUNCE_STATE: LazyLock<parking_lot::Mutex<DebounceStates>> =
|
|||||||
LazyLock::new(|| parking_lot::Mutex::new(DebounceStates::default()));
|
LazyLock::new(|| parking_lot::Mutex::new(DebounceStates::default()));
|
||||||
|
|
||||||
pub async fn inline_query_handler(bot: Bot, query: InlineQuery) -> Result<(), RequestError> {
|
pub async fn inline_query_handler(bot: Bot, query: InlineQuery) -> Result<(), RequestError> {
|
||||||
if query.query.is_empty() {
|
let ctx = AppContext::from_statics(&bot);
|
||||||
return respond(());
|
if query.query.is_empty() || x_media::site::cache_key(&query.query).is_none() {
|
||||||
|
return answer_inline_query(&ctx, query).await.map(|_| ());
|
||||||
}
|
}
|
||||||
// Only run a fetch for something that is actually a supported post URL.
|
|
||||||
if x_media::site::cache_key(&query.query).is_none() {
|
|
||||||
return respond(());
|
|
||||||
}
|
|
||||||
// Debounce: record the query and answer only after it has been stable for
|
|
||||||
// INLINE_DEBOUNCE (the timer below). An already-answered repeat of the
|
|
||||||
// same query is left to Telegram's inline cache instead of re-fetching.
|
|
||||||
let user_id = query.from.id.0;
|
let user_id = query.from.id.0;
|
||||||
if !INLINE_DEBOUNCE_STATE.lock().note(user_id, &query.query) {
|
if !INLINE_DEBOUNCE_STATE.lock().note(user_id, &query.query) {
|
||||||
return respond(());
|
return respond(());
|
||||||
@@ -131,19 +125,15 @@ pub async fn inline_query_handler(bot: Bot, query: InlineQuery) -> Result<(), Re
|
|||||||
let query_text = query.query.clone();
|
let query_text = query.query.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
tokio::time::sleep(INLINE_DEBOUNCE).await;
|
tokio::time::sleep(INLINE_DEBOUNCE).await;
|
||||||
// Only the user's last query of a typing burst survives: earlier
|
|
||||||
// timers see the query changed and give up without answering.
|
|
||||||
if !INLINE_DEBOUNCE_STATE.lock().claim(user_id, &query_text) {
|
if !INLINE_DEBOUNCE_STATE.lock().claim(user_id, &query_text) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let ctx = AppContext::from_statics(&bot);
|
let ctx = AppContext::from_statics(&bot);
|
||||||
match answer_inline_query(&ctx, query).await {
|
match answer_inline_query(&ctx, query).await {
|
||||||
Ok(true) => {}
|
Ok(true) => {}
|
||||||
// The fetch or the answer call failed: release so a repeat of the
|
Ok(false) | Err(_) => {
|
||||||
// same query may retry it. An *empty* answer is a real answer
|
INLINE_DEBOUNCE_STATE.lock().release(user_id, &query_text);
|
||||||
// (`Ok(true)`), so a link whose media Telegram cannot fetch is not
|
}
|
||||||
// re-fetched on every keystroke.
|
|
||||||
Ok(false) | Err(_) => INLINE_DEBOUNCE_STATE.lock().release(user_id, &query_text),
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
respond(())
|
respond(())
|
||||||
@@ -160,7 +150,8 @@ async fn answer_inline_query(
|
|||||||
log::debug!("inline query [key={}]", log_key(&query.query));
|
log::debug!("inline query [key={}]", log_key(&query.query));
|
||||||
log::trace!("inline query: {}", query.query);
|
log::trace!("inline query: {}", query.query);
|
||||||
let Some(key) = x_media::site::cache_key(&query.query) else {
|
let Some(key) = x_media::site::cache_key(&query.query) else {
|
||||||
return Ok(false);
|
answer(ctx.sender, query.id, Vec::new()).await?;
|
||||||
|
return Ok(true);
|
||||||
};
|
};
|
||||||
// A post that was already sent to some chat is answered from the link
|
// A post that was already sent to some chat is answered from the link
|
||||||
// cache: its Telegram file ids make the answer instant, and — unlike a URL
|
// cache: its Telegram file ids make the answer instant, and — unlike a URL
|
||||||
@@ -237,10 +228,17 @@ async fn answer_inline_query(
|
|||||||
answer(ctx.sender, query.id, results).await?;
|
answer(ctx.sender, query.id, results).await?;
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
Ok(None) => {}
|
Ok(None) | Err(_) => {
|
||||||
Err(e) => log::error!("inline fetch [key={}]: {e}", log_key(&query.query)),
|
if let Err(e) = answer(ctx.sender, query.id, Vec::new()).await {
|
||||||
|
log::error!(
|
||||||
|
"inline empty answer failed for [key={}]: {e}",
|
||||||
|
log_key(&query.query)
|
||||||
|
);
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
|
return Ok(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The caption of an inline answer, from a cached post: the caption that was
|
/// The caption of an inline answer, from a cached post: the caption that was
|
||||||
|
|||||||
Reference in New Issue
Block a user