Вебхук для Telegram-бота на Node.js: HTTPS, nginx и secret_token

Как настроить вебхук Telegram-бота на Node.js: требования к HTTPS и портам, nginx, secret_token, setWebhook, локальная отладка и почему бот не отвечает.

Вебхук для Telegram-бота на Node.js: HTTPS, nginx и secret_token

26 Сентября, 2026 Автор: Максим М

Вебхук для Telegram-бота на Node.js: HTTPS, nginx, secret_token и отладка

Разбираемся, как перевести Telegram-бота на вебхук: требования Telegram, настройка сервера и сертификата, защита секретным токеном и типичные ошибки, из-за которых бот молчит.

Пока бот живёт на ноутбуке разработчика, long polling удобен: процесс сам забирает обновления у Telegram, не нужны ни домен, ни сертификат. Но в продакшене у polling есть минусы: процесс должен работать постоянно, его сложно масштабировать на несколько экземпляров, а в serverless он не работает вовсе. Вебхук решает это: Telegram сам присылает каждое обновление POST-запросом на ваш адрес. Разберём, как настроить вебхук для Telegram-бота на Node.js от начала до конца.

Что нужно для вебхука

  • Публичный HTTPS-адрес. Telegram отправляет обновления только по HTTPS с валидным сертификатом. Подойдёт бесплатный сертификат Let's Encrypt.
  • Поддерживаемый порт. Telegram принимает вебхуки на портах 443, 80, 88 и 8443. На практике используют 443, а приложение слушает внутренний порт за прокси.
  • Токен бота от @BotFather.
  • Секретный токен вебхука — строка, по которой вы отличите запросы Telegram от поддельных. Про неё ниже.

Шаг 1. Сертификат и nginx

Классическая схема: nginx принимает HTTPS на 443 порту и проксирует запросы в Node.js-приложение на локальном порту 3000. Сертификат удобно выпустить через acme.sh или certbot. Минимальная конфигурация nginx:

