Inline-поиск
Что получится
Пользователь вызовет бота из поля ввода обычного клиента Скрепы, увидит
текстовые варианты и отправит выбранный результат в текущий диалог. Бот также
получит chosen_inline_result.
Что понадобится
- выполненный quickstart по созданию бота и запуску gateway;
- gateway профиля
telegram-v1-core-preview-4наhttp://127.0.0.1:8081; - Python 3,
python-telegram-bot 22.8иSKREPA_BOT_TOKEN; - обычный клиент Скрепы, вошедший под пользовательской учётной записью.
Inline session всегда инициирует обычный клиент. Вызов answerInlineQuery
отвечает на уже открытую сессию и сам по себе её не создаёт.
Запускаем inline-бота
python3 -m venv .venv
.venv/bin/python -m pip install 'python-telegram-bot==22.8'
Сохраните как inline_bot.py:
import os
import uuid
from telegram import InlineQueryResultArticle, InputTextMessageContent, Update
from telegram.ext import (
Application,
ChosenInlineResultHandler,
ContextTypes,
InlineQueryHandler,
)
async def search(update: Update, _context: ContextTypes.DEFAULT_TYPE) -> None:
query = update.inline_query.query.strip()
shown = query or "пустой запрос"
await update.inline_query.answer(
[
InlineQueryResultArticle(
id=uuid.uuid4().hex,
title=f"Отправить: {shown}",
description="Текст попадёт в текущий диалог",
input_message_content=InputTextMessageContent(
f"Результат inline-поиска: {shown}"
),
)
],
is_personal=True,
cache_time=0,
)
async def chosen(update: Update, _context: ContextTypes.DEFAULT_TYPE) -> None:
result = update.chosen_inline_result
print(
f"chosen result_id={result.result_id} query={result.query!r}",
flush=True,
)
application = (
Application.builder()
.token(os.environ["SKREPA_BOT_TOKEN"])
.base_url("http://127.0.0.1:8081/bot")
.base_file_url("http://127.0.0.1:8081/file/bot")
.build()
)
application.add_handler(InlineQueryHandler(search))
application.add_handler(ChosenInlineResultHandler(chosen))
application.run_polling(
allowed_updates=["inline_query", "chosen_inline_result"]
)
Запустите .venv/bin/python inline_bot.py.
Действия в клиенте Скрепы
- Откройте любой приватный диалог обычного пользователя.
- В поле ввода наберите
@username_бота поисковая фраза. - Выберите появившуюся карточку.
- Убедитесь, что в диалог отправлен текст
Результат inline-поиска: поисковая фраза.
В терминале бота должна появиться строка chosen result_id=.... Выбор
закрывает inline session. Gateway сохраняет cursor в state_dir, поэтому его
рестарт не создаёт второй update для той же сессии.
Как проверить HTTP-контракт
Если вы обрабатываете updates вручную, найдите inline_query.id через
getUpdates, затем ответьте:
set -o pipefail
curl --fail-with-body -sS \
-H 'content-type: application/json' \
-d "$(jq -n --arg id "$INLINE_QUERY_ID" '{
inline_query_id: $id,
results: [{
type: "article",
id: "curl-result-1",
title: "Ответ curl",
input_message_content: {
message_text: "Inline-результат из curl"
}
}]
}')" \
"http://127.0.0.1:8081/bot${SKREPA_BOT_TOKEN}/answerInlineQuery" | jq .
INLINE_QUERY_ID относится к конкретному боту и активен пять минут.
Типичные ошибки
- Inline query не появляется: пользователь открыл обычный диалог с ботом вместо inline-вызова из поля ввода другого диалога.
- Бот получает другие updates: при явном фильтре забыты
inline_queryилиchosen_inline_result. 400при ответе: повторяютсяidрезультатов, передан неподдерживаемый тип либо отсутствует текстовыйinput_message_content.- Ответ после выбора или долгой паузы отклонён: сессия закрыта выбором или истекла через пять минут по серверному времени.
- Результаты не обновились: повторный ответ должен содержать весь новый список; он целиком заменяет прежний.
Границы поддержки
Профиль принимает inline results типа article с
InputTextMessageContent. Media results, inline media upload и другие типы
результатов пока не поддерживаются. Выбранный текст отправляет клиент по
обычному E2E-пути после выбора.