TunnelHunt

Telegram-бот локально: webhook, secret_token и отладка на localhost

6 мин чтения

Запустите Telegram-бота на localhost: выберите polling или webhook, настройте HTTPS и secret_token, проверьте getWebhookInfo и исправьте ошибки доставки.

Как создать и отладить Telegram-бота локально с помощью TunnelHunt

Telegram-бота можно разрабатывать локально двумя способами. Long polling (getUpdates) получает обновления исходящими запросами и не требует публичного адреса. Webhook (setWebhook) принимает обновления по входящему HTTPS-запросу — для этого нужен доступный Telegram endpoint.

Выберите polling для простого локального бота, если не нужно проверять серверный обработчик вебхука. В этой статье разбираем webhook: локальный Node.js-сервер, SSH-туннель и проверка секретного заголовка. Способы получения обновлений взаимоисключающие; это описано в Telegram Bot API.

Проблема: Telegram не видит ваш localhost

Когда вы запускаете код бота локально, он обычно слушает порт, например, 3000. Этот адрес доступен только на вашей машине. Если вы попытаетесь указать http://localhost:3000 в качестве вебхука в Telegram API, серверы Telegram выдадут ошибку, так как не смогут достучаться до вашего компьютера из интернета.


Решение: Создаем мост с TunnelHunt

TunnelHunt создает безопасный публичный HTTPS-адрес, который перенаправляет все входящие запросы от Telegram на ваш локальный порт. Нам не нужно устанавливать дополнительный софт — достаточно стандартного SSH-клиента, который уже есть на вашей операционной системе.

Шаг 1: Создаем бота и получаем токен

Если у вас еще нет бота:

  1. Найдите официального бота @BotFather в Telegram.
  2. Отправьте команду /newbot и следуйте инструкциям.
  3. Скопируйте полученный токен (строка вида 123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ). Держите его в секрете.

Шаг 2: Пишем код бота с проверкой безопасности (Node.js / Express)

Создадим простой эхо-бот на Node.js. Чтобы защитить нашего бота от поддельных запросов, мы используем встроенную функцию Telegram — секретный токен вебхука (secret_token). Telegram будет присылать этот токен в заголовке X-Telegram-Bot-Api-Secret-Token при каждом запросе.

Создайте файл bot.cjs:

// bot.cjs
const express = require('express');
const axios = require('axios');

const app = express();
app.use(express.json()); // Парсим входящие JSON-данные

const BOT_TOKEN = process.env.BOT_TOKEN;
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET;
if (!BOT_TOKEN || !WEBHOOK_SECRET) throw new Error('Set BOT_TOKEN and WEBHOOK_SECRET');
const API_URL = `https://api.telegram.org/bot${BOT_TOKEN}`;
const PORT = 3000;

// Наш обработчик вебхуков
app.post('/webhook', async (req, res) => {
  // 1. Проверяем секретный токен от Telegram
  const secretHeader = req.headers['x-telegram-bot-api-secret-token'];
  if (secretHeader !== WEBHOOK_SECRET) {
    console.log('🚨 Попытка несанкционированного доступа к вебхуку!');
    return res.sendStatus(403); // Отклоняем запрос
  }

  console.log('Получено обновление:', req.body.update_id);

  const message = req.body.message;
  if (message && message.text) {
    const chatId = message.chat.id;
    const text = message.text;

    // Отправляем ответное сообщение через API Telegram
    try {
      await axios.post(`${API_URL}/sendMessage`, {
        chat_id: chatId,
        text: `Вы написали: "${text}"`,
      });
    } catch (error) {
      console.error('Ошибка отправки сообщения:', error.message);
    }
  }

  // Всегда отвечаем 200 OK, подтверждая получение вебхука
  res.sendStatus(200);
});

app.listen(PORT, () => {
  console.log(`Бот запущен локально и слушает порт ${PORT}`);
});

Установите Node.js и зависимости в отдельной папке проекта. Сохраните пример как bot.cjs (CommonJS). Перед запуском задайте переменные окружения в том же терминале. В Bash/zsh это export BOT_TOKEN='ваш-токен', в PowerShell — $env:BOT_TOKEN='ваш-токен'. Аналогично задайте WEBHOOK_SECRET: отдельную случайную строку, например вывод openssl rand -hex 32. Токен бота и секрет вебхука — разные значения; не сохраняйте их в репозиторий.

Установите зависимости и запустите бота:

npm install express axios
node bot.cjs

До регистрации вебхука проверьте обработчик искусственным обновлением без message: он не отправит сообщение в Telegram. В терминале с заданным WEBHOOK_SECRET:

curl -i http://127.0.0.1:3000/webhook \
  -H 'Content-Type: application/json' \
  -H "X-Telegram-Bot-Api-Secret-Token: ${WEBHOOK_SECRET}" \
  --data '{"update_id":9001}'

Ожидаются HTTP 200 и запись Получено обновление: 9001. Тот же запрос без секретного заголовка должен вернуть 403. Если локальная проверка не проходит, сначала исправьте обработчик.

