Всем привет!
Очень долгое время разработчики Telegram-ботов довольствовались двумя способами форматирования сообщений: HTML и Markdown. Оба этих способа делали одно и то же: добавляли простое форматирование в обычный текст.
Например, можно было сделать: <b>Жирный текст</b> в HTML или Жирный текст в Markdown
Помимо этого, были курсив, подчеркивание, зачеркивание, код, ссылки и спойлеры:
<i>Курсив</i> или Курсив <u>Подчеркнутый текст</u> или Подчеркнутый текст <s>Зачеркнутый текст</s> или ~Зачеркнутый текст~ <code>print("Какой-то код")</code> или print("какой-то код") и так далее.
Для большинства задач этого было достаточно, но в какой-то момент обычного HTML и Markdown может не хватать.
Специально для статьи я опубликовал бота с Preview Rich Messages. Помимо того, что вы сможете увидеть как выглядит само сообщение, бот отправит и его HTML-шаблон (зачем нужен шаблон - узнаете дальше по статье) https://t.me/amvera_rich_messages_preview_bot

Например (что является очень частым сценарием), если ваш бот - нейро-ассистент, который привык присылать сложные сообщения с математическими формулами, вложениями, списками, таблицами и тому подобное.
В недавнем обновлении Telegram Bot API 10.1 эту проблему решили!
Что нового в Bot API 10.1
В Bot API 10.1 Telegram добавил Rich Messages. Если коротко, это новый формат сообщений, который позволяет отправлять более сложную структуру: заголовки, таблицы, списки, раскрывающиеся блоки, цитаты, формулы и даже медиа-вложения практически в любом месте сообщения!
Грубо говоря, сейчас вы можете отправлять сообщение, которое больше похоже на небольшой документ.
Классы и методы
Обычный sendMessage никуда не делся и можно сказать не модифицировался. С Rich Messages все более уникально: для него есть отдельные методы и классы.
InputRichMessage- rich-сообщение, которое бот отправляет;RichMessage- rich-сообщение, которое бот получает;sendRichMessage- метод для отправки rich-сообщения;sendRichMessageDraft- метод для отправки черновика (ниже разберем);rich_messageв объектеMessage;rich_messageвeditMessageText;отдельные rich-блоки и тексты.
Примерно так теперь может выглядеть обычное сообщение от бота:

В коде же это выглядит примерно так (показано на примере aiogram>=3.29.1):
import asyncio import os from aiogram import Bot, Dispatcher from aiogram.filters import Command, CommandStart from aiogram.types import Message from aiogram.types.input_rich_message import InputRichMessage BOT_TOKEN = os.getenv("BOT_TOKEN") dp = Dispatcher() ### Изначально Rich Messages должен быть в формате HTML ORDER_RICH_HTML = """ <h1>Заказ #1842</h1> <p> Статус: <mark>готов к выдаче</mark> </p> <table bordered striped> <caption>Состав заказа</caption> <tr> <th>Позиция</th> <th>Кол-во</th> <th>Сумма</th> </tr> <tr> <td>Пицца Маргарита</td> <td>2</td> <td>1200 ₽</td> </tr> <tr> <td>Кола</td> <td>1</td> <td>150 ₽</td> </tr> </table> <details> <summary>Что дальше?</summary> <p> Курьер заберет заказ после подтверждения. Если адрес изменился, лучше написать в поддержку до передачи заказа. </p> </details> """ @dp.message(CommandStart()) async def start_handler(message: Message): # Берем текст в формате HTML как Rich Message rich_message = InputRichMessage(html=ORDER_RICH_HTML) # И отправляем его через answer_rich await message.answer_rich(rich_message=rich_message) async def main(): bot = Bot(token=BOT_TOKEN) await dp.start_polling(bot) if __name__ == "__main__": asyncio.run(main())
Что еще может быть в Rich Messages
На примере выше мы использовали заголовок, таблицу и раскрывающийся блок, но на этом возможности Rich Messages не заканчиваются:
Заголовки;
Списки;
Таблицы;
Цитаты;
Формулы;
Footnotes (сноски);
Медиа-блоки внутри сообщения;
Коллажи;
Слайдшоу;
Карты.
Все это вы можете увидеть в специальном Preview боте, который я подготовил для статьи: https://t.me/amvera_rich_messages_preview_bot

Я решил, что дополнительно будет полезно присылать HTML-шаблоны отправленных сообщений. Так вы можете просто скопировать нужную вам часть и использовать ее в своем коде.
Черновики для AI-ботов
Как я уже писал выше, в обновлении добавили черновики - sendRichMessageDraft.
Он нужен не для обычной отправки сообщения, а для временного черновика. Например, если бот генерирует длинное сообщение LLM, можно показывать пользователю временный результат в реальном времени.
Черновик является временным превью примерно на 30 секунд. Когда финальный ответ будет готов, его все равно нужно будет отправить обычным sendRichMessage.
Ограничения
И хочется немного сказать про ограничения этого метода.
Для обычного бота этих лимитов будет более чем достаточно:
Rich Messages поддерживает до 32768 UTF-8 символов;
До 500 блоков;
До 16 уровней вложенности;
До 50 медиа-вложений;
До 20 колонок в таблице.
Вся информация взята с документации
Итог
В этой статье я постарался показать, что такое Rich Messages и как их можно использовать в своем боте. Эта статья больше обзорная, но если вы захотите разработать своего бота с Rich Messages, надеюсь, она вам поможет.