Создание интерактивного бота с кнопками
Чтобы создать Telegram-бота и добавить кнопки, нужно зарегистрировать его через @BotFather, получить токен и написать код на выбранном языке (чаще всего Python), где для отправки сообщений используется параметр reply_markup. Существует два типа кнопок: Reply (отправляют текст в чат) и Inline (работают внутри сообщения через callback или ссылки). Весь процесс занимает от 15 минут до часа в зависимости от сложности логики.
Подготовка и регистрация в BotFather
Первый шаг — создание самого бота. Это делается исключительно через официального представителя Telegram — аккаунт @BotFather.
- Найдите в поиске Telegram пользователя
@BotFatherи запустите диалог. - Отправьте команду
/newbot. - Бот попросит ввести имя (Name) — это то, что будут видеть пользователи (например, «Мой Магазин»).
- Затем потребуется ввести юзернейм (Username). Он должен быть уникальным, латиницей и обязательно заканчиваться на
bot(например,my_shop_bot). - Если имя свободно, BotFather пришлет длинный строковый ключ — токен.
Никогда не публикуйте токен в открытом доступе (на GitHub, в чатах, на форумах). Токен дает полный доступ к управлению ботом. Храните его в переменных окружения или защищенных конфигурационных файлах.
После получения токена бот технически создан, но пока он «пустой» и не реагирует на сообщения. Для оживления нужна программа-сервер.
Типы клавиатур: когда и какие использовать
Telegram предлагает два принципиально разных механизма взаимодействия через кнопки. Выбор зависит от задачи.
Reply-клавиатура (Ответная)
Кнопки отображаются вместо обычной клавиатуры смартфона. При нажатии в чат отправляется текстовое сообщение с названием кнопки.
- Для чего подходит: Простые меню («Контакты», «О нас»), замена ручного ввода, опросы, где ответ должен остаться в истории переписки.
- Особенность: Пользователь может легко переключиться на обычную клавиатуру, если нажмет крестик. Кнопки «прилипают» к полю ввода, пока вы явно не уберете их.
Inline-клавиатура (Встроенная)
Кнопки прикреплены непосредственно к сообщению бота. Они выглядят аккуратнее и работают «под капотом».
- Для чего подходит: Навигация по меню, пагинация (страницы 1, 2, 3...), подтверждение действий («Купить», «Удалить»), переходы по ссылкам без спама в чате.
- Особенность: При нажатии сообщение не дублируется в чат. Бот получает скрытый сигнал (
callback_data) и может отредактировать исходное сообщение или ответить новым. Также поддерживаются прямые ссылки (url).
Для современных сервисных ботов (магазины, поддержка, сервисы) почти всегда лучше использовать Inline-кнопки. Они создают более профессиональный интерфейс и не засоряют историю чата техническими сообщениями.
Реализация на Python с библиотекой Aiogram
Самый популярный стек для разработки — язык Python и асинхронная библиотека aiogram (актуальная версия 3.x). Она обеспечивает высокую скорость работы и простоту кода.
Установка зависимостей
В терминале выполните команду:
pip install aiogram
Пример кода с Inline-кнопками
Ниже представлен готовый шаблон бота, который приветствует пользователя и показывает меню с двумя типами действий: открытие сайта и внутренняя навигация.
import asyncio
from aiogram import Bot, Dispatcher, F, Router
from aiogram.types import Message, CallbackQuery
from aiogram.utils.keyboard import InlineKeyboardBuilder
from aiogram.fsm.storage.memory import MemoryStorage
# Вставьте сюда ваш токен от BotFather
TOKEN = "YOUR_BOT_TOKEN"
bot = Bot(token=TOKEN)
dp = Dispatcher(storage=MemoryStorage())
router = Router()
# Создаем конструктор клавиатуры
def get_main_keyboard():
builder = InlineKeyboardBuilder()
# Кнопка с переходом на сайт
builder.button(text="🌐 Наш сайт", url="https://example.com")
# Кнопка с обратным вызовом (внутренняя логика)
builder.button(text="📦 Каталог", callback_data="catalog_open")
# Выстраиваем кнопки по одной в ряд
builder.adjust(1)
return builder.as_markup()
@router.message(F.text == "/start")
async def cmd_start(message: Message):
await message.answer(
"Привет! Выберите действие:",
reply_markup=get_main_keyboard()
)
@router.callback_query(F.data == "catalog_open")
async def process_catalog(callback: CallbackQuery):
# Отвечаем на нажатие, чтобы убрать индикатор загрузки
await callback.answer("Загружаю каталог...")
# Редактируем сообщение или отправляем новое
await callback.message.edit_text("Здесь будет список товаров.")
# Подключаем роутер к диспетчеру
dp.include_router(router)
async def main():
await dp.start_polling(bot)
if __name__ == "__main__":
asyncio.run(main())
Разбор ключевых моментов
InlineKeyboardBuilder: Удобный инструмент для сборки кнопок. Методadjust(1)выстраивает их в один столбец. Можно передатьadjust(2, 2, 1)для сложной сетки.callback_data: Строка, которую бот получит при нажатии. Максимальная длина — 64 байта. В ней часто кодируют ID товара или название действия.callback.answer(): Обязательный метод. Если его не вызвать, у пользователя на телефоне будет бесконечно крутиться значок загрузки рядом с кнопкой.
Обработка нажатий и логика меню
Главное отличие обработки Inline-кнопок от обычных команд — использование хендлера callback_query.
Когда пользователь нажимает кнопку:
- Бот получает объект
CallbackQuery. - Вы проверяете поле
data(то, что вы зашили вcallback_data). - Выполняете действие: меняете текст сообщения (
edit_text), удаляете кнопки, отправляете фото или формируете ответное сообщение.
Лайфхак для навигации: Чтобы сделать кнопку «Назад», просто передайте в callback_data специальное значение (например, back_to_main). В обработчике проверьте это значение и вызовите функцию генерации главного меню, обновив текущее сообщение.
Если вы используете Reply-кнопки, логика проще: бот получает обычное текстовое сообщение. Вам нужно лишь сравнить текст сообщения с ожидаемым названием кнопки через условие if message.text == "Каталог":.
Частые ошибки разработчиков
Даже опытные разработчики иногда допускают типовые промахи при работе с интерфейсом ботов.
| Ошибка | Последствие | Как исправить |
|---|---|---|
Отсутствие answer() на callback | У пользователя висит «вечная загрузка» (часики) у кнопки. | Всегда вызывайте await callback.answer() в начале обработчика. |
| Хардкод токена в коде | Утечка доступа при публикации кода на GitHub. | Используйте .env файлы и библиотеку python-dotenv. |
| Путаница типов кнопок | Попытка получить callback_data от Reply-кнопки (её там нет). | Помните: Reply шлет текст в чат, Inline шлет скрытый запрос. |
Длинный callback_data | Кнопка не создается или работает некорректно. | Лимит данных — 64 байта. Используйте сокращения или ID. |
| Неуникальный юзернейм | BotFather не создает бота. | Username должен быть свободен во всем Telegram и оканчиваться на bot. |
FAQ
Можно ли добавить картинку к кнопке? Нет, в стандартном API Telegram нельзя разместить иконку прямо на кнопке. Кнопка содержит только текст и эмодзи. Однако вы можете отправить картинку сообщением, а под ней разместить Inline-клавиатуру.
Как сделать кнопку, которая просит номер телефона?
Это возможно только через Reply-клавиатуру. Нужно передать специальный параметр request_contact=True. Inline-кнопки не умеют запрашивать личные данные пользователя напрямую.
Бот не видит нажатия на кнопки, что делать?
Проверьте, правильно ли вы подключили роутер с хендлером callback_query к диспетчеру (dp.include_router). Также убедитесь, что строка в callback_data при создании кнопки и в условии фильтра (F.data == ...) совпадает до символа.
Можно ли редактировать сообщение с кнопками?
Да, это основная фишка Inline-режима. Метод edit_message_text позволяет изменить текст и набор кнопок в уже отправленном сообщении, создавая эффект перехода по экранам без новой переписки.