Недавно встала передо мной задача сделать пагинацию списка элементов в телеграм боте. И с удивлением обнаружила, что для такой, казалось бы типовой задачи в PyPi нет ни одной библиотеки. Поэтому решено было исправить это досадное упущение и опубликовать свою реализацию.


Установить пакет можно из PyPi, выполнив в консоли:


pip install python-telegram-bot-pagination

Класс InlineKeyboardPaginator из пакета telegram_bot_pagination позволяет легко получить набор inline-кнопок для перемещения по страницам списка. В конструктор необходимо передать количество страниц, на которое разбит список элементов, а так же текущую страницу и паттерн для формирования данных, возвращаемых по нажатию на кнопку боту. После чего пагинатор сам сформирует необходимую клавиатуру, которая будет доступна через свойство markup.


from telegram_bot_pagination import InlineKeyboardPaginator

paginator = InlineKeyboardPaginator(
        10,
        current_page=1,
        data_pattern='elements#{page}'
    )

Теперь paginator.markup вернет json объект для поля reply_markup метода sendMessage Telegram Bot API. В данном случае будет сформированы пять кнопок. Если количество страниц пять или меньше, то кнопок будет соответственно. Если страница только одна, то markup будет пустым. В случае же если страниц больше пяти, то клавиатура будет содержать 5 кнопок для:


  • первой страницы;
  • предыдущей страницы;
  • текущей страницы;
  • следующей страницы;
  • последней страницы.

Например, если есть массив character_pages, содержащей описания персонажей Гарри Поттера для создания бота, который показывает листаемый список персонажей, нам понадобиться функция отправляющая текущею страницу списка:


def send_character_page(message, page=1):
    paginator = InlineKeyboardPaginator(
        len(character_pages),
        current_page=page,
        data_pattern='character#{page}'
    )

    bot.send_message(
        message.chat.id,
        character_pages[page-1],
        reply_markup=paginator.markup,
        parse_mode='Markdown'
    )

И обработчик нажатия кнопок в боте:



@bot.callback_query_handler(func=lambda call: call.data.split('#')[0]=='character')
def characters_page_callback(call):
    page = int(call.data.split('#')[1])
    bot.delete_message(
        call.message.chat.id,
        call.message.message_id
    )
    send_character_page(call.message, page)

*В примере используется pyTelegramBotAPI для работы с ботом.


Полный код примера можно посмотреть здесь.


Результат в зависимости от количества записей в списке будет выглядеть следующим образом:





Спасибо за внимание. Буду руда любой конструктивной критике.