Помогите с inline кнопками telegram bot python
В общем простой поисковый бот по БД sqlite с выдачей в бот в виде списка записей. В связи с ограничениеми телеграм на длину текста, принято решение выдавать записи по 20 шт и кнопками пагинации перелистывать. Проблема в том что при повторном запросе пропадают кнопки пререлистывания. видимо бот не сбрасывает из памяти номер page. есть вариант сбрасывать состояние пользователя через await state.reset_state() но это не удобно перезапускать каждый раз бот при повторном поиске. Как можно решить проблему?
import sqlite3
from aiogram.dispatcher import Dispatcher
from aiogram.types import CallbackQuery
from aiogram.dispatcher.filters import Text
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton, CallbackQuery as CQ
from aiogram.utils.exceptions import MessageTextIsEmpty
from aiogram.dispatcher import FSMContext
from aiogram import executor
from aiogram import Bot, Dispatcher, types
from aiogram.contrib.fsm_storage.memory import MemoryStorage
# Создаем экземпляр бота
bot = Bot(token='', parse_mode=types.ParseMode.HTML)
storage = MemoryStorage()
dp = Dispatcher(bot, storage=storage)
# Обработчик нажатий на кнопки клавиатуры
@dp.callback_query_handler(Text('prev_page'), state='*')
@dp.callback_query_handler(Text('next_page'), state='*')
async def process_pagination_buttons(callback_query: CQ, state: FSMContext):
# Получаем текущую страницу из состояния
data = await state.get_data()
page = data.get('page', 0)
# Обновляем номер страницы в зависимости от нажатой кнопки
if callback_query.data == 'prev_page':
page -= 1
elif callback_query.data == 'next_page':
page += 1
# Сохраняем номер страницы в состоянии
await state.update_data(page=page)
# Получаем список книг из базы данных
conn = sqlite3.connect('ru.db')
cursor = conn.cursor()
search_text = data.get('search_text', '')
offset = page * 20
limit = 20
cursor.execute(f"SELECT fullname FROM abooks WHERE fullname LIKE '%{search_text}%' LIMIT {limit} OFFSET {offset}")
books = cursor.fetchall()
results = cursor.fetchmany()
num_rows = str(len(books))
keyboard = InlineKeyboardMarkup(row_width=2)
if page > 0:
keyboard.row(InlineKeyboardButton('<< Назад', callback_data='prev_page'))
if int(num_rows) == 20:
keyboard.row(InlineKeyboardButton('Далее >>', callback_data='next_page'))
print(num_rows)
# Формируем сообщение
message_text = 'Результаты поиска:\n\n'
for book in books:
message_text += f"{book}\n"
# Обновляем сообщение с результатами поиска и клавиатурой
try:
await bot.edit_message_text(chat_id=callback_query.message.chat.id, message_id=callback_query.message.message_id, text=message_text, reply_markup=keyboard)
except MessageTextIsEmpty:
pass
# Закрываем соединение с базой данных
cursor.close()
conn.close()
# Обработчик текстовых сообщений
# Обработчик текстовых сообщений
@dp.message_handler(content_types=types.ContentTypes.TEXT)
async def process_text_message(message: types.Message, state: FSMContext):
# Сохраняем текст запроса в состоянии
await state.update_data(search_text=message.text)
# Получаем список книг из базы данных
conn = sqlite3.connect('ru.db')
cursor = conn.cursor()
search_text = message.text
offset = 0
limit = 20
cursor.execute(f"SELECT fullname FROM abooks WHERE fullname LIKE '%{search_text}%' LIMIT {limit} OFFSET {offset}")
results = cursor.fetchmany()
books = cursor.fetchall()
num_rows = str(len(search_text))
# Формируем сообщение
message_text = 'Результаты поиска:\n\n'
for book in books:
message_text += f"{book}\n"
# Создаем клавиатуру для пагинации
data = await state.get_data()
page = data.get('page', 0)
keyboard = InlineKeyboardMarkup(row_width=2)
if page == 0:
keyboard.row(InlineKeyboardButton('Далее >>', callback_data='next_page'))
print(page)
# Удаляем предыдущее сообщение, если оно было отправлено
if 'last_message_id' in data:
try:
await bot.delete_message(chat_id=message.chat.id, message_id=data['last_message_id'])
except Exception as e:
print(f"Failed to delete message: {e}")
# Создаем новое сообщение и клавиатуру
try:
sent_message = await bot.send_message(chat_id=message.chat.id, text=message_text, reply_markup=keyboard)
await state.update_data(last_message_id=sent_message.message_id)
except MessageTextIsEmpty:
pass
# Закрываем соединение с базой данных
cursor.close()
conn.close()
if __name__ == '__main__':
executor.start_polling(dp, skip_updates=True)