Короткий ответ: 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. Для соседних задач пригодятся эти разборы:
- Node.js и TypeScript: как разбирать и исправлять ошибки
- TypeScript в Node.js: первый Express API
- Как настроить транспайлинг TypeScript в ES6 для Node.js
- 10 вопросов по TypeScript и ответы на них



