diff --git a/README.md b/README.md index 5a20431..ea31dbc 100644 --- a/README.md +++ b/README.md @@ -124,3 +124,80 @@ from config_reader import config # чтобы получить настоящее содержимое вместо '*******' bot = Bot(token=config.bot_token.get_secret_value()) ``` + +## Работа с сообщениями + +Разберёмся, как применять различные типы форматирования к сообщениям и работать с медиафайлами. + +### ТЕКСТ + +В распоряжении у разработчика имеется три способа разметки текста: HTML, Markdown и MarkdownV2. +Наиболее продвинутыми из них считаются HTML и MarkdownV2 + +#### Форматированный вывод +За выбор форматирования при отправке сообщений отвечает аргумент ``parse_mode``, например: + +```py +from aiogram import F +from aiogram.types import Message +from aiogram.filters import Command +from aiogram.enums import ParseMode + +# Если не указать фильтр F.text, +# то хэндлер сработает даже на картинку с подписью /test +@dp.message(F.text, Command("test")) +async def any_message(message: Message): + await message.answer( + "Hello, world!", + parse_mode=ParseMode.HTML + ) + await message.answer( + "Hello, *world*\!", + parse_mode=ParseMode.MARKDOWN_V2 + ) +``` + +В aiogram можно задать параметры бота по умолчанию. Для этого создайте объект DefaultBotProperties и передайте туда нужные настройки: + +```py +from aiogram.client.default import DefaultBotProperties + +bot = Bot( + token=config.bot_token.get_secret_value(), + default=DefaultBotProperties( + parse_mode=ParseMode.HTML + # тут ещё много других интересных настроек + ) +) + +# где-то в функции... +await message.answer("Сообщение с HTML-разметкой") +# чтобы явно отключить форматирование в конкретном запросе, +# передайте parse_mode=None +await message.answer( + "Сообщение без какой-либо разметки", + parse_mode=None +) +``` + +#### Экранирование ввода + +Второе чуть сложнее, но более продвинутое: воспользоваться специальным инструментом, +который будет собирать отдельно текст и отдельно информацию о том, какие его куски должны быть отформатированы. + +```py +from aiogram.filters import Command +from aiogram.utils.formatting import Text, Bold + +@dp.message(Command("hello")) +async def cmd_hello(message: Message): + content = Text( + "Hello, ", + Bold(message.from_user.full_name) + ) + await message.answer( + **content.as_kwargs() + ) +``` + +В примере выше конструкция **content.as_kwargs() вернёт аргументы text, entities, parse_mode и подставит их в вызов answer() \ No newline at end of file diff --git a/bot.py b/bot.py index bb5af1e..579e975 100644 --- a/bot.py +++ b/bot.py @@ -6,7 +6,12 @@ from datetime import datetime from aiogram import Bot, Dispatcher, types from aiogram.enums.dice_emoji import DiceEmoji -from aiogram.filters.command import Command +from aiogram import F, html +from aiogram.types import Message +from aiogram.filters import Command +from aiogram.utils.formatting import Text, Bold, as_list, as_marked_section, as_key_value, HashTag +from aiogram.enums import ParseMode +from aiogram.client.default import DefaultBotProperties from config_reader import config # Включаем логирование, чтобы не пропустить важные сообщения @@ -15,7 +20,12 @@ logging.basicConfig(level=logging.INFO) # Для записей с типом Secret* необходимо # вызывать метод get_secret_value(), # чтобы получить настоящее содержимое вместо '*******' -bot = Bot(token=config.bot_token.get_secret_value()) +bot = Bot( + token=config.bot_token.get_secret_value(), + default=DefaultBotProperties( + parse_mode=ParseMode.HTML + # тут ещё много других интересных настроек + )) # Объект бота напрямую из .env # bot = Bot(token=os.getenv("BOT_TOKEN")) @@ -27,7 +37,36 @@ dp["started_at"] = datetime.now().strftime("%Y-%m-%d %H:%M") # Хэндлер на команду /start @dp.message(Command("start")) async def cmd_start(message: types.Message): - await message.answer("Привет!") + # await message.answer("Привет! ") + content = as_list( + Text( + "Привет! ", + Bold(message.from_user.first_name) + ), + as_marked_section( + Bold("Я умею:"), + "/test1 - Отвечу Test1", + "/answer - Просто отвечу", + "/reply - Отвечу ответом", + "/name - Поприветствую тебя по Имени и Фамилии", + "/aboute - Дам тебе характеристику", + "/dice - Подкину для тебя кубик, загадай число ;)", + marker="✅ ", + ), + as_marked_section( + Bold("Failed:"), + "Не смогу назвать номер твоего телефона :( )", + marker="❌ ", + ), + HashTag("#я"), + # Text( + # "Номер телефона, ", + # Bold(message.contact.phone_number) + # ) + ) + await message.answer( + **content.as_kwargs() + ) # Хэндлер на команду /test1 @dp.message(Command("test1")) @@ -44,6 +83,45 @@ async def cmd_test2(message: types.Message): async def cmd_answer(message: types.Message): await message.answer("Это простой ответ") +# Хэндлер на команду /name + +@dp.message(Command("name")) +async def cmd_name(message: Message): + await message.answer( + f"Доброго дня тебе, {html.bold(html.quote(message.from_user.full_name))}", + parse_mode=ParseMode.HTML + # f"Мой ник, {html.bold(html.quote(message.from_user.username))}", + # parse_mode=ParseMode.HTML + ) + +@dp.message(Command("aboute")) +async def cmd_aboute(message: Message): + content = as_list( + Text( + "User_name, ", + Bold(message.from_user.username) + ), + as_marked_section( + Bold("Это Ты:"), + "Молодец", + "Красава", + "Умка", + marker="✅ ", + ), + as_marked_section( + Bold("Это точно не ты:"), + "Душнила", + marker="❌ ", + ), + HashTag("#характеристика"), + # Text( + # "Номер телефона, ", + # Bold(message.contact.phone_number) + # ) + ) + await message.answer( + **content.as_kwargs() + ) @dp.message(Command("reply")) async def cmd_reply(message: types.Message):