Advanced Filters

Ernest Benedito

2022-09-07

This vignette describes advanced use cases for the filters used with MessageHandler or CommandHandler.

Combining filters

When using MessageHandler it is sometimes useful to have more than one filter. This can be done using so called binary operators. Using telegram.bot, you can operate BaseFilter instances with &, | and ! meaning AND, OR and NOT respectively.

Examples

Message is either video, photo, or document (generic file)

handler <- MessageHandler(callback, 
  MessageFilters$video | MessageFilters$photo | MessageFilters$document
)

Message is a forwarded photo

handler <- MessageHandler(callback,
  MessageFilters$forwarded & MessageFilters$photo
)

Message is a photo and it’s not forwarded

handler <- MessageHandler(callback,
  MessageFilters$photo & (!MessageFilters$forwarded)
)

Custom filters

It is also possible to write your own filters used with MessageHandler and CommandHandler. In essence, a filter is simply a function that receives a Message instance and returns either TRUE or FALSE. This function has to be implemented in a new class that inherits from BaseFilter, which allows it to be combined with other filters. If a filter evaluates to TRUE, the message will be handled.

Examples

Restricting users

Say that for the kill example we saw in the previous page, we would like to filter that command so to make it accessible only for a specific USER_ID. Thereby, you could add a filter:

filter_user <- function(message) message$from_user  == "USER_ID"

You can make the function an instance of BaseFilter either with its generator:

filter_user <- BaseFilter(filter = filter_user)

Or by coercing it with as.BaseFilter:

filter_user <- as.BaseFilter(function(message) message$from_user  == "USER_ID")

Remember that to make it work, your filter must be a function that takes a message as input and returns a boolean: TRUE if the message should be handled, FALSE otherwise.

Now, you could update the handler with this filter:

kill_handler <- CommandHandler("kill", kill, filter_user)

Text or command filter

Filters can also be added to the MessageFilters object. Within it, we can see that MessageFilters$text and MessageFilters$command are mutually exclusive, so we could add a filter for messages that can be either one of them. This would result as:

MessageFilters$text_or_command <- BaseFilter(function(message) {
  !is.null(message$text))
}

The class can of cause be named however you want, the only important things are:

  • The class has to inherit from BaseFilter.
  • It has to implement a filter method.
  • The filter must be a function that takes a message as input and returns a boolean.

The filter can then be used as:

handler <- MessageHandler(callback, MessageFilters$text_or_command)