File: botcommands.rst

package info (click to toggle)
errbot 6.2.0%2Bds-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,796 kB
  • sloc: python: 11,557; makefile: 164; sh: 97
file content (151 lines) | stat: -rw-r--r-- 5,313 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
Advanced bot commands
=====================


Automatic argument splitting
----------------------------

With the `split_args_with` argument to :func:`~errbot.decorators.botcmd`,
you can specify a delimiter of the arguments and it will give you an
array of strings instead of a string:

.. code-block:: python

    @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 :func:`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.


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.

.. code-block:: python

    @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.


Argparse argument splitting
----------------------------

With the :func:`~errbot.decorators.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.

.. _`argparse format`: https://docs.python.org/3/library/argparse.html
.. _`add_arguments()`: https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser.add_argument

.. code-block:: python

    @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 :func:`~errbot.decorators.arg_botcmd` call.



Commands using regular expressions
----------------------------------

In addition to the fixed commands created with the :func:`~errbot.decorators.botcmd`
decorator, Errbot supports an alternative type of bot function which can be triggered
based on a regular expression. These are created using the
:func:`~errbot.decorators.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
:func:`~errbot.decorators.botcmd`, but instead of an `args` parameter, it takes
a `match` parameter which will receive an :class:`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 :class:`re.MatchObject` items, containing all the
    non-overlapping matches that were found in the message.


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:

.. code-block:: python

    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."


Without a bot prefix
~~~~~~~~~~~~~~~~~~~~

It's also possible to trigger commands even when no bot prefix is specified,
by passing `prefixed=False` to the :func:`~errbot.decorators.re_botcmd`
decorator. This is especially useful if you want to trigger on specific
keywords that could show up anywhere in a conversation:

.. code-block:: python

    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!"