Перейти к основному содержимому
Версия: 2.2.2-1

Кнопки

RimTUB 2.2 предоставляет удобные (в отличии от прошлых версий юб) инструменты для работы с кнопками.

Личным аккаунтам телеграм не дает возможности создавать кнопки, поэтому для их создания используется привязанный бот и inline режим.


Типы данных

class Buttons

Создаёт набор инлайн-кнопок

Аргументы:

  • inline_keyboard (list[Button]) - Список строк кнопок, где каждая строка - это список объектов Button.
  • general_extra_data (dict, опционально) = None - Дополнительные данные, применяемые ко всем кнопкам.

Пример:

buttons = Buttons([
[ # первый ряд кнопок
Button('Привет', callback_data='hello'), # первая кнопка в ряду
Button('Копировать', copy_text='скопировано!') # вторая кнопка в ряду
],
[ # второй ряд кнопок
Button('Ссылка', url='https://example.com') # первая кнопка в ряду
]
])

Как кнопки выглядят в ТГ

class Button

Создаёт отдельную инлайн-кнопку с разными параметрами.

Аргументы:

  • text (str) - Текст кнопки.
  • callback_data (str, опционально) - Идентификатор колбека для обработки нажатий.
  • url (str, опционально) - Ссылка, открываемая при нажатии.
  • copy_text (str, опционально) - Текст, копируемый при нажатии.
  • extra_data (dict, опционально) - Дополнительные данные, передаваемые в обработчик @mod.callback.

Пример:

button = Button('Нажми меня', callback_data='click')

Отправка кнопок

Отправлять кнопки следует методом send_buttons. Подробнее читай тут

Пример:

await mod.send_buttons(
msg.chat.id,
"Держи кнопки!",
buttons,
message_thread_id=msg.message_thread_id
)

Обработка нажатий на кнопки

Для обработки нажатий надо указать callback_data в кнопке. По этому колбеку можно отследить нажатие с помощью декоратора @mod.callback

@mod.callback('hello')
async def _hello(c: C):
await c.answer("Привет!", True)

Подробнее про этот декоратор смотри тут


Передача данных

Часто нужно передавать какие-то данные через кнопки. Для этого есть два пути, у каждого есть свои плюсы и минусы

Extra Data

Кнопки с callback_data поддерживают дополнительное поле extra_data, в котором можно передавать произвольные данные в формате dict. Эти данные доступны только обработчику и не отображаются в callback_data. Они сериализуются с помощью pickle и хранятся в течение 3 дней, после чего автоматически удаляются. Время жизни можно изменить в конфигурации через параметр DEFAULT_STORAGE_FILES_TTL.

Плюсы:

  • Можно хранить любые Python объекты.
  • Нет ограничений по размеру данных.
  • Данные не видны в callback_data.
  • Можно легко получить в обработчике.

Минусы:

  • Занимают место на диске.
  • Сложнее дебажить.
  • Данные хранятся ограниченное время.

Пример:

buttons = Buttons([
[
Button(
'Приватная кнопка с секретом',
callback_data='private',
extra_data={'secret': 8}
)
]
])
@mod.callback('private')
async def _private(c: C):
if c.from_user.id != app.me.id: # делаем кнопку приватной, только для себя
return await c.answer("Эта не твоя кнопка!", True)
secret = c.extra_data.get('secret')
await c.answer(f"Твой секрет: {secret}")

Через callback_data

Так-же передавать можно и через callback_data. Просто засунуть их прямо в текст колбека, разделяя, например, двоеточием (:).

Плюсы:

  • Данные хранится бесконечно.
  • Удобно дебажить.
  • Удобно передавать маленькие данные, например ID чего-либо.
  • Не засоряет память

Минусы:

  • Можно передавать только строки.
  • Сильное ограничение по длине. (Максимальная длинна всей колбек даты считается по формуле 64-(длинна названия модуля)-12 символов).
  • Данные видны для других людей.
  • Нужно будет самому доставать эти данные

Пример:

my_id = 1234567890
buttons = Buttons([
[
Button(
'Передача ID в колбек дате',
callback_data=f'id:{my_id}',
)
]
])
# Проверяем начало колбек даты
@mod.callback(startswith='id')
async def _id(c: C):
my_id = int(c.data.split(':')[-1])

await c.answer(f"Твой ID: {my_id}")

Изменение сообщений и кнопок

Изменение текста сообщения

Сообщение можно изменить без пересылки нового, заменяя его содержимое и кнопки.

warning

Особенность ТГ: При изменении текста надо заново передать кнопки, иначе они пропадут

Изменение текста осуществляется стандартными методами Kurigram, единственное, надо предварительно подготовить кнопки методом prepare_buttons. Подробнее про метод смотри тут

buttons = await mod.prepare_buttons(buttons)
await c.edit_message_text(new_text, reply_markup=buttons)

Изменение кнопок

Менять можно не только текст сообщения, но и сами кнопки.

Изменение кнопок осуществляется стандартными методами Kurigram, единственное, надо предварительно подготовить кнопки методом prepare_buttons. Подробнее про метод смотри тут

new_buttons = await mod.prepare_buttons(new_buttons)
await c.edit_message_reply_markup(new_buttons)

Приватные кнопки

Иногда надо сделать так, чтобы кнопка была только твоей, чтобы никто посторонний не мог ее нажать.

Это реализовывается простой проверкой ID.

@mod.callback('private')
async def _private(c: C):
if c.from_user.id != app.me.id: # проверяем, совпадает ли ид клиента с ид чела кто жмет на кнопку
return await c.answer("Эта не твоя кнопка!", True)

Примеры

Смотри Примеры > Buttons