Skip to content

Handlers

Jey edited this page Jun 30, 2024 · 14 revisions

Variety of Handlers

In bot development, particularly in systems involving user interactions, it is crucial to manage and process commands and events efficiently.

These annotations mark functions designed to process specific commands, inputs, or updates and provide metadata such as command keywords, rate limits, scopes, and guards.

Annotations Overview

CommandHandler

The CommandHandler annotation is used to mark functions that process specific commands.

This annotation includes properties that define the command's keywords, rate limits, scopes, and guards. It is intended for functions that should handle commands at runtime.

  • value: Specifies the keywords associated with the command.
  • rateLimits: Defines the query limits for this particular command.
  • scope: Determines the context or scope in which the command will be checked.
  • guard: Specifies a guard class that provides additional validation and processing control for the command.
@CommandHandler(["text"], guard = isAdminGuard::class)
suspend fun test(user: User, bot: TelegramBot) {
    //...
}

CommandHandler.CallbackQuery

A specialized version of the CommandHandler annotation designed specifically for handling callback queries.

It includes similar properties as CommandHandler, with a focus on callback-related commands.

It's actually the same as just @CommandHandler with a preset UpdateType.CALLBACK_QUERY scope.

@CommandHandler.CallbackQuery(["text"], rateLimits = RateLimits(period = 10, rate = 5))
suspend fun test(user: User, bot: TelegramBot) {
    //...
}

CommonHandler

The CommonHandler annotation is intended for functions that process commands with lower priority compared to CommandHandler and InputHandler. It is used at the source level and provides a flexible way to define common command handlers.

Be aware, priority works within just @CommonHandler's itself.

CommonHandler.Text

This annotation specifies text matching against updates. It includes properties to define the matching text, filtering conditions, priority, scope, and rate limits.

  • value: The text to match against incoming updates.
  • filter: A class that defines conditions used in the matching process.
  • priority: The priority level of the handler, where 0 is the highest priority.
  • scope: The context or scope in which the text matching will be checked.
  • rateLimits: The query limits for this specific text matching handler.
@CommonHandler.Text(["text"], filter = isNewUserFilter::class, priority = 10)
suspend fun test(user: User, bot: TelegramBot) {
    //...
}

CommonHandler.Regex

Similar to CommonHandler.Text, this annotation is used for matching updates based on regular expressions. It includes properties for defining the regex pattern, options, filtering conditions, priority, scope, and rate limits.

  • value: The regex pattern used for matching.
  • options: Regex options that modify the behavior of the regex pattern.
  • filter: A class that defines conditions used in the matching process.
  • priority: The priority level of the handler, where 0 is the highest priority.
  • scope: The context or scope in which the regex matching will be checked.
  • rateLimits: The query limits for this specific regex matching handler.
@CommonHandler.Regex("^\d+$", scope = [UpdateType.EDIT_MESSAGE])
suspend fun test(update: EditedMessageUpdate, user: User, bot: TelegramBot) {
    //...
}

Matching

The CommonHandler annotation is has its own matching process. This process includes checking if updates match specified text or regex patterns, ensures is given filter passes, and ensures the command is processed in the correct scope, only when all these conditions are met handler will be match against update.

So basically same text payload can be matched to different activities depending on filter and other context.

InputHandler

The InputHandler annotation marks functions that process specific input events. It is intended for functions that handle inputs at runtime and includes properties for defining input keywords, rate limits, and guards.

  • value: Specifies the keywords associated with the input event.
  • rateLimits: Defines the query limits for this particular input.
  • guard: Specifies a guard class that provides additional validation and processing control for the input.
@InputHandler("text")
suspend fun test(update: ProcessedUpdate, user: User, bot: TelegramBot) {
    //...
}

UnprocessedHandler

The UnprocessedHandler annotation is used to mark functions that handle updates not processed by other handlers. It ensures that any unprocessed updates are managed appropriately, with only one processing point possible for this handler type.

@UnprocessedHandler
suspend fun test(update: ProcessedUpdate, user: User, bot: TelegramBot) {
    //...
}

UpdateHandler

The UpdateHandler annotation marks functions that handle specific types of incoming updates. It provides a way to categorize and process different update types systematically.

  • type: Specifies the types of updates the handler function will process.
@UpdateHandler([UpdateType.PRE_CHECKOUT_QUERY])
suspend fun test(update: PreCheckoutQueryUpdate, user: User, bot: TelegramBot) {
    //...
}

Request limiting

In addition, let us also disclose the rate limiting mechanism described in the annotations.

You can set general limits for each user:

// ...
val bot = TelegramBot("BOT_TOKEN") {
    rateLimiter { // general limits
        limits = RateLimits(period = 10000, rate = 5)
    }
}

// Limits on certain actions
@CommandHandler(["/start"], RateLimits(period = 1000L, rate = 1L))
suspend fun start(user: User, bot: TelegramBot) {
    // ...
}

By default after limit is exceeded bot will send message:

message("Request limit exceeded, try again later.").send(telegramId, bot)

But it can be changed in configuration

val bot = TelegramBot("...") {
    rateLimiter {
        exceededAction = {telegramId: Long, bot: TelegramBot ->
            message("limit exceeded aaaaa...").send(telegramId, bot)
            // change message there or do whatever you like
        }
    }
}

Practical Handlers Applications

Command Processing

In chat applications, command handlers are crucial for processing user commands such as /start, /help, or custom commands specific to the application. By using CommandHandler annotations, developers can easily define which functions should handle specific commands, apply rate limits to prevent abuse, and use guards to ensure the command is executed under the right conditions.

Event Handling

For applications that involve various types of events, such as message updates, callback queries, or other interactions, the UpdateHandler and CommonHandler annotations provide a structured way to manage these events. Developers can specify the types of updates and the conditions under which they should be handled, ensuring the application responds appropriately to different user actions.

Default and Fallback Handling

The UnprocessedHandler annotation allows developers to define a default handler for updates that are not processed by any other handler. This ensures that no update goes unhandled, providing a fallback mechanism to manage unexpected or uncategorized updates.

Conclusion

These annotations provide a robust and flexible tools for handling commands, inputs, and events.

See also

Clone this wiki locally