7 самых частых ошибок при разработке Telegram-ботов и способы их решения
Автор: Javohir Abdullayev · · Telegram-боты

Почему при разработке Telegram-ботов часто возникают ошибки?
Сегодня Telegram-боты стали одним из самых популярных инструментов для бизнеса и сервисов в Узбекистане. Многие начинающие разработчики входят в мир программирования именно через Python и библиотеку aiogram. Однако, как только число пользователей проекта переваливает за несколько сотен, бот начинает зависать, сообщения теряются или сервер неожиданно падает.
В этой статье мы рассмотрим 7 наиболее серьезных технических ошибок, часто допускаемых при разработке Telegram-ботов, и профессиональные методы их устранения.
1. Хардкод токена бота в коде (Hardcoded Secrets)
Одна из самых опасных и, к сожалению, распространенных ошибок — это прописывание токена бота прямо внутри файла Python. При загрузке кода на GitHub или GitLab токен бота может быть скомпрометирован, и управление ботом перейдет в чужие руки.
Правильное решение: Используйте переменные окружения (environment variables) и файл .env. В качестве библиотек рекомендуются python-decouple или pydantic-settings.
from aiogram import Bot
from decouple import config
BOT_TOKEN = config('BOT_TOKEN')
bot = Bot(token=BOT_TOKEN)Никогда не забывайте добавлять строку .env в файл .gitignore.
2. Хранение состояний (State) в оперативной памяти (In-Memory)
Начинающие разработчики часто хранят состояния FSM (Finite State Machine) с помощью MemoryStorage или удерживают данные пользователей в обычном словаре Python (dict). В итоге при перезапуске бота (restart) все заполняемые пользователями заявки и корзины безвозвратно удаляются.
Правильное решение: Для хранения состояний используйте быстрые базы данных в памяти, такие как Redis:
from aiogram.fsm.storage.redis import RedisStorage
from redis.asyncio import Redis
redis = Redis(host='localhost', port=6379)
storage = RedisStorage(redis=redis)3. Выполнение медленного и тяжелого кода в основном Event Loop
Асинхронные библиотеки в Python (aiogram, asyncio) работают в одном потоке (single thread). Если при обработке запроса одного пользователя вы вызываете requests.get(), тяжелую обработку файлов или синхронный time.sleep(), весь бот блокируется и перестает отвечать другим пользователям.
Правильное решение: Все запросы должны быть асинхронными. Вместо requests используйте aiohttp или httpx. Тяжелые вычисления выносите в отдельный фоновый поток с помощью asyncio.to_thread() или инструментов вроде Celery.
import asyncio
import aiohttp
# Неправильно: time.sleep(5)
# Правильно:
await asyncio.sleep(5)
# Неправильно: requests.get(url)
# Правильно:
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
data = await response.json()4. Игнорирование лимитов Telegram (Rate Limits)
При массовой рассылке (broadcast) сообщений разработчики нередко запускают цикл по всем ID и подряд вызывают await bot.send_message(). В результате Telegram выдает ошибку 429 Too Many Requests: retry after X seconds, и отправка прекращается.
Telegram разрешает отправлять не более 30 сообщений в секунду. Для массовых рассылок обязательно используйте очереди сообщений (например, Celery, RabbitMQ), асинхронные ограничители (asyncio.Semaphore) или готовые библиотеки, такие как aiogram-broadcaster.
5. Отсутствие фильтрации и валидации пользовательского ввода
Любой текст, номер телефона или формат файла, отправленный пользователем, может отличаться от ожидаемого. Запись необработанных («сырых») данных напрямую в базу данных приводит к сбоям или SQL-инъекциям.
Всегда проверяйте длину и формат входящего текста. При отправке ответов с HTML-разметкой обязательно экранируйте текст пользователя с помощью html.escape() или функций из aiogram.utils.text_decorations.
6. Неиспользование drop_pending_updates при перезапуске
Если бот был отключен на некоторое время или остановился из-за сбоя сервера, на серверах Telegram накапливаются обновления. При повторном запуске бот пытается моментально обработать все скопившиеся старые сообщения, что может перегрузить сервер или отправить пользователям неактуальные ответы.
Правильное решение: Очищайте старые запросы перед запуском polling:
await bot.delete_webhook(drop_pending_updates=True)
await dp.start_polling(bot)7. Отсутствие глобального обработчика ошибок (Error Handling Middleware)
Когда бот сталкивается с непредвиденной ситуацией (например, внешний API не отвечает или пользователь заблокировал бота), он падает с ошибкой и никак не отвечает пользователю, оставаясь безмолвным. Из-за этого у пользователя создается впечатление, что сервис полностью сломался.
В aiogram 3.x для отлова ошибок предусмотрен специальный Error Router:
from aiogram import Router
from aiogram.types.error_event import ErrorEvent
import logging
error_router = Router()
@error_router.errors()
async def global_error_handler(event: ErrorEvent):
logging.exception(f'Непредвиденная ошибка: {event.exception}')
if event.update.message:
await event.update.message.answer(
'Извините, произошел сбой в системе. Пожалуйста, попробуйте позже.'
)Заключение
Создание качественного Telegram-бота, способного выдерживать миллионы пользователей, — это не просто добавление кнопок интерфейса. Соблюдение правил асинхронного программирования, хранение состояний в Redis и грамотное управление лимитами выведут разработку вашего бота на профессиональный уровень.
Теги: #telegram bot #aiogram #python #backend