Skip to main content

104. NestJS Service Pattern for Bots

Status: Accepted Date: 2025-07-06

Context

The kaido-telegram library needs to be integrated into our main mercury-backend application, which is built on NestJS (adr://nestjs-enterprise-framework). The different bots (e.g., MercuryBot, ArcanaBot) are themselves modules within the main application. We need a clean, standard way for these bot modules to access the functionality of the kaido-telegram library and to wire up their command handlers.

Decision

The kaido-telegram library will be exposed as a standard, injectable NestJS Service.

  • A TelegramModule will be created that provides a TelegramBotService.
  • Specific bot implementations (like MercuryBotModule) will import this TelegramModule.
  • They can then inject the TelegramBotService into their own services or controllers using NestJS's standard dependency injection.
  • The TelegramBotService will expose the underlying grammY bot instance and provide methods for registering command handlers and middleware.
  • The bot modules will use their onModuleInit lifecycle hook to register their specific commands with the injected TelegramBotService.

This pattern allows the Telegram integration to feel like a natural, first-class part of the main NestJS application.

Consequences

Positive:

  • Seamless Integration: This approach integrates perfectly with our existing NestJS architecture. The Telegram functionality becomes just another injectable service, which is a familiar pattern for our developers.
  • Dependency Injection: Bot command handlers can have other application services (like PortfolioService or TournamentService) injected into them, giving them easy access to the full power of the application's business logic.
  • Testability: The TelegramBotService can be easily mocked in unit tests for the bot modules, allowing us to test the command logic without making real calls to the Telegram API.
  • Centralized Configuration: The bot's token and other configurations can be managed by NestJS's central ConfigService, just like any other part of the application.

Negative:

  • Tightly Coupled to NestJS: This pattern makes the kaido-telegram library tightly coupled to the NestJS framework. It would be difficult to use it in a non-NestJS application.

Mitigation:

  • Acceptable Coupling: This is an acceptable trade-off. The kaido-telegram library is being built specifically to serve the bots within our NestJS monorepo. It is not intended to be a general-purpose, framework-agnostic library. Coupling it to NestJS allows us to take full advantage of the framework's power and provides a much better developer experience for its intended use case.