Создание интерактивного интерфейса в Telegram

Иван Корнев·14.04.2026·4 мин

Чтобы добавить кнопки в сообщение или бота Telegram, необходимо использовать параметр reply_markup при отправке сообщения. Существует два основных типа клавиатур: Inline (кнопки под сообщением для навигации и действий) и Reply (замена стандартной клавиатуры пользователя для ввода данных). Выбор зависит от задачи: Inline подходит для меню и переходов, Reply — для быстрого ввода ответов.

Главное отличие: Кнопки Inline не отправляют текст в чат, а передают данные боту «тихо» (callback), тогда как Reply-кнопки вставляют текст в поле ввода как обычное сообщение.

Типы клавиатур и сценарии использования

Понимание различий между типами кнопок критично для создания удобного пользовательского опыта (UX).

Inline Keyboard (Встроенная клавиатура)

Кнопки отображаются непосредственно под сообщением бота. Они не занимают место в поле ввода текста пользователя.

  • Назначение: Навигация по меню, выбор опций, переходы по ссылкам, подтверждение действий.
  • Особенность: При нажатии бот получает callback_data, но само сообщение от пользователя в чат не поступает (если не запрограммировано иное).
  • Где использовать: Главное меню, настройки, оплата, ссылки на сайт.

Reply Keyboard (Клавиатура ответа)

Временная или постоянная панель, заменяющая стандартную клавиатуру смартфона или компьютера пользователя.

  • Назначение: Упрощение ввода текста, выбор из предустановленных вариантов, быстрые команды.
  • Особенность: При нажатии текст кнопки отправляется в чат как обычное сообщение от пользователя.
  • Где использовать: Выбор города, ввод категории товара, быстрые ответы в поддержке («Да», «Нет», «Связаться с оператором»).

Реализация на Python (библиотека aiogram 3.x)

Библиотека aiogram является стандартом для разработки ботов на Python. Ниже приведены актуальные примеры для версии 3.x.

Создание Inline-кнопок

Используем InlineKeyboardMarkup и InlineKeyboardButton.

from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
from aiogram.utils.keyboard import InlineKeyboardBuilder

def get_main_keyboard():
    builder = InlineKeyboardBuilder()
    
    # Кнопка с ссылкой
    builder.button(text="🌐 Наш сайт", url="https://example.com")
    
    # Кнопка с обратным вызовом (callback)
    builder.button(text="💰 Узнать цену", callback_data="get_price")
    
    # Настройка сетки: 1 кнопка в ряду
    builder.adjust(1)
    
    return builder.as_markup()

# Использование в хендлере
# await message.answer("Выберите действие:", reply_markup=get_main_keyboard())

Создание Reply-клавиатуры

Используем ReplyKeyboardMarkup. Важно настроить параметр resize_keyboard=True, чтобы клавиатура не занимала пол-экрана.

from aiogram.types import ReplyKeyboardMarkup, KeyboardButton
from aiogram.utils.keyboard import ReplyKeyboardBuilder

def get_contact_keyboard():
    builder = ReplyKeyboardBuilder()
    
    builder.button(text="📍 Моя геопозиция", request_location=True)
    builder.button(text="📞 Поделиться контактом", request_contact=True)
    builder.button(text="❌ Отмена")
    
    # Настройка: 2 кнопки в первом ряду, 1 во втором
    builder.adjust(2, 1)
    
    return builder.as_markup(resize_keyboard=True, one_time_keyboard=True)

Параметр one_time_keyboard=True скрывает клавиатуру сразу после первого нажатия. Это полезно для одноразовых выборов (например, выбор языка), чтобы не загромождать интерфейс.

Реализация на Node.js (библиотека Telegraf)

Для JavaScript/TypeScript разработчиков библиотека telegraf предоставляет удобный синтаксис.

Пример Inline-клавиатуры

const { Markup } = require('telegraf');

