diff --git a/README.md b/README.md index 0bf67ad..9f079be 100644 --- a/README.md +++ b/README.md @@ -427,4 +427,94 @@ async def somebody_added(message: Message): # (на скриншоте выше у юзеров нет фамилии) await message.reply(f"Привет, {user.full_name}") -``` \ No newline at end of file +``` + +## Кнопки + +### Обычные кнопки +Это то, что выводится внизу экрана + +#### Кнопки как шаблоны + +Напишем хэндлер, который будет при нажатии на команду /start отправлять сообщение с двумя кнопками в bot2.py. + +С точки зрения Bot API, клавиатура — это массив массивов кнопок, а если говорить проще, массив рядов.: + +```py +@dp.message(Command("start")) +async def cmd_start(message: types.Message): + kb = [ + [ + types.KeyboardButton(text="С пюрешкой"), + types.KeyboardButton(text="Без пюрешки") + ], + ] + keyboard = types.ReplyKeyboardMarkup( + keyboard=kb, + resize_keyboard=True, + input_field_placeholder="Выберите способ подачи" + ) + await message.answer("Как подавать котлеты?", reply_markup=keyboard) +``` + +Осталось научить бота реагировать на нажатие таких кнопок. Как уже было сказано выше, +необходимо делать проверку на полное совпадение текста. + +Сделаем это при помощи магического *фильтра F* + +```py +@dp.message(F.text.lower() == "с пюрешкой") +async def with_puree(message: types.Message): + await message.reply("Отличный выбор!", reply_markup=types.ReplyKeyboardRemove()) #удалим клавиатуру после ответа +``` +#### Keyboard Builder + +Сборщик клавиатур для генерации кнопок. + +Нам пригодятся следующие методы: + +``add()`` — добавляет кнопку в память сборщика; +``adjust(int1, int2, int3...)`` — делает строки по int1, int2, int3... кнопок; +``as_markup()`` — возвращает готовый объект клавиатуры; +``button()`` — добавляет кнопку с заданными параметрами, тип кнопки (Reply или Inline) определяется автоматически. + +Создадим пронумерованную клавиатуру размером 4×4: +```py +# новый импорт! +from aiogram.utils.keyboard import ReplyKeyboardBuilder + +@dp.message(Command("reply_builder")) +async def reply_builder(message: types.Message): + builder = ReplyKeyboardBuilder() + for i in range(1, 17): + builder.add(types.KeyboardButton(text=str(i))) + builder.adjust(4) + await message.answer( + "Выберите число:", + reply_markup=builder.as_markup(resize_keyboard=True), + ) +``` + +#### Специальные обычные кнопки¶ +На момент написания этой главы в Telegram существует шесть специальных видов обычных кнопок, не являющихся обычными шаблонами сообщений. Они предназначены для: + +отправки текущей геолокации; +отправки своего контакта с номером телефона; +создания опроса/викторины; +выбора и отправки боту данных пользователя с нужными критериями; +выбора и отправки боту данных (супер)группы или канала с нужными критериями; +запуска веб-приложения (WebApp). +Поговорим про них подробнее. + +**Отправка текущей геолокации.** Здесь всё просто: где пользователь находится, те координаты и отправляет. Это будет статическое гео, а не Live Location, который обновляется автоматически. Разумеется, хитрые юзеры могут подменить своё местонахождение, иногда даже на уровне всей системы (Android). + +**Отправка своего контакта с номером телефона.** При нажатии на кнопку (с предварительным подтверждением) пользователь отправляет свой контакт с номером телефона боту. Те же хитрые юзеры могут проигнорировать кнопку и отправить любой контакт, но в этом случае на них можно найти управу: достаточно проверить в хэндлере или в фильтре равенство message.``contact.user_id == message.from_user.id``. + +**Создание опроса/викторины.** По нажатию на кнопку пользователю предлагается создать опрос или викторину, которые потом отправятся в текущий чат. Необходимо передать объект KeyboardButtonPollType, необязательный аргумент type служит для уточнения типа опроса (опрос или викторина). + +**Выбор и отправка боту данных пользователя с нужными критериями.** Показывает окно выбора пользователя из списка чатов юзера, нажавшего на кнопку. Необходимо передать объект KeyboardButtonRequestUser, в котором надо указать сгенерированный любым способом айди запроса и критерии, например, "бот", "есть подписка Telegram Premium" и т.д. После выбора юзера бот получит сервисное сообщение с типом **UserShared**. + +**Выбор и отправка боту чата с нужными критериями.** Показывает окно выбора пользователя из списка чатов юзера, нажавшего на кнопку. Необходимо передать объект KeyboardButtonRequestChat, в котором надо указать сгенерированный любым способом айди запроса и критерии, например, "группа или канал", "юзер — создатель чата" и т.д. После выбора юзера бот получит сервисное сообщение с типом ChatShared. + +**Запуск веб-приложения (WebApp)**. При нажатии на кнопку открывает WebApp. Необходимо передать объект WebAppInfo. В этой книге веб-аппы пока рассматриваться не будут. + diff --git a/bot.py b/bot.py index c1d0465..bb5fa31 100644 --- a/bot.py +++ b/bot.py @@ -10,11 +10,13 @@ from aiogram.enums import ParseMode from aiogram.enums.dice_emoji import DiceEmoji from aiogram import F, html from aiogram.types import Message -from aiogram.filters import Command, CommandObject +from aiogram.filters import Command, CommandObject, CommandStart from aiogram.utils.formatting import Text, Bold, as_list, as_marked_section, as_key_value, HashTag from aiogram.types import FSInputFile, URLInputFile, BufferedInputFile # новый импорт! from aiogram.utils.markdown import hide_link #для скрытой ссылки +# новый импорт! +from aiogram.utils.keyboard import ReplyKeyboardBuilder # для создания кнопок from config_reader import config @@ -59,15 +61,16 @@ async def cmd_start(message: types.Message): "Если ты мне отправишь гифку, я тебе ей же и отвечу", "----------", "/more - Еще больше возможностей!", + "/vfy - Получить подтверждение Вашего номера телефона", marker="✅ ", ), as_marked_section( Bold("Failed:"), - "Не смогу назвать номер твоего телефона :( )", + "Не смогу полететь на луну:( ", marker="❌ ", ), - HashTag("#я"), + HashTag("#ищу"), # Text( # "Номер телефона, ", # Bold(message.contact.phone_number) @@ -93,6 +96,7 @@ async def cmd_more(message: types.Message): "e-mail,", "Номер телефона,", "Я распознаю их и напишу что нашел", + "/special_buttons - выведу спецкнопки с командами", "/dice - Подкину для тебя кубик, загадай число ;)", "/settimer