все статьи
15 ноября 2024 г.·обновлено 23 сентября 2026 г.·10 мин

Как написать Telegram-бота на Python: рабочий пример на Aiogram 3

Создайте первого Telegram-бота на Python и Aiogram 3: настройте токен, обработайте /start, добавьте inline-кнопку и проверьте запуск.

PythonTelegramAiogramБоты

Автор: Shcoder, независимый разработчик

Чтобы написать Telegram-бота на Python, достаточно начать с небольшого проверяемого сценария: команда /start, ответ пользователю и одна inline-кнопка. Ниже соберём такой проект на Aiogram 3, безопасно вынесем токен из кода и проверим его в Telegram. Это рабочая основа, но ещё не production-сервис: базу данных, постоянное хранилище состояний, мониторинг и деплой добавляют отдельно.

Если нужен маршрут с заданиями от первого ответа до публикации, пройдите бесплатный практикум Aiogram 3. Для более подробного разбора клавиатур и FSM есть отдельный туториал Aiogram 3.

1. Создайте бота и окружение

Создайте бота через @BotFather и скопируйте токен в .env. Не отправляйте токен в чат, не вставляйте его в исходный код и не коммитьте .env в Git.

Пример ниже рассчитан на Python 3.10+ и проверен с Aiogram 3.31.0. Для проекта зафиксируйте версии зависимостей и обновляйте их осознанно.

mkdir telegram-bot
cd telegram-bot
python -m venv .venv

Активируйте окружение:

# macOS / Linux
source .venv/bin/activate
# Windows PowerShell
.\.venv\Scripts\Activate.ps1

Создайте requirements.txt:

aiogram==3.31.0
python-dotenv==1.1.1

Установите зависимости:

python -m pip install -r requirements.txt

Создайте .env:

BOT_TOKEN=вставьте_токен_от_BotFather

И добавьте .gitignore, чтобы секрет и виртуальное окружение не попали в репозиторий:

.env
.venv/
__pycache__/

2. Добавьте обработчик и кнопку

Создайте bot.py:

import asyncio
import os

from aiogram import Bot, Dispatcher, F, Router
from aiogram.filters import CommandStart
from aiogram.types import CallbackQuery, InlineKeyboardMarkup, Message
from aiogram.utils.keyboard import InlineKeyboardBuilder
from dotenv import load_dotenv

router = Router(name="main")


def main_keyboard() -> InlineKeyboardMarkup:
    keyboard = InlineKeyboardBuilder()
    keyboard.button(text="Что умеет бот", callback_data="about")
    return keyboard.as_markup()


@router.message(CommandStart())
async def start(message: Message) -> None:
    name = message.from_user.full_name if message.from_user else "друг"
    await message.answer(
        f"Привет, {name}! Бот запущен.",
        reply_markup=main_keyboard(),
    )


@router.callback_query(F.data == "about")
async def show_about(callback: CallbackQuery) -> None:
    await callback.answer()
    if isinstance(callback.message, Message):
        await callback.message.edit_text(
            "Это минимальный пример на Aiogram 3. Следующий шаг — добавить свой сценарий.",
            reply_markup=main_keyboard(),
        )


async def main() -> None:
    load_dotenv()
    token = os.getenv("BOT_TOKEN")
    if not token:
        raise RuntimeError("Добавьте BOT_TOKEN в файл .env")

    bot = Bot(token=token)
    dispatcher = Dispatcher()
    dispatcher.include_router(router)
    await dispatcher.start_polling(
        bot,
        allowed_updates=dispatcher.resolve_used_update_types(),
    )


if __name__ == "__main__":
    asyncio.run(main())

Запустите приложение:

python bot.py

Откройте бота в личном чате, отправьте /start и нажмите кнопку. Остановите polling через Ctrl+C.

Dispatcher принимает обновления, а Router группирует обработчики. CommandStart() выбирает команду запуска, F.data == "about" фильтрует callback кнопки. После каждого callback нужно вызвать callback.answer(), иначе Telegram-клиент продолжит показывать индикатор ожидания. Подробнее: Dispatcher и маршрутизация, фильтр команд, ответ на callback.

3. Если бот не отвечает

  • Проверьте, что .venv активировано и зависимости установлены именно в него.
  • Убедитесь, что BOT_TOKEN есть в .env и в нём нет лишних пробелов или кавычек.
  • Запустите только один polling-процесс для этого токена. Два процесса одновременно обычно конфликтуют за получение обновлений.
  • Если раньше настраивали webhook, проверьте режим получения обновлений: polling и webhook нельзя использовать одновременно для одного бота.
  • Посмотрите traceback в терминале. Не добавляйте в логи полный токен или содержимое приватных сообщений.

4. Что потребуется для production

Рабочий локальный пример ещё не означает, что сервис готов к реальным клиентам. Перед публикацией продумайте:

  1. Хранилище. Данные заказов и заявок записывайте в базу с миграциями. FSM хранит временный шаг диалога и не заменяет основную базу. Стандартный MemoryStorage очищается при перезапуске; для сохраняемых между рестартами состояний можно подключить Redis. См. документацию Aiogram по FSM storage.
  2. Внешние зависимости. При Docker Compose база может стать доступной позже приложения. Используйте healthcheck и depends_on: condition: service_healthy, а также предусмотрите повторное подключение. Документация Docker Compose.
  3. Надёжность сценариев. Проверяйте ввод, права пользователя, повторную доставку обновлений и ошибки внешних API. Платёж или выдача цифрового товара должны обрабатываться идемпотентно.
  4. Эксплуатация. Добавьте структурированные логи без секретов, перезапуск процесса, резервные копии и проверку после деплоя.
  5. Тесты. Проверяйте бизнес-логику отдельно от Telegram API и добавьте сценарии на команды, FSM, ошибки и повторы.

Для следующего практического шага начните с бесплатного курса по Aiogram 3, а если нужна структура коммерческого проекта — посмотрите разбор production-архитектуры. Полный курс по Telegram-ботам продолжает маршрут базой данных, платежами, Mini App, тестами и релизом. Примеры реальных продуктов собраны в портфолио.

Собрать первого Telegram-бота

Бесплатный практикум Aiogram 3 помогает пройти путь от первого ответа до FSM и деплоя на VPS.

Начать бесплатный практикум

Нужна разработка Telegram-бота?

Разрабатываю ботов, Mini Apps, платежи и автоматизацию под ключ.