From 670a7bd02b4a7c117376cc1a0c85ad3587733263 Mon Sep 17 00:00:00 2001 From: YoursFunny Date: Mon, 21 Sep 2026 13:49:21 +0800 Subject: [PATCH] fix: answer an inline query whose media Telegram cannot fetch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every item was skipped — `needs_media_headers` for pixiv's pximg.net, or a local ugoira/bsky MP4 that does not parse as a URL — and the function fell through to `Ok(false)`, which the debounce reads as "retry this query". The client got no answer at all (a spinner with nothing behind it) and every keystroke re-ran the fetch, while an unsatisfiable link is the *permanent* truth for that query: Telegram fetches inline result URLs itself and never sends a Referer. It now answers the empty result set with a 300 s window, so the client stops spinning and the same query is served from Telegram's cache and from the debounce (which only releases on a failure). A *failed* fetch still releases, so a retry is not answered from a stale empty answer. Verified with a real pixiv link through a real `Bot` against the stand-in API: `AnswerInlineQuery` with `results: []` and `cache_time: 300` (and `Ok(true)`, so no release). `cargo fmt --check`, `cargo clippy --workspace --all-targets --locked -- -D warnings` and `cargo test --workspace --locked` clean. --- crates/xmedia-bot/src/handlers/inline.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/crates/xmedia-bot/src/handlers/inline.rs b/crates/xmedia-bot/src/handlers/inline.rs index a705f80..a4775ef 100644 --- a/crates/xmedia-bot/src/handlers/inline.rs +++ b/crates/xmedia-bot/src/handlers/inline.rs @@ -135,8 +135,10 @@ pub async fn inline_query_handler(bot: Bot, query: InlineQuery) -> Result<(), Re } match answer_inline_query(bot, query).await { Ok(true) => {} - // No results produced (or nothing to answer): let a repeat of the - // same query retry the fetch. + // The fetch or the answer call failed: release so a repeat of the + // same query may retry it. An *empty* answer is a real answer + // (`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), } }); @@ -233,6 +235,18 @@ async fn answer_inline_query(bot: Bot, query: InlineQuery) -> Result {} Err(e) => log::error!("inline fetch [key={}]: {e}", log_key(&query.query)),