Шаг 3: Запускаем туннель TunnelHunt

Откройте новое окно терминала и выполните команду, чтобы пробросить локальный порт 3000 в интернет:

Для лимитов Free сначала добавьте публичный SSH-ключ в кабинет. Если ключ отдельный, укажите его через -i /путь/к/ключу.

ssh -R 80:localhost:3000 -p 2222 tunnelhunt.ru

Сервер выдаст вам ваш публичный HTTPS-адрес, например: https://pretty-horse-789.tunnelhunt.ru

[!TIP] На Pro за 199 ₽/месяц можно зарезервировать постоянный субдомен, чтобы сохранить URL вебхука после переподключения. Тариф включает 50 ГБ в месяц. В разделе «Туннели» зарезервируйте свободное имя, привяжите свой SSH-ключ и переподключитесь с ним; затем используйте адрес из SSH-терминала.

Шаг 4: Регистрируем вебхук в Telegram

Задайте PUBLIC_URL равным HTTPS-адресу из SSH-терминала, без завершающего слеша. В Bash/zsh зарегистрируйте webhook так:

curl --fail-with-body -X POST "https://api.telegram.org/bot${BOT_TOKEN}/setWebhook" \
  --data-urlencode "url=${PUBLIC_URL}/webhook" \
  --data-urlencode "secret_token=${WEBHOOK_SECRET}"

Ожидается JSON с "ok":true. В PowerShell используйте curl.exe и синтаксис переменных $env:BOT_TOKEN, $env:PUBLIC_URL, $env:WEBHOOK_SECRET либо выполните пример в WSL. Для разработки используйте отдельного тестового бота: регистрация заменяет его текущий webhook.

Шаг 5: Тестируем!

Сначала повторите искусственный запрос из шага 2, заменив локальный адрес на ${PUBLIC_URL}/webhook. Ожидается тот же 200. Затем напишите сообщение своему тестовому боту: в консоли должен появиться update_id, а в Telegram — эхо-ответ. Это две разные проверки: доставка входящего события и отправка ответа ботом.


Секретное оружие разработки: Request Replay

При отладке сложных сценариев бота (например, обработке callback-кнопок или заполнении анкеты) вам обычно приходится многократно вручную нажимать кнопки в Telegram.

С TunnelHunt вы можете автоматизировать этот процесс. Перейдите в личный кабинет TunnelHunt в раздел Logs:

  1. Найдите лог входящего вебхука от Telegram.
  2. Проверьте тело запроса.
  3. Нажмите кнопку Replay (Повторить запрос).
  4. TunnelHunt отправит этот вебхук на ваш компьютер еще раз.

Вы можете вносить правки в свой код и повторно тестировать логику обработки одного и того же события в один клик, не заходя в приложение Telegram!


Заключение

Использование TunnelHunt избавляет от необходимости постоянного деплоя бота для тестирования мелких изменений. Вы разрабатываете код локально, тестируете его в реальном времени с использованием брейкпоинтов и логов, а поддержка HTTPS-туннелей «из коробки» позволяет работать с API Telegram напрямую.

Вебхук Telegram не приходит: getWebhookInfo

Выполните в Bash/zsh:

curl --fail-with-body "https://api.telegram.org/bot${BOT_TOKEN}/getWebhookInfo"

Проверьте url, pending_update_count и, если присутствуют, last_error_message и last_error_date. Пустой url означает, что webhook не установлен. Старый домен требует повторной регистрации; 403 у нашего обработчика указывает на несовпадение секретного заголовка. Ошибка соединения требует проверки локального процесса и туннеля.

Если сообщение дошло, но бот не отвечает, смотрите ошибку исходящего sendMessage. Демонстрационный код подтверждает приём обновления ответом 200 даже при ошибке отправки эха; для надёжной обработки добавьте очередь, повтор исходящего запроса и защиту от повторной обработки update_id.

Как вернуться к long polling

Остановите обработчик и удалите webhook тестового бота:

curl --fail-with-body -X POST "https://api.telegram.org/bot${BOT_TOKEN}/deleteWebhook"

После этого можно запускать polling-клиент. Не используйте drop_pending_updates, если не собираетесь намеренно удалять ожидающие обновления. Подробнее: getWebhookInfo и deleteWebhook.

Для автоматизаций без собственного обработчика смотрите Telegram Trigger в n8n, для повторного воспроизведения события — Replay.

Проверьте webhook своего Telegram-бота

Начните с тестового бота и бесплатного туннеля. Когда обработчик работает, постоянный адрес на Pro позволит сохранять URL вебхука после переподключения.

Free: 1 ГБ трафика в месяц, 1 туннель, сессия до 4 часов. Pro: 199 ₽/месяц, 50 ГБ, до 5 туннелей и резервирование поддомена. Компьютер, приложение и SSH-соединение должны работать; постоянный адрес сохраняет имя, а не доступность выключенного сервера.

Готовы запустить свой первый туннель?

Начните использовать TunnelHunt бесплатно уже сегодня и откройте доступ к локальному серверу всего одной командой.

Зарегистрироваться бесплатно →

По теме