Кнопки
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}")
Изменение сообщений и кнопок
Изменение текста сообщения
Сообщение можно изменить без пересылки нового, заменяя его содержимое и кнопки.
Особенность ТГ: При изменении текста надо заново передать кнопки, иначе они пропадут
Изменение текста осуществляется стандартными методами 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