bot.start((ctx) => {
  ctx.reply('Добро пожаловать! Выберите опцию:', 
    Markup.inlineKeyboard([
      Markup.button.url('🔗 Сайт', 'https://example.com'),
      Markup.button.callback('⚙️ Настройки', 'btn_settings')
    ]).extra()
  );
});

// Обработка нажатия
bot.action('btn_settings', (ctx) => {
  ctx.editMessageText('Открываем настройки...');
  ctx.answerCbQuery(); // Обязательно подтверждаем запрос
});

Пример Reply-клавиатуры

bot.command('menu', (ctx) => {
  ctx.reply('Чем могу помочь?', 
    Markup.keyboard([
      ['🍕 Пицца', '🍔 Бургеры'],
      ['🥤 Напитки'],
      Markup.button.contactRequest('📞 Позвонить нам')
    ])
    .oneTime()
    .resize()
    .extra()
  );
});

Обработка нажатий и логика работы

Просто отобразить кнопки недостаточно — нужно обработать реакцию пользователя.

  1. Обработка Callback (для Inline): Когда пользователь нажимает Inline-кнопку, бот получает обновление типа callback_query.

    • Важно: Всегда вызывайте метод ответа на колбэк (answer_callback_query в aiogram или answerCbQuery в telegraf). Если этого не сделать, у пользователя на экране будет бесконечно крутиться индикатор загрузки.
    • Лимиты: Поле callback_data ограничено 64 байтами. Не передавайте туда большие объекты или длинные тексты. Используйте уникальные ID, а данные загружайте из базы по этому ID.
  2. Обработка текста (для Reply): Нажатие на Reply-кнопку равносильно тому, что пользователь вручную напечатал текст и отправил сообщение. Обрабатывайте такие сообщения через обычные текстовые фильтры или точное совпадение строк.

Безопасность данных: Никогда не передавайте чувствительные данные (токены, пароли, персональную информацию) в параметре callback_data. Эти данные могут быть перехвачены или сохранены в логах промежуточных серверов.

Сравнение методов реализации

ХарактеристикаInline KeyboardReply Keyboard
РасположениеПод сообщением ботаВ поле ввода пользователя
Видимость сообщенияНет (тихое нажатие)Да (текст уходит в чат)
Поддержка ссылокДа (url)Нет
Запрос контакта/геоНетДа (requestcontact, requestlocation)
Лучшее применениеМеню, навигация, действияВвод данных, быстрые ответы
УдалениеМожно скрыть редактированием сообщенияИсчезает сама или по команде /start

Частые ошибки разработчиков

  • «Висящий» лоадер: Пользователь нажал кнопку, но ничего не произошло визуально. Причина: забыли отправить подтверждение answer_callback_query.
  • Перегруженность интерфейса: Попытка впихнуть 20 кнопок в одно сообщение. Telegram имеет лимиты на количество кнопок в ряду и общее количество. Оптимально — 2–4 кнопки в ряду.
  • Длинные подписи: Текст на кнопке обрезается, если он слишком длинный. Формулируйте мысли кратко (до 1–3 слов).
  • Отсутствие выхода: Создав меню из кнопок, забыли добавить кнопку «Назад» или «Главное меню», загнав пользователя в тупик.

FAQ

Можно ли динамически менять кнопки в уже отправленном сообщении? Да. Для Inline-клавиатур используйте метод редактирования сообщения (editMessageReplyMarkup). Вы можете полностью заменить набор кнопок, не меняя текст сообщения. Для Reply-клавиатур это невозможно — нужно отправлять новое сообщение.

Как убрать клавиатуру после выбора?

  • Inline: Отправьте редактирование сообщения с пустой разметкой или просто игнорируйте её в следующих шагах.
  • Reply: Отправьте новое сообщение со специальной клавиатурой, где параметр remove_keyboard=true (в aiogram: ReplyKeyboardRemove()).

Есть ли лимит на количество кнопок? Да. В одном ряду может быть до 8 кнопок (на некоторых клиентах меньше), а всего в клавиатуре — до 100 кнопок. Однако для удобства пользователей рекомендуется не превышать 5–6 кнопок на экран.