jTelegram / jTelegramBotAPI

Java Telegram Bot API Wrapper
https://jtelegram.github.io/jTelegramBotAPI/
MIT License
20 stars 12 forks source link

Command Filters API #11

Closed nickrobson closed 6 years ago

nickrobson commented 6 years ago

TL;DR: Relatively minor revamp of how commands are created by API consumers.

Example Usage

// Create a filter that passes case-insensitive "start" commands to a StartHandler
CommandFilter startCommand = new TextFilter("start", false, new StartHandler());

// Create a filter that passes case-insensitive "help" commands to a HelpHandler
CommandFilter helpCommand = new TextFilter("help", false, new HelpHandler());

// Create a filter that only allows commands in the form /command@mycustombot (or PM)
CommandFilter myCommands = new MentionFilter(startCommand, helpCommand);

// Registers these commands
bot.getCommandRegistry().registerCommand(myCommands);

The current method of adding command handlers involves:

  1. Creating a CommandListener which tests if a Command will be handled.
  2. Creating a CommandHandler which handles any Commands passed to it.
  3. Registering these so only Commands allowed by the Listener are handled by the Handler.

Why do I think the current system is convoluted?

I personally do not see why listeners and handlers should be entirely separated in functionality. There is enough overlap between the two types where a handler could be a listener that when testing just executes the desired functionality and says "Yup! It passed me!"


Information on the new command filters API

This API merges the concepts of listeners and handlers into filters. Handlers should extend CommandHandler, and filters should extend CommandFilter, though this is not enforced. It is however highly recommended that new filters add a constructor that has a super call providing children to the CommandFilter constructor: CommandFilter(CommandFilter... children). This allows for layering.

I decided not to use CommandFilter[] as the parameter type to prevent horrifically verbose code such as new CommandFilter(new CommandFilter[]{ new MentionFilter(), ... });

It comes with three filter implementations out of the box: TextFilter (matches text directly), RegexFilter (matches a regular expression), and MentionFilter (was the bot mentioned?).

I believe that this API simplifies the creation of more complex command handlers as they can be layered, instead of reinventing the wheel each time more complex functionality is required.

As evident in the implementations of the three provided filters, it is easy to implement new filters - the longest implementation is the MentionFilter which is two lines of code split up for legibility, the others are one line each.

bo0tzz commented 6 years ago

+1

mkotb commented 6 years ago

Hey!

Things look pretty good, and I'd be happy to accept these changes. I just woke up, so I'll find time during the day today to look over the code and either approve it for merging or request changes. If possible, would you be willing to update the wiki if and when I accept this PR? Thanks!