Как разрабатывать и отлаживать Telegram-бота на Node.js, NestJS и TypeScript

Короткий ответ: Telegram-бота на Node.js, NestJS и TypeScript лучше держать как отдельный модуль приложения. Токен храните в переменных окружения, обработчики команд выносите в сервис, входящие события логируйте, а для первой отладки используйте long polling. Webhook подключайте уже после того, как логика стабильно работает локально

Базовая структура

src/
  app.module.ts
  bot/
    bot.module.ts
    bot.service.ts

Идея простая: NestJS отвечает за структуру приложения, dependency injection и конфигурацию. Telegram-клиент отвечает за получение update и отправку сообщений

Установка

npm install @nestjs/config telegraf
npm install -D @types/node

Токен кладем в .env:

TELEGRAM_BOT_TOKEN=123456:ABCDEF

Не коммитьте .env в репозиторий. Токен бота дает доступ к отправке сообщений от имени бота

Модуль

import { Module } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";
import { BotService } from "./bot.service";

@Module({
  imports: [ConfigModule],
  providers: [BotService],
})
export class BotModule {}

Подключите модуль в AppModule:

import { Module } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";
import { BotModule } from "./bot/bot.module";

@Module({
  imports: [ConfigModule.forRoot(), BotModule],
})
export class AppModule {}

Сервис бота

import { Injectable, Logger, OnModuleInit } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { Telegraf } from "telegraf";

@Injectable()
export class BotService implements OnModuleInit {
  private readonly logger = new Logger(BotService.name);

  constructor(private readonly config: ConfigService) {}

  async onModuleInit() {
    const token = this.config.get<string>("TELEGRAM_BOT_TOKEN");

    if (!token) {
      throw new Error("TELEGRAM_BOT_TOKEN is not set");
    }

    const bot = new Telegraf(token);

    bot.start((ctx) => ctx.reply("Привет! Бот запущен."));
    bot.command("ping", (ctx) => ctx.reply("pong"));
    bot.on("text", (ctx) => {
      this.logger.log(`Message: ${ctx.message.text}`);
      return ctx.reply("Сообщение получено");
    });

    await bot.launch();
    this.logger.log("Telegram bot launched");
  }
}

Для первого запуска этого достаточно

Как отлаживать

Первый шаг — проверить токен:

https://api.telegram.org/bot<token>/getMe

Если ответ ok: true, токен живой. Если нет, проверьте BotFather, .env и пробелы в значении переменной

Второй шаг — включить логи входящих сообщений. Не логируйте персональные данные без необходимости, но на этапе разработки полезно видеть тип update, chat id и команду

Третий шаг — отдельно проверять бизнес-логику. Не привязывайте всю логику к ctx. Лучше сделать сервис:

function buildAnswer(text: string): string {
  return text.trim().toLowerCase() === "цена" ? "Прайс отправлен" : "Не понял";
}

Такую функцию можно тестировать без Telegram

Long polling и webhook

Для локальной разработки проще long polling: бот сам забирает обновления у Telegram. Для продакшена часто используют webhook: Telegram отправляет update на ваш HTTPS endpoint

Webhook требует публичный HTTPS-адрес. Если у вас локальный компьютер без туннеля или VPS, сначала не усложняйте. Запустите polling, проверьте команды, потом переносите на сервер

Типовые проблемы

Первая проблема — бот не отвечает, потому что уже запущен второй экземпляр с тем же токеном. Остановите старый процесс

Вторая проблема — .env не подхватился. Проверьте ConfigModule.forRoot() и имя переменной

Третья проблема — забыли await bot.launch()

Четвертая проблема — ошибки падают без логов. Оборачивайте сложные обработчики в try/catch или добавляйте middleware для логирования

Пятая проблема — вся логика живет в одном callback. Тогда отладка быстро превращается в боль. Разносите команды по методам и сервисам

Самопроверка

Добавьте команды /start и /ping, запустите проект, отправьте команду боту и проверьте лог в терминале. Затем временно уберите TELEGRAM_BOT_TOKEN из .env и убедитесь, что приложение падает понятной ошибкой, а не молча висит

Что почитать дальше по TypeScript

Если нужен общий маршрут по теме, откройте рубрику TypeScript. Для соседних задач пригодятся эти разборы:

Оцените статью
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x