Как написать Telegram-бота на Python: рабочий пример на Aiogram 3
Создайте первого Telegram-бота на Python и Aiogram 3: настройте токен, обработайте /start, добавьте inline-кнопку и проверьте запуск.
Автор: 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
Рабочий локальный пример ещё не означает, что сервис готов к реальным клиентам. Перед публикацией продумайте:
- Хранилище. Данные заказов и заявок записывайте в базу с миграциями. FSM хранит временный шаг диалога и не заменяет основную базу. Стандартный
MemoryStorageочищается при перезапуске; для сохраняемых между рестартами состояний можно подключить Redis. См. документацию Aiogram по FSM storage. - Внешние зависимости. При Docker Compose база может стать доступной позже приложения. Используйте healthcheck и
depends_on: condition: service_healthy, а также предусмотрите повторное подключение. Документация Docker Compose. - Надёжность сценариев. Проверяйте ввод, права пользователя, повторную доставку обновлений и ошибки внешних API. Платёж или выдача цифрового товара должны обрабатываться идемпотентно.
- Эксплуатация. Добавьте структурированные логи без секретов, перезапуск процесса, резервные копии и проверку после деплоя.
- Тесты. Проверяйте бизнес-логику отдельно от Telegram API и добавьте сценарии на команды, FSM, ошибки и повторы.
Для следующего практического шага начните с бесплатного курса по Aiogram 3, а если нужна структура коммерческого проекта — посмотрите разбор production-архитектуры. Полный курс по Telegram-ботам продолжает маршрут базой данных, платежами, Mini App, тестами и релизом. Примеры реальных продуктов собраны в портфолио.
по теме
следующий шаг
Собрать первого Telegram-бота
Бесплатный практикум Aiogram 3 помогает пройти путь от первого ответа до FSM и деплоя на VPS.
поделиться
Нужна разработка Telegram-бота?
Разрабатываю ботов, Mini Apps, платежи и автоматизацию под ключ.