Если вы когда-нибудь пытались сделать инлайн кнопки в Telegram боте, то знаете: документация разбросана по кускам. На Хабре одно, в официалке другое, а в итоге всё работает через раз. Я сам через это прошел, когда писал своих первых ботов. Сейчас покажу, как сделать правильно, без танцев с бубном. Поехали.
Что такое инлайн кнопки и зачем они нужны
Инлайн кнопки - это те самые кнопки, которые прикрепляются прямо к сообщению бота. Они бывают двух типов: с ссылкой (url) и с callback-данными. Первые просто открывают ссылку, вторые отправляют боту невидимый сигнал, по которому он может менять сообщение, показывать следующее меню или что-то записывать в базу.
Обычные кнопки (reply keyboard) - это панель снизу, она привязана к чату. Инлайн кнопки намного удобнее в продажах и воронках: они не переключают внимание, не занимают место в поле ввода, и их можно менять прямо на лету. Например, кнопка «Записаться» под сообщением о товаре продает лучше, чем панель внизу экрана. Если вы делаете бота для бизнеса, скорее всего, нужны именно они.
Подготовка: ставим aiogram
Самый популярный фреймворк для ботов на Python - aiogram. Ставим через pip: pip install aiogram. Всё, больше ничего не нужно. Никаких selenium, никаких танцев с API. Только этот пакет.
Импортируем нужные классы
В коде нам понадобятся два класса из модуля types: InlineKeyboardMarkup и InlineKeyboardButton. Импортируем их одной строкой:
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton
Без этих импортов ничего не заработает. Класс Markup создает саму клавиатуру, а Button - отдельную кнопку. Это всё.
Создаем первую инлайн клавиатуру
Теперь давайте создадим простое меню с двумя кнопками. Одна будет ссылкой на ваш сайт, вторая - callback. Выглядит это так:
keyboard = InlineKeyboardMarkup()
url_button = InlineKeyboardButton('Наш сайт', url='https://example.com')
callback_button = InlineKeyboardButton('Нажми меня', callback_data='press')
keyboard.add(url_button, callback_button)
Метод add добавляет кнопки в один ряд. Если хотите, чтобы каждая кнопка была на своей строке, вызывайте add отдельно для каждой или используйте row(), но пока разберем базовый вариант.
Дальше при отправке сообщения передаем эту клавиатуру в параметр reply_markup:
await bot.send_message(chat_id, 'Вот мое меню:', reply_markup=keyboard)
Всё, кнопки появятся под сообщением. Пользователь жмет на них, и либо открывается ссылка, либо боту прилетает callback.
Обработка callback-кнопок
Просто создать кнопку мало. Надо научить бота реагировать. Для этого в aiogram есть декоратор @dp.callback_query_handler(). Вот пример:
@dp.callback_query_handler(lambda c: c.data == 'press')
async def process_press(callback_query: types.CallbackQuery):
await bot.answer_callback_query(callback_query.id)
await bot.send_message(callback_query.from_user.id, 'Вы нажали кнопку')
Обратите внимание: всегда нужно отвечать на callback через answer_callback_query, иначе у пользователя будет крутиться спиннер. Это частая ошибка новичков.
Раскладка кнопок: ряды и колонки
Иногда нужно разместить кнопки не в одну линию, а например, две в ряд, потом одну. Для этого используем метод row() или создаем список списков. Например:
kb = InlineKeyboardMarkup(row_width=2)
btn1 = InlineKeyboardButton('Кнопка 1', callback_data='one')
btn2 = InlineKeyboardButton('Кнопка 2', callback_data='two')
btn3 = InlineKeyboardButton('Кнопка 3', callback_data='three')
kb.add(btn1, btn2, btn3)
Параметр row_width=2 говорит, что максимум 2 кнопки в ряду. Третья автоматически перейдет на следующую строку. Или можно формировать ряды вручную: создаете список списков, где каждый внутренний список - это ряд, и передаете в конструктор клавиатуры как keyboard.
Например, в Kotlin это делается через ключ-значение, как показывают в Devmark, но мы на Python.
Ссылка или callback: правила выбора
Если вам нужно просто увести человека на сайт или в канал - используйте url. Это уменьшает нагрузку на бота и работает без дополнительных хендлеров. Если нужно изменить сообщение, показать новое меню, или записать действие в базу - тогда callback.
Я всегда советую клиентам: если не требуется логика - ставьте url. Меньше кода, меньше шансов на ошибку. А для интерактивных сценариев (квизы, регистрация, корзина) - только callback.
Типичные ошибки и как их избежать
Первая ошибка - забыть ответить на callback. Если не вызвать answer_callback_query, Telegram будет показывать загрузку у кнопки и ругаться в логах.
Вторая - использовать callback_data длиной больше 64 байт. Telegram просто не даст отправить такую клавиатуру. На практике хватает коротких меток типа press, buy_1.
Третья - забыть передать reply_markup при редактировании сообщения. Если вы хотите обновить кнопки, обязательно передавайте новую клавиатуру в edit_message_reply_markup.
И четвертая - путать инлайн и обычные кнопки. Это разные механики. Не пытайтесь использовать reply keyboard там, где нужны инлайн.
Кейс: кнопки в продающей воронке
Когда я делаю воронки для экспертов, инлайн кнопки - основа. Например, коуч по отношениям хочет продать консультацию. Бот отправляет серию сообщений с вопросами, в конце - кнопку «Записаться» с ссылкой на оплату. Или кнопку «Подробнее», которая раскрывает следующий блок.
Всё это реализуется связкой callback-кнопок и логикой состояний. Но если вы не программист, то писать такое вручную - адская боль. Приходится разбираться в aiogram, состояниях, базах данных.
Я знаю это по себе: когда-то я неделю верстал простенькую воронку на aiogram, а потом понял, что можно обойтись без кода вообще. Есть сервисы, которые строят таких ботов визуально. Например, Отклик - это ИИ для создания автоворонок в Telegram за 3 минуты. Просто напишите обычными словами, что хотите продать, - и он соберет воронку: с инлайн кнопками, прогревами, рассылкой. При этом внутри уже встроен эмпатичный ИИ-ассистент, который общается с клиентами и закрывает возражения. Конверсия вырастает до 37% без вашего участия.
Вот видео, если интересно, как это работает:
Если вы хотите глубоко разобраться в программировании ботов, то моя инструкция выше - отличный старт. Но если вам нужен рабочий инструмент для бизнеса, не тратьте время. Зайдите на https://3seller.com/funnels и сделайте бота без единой строчки кода.
Что касается самой техники инлайн кнопок, запомните три вещи: используйте InlineKeyboardMarkup для клавиатуры, InlineKeyboardButton для кнопок, и добавляйте их через add(). Обрабатывайте callback через callback_query_handler и не забывайте отвечать на запрос. Этого достаточно, чтобы сделать 90% всех нужных сценариев.
Соберите первую клавиатуру из примера выше и запустите бота. Когда увидите, что callback приходит, добавьте вторую кнопку и обработайте её. Так вы быстро освоите механику. А для полноценной воронки продаж не обязательно писать код самому - «Отклик» сделает это за 3 минуты.