Skip to main content

103. Middleware-Driven Bot Design

Status: Accepted Date: 2025-07-06

Context

When handling incoming updates for a Telegram bot, there are several cross-cutting concerns that apply to almost every message. These include logging the incoming request, handling errors gracefully, parsing the request body, and checking user authentication. Implementing this logic inside every single command handler (/start, /help, etc.) would lead to massive code duplication and would be a maintenance nightmare.

Decision

We will use a middleware-driven design for processing incoming Telegram updates. This pattern, common in web frameworks like Express, involves creating a pipeline of small, focused functions that process a request in sequence before it reaches the final command handler.

Our kaido-telegram library, using the grammY framework (adr://grammy-framework-adoption), will establish a standard middleware pipeline for all our bots. This pipeline will include:

  1. Logging Middleware: Logs key information about every incoming update.
  2. Error Handling Middleware: A global error handler that catches any errors thrown by downstream middleware or command handlers, logs the error, and sends a user-friendly error message to the chat.
  3. Authentication Middleware: Checks if the user is authorized to use the bot or a specific command.
  4. Session Middleware: (If needed) Manages user-specific session data.

Specific bots can then add their own custom middleware to this pipeline before defining their command handlers.

Consequences

Positive:

  • DRY and Composable: Logic for cross-cutting concerns is written once, in a dedicated middleware function, and then composed into a pipeline. This is extremely clean and avoids code duplication.
  • Separation of Concerns: Each middleware has a single, well-defined responsibility. This makes the code easier to understand, test, and maintain.
  • Extensibility: It's very easy to add new cross-cutting functionality to the bot by simply adding a new middleware to the pipeline.

Negative:

  • Order Matters: The order of middleware in the pipeline is critical. For example, the authentication middleware must run before the command handler it's protecting. This can be a source of bugs if not managed carefully.
  • "Magic" Control Flow: The flow of control can be less explicit than a simple sequence of function calls. A middleware function can decide to end the request early or pass control to the next function, which can be slightly harder to follow for developers new to the pattern.

Mitigation:

  • Standardized Pipeline: The kaido-telegram library will provide a standardized, default pipeline with a well-documented and sensible order for the common middleware (logging, errors, auth). Most bots will just use this standard setup.
  • Clear Documentation: The middleware pattern is a well-known concept in web development. We will clearly document our specific middleware pipeline and the purpose of each function within it. grammY's documentation on this is also excellent.