- Коротко про головне
- Polling или webhook: от чего зависит весь остальной выбор
- Polling
- Webhook
- Где запустить бота бесплатно: сравнение платформ
- Минимальный рабочий бот: полный код с нуля
- Деплой на Render: пошаговый процесс
- Вариант без постоянного процесса: webhook на Vercel
- Хранение данных без выделенной базы
- Ограничения и кому этот подход не подойдёт
- Частые вопросы
- Насколько надёжен бесплатный хостинг для Telegram-бота?
- Что лучше использовать — polling или webhook?
- Как хранить данные пользователей без выделенной базы данных?
- Можно ли запустить бота прямо на своём компьютере?
- Какую библиотеку выбрать — python-telegram-bot или aiogram?
- Похожие материалы
- 🔥 Читайте также:
Коротко про головне
Материал для тех, кто уже написал хотя бы один Python-скрипт и хочет запустить Telegram-бота без аренды VPS и ежемесячных платежей за сервер.
На старт достаточно: Python 3.10+, аккаунт Telegram для регистрации бота через BotFather, и бесплатный слот на одной из платформ — Render, Railway или Vercel.
Реалистичный результат: рабочий бот за один вечер, отвечает на команды и сообщения круглосуточно, при умеренной нагрузке не стоит ничего.
Главный риск: условия бесплатных планов меняются — уточняйте актуальные лимиты и наличие бесплатного тарифа на сайте платформы перед началом работы.
Polling или webhook: от чего зависит весь остальной выбор
Telegram-бот взаимодействует с серверами Telegram одним из двух способов. Выбор способа определяет, где вы сможете хостить бота и насколько сложным будет код.
Polling
Бот сам периодически спрашивает у Telegram API: «есть новые сообщения?» Это постоянно работающий процесс — он не завершается, пока вы его не остановите. Плюсы: не нужен публичный адрес и HTTPS-сертификат, код проще, локальная отладка работает без танцев с туннелями. Минус: платформа должна держать процесс живым постоянно. Сервисы, которые засыпают при отсутствии HTTP-трафика, могут убивать процесс через несколько минут простоя.
Webhook
Telegram сам отправляет POST-запрос на ваш URL при каждом новом сообщении. Бот «спит» и запускается только по событию. Это идеальная модель для serverless-платформ: вы не занимаете постоянный слот, а платите только за реальные вызовы. Минусы: нужен публичный HTTPS-адрес, при холодном старте первый ответ может идти несколько секунд, хранить состояние между вызовами нельзя без внешнего хранилища.
Для первого бота рекомендую polling — меньше инфраструктуры, проще отлаживать. К webhook переходите, когда polling не вписывается в ограничения выбранной платформы.
Где запустить бота бесплатно: сравнение платформ
Ниже — актуальная картина на момент написания статьи. Конкретные лимиты и наличие бесплатных планов меняются, поэтому перед регистрацией уточните условия на сайте каждого сервиса.
| Платформа | Режим работы бота | Что стоит уточнить на сайте | Сложность деплоя |
|---|---|---|---|
| Render | Polling (Background Worker) | Лимиты памяти и CPU, поведение при простое | Низкая |
| Railway | Polling или webhook | Лимит часов в месяц, наличие бесплатного плана | Низкая |
| PythonAnywhere | Polling (Always-on task) | Включён ли Always-on в бесплатный тариф | Средняя |
| Vercel | Webhook (serverless functions) | Лимит вызовов и максимальное время выполнения | Средняя |
| Google Cloud Run | Webhook (serverless) | Условия бесплатного уровня, лимит запросов | Высокая |
Для абсолютного старта Render и Railway проще всего: деплой через подключение GitHub-репозитория, переменные среды через веб-интерфейс, логи доступны в браузере.
Минимальный рабочий бот: полный код с нуля
Используем библиотеку python-telegram-bot — она поддерживает async, активно развивается и имеет подробную документацию. Устанавливается стандартно:
pip install "python-telegram-bot>=21.0"Файл main.py — полный эхо-бот с командой /start:
import logging
import os
from telegram import Update
from telegram.ext import (
Application,
CommandHandler,
MessageHandler,
filters,
ContextTypes,
)
logging.basicConfig(
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
level=logging.INFO,
)
TOKEN = os.environ.get("BOT_TOKEN", "ВАШ_ТОКЕН_ОТ_BOTFATHER")
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
await update.message.reply_text(
"Привет! Я эхо-бот. Напиши что-нибудь, и я повторю."
)
async def echo(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
await update.message.reply_text(update.message.text)
def main() -> None:
app = Application.builder().token(TOKEN).build()
app.add_handler(CommandHandler("start", start))
app.add_handler(
MessageHandler(filters.TEXT & ~filters.COMMAND, echo)
)
app.run_polling(allowed_updates=Update.ALL_TYPES)
if __name__ == "__main__":
main()Рядом с main.py создайте файл requirements.txt:
python-telegram-bot>=21.0Этих двух файлов достаточно для деплоя на большинство платформ. Токен передаётся через переменную среды BOT_TOKEN — никогда не вшивайте его прямо в код и не коммитьте в репозиторий.
Деплой на Render: пошаговый процесс
Render поддерживает тип сервиса Background Worker — процесс без HTTP-порта, который не засыпает от отсутствия веб-запросов. Это подходит для polling-бота лучше, чем обычный Web Service. Уточните актуальные условия бесплатного плана на сайте render.com перед началом.
- Создайте публичный или приватный репозиторий на GitHub с файлами
main.pyиrequirements.txt, закоммитьте и запушьте. - Зарегистрируйтесь на Render, перейдите в Dashboard и нажмите New → Background Worker.
- Подключите GitHub-аккаунт и выберите созданный репозиторий.
- Укажите Runtime: Python 3. Build Command:
pip install -r requirements.txt. Start Command:python main.py. - Перейдите в раздел Environment, добавьте переменную
BOT_TOKENсо значением токена от BotFather. - Нажмите Create Background Worker и наблюдайте за логами. Когда polling запустится, в логах появится строка вида
Application started. - Напишите боту в Telegram — он должен ответить в течение нескольких секунд.
Если в логах видна ошибка Unauthorized — неверный токен в переменных среды. Ошибка Conflict означает, что где-то ещё запущен второй экземпляр бота с тем же токеном — остановите его.
Вариант без постоянного процесса: webhook на Vercel
Если хотите полностью serverless-подход, где бот запускается только при входящем сообщении — используйте Vercel. Telegram отправляет POST-запрос на ваш URL, функция отрабатывает за секунду и завершается. Никакого постоянного процесса.
Структура проекта:
my-bot/
├── api/
│ └── webhook.py
├── requirements.txt
└── vercel.jsonФайл api/webhook.py. Обратите внимание: экземпляр Application создаётся на уровне модуля — один раз при холодном старте функции, а не на каждый запрос. Создание нового экземпляра внутри обработчика — распространённая ошибка: она пересоздаёт всю инфраструктуру библиотеки при каждом сообщении и легко упирается в лимит времени выполнения Vercel. Предел модульного подхода: при масштабировании до нескольких параллельных инстанций у каждой будет свой экземпляр — разделяемое состояние между ними недоступно без внешнего хранилища.
import json
import os
import asyncio
from http.server import BaseHTTPRequestHandler
from telegram import Update
from telegram.ext import Application, CommandHandler, ContextTypes
TOKEN = os.environ["BOT_TOKEN"]
# Application инициализируется один раз на уровне модуля (при холодном старте).
# Создание нового экземпляра внутри do_POST — ошибка: пересоздаёт всю
# инфраструктуру библиотеки на каждый запрос и упирается в лимит Vercel.
app = Application.builder().token(TOKEN).build()
async def cmd_start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
await update.message.reply_text("Привет от serverless-бота.")
app.add_handler(CommandHandler("start", cmd_start))
async def process_update(body: dict) -> None:
await app.initialize()
update = Update.de_json(body, app.bot)
await app.process_update(update)
class handler(BaseHTTPRequestHandler):
def do_POST(self):
length = int(self.headers.get("Content-Length", 0))
body = json.loads(self.rfile.read(length))
# asyncio.run() может конфликтовать с уже запущенным event loop
# в некоторых версиях рантайма — создаём новый loop явно.
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
try:
loop.run_until_complete(process_update(body))
finally:
loop.close()
self.send_response(200)
self.end_headers()
self.wfile.write(b"ok")
def log_message(self, format, *args):
passФайл vercel.json. Vercel автоматически определяет Python-рантайм для файлов в директории api/ — явно указывать строку runtime не нужно. В блоке functions задайте только ограничения выполнения; максимально допустимое значение maxDuration зависит от вашего тарифного плана — уточните в официальной документации Vercel:
{
"functions": {
"api/webhook.py": {
"maxDuration": 10
}
}
}После деплоя через Vercel CLI (vercel --prod) или GitHub-интеграцию зарегистрируйте webhook одним curl-запросом. Замените заглушки в угловых скобках своими значениями:
curl "https://api.telegram.org/bot<ВАШ_ТОКЕН>/setWebhook?url=https://<ВАШ_ПРОЕКТ>.vercel.app/api/webhook"В ответ придёт JSON с полем "ok": true. После этого Telegram будет слать каждое сообщение прямо в вашу функцию.
Хранение данных без выделенной базы
Serverless-функция не помнит ничего между вызовами. Если боту нужно хранить состояние — шаг диалога, настройки пользователя, счётчики — нужно внешнее хранилище. Несколько вариантов, которые работают на бесплатных платформах:
- Redis через Upstash — managed Redis с HTTP API. Подключается через официальный SDK одной строкой. Уточните актуальный бесплатный лимит на upstash.com.
- Google Sheets через gspread — неожиданно удобно для прототипов: читаете и пишете строки как в простую таблицу. Работает бесплатно при разумном числе запросов, не требует отдельной БД.
- SQLite при polling — для бота на Render или Railway подойдёт SQLite прямо в файловой системе. Быстро, никаких внешних сервисов.
Важно для SQLite на Render: файловая система сбрасывается при каждом перезапуске сервиса — все данные в SQLite-файле теряются безвозвратно. Это не второстепенная деталь: если сервис перезапустится из-за деплоя, ошибки или планового обслуживания, данные пропадут. Используйте SQLite на Render только если потеря данных допустима (например, кэш), либо подключите постоянный диск (Disk) в настройках сервиса.
Для простых сценариев — флаг «пользователь подтвердил согласие», последний выбранный язык — достаточно хранить данные в словаре в памяти процесса. Это работает, пока процесс не перезапустится. Приемлемо для инструментов, где сброс состояния не критичен.
Ограничения и кому этот подход не подойдёт
Бесплатные платформы — рабочий инструмент для прототипов, учебных проектов и небольших инструментов для себя или узкого круга. Но есть сценарии, где они становятся проблемой, а не решением.
Этот подход не подходит, если:
- Бот обслуживает сотни активных пользователей одновременно. Бесплатные планы ограничены по CPU и памяти — при пиковой нагрузке сообщения начнут теряться или обрабатываться с задержкой.
- Нужна гарантия аптайма. SLA на бесплатных планах не предусмотрено, платформа может уходить на техобслуживание без предупреждения.
- Бот работает с платёжными данными, персональными данными третьих лиц или в регулируемой отрасли — здесь важна предсказуемость инфраструктуры и возможность быстро масштабироваться.
- Первый ответ должен приходить мгновенно. Serverless с холодным стартом даёт задержку после периода простоя — от нескольких сотен миллисекунд до десятков секунд в зависимости от объёма зависимостей и платформы. Конкретные значения уточняйте в официальной документации выбранной платформы.
Отдельные риски, о которых стоит знать заранее:
- Условия бесплатных планов меняются без предупреждения. Heroku убрал бесплатный тариф в 2022 году — тысячи ботов разом перестали работать. Храните код в репозитории и документируйте переменные среды, чтобы переезд занимал минуты.
- Токен бота в открытом коде или публичном репозитории — критическая уязвимость. Всегда используйте переменные среды, никогда не коммитьте
.env-файлы. - Polling на платформе, которая засыпает, даст задержку первого ответа в несколько минут. Тестируйте поведение при простое, прежде чем отдавать бота пользователям.
Для проекта с реальной аудиторией и монетизацией минимальный VPS за 5-7 долларов в месяц надёжнее любого бесплатного решения: предсказуемые ресурсы, постоянный диск, возможность запустить несколько сервисов рядом. Бесплатные платформы — хороший старт для обучения и проверки идеи, но не основа для чего-то, на что рассчитывают пользователи.
Частые вопросы
Насколько надёжен бесплатный хостинг для Telegram-бота?
Для прототипов и личных инструментов — вполне рабочий вариант. Для продакшена с реальной аудиторией лучше взять недорогой VPS: бесплатные платформы могут засыпать, ограничивать ресурсы или менять условия без предупреждения. Держите код в репозитории, чтобы переезд занимал минуты.
Что лучше использовать — polling или webhook?
Для первого бота начните с polling: не нужен публичный HTTPS-адрес, проще отлаживать локально. Webhook подходит для serverless-платформ вроде Vercel, где нет постоянного процесса — бот запускается только при входящем сообщении от Telegram.
Как хранить данные пользователей без выделенной базы данных?
Для serverless-бота подойдёт Redis через Upstash или Google Sheets через gspread — оба варианта имеют бесплатные уровни, уточните актуальные условия на сайтах сервисов. Для polling-бота на Render или Railway можно использовать SQLite прямо в файловой системе, но данные теряются при перезапуске, если не подключён постоянный диск.
Можно ли запустить бота прямо на своём компьютере?
Да, polling работает с вашего ноутбука без какой-либо публичной ссылки — просто запустите python main.py. Это удобно для разработки и тестирования. Минус очевиден: бот недоступен, когда компьютер выключен или теряет интернет.
Какую библиотеку выбрать — python-telegram-bot или aiogram?
Обе активно поддерживаются. python-telegram-bot удобнее для начинающих — больше готовых примеров и подробная документация. aiogram даёт больше контроля над async-логикой и чуть производительнее при высоких нагрузках. Для первого бота разница несущественна — выбирайте ту, для которой нашли больше понятных туториалов.