4. Advanced bot commands¶
4.1. Automatic argument splitting¶
With the split_args_with argument to botcmd(),
you can specify a delimiter of the arguments and it will give you an
array of strings instead of a string:
@botcmd(split_args_with=None) def action(self, mess, args): # if you send it !action one two three # args will be ['one', 'two', 'three']
Note
split_args_with behaves exactly like str.split(), therefore
the value None can be used to split on any type of whitespace, such
as multiple spaces, tabs, etc. This is recommended over ‘ ‘ for
general use cases but you’re free to use whatever argument you see
fit.
4.2. Subcommands¶
If you put an _ in the name of the function, Errbot will create what looks like a subcommand for you. This is useful to group commands that belong to each other together.
@botcmd def basket_add(self, mess, args): # Will respond to !basket add pass @botcmd def basket_remove(self, mess, args): # Will respond to !basket remove pass
Note
It will still respond to !basket_add and !basket_remove as well.
4.3. Argparse argument splitting¶
With the arg_botcmd() decorator you can specify
a command’s arguments in argparse format. The decorator can be used multiple times, and each use adds a new argument to the command. The decorator can be passed any valid add_arguments() parameters.
@arg_botcmd('first_name', type=str) @arg_botcmd('--last-name', dest='last_name', type=str) @arg_botcmd('--favorite', dest='favorite_number', type=int, default=42) def hello(self, mess, first_name=None, last_name=None, favorite_number=None): # if you send it !hello Err --last-name Bot # first_name will be 'Err' # last_name will be 'Bot' # favorite_number will be 42
Note
An argument’s dest parameter is used as its kwargs key when your command is called.
favorite_number would be None if we removed default=42 from the
arg_botcmd()call.
4.4. Commands using regular expressions¶
In addition to the fixed commands created with the botcmd()
decorator, Errbot supports an alternative type of bot function which can be triggered
based on a regular expression. These are created using the
re_botcmd() decorator. There are two forms these can be
used, with and without the usual bot prefix.
In both cases, your method will receive the message object same as with a regular
botcmd(), but instead of an args parameter, it takes
a match parameter which will receive an re.MatchObject.
Note
By default, only the first occurrence of a match is returned, even if it can
match multiple parts of the message. If you specify matchall=True, you will
instead get a list of re.MatchObject items, containing all the
non-overlapping matches that were found in the message.
4.4.1. With a bot prefix¶
You can define commands that trigger based on a regular expression, but still require a bot prefix at the beginning of the line, in order to create more flexible bot commands. Here’s an example of a bot command that lets people ask for cookies:
from errbot import BotPlugin, re_botcmd class CookieBot(BotPlugin): """A cookiemonster bot""" @re_botcmd(pattern=r"^(([Cc]an|[Mm]ay) I have a )?cookie please\?$") def hand_out_cookies(self, msg, match): """ Gives cookies to people who ask me nicely. This command works especially nice if you have the following in your `config.py`: BOT_ALT_PREFIXES = ('Err',) BOT_ALT_PREFIX_SEPARATORS = (':', ',', ';') People are then able to say one of the following: Err, can I have a cookie please? Err: May I have a cookie please? Err; cookie please? """ yield "Here's a cookie for you, {}".format(msg.frm) yield "/me hands out a cookie."
4.4.2. Without a bot prefix¶
It’s also possible to trigger commands even when no bot prefix is specified,
by passing prefixed=False to the re_botcmd()
decorator. This is especially useful if you want to trigger on specific
keywords that could show up anywhere in a conversation:
import re from errbot import BotPlugin, re_botcmd class CookieBot(BotPlugin): """A cookiemonster bot""" @re_botcmd(pattern=r"(^| )cookies?( |$)", prefixed=False, flags=re.IGNORECASE) def listen_for_talk_of_cookies(self, msg, match): """Talk of cookies gives Errbot a craving...""" return "Somebody mentioned cookies? Om nom nom!"