server {
    listen 443 ssl;
    server_name bot.example.ru;

    ssl_certificate /etc/ssl/certs/bot.example.ru.crt;
    ssl_certificate_key /etc/ssl/private/bot.example.ru.key;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Пошагово — выпуск сертификата, автопродление, запуск через pm2 — в руководстве по развёртыванию.

Шаг 2. Секретный токен: зачем он нужен

Адрес вебхука — не секрет: он может попасть в логи, в репозиторий, в скриншот. Без проверки любой, кто его знает, сможет отправить боту поддельное обновление «от имени» любого пользователя. Поэтому при установке вебхука Telegram позволяет задать secret_token — тогда в каждом запросе приходит заголовок X-Telegram-Bot-Api-Secret-Token с этим значением. Сервер должен сверять его и отклонять запросы без правильного заголовка.

Сгенерируйте случайный секрет:

node -e "console.log(require('crypto').randomBytes(24).toString('base64url'))"

Шаг 3. Бот на Node.js

Приём вебхука, проверку секретного заголовка и отправку ответов берёт на себя адаптер Telegram во фреймворке umbot. В .env проекта:

TELEGRAM_TOKEN=123456:ABC-DEF...
TELEGRAM_WEBHOOK_SECRET=сгенерированный_секрет

Код бота:

import { Bot, FALLBACK_COMMAND } from 'umbot';
import { TelegramAdapter } from 'umbot/plugins';

process.loadEnvFile(); // загружает .env в process.env (встроено в Node.js 20.12+)

const bot = new Bot()
    .use(new TelegramAdapter(process.env.TELEGRAM_TOKEN))
    .setAppConfig({
        isLocalStorage: true,
        tokens: {
            // запросы без правильного заголовка получат 401 до выполнения логики
            telegram: { webhookSecret: process.env.TELEGRAM_WEBHOOK_SECRET },
        },
    });

bot.addCommand('start', ['/start', 'привет'], (_, bc) => {
    bc.text = 'Привет! Бот работает через вебхук.';
    bc.buttons.addBtn('Помощь');
});

bot.addCommand(FALLBACK_COMMAND, [], (userCommand, bc) => {
    bc.text = `Вы написали: ${userCommand}`;
});

bot.start('127.0.0.1', 3000); // снаружи доступен только через nginx

Сборка и запуск: npm run build, затем pm2 start dist/index.js — чтобы процесс перезапускался после падения и перезагрузки сервера. Если у вас уже есть сервер на Express или Fastify, отдельный порт не нужен: бот подключается к существующему маршруту через bot.webhookHandle(req, res).

Шаг 4. Регистрация вебхука в Telegram

Вебхук устанавливается методом setWebhook. Секрет — тот же, что в .env:

curl "https://api.telegram.org/bot<ТОКЕН>/setWebhook" \
     -d "url=https://bot.example.ru/" \
     -d "secret_token=<СЕКРЕТ>"

Проверить состояние — методом getWebhookInfo: он показывает текущий адрес, количество неотправленных обновлений и последнюю ошибку доставки.

curl "https://api.telegram.org/bot<ТОКЕН>/getWebhookInfo"

Обратите внимание: пока вебхук установлен, long polling не работает — Telegram не отдаёт обновления через getUpdates. Чтобы вернуться к polling (например, для локальной отладки), удалите вебхук методом deleteWebhook.

Как отлаживать вебхук локально

Поднимать сервер ради каждой правки не нужно. Два способа:

  • Туннель. ngrok http 3000 или cloudflared выдаёт временный HTTPS-адрес, который пробрасывает запросы на ваш компьютер. Установите его вебхуком — и Telegram будет присылать обновления прямо в локальный процесс.
  • Без сети. Логику бота можно проверять вовсе без Telegram: в umbot класс BotTest запускает диалог в консоли и прогоняет автотесты, не отправляя запросы в API. Подробно — в статье про тестирование без публикации.

Типичные ошибки: почему бот молчит

Симптом Причина Что сделать
В getWebhookInfo ошибка SSL Самоподписанный сертификат или неполная цепочка Используйте fullchain-сертификат (Let's Encrypt)
Все запросы получают 401 Секрет в setWebhook и в приложении не совпадает Переустановите вебхук с тем же секретом, что в .env
Копятся неотправленные обновления Приложение не запущено или nginx не проксирует на нужный порт Проверьте процесс (pm2) и proxy_pass
Бот отвечает с большой задержкой или дублями Сервер отвечает слишком долго, Telegram повторяет доставку Отвечайте быстро, тяжёлую работу выносите в фон
Polling перестал работать Установлен вебхук Вызовите deleteWebhook

Вебхук без своего сервера

Если сервер держать не хочется, вебхук можно направить в облачную функцию: код выполняется только в момент обновления, а оплата идёт за вызовы. Для этого сценария важно хранить состояние пользователей во внешней базе данных — у функций нет постоянной файловой системы и памяти между вызовами. Как это устроено на примере Yandex Cloud Functions — в статье про serverless-навык.

Частые вопросы

Что лучше: вебхук или long polling? Для продакшена — вебхук: не нужен постоянно работающий опрос, проще масштабировать, работает в serverless. Для локальной разработки и небольших ботов на одном процессе polling проще.

Можно ли повесить несколько ботов на один сервер? Да: у каждого бота свой адрес или путь вебхука. В umbot одно приложение может принимать и Telegram, и другие платформы — Алису, VK, MAX — по одному адресу.

Обязателен ли secret_token? Технически нет, но без него любой, кто узнал адрес вебхука, может подделывать сообщения. Для продакшена — обязателен.

Куда дальше

Рекомендую к прочтению следующие статьи:

Навык для Алисы без своего сервера: serverless на Yandex Cloud

Навык для Алисы без своего сервера: serverless на Yandex Cloud

Как запустить навык Алисы в Yandex Cloud Functions без своего сервера: генерация serverless-проекта через CLI umbot, деплой, публичный вызов и лимиты.

Читать статью

Алиса поможет медитировать 🧘‍♂️

Алиса поможет медитировать 🧘‍♂️

В голосовом помощнике Алисе появились треки для медитаций. Они пригодятся тем, кто хочет привести в порядок мысли, избавиться от тревоги или наладить сон.

Читать статью

Умные колонки с Алисой научились вызывать такси

Умные колонки с Алисой научились вызывать такси

С помощью умных колонок с Алисой теперь можно вызвать такси — достаточно попросить об этом голосового помощника. Алиса сама сделает заказ и сообщит, когда водитель будет у подъезда.

Читать статью

Весеннее обновление платформы Диалогов

Весеннее обновление платформы Диалогов

Команда Яндекс.Диалогов подготовила большой пакет обновлений и сегодня представляет его сообществу разработчиков голосовых приложений в формате Dev Preview.

Читать статью

Бот для мессенджера MAX: создание на typescript и Node.js

Бот для мессенджера MAX: создание на typescript и Node.js

Создание бота для мессенджера MAX на Node.js: регистрация, подключение вебхука, отличия API от Telegram и VK, лимиты отправки и пример бота на фреймворке umbot.

Читать статью

Комментарии

Оставить комментарий

Как со мной связаться находясь в Санкт-Петербурге

Я работаю по всей России, поэтому вы можете спокойно связаться со мной находясь в Санкт-Петербурге!
Задавайте свои вопросы в форме обратной связи, и я с радостью отвечу на все вопросы!

Телефон:

+7(909) 281 35-20

Дополнительная почта:

info@maxim-m.ru

Я в социальных сетях:

ВверхВверх 👆