Если задача звучит как «создать чат бота», а бот должен принимать заявки, отвечать по правилам и жить на сервере без вас, конструктор упрётся в потолок, а код на Python нет. Ниже весь путь: токен у BotFather, библиотека, первый хендлер, кнопки, анкета на состояниях, вызов внешней модели, переход с long polling на вебхук, лимиты Bot API и выкладка на сервер. Версии и ограничения сверены с официальной документацией 21 августа 2026 года.
Что закрывает бот на Python и где проходит граница
Бот в Telegram это клиент Bot API: всё, что он умеет, описано методами API. Текущая версия Bot API 10.2 от 14 июля 2026 года, и она задаёт рамки проекта ещё до первой строки кода. Границы, о которые бьётся первый рабочий бот:
- Текст одного сообщения в методе sendMessage: от 1 до 4096 символов после разбора разметки. Длинный ответ придётся резать на части самому.
- Подпись к фото и другим медиа: 0-1024 символа. Всё остальное уходит отдельным сообщением.
- Отправка файла через multipart: до 50 МБ, фото до 10 МБ. По HTTP-ссылке Telegram заберёт до 20 МБ и до 5 МБ для фото.
- Скачивание файла ботом через getFile: не более 20 МБ, ссылка живёт минимум час.
- Удалить сообщение методом deleteMessage можно, только если оно отправлено меньше 48 часов назад.
Эти цифры определяют интерфейс: длинные ответы разбиваются на экраны, тяжёлые документы отдаются ссылкой на хранилище, а «отменить отправленное вчера» технически невозможно.
Токен у BotFather: что вы получаете и как его хранить
Бот создаётся не в коде, а в диалоге с @BotFather. Команда /newbot запрашивает отображаемое имя и username, который обязан заканчиваться на bot, после чего выдаёт токен. Это единственный фактор аутентификации: токен подставляется прямо в URL запроса вида api.telegram.org/bot<token>/methodName. Отсюда три правила:
- Токен не хранится в файле с кодом. Переменная окружения или .env, который добавлен в .gitignore до первого коммита.
- Утёкший токен отзывается там же, командой /revoke в BotFather. Старый перестаёт работать сразу.
- Список команд бота задаётся не в коде интерфейса, а методом setMyCommands или командой /setcommands: не более 100 команд, каждая от 1 до 32 символов, только строчные латинские буквы, цифры и подчёркивание.
Окружение и выбор библиотеки: aiogram, pyTelegramBotAPI, python-telegram-bot
Актуальная стабильная версия языка на момент подготовки материала Python 3.14.7 от 5 августа 2026 года. Все три живые библиотеки требуют минимум Python 3.10, так что версия из системного репозитория пятилетней давности не подойдёт.
| Библиотека | Версия и дата | Требования | Модель работы |
|---|---|---|---|
| aiogram | 3.30.0, 17 июля 2026 | Python 3.10-3.14 | Асинхронная, роутеры, встроенный FSM |
| pyTelegramBotAPI (telebot) | 4.36.1, 13 августа 2026 | Python 3.10+ | Синхронная, есть async-ветка |
| python-telegram-bot | 22.8, 12 июня 2026 | Python 3.10+ | Асинхронная, ConversationHandler |
Порядок подготовки одинаковый для любой из трёх: python -m venv venv, активация окружения, установка пакета через pip, фиксация зависимостей в requirements.txt. Последний пункт не формальность: без него бот, поднятый на сервере через полгода, соберётся с другой минорной версией и упадёт на импорте. Дальше примеры описаны на aiogram: у него строгая структура проекта, а асинхронность понадобится в тот же день, когда бот пойдёт во внешние API.
Минимальный каркас бота на aiogram
Рабочий каркас это четыре объекта и один цикл.
- Bot, которому передан токен из переменной окружения. Он умеет только вызывать методы API.
- Dispatcher, который принимает объекты Update и раздаёт их дальше.
- Router, куда регистрируются хендлеры. Роутеры вкладываются друг в друга, поэтому логика режется по файлам: команды, анкета, админка.
- Хендлер, обычная асинхронная функция с декоратором фильтра, например по команде start.
Запуск в разработке делается вызовом start_polling у диспетчера внутри asyncio.run. Проверка живости бота отдельным методом getMe: если он вернул объект с username, токен корректен и сеть до api.telegram.org есть. Это первое, что стоит выполнить при любой ошибке запуска, чтобы отделить проблему кода от проблемы окружения.
Кнопки, команды и callback-запросы
Клавиатур в Bot API две. ReplyKeyboardMarkup подменяет системную клавиатуру и отправляет обычный текст: бот получает строку и не отличает её от набранной руками. InlineKeyboardMarkup живёт под конкретным сообщением и присылает объект CallbackQuery.
Технические ограничения инлайн-кнопок:
- Поле callback_data вмещает от 1 до 64 байт. В кириллице это примерно 32 символа, поэтому в кнопку кладут короткий идентификатор, а не название товара.
- На каждый CallbackQuery обязателен ответ методом answerCallbackQuery. Без него у пользователя висит индикатор загрузки на кнопке, пока клиент не сбросит его сам.
- Всплывающее уведомление у ответа на callback короткое, при необходимости показывается как alert поверх экрана.
Если ответ готовится дольше секунды, до отправки вызывается sendChatAction. Статус набора текста держится 5 секунд или меньше и сбрасывается, как только бот пришлёт сообщение, поэтому при долгой операции вызов повторяют.
Анкета через FSM: состояния и хранилище
Бот не помнит контекст сам: каждый апдейт приходит отдельно. Чтобы собрать имя, телефон и услугу тремя сообщениями, нужна машина состояний. В aiogram она встроена: класс на базе StatesGroup описывает шаги, хендлер фильтруется по состоянию, промежуточные данные лежат в FSMContext.
Ключевой выбор здесь не синтаксис, а хранилище состояний. MemoryStorage держит всё в оперативной памяти процесса: перезапуск бота, и половина пользователей зависла на шаге «введите телефон» без возможности продолжить. Внешнее хранилище вроде Redis переживает рестарт и обязательно, если процесс запускается больше чем в одном экземпляре.
Что закладывается в анкету сразу, чтобы не переделывать:
- Валидация на каждом шаге: телефон проверяется регулярным выражением.
- Кнопка отмены, доступная в любом состоянии, и обработчик, чистящий контекст.
- Запрос номера отдельной кнопкой запроса контакта: так номер приходит от клиента Telegram, а не набирается вручную с опечатками.
Искусственный интеллект в чат-боте: вызов модели из хендлера
Когда в сценарии появляется искусственный интеллект, чат перестаёт быть детерминированным: ответ приходит от внешнего HTTP API за непредсказуемое время. С точки зрения кода бота это обычный асинхронный запрос, и вся сложность в таймаутах.
Библиотека aiohttp, на которой работает aiogram, по умолчанию даёт общий таймаут 300 секунд на всю операцию. Для бота это неприемлемо: пользователь уйдёт из чата на второй минуте, а хендлер продолжит удерживать соединение. Практика простая.
- Свой ClientTimeout на каждый запрос к модели, разумный потолок несколько десятков секунд.
- Перед запросом sendChatAction, чтобы в чате был виден статус набора, и повтор вызова каждые 5 секунд при долгом ответе.
- Ветка на исключение по таймауту с человеческим текстом и повторной попыткой, а не молчание бота.
- Ответ модели режется под лимит sendMessage в 4096 символов до отправки, иначе API вернёт ошибку на длинном ответе.
- Клиентская сессия создаётся один раз на жизнь процесса, а не в каждом хендлере.
Выбор самой модели, промпт роли, база знаний и эскалация на оператора это отдельная тема: подробный разбор в материале о том, как создать чат-бота на нейросети. Здесь важно только то, что со стороны Python это ещё один вызов внешнего сервиса, который обязан быть обёрнут в таймаут.
Long polling или вебхук: как бот получает апдейты
Способов доставки апдейтов ровно два, и переключение между ними это одна строка в коде плюс настройки инфраструктуры.
Long polling через getUpdates: процесс сам опрашивает Telegram. Параметр limit принимает значения от 1 до 100, по умолчанию 100. Параметр timeout по умолчанию 0, то есть короткий опрос, который документация прямо рекомендует использовать только для тестов. В продакшене ставится положительный timeout, иначе процесс молотит запросы вхолостую.
Вебхук через setWebhook: Telegram сам присылает POST на ваш адрес. Требования жёсткие.
- Только HTTPS. Поддерживаются порты 443, 80, 88 и 8443, других нет.
- Параметр max_connections задаёт число одновременных соединений от 1 до 100, по умолчанию 40.
- Параметр secret_token от 1 до 256 символов из набора A-Z, a-z, 0-9, подчёркивание и дефис. Telegram добавит его в заголовок X-Telegram-Bot-Api-Secret-Token, и ваш обработчик обязан этот заголовок проверять. Без проверки endpoint принимает апдейты от кого угодно.
- Параметр drop_pending_updates сбрасывает накопленную очередь при переключении, иначе после простоя бот разом ответит на все старые сообщения.
- Состояние доставки смотрится методом getWebhookInfo: он возвращает last_error_message и last_error_date. Это первое место, куда идут при жалобе «бот молчит».
Правило выбора: разработка и внутренний бот на десятки пользователей это long polling, публичный бот с уведомлениями и нагрузкой это вебхук за уже имеющимся HTTPS-доменом.
Лимиты Bot API и ошибка 429
Рассылка это то место, где первый бот получает бан на отправку. Официальные ориентиры из FAQ Telegram:
- В один чат не чаще одного сообщения в секунду. Короткие всплески допускаются, но на длинной дистанции лимит соблюдается.
- В одну группу не более 20 сообщений в минуту.
- Массовая рассылка около 30 сообщений в секунду суммарно.
Превышение возвращает ошибку 429, а в объекте ResponseParameters приходит поле retry_after с числом секунд ожидания. Обработчик обязан читать это поле и засыпать ровно на указанное время, а не повторять запрос немедленно.
Платные рассылки поднимают потолок до 1000 сообщений в секунду: каждое сообщение сверх бесплатных 30 в секунду стоит 0,1 Telegram Stars. Порог входа отсекает почти всех: нужно не менее 100 000 Stars на балансе и не менее 100 000 активных пользователей в месяц. Для обычного проекта вывод такой: рассылка на 10 000 подписчиков при 30 в секунду займёт около 6 минут и делается очередью, а не циклом for.
Бот перерос вечерний проект
Токен, хендлер и кнопки собираются за вечер. Очередь рассылки с учётом retry_after, вебхук с проверкой секретного заголовка, внешнее хранилище состояний и мониторинг падений это уже недели работы. Мы разрабатываем и сопровождаем Telegram-ботов под задачу: от анкеты с выгрузкой в вашу систему до сценариев с вызовом моделей.
Выкладка на сервер: systemd, Docker и логи
Бот, запущенный командой в терминале, умирает вместе с SSH-сессией. Рабочих схем две.
Первая, systemd-юнит на VPS. Директива Restart=always поднимает процесс после любого завершения, RestartSec по умолчанию 100 мс. Деталь, о которую спотыкаются: перезапуск ограничен рейт-лимитом, по умолчанию 5 попыток за 10 секунд (DefaultStartLimitBurst равен 5, DefaultStartLimitIntervalSec равен 10 с). Бот, падающий на старте из-за неверного токена, через полсекунды окажется в состоянии failed и не поднимется, пока не выполните systemctl reset-failed. Поэтому RestartSec выставляют в несколько секунд.
Вторая схема, контейнер с политикой restart unless-stopped: зависимости зафиксированы образом, Redis и база поднимаются рядом одним файлом compose.
Что настраивается до первого пользователя:
- Логи через модуль logging с уровнем INFO в journald или файл. Print это не логи.
- Секреты в переменных окружения юнита или в env-файле с правами 600.
- Один экземпляр процесса. Два запущенных polling-процесса с одним токеном дают ошибку 409 Conflict: getUpdates разрешён только одному потребителю.
Чек-лист запуска и ошибки, на которых спотыкается первый бот
- Получить токен у @BotFather, сразу задать команды через setMyCommands.
- Поставить Python не ниже 3.10, создать venv, зафиксировать requirements.txt.
- Вынести токен в переменную окружения и добавить .env в .gitignore.
- Собрать каркас: Bot, Dispatcher, Router, хендлер команды start, проверка через getMe.
- Добавить инлайн-кнопки с коротким callback_data и обязательным answerCallbackQuery.
- Сделать анкету на FSM с валидацией и внешним хранилищем состояний.
- Обернуть каждый внешний запрос своим таймаутом.
- Реализовать обработку 429 с чтением retry_after и очередь для рассылок.
- Развернуть на сервере с автоперезапуском и логами, RestartSec выставить вручную.
- Перевести на вебхук с проверкой secret_token, когда появится домен и нагрузка.
Ошибки, которые встречаются чаще прочих: токен в коде и утечка через публичный репозиторий; две копии бота и постоянный 409; синхронный блокирующий вызов внутри асинхронного хендлера, который останавливает весь бот; отправка ответа длиннее 4096 символов без нарезки; отсутствие ответа на callback и вечный индикатор на кнопке; попытка удалить сообщение старше 48 часов.
Частые вопросы
Какая версия Python нужна для бота в 2026 году
Не ниже 3.10: этого требуют все три живые библиотеки. aiogram 3.30.0 объявляет поддержку диапазона от 3.10 до 3.14 включительно, pyTelegramBotAPI 4.36.1 и python-telegram-bot 22.8 требуют 3.10 и выше. Актуальная стабильная версия языка 3.14.7 от 5 августа 2026 года.
Сколько сообщений в секунду можно рассылать
По умолчанию около 30 сообщений в секунду суммарно, не чаще одного в секунду в один чат и не более 20 в минуту в одну группу. При превышении API возвращает 429 с полем retry_after. Потолок 1000 сообщений в секунду доступен только через платные рассылки: 0,1 Stars за каждое сообщение сверх 30 в секунду и порог в 100 000 Stars на балансе.
Можно ли писать бота на телефоне
Технически да: официальные сборки Termux распространяются через GitHub и F-Droid, внутри ставится Python и pip. Для постоянной работы это не годится: телефон уходит в сон, процесс убивается системой.
Обязателен ли домен и HTTPS
Для long polling нет, для вебхука да: setWebhook принимает только HTTPS-адреса и работает по портам 443, 80, 88 и 8443. Пока бота используют десятки человек, long polling с положительным параметром timeout закрывает задачу полностью.
Что делать, если бот перестал отвечать
Порядок проверки занимает три минуты. Вызов getMe отвечает на вопрос, жив ли токен и есть ли сеть. Для вебхука getWebhookInfo показывает last_error_message и last_error_date с причиной отказа доставки. Дальше смотрят логи процесса: 409 Conflict означает вторую запущенную копию, 429 означает упор в лимит рассылки.








