Большинство Telegram-ботов написано одинаково: программа в бесконечном цикле спрашивает у Telegram «есть что-нибудь новое?». Схема простая, но у неё есть цена — процесс обязан работать круглосуточно, иначе сообщения теряются. Webhook переворачивает эту логику: вы один раз сообщаете Telegram адрес, и он сам приходит, когда пользователь что-то написал. Загвоздка в одном — адрес должен быть публичным и работать по HTTPS, а значит нужны домен и сертификат. В Dockbox эту часть платформа закрывает целиком: вы загружаете код, приложение поднимается и получает публичный HTTPS-адрес. Остаётся сказать Telegram'у, куда стучаться.
Почему бесконечный поллинг — не лучшая идея
Нагрузка без пользы. Бот дёргает Telegram десятки раз в минуту, даже когда ему никто не пишет. Почти все запросы возвращаются пустыми — вы тратите трафик и процессорное время на тишину.
Процесс нельзя останавливать. Поллинг живёт только внутри работающего приложения. Упал процесс, перезагрузился сервер — бот замолчал, и сообщения, отправленные в этот момент, до него просто не дошли.
Экземпляр может быть только один. Запустите два процесса с одним токеном — Telegram вернёт 409 Conflict, и работать будет лишь один из них. Горизонтально масштабировать поллинг нельзя.
Как webhook меняет схему
Адрес диктуете вы, Telegram стучится сам. Метод setWebhook один раз передаёт Telegram URL, и дальше каждое новое сообщение превращается в обычный HTTP-запрос к вашему приложению. Нет сообщений — нет запросов.
Запросы приходят строго по делу. Приложение отвечает на конкретное событие и снова ждёт. Никакого расхода ресурсов на опрос пустой очереди.
Бот становится обычным сайтом. И у сайтов, и у ботов на Dockbox нет ограничения по времени: контейнер работает постоянно, а при сбое платформа перезапускает его автоматически. Разница между вебхуком и поллингом только в способе получения сообщений — на время работы она не влияет. Тариф определяет ресурсы и число проектов, но не режим работы: контейнер запущен постоянно.
Шаг 1. Превратите бота в веб-приложение
Вместо вечного цикла приложение должно подниматься как небольшой веб-сервер и разбирать входящие запросы от Telegram. На Python это Flask, FastAPI или веб-режим aiogram, на Node.js — Express рядом с Telegraf или grammY. Логика ответов не меняется вообще: меняется только способ доставки сообщений.
Точка входа для aiogram 3 выглядит примерно так:
import os
from aiohttp import web
from aiogram import Bot, Dispatcher
from aiogram.webhook.aiohttp_server import SimpleRequestHandler, setup_application
TOKEN = os.environ["BOT_TOKEN"]
SECRET = os.environ["WEBHOOK_SECRET"]
PUBLIC_URL = os.environ["PUBLIC_URL"]
bot = Bot(token=TOKEN)
dp = Dispatcher()
async def on_startup(app):
await bot.set_webhook(f"{PUBLIC_URL}/webhook/{SECRET}", secret_token=SECRET)
def main():
app = web.Application()
app.on_startup.append(on_startup)
handler = SimpleRequestHandler(dispatcher=dp, bot=bot, secret_token=SECRET)
handler.register(app, path=f"/webhook/{SECRET}")
setup_application(app, dp, bot=bot)
web.run_app(app, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))
if __name__ == "__main__":
main()
Шаг 2. Слушайте порт из переменной окружения
Порт задаёт платформа. Приложение обязано слушать тот порт, который платформа передала через переменную PORT, а не захардкоженный в коде. Иначе запросы просто не доедут до вашего процесса, и вы будете долго искать причину в настройках Telegram, хотя дело в коде.
Слушайте на всех интерфейсах. Привязка к 127.0.0.1 означает «доступно только внутри контейнера» — снаружи приложение окажется недостижимым. Нужен 0.0.0.0, как в примере выше.
Шаг 3. Загрузите код и получите HTTPS-адрес
Загрузите проект архивом или импортируйте репозиторий из GitHub — включая приватный. Токен от BotFather введите на этапе создания проекта: он попадёт в переменные окружения и будет храниться в зашифрованном виде. Dockbox соберёт приложение, запустит его и выдаст публичную HTTPS-ссылку — именно она станет адресом вебхука. Подробности по деплою и тарифам — на dockbox.host.
Шаг 4. Расскажите Telegram'у про адрес
Осталось сообщить Telegram, куда отправлять сообщения. Делается это один раз методом setWebhook — вручную через ссылку в браузере или прямо из кода при старте. Второй вариант удобнее: вебхук переустанавливается после каждой публикации, и забыть про него невозможно.
Ручная установка выглядит так:
curl -X POST "https://api.telegram.org/bot$BOT_TOKEN/setWebhook" -d "url=https://ваш-проект.dockbox.host/webhook/$WEBHOOK_SECRET"
Проверка и переход на webhook
Убедитесь, что адрес встал. Спросите Telegram методом getWebhookInfo — он покажет текущий адрес и последнюю ошибку доставки, если она была. Плюс логи проекта видны в панели в реальном времени: сразу понятно, доходят ли запросы до приложения.
Секрет в пути — не роскошь. Добавьте к пути вебхука случайную строку: тогда посторонний не сможет прикинуться Telegram и слать вашему боту поддельные апдейты.
Вернуться к поллингу можно. Достаточно вызвать deleteWebhook и вернуть прежний код. Но помните: бот на поллинге работает так же постоянно, как на вебхуке, — пока запущен его контейнер, платформа держит процесс и перезапускает его при сбое. Разница только в способе доставки сообщений.
Webhook убирает необходимость держать процесс в бесконечном цикле опроса, а вместе с ним и главный аргумент в пользу аренды отдельного сервера. Публичный HTTPS-адрес выдаётся автоматически, сертификат настраивать не нужно, и такой бот работает без ограничения по времени — и на Starter, и на старших тарифах. Попробуйте Dockbox.
Частые вопросы
Почему вебхук лучше постоянного опроса?
При поллинге бот сам постоянно спрашивает Telegram о новых сообщениях, поэтому процесс обязан работать непрерывно. С вебхуком Telegram приходит к вам только тогда, когда есть что доставить. Для бота это меньше впустую потраченной работы, а для вас — возможность запускать его как обычный сайт.
Нужны ли для вебхука свой домен и сертификат?
Telegram требует адрес с защищённым соединением, но покупать домен или настраивать сертификат не обязательно: Dockbox выдаёт публичную HTTPS-ссылку сразу после публикации. Свой домен можно привязать позже — это доступно на тарифе Pro.
Будет ли бот на вебхуке работать на Starter?
Да, и без ограничения по времени. Такой бот ведёт себя как обычное веб-приложение: контейнер запущен постоянно, и бот отвечает на входящий запрос.
Как проверить, что вебхук установлен правильно?
Спросите Telegram методом getWebhookInfo: он покажет текущий адрес и последнюю ошибку доставки, если она была. Дополнительно логи видны в вашей панели в реальном времени — по ним понятно, доходят ли запросы до приложения.
Где хранить токен и секрет вебхука?
В переменных окружения — на платформе для этого есть отдельный раздел с секретами. Ключи BOT_TOKEN, WEBHOOK_SECRET и им подобные задаются там, а в коде остаётся только чтение через os.environ. Значения хранятся в зашифрованном виде: имена переменных видны, а сами значения не показываются никому, включая вас.