16
16
#
17
17
# You should have received a copy of the GNU Lesser Public License
18
18
# along with this program. If not, see [http://www.gnu.org/licenses/].
19
- """This module contains the CommandHandler and PrefixHandler classes."""
20
- import re
21
-
19
+ """This module contains the CommandHandler class."""
22
20
from future .utils import string_types
23
21
24
- from telegram import Update , MessageEntity
22
+ from telegram import Update
25
23
from .handler import Handler
26
24
27
25
28
26
class CommandHandler (Handler ):
29
27
"""Handler class to handle Telegram commands.
30
28
31
29
Commands are Telegram messages that start with ``/``, optionally followed by an ``@`` and the
32
- bot's name and/or some additional text. The handler will add a ``list`` to the
33
- :class:`CallbackContext` named :attr:`CallbackContext.args`. It will contain a list of strings,
34
- which is the text following the command split on single or consecutive whitespace characters.
30
+ bot's name and/or some additional text.
35
31
36
32
Attributes:
37
33
command (:obj:`str` | List[:obj:`str`]): The command or list of commands this handler
38
- should listen for. Limitations are the same as described here
39
- https://core.telegram.org/bots#commands
34
+ should listen for.
40
35
callback (:obj:`callable`): The callback function for this handler.
41
36
filters (:class:`telegram.ext.BaseFilter`): Optional. Only allow updates with these
42
37
Filters.
@@ -55,7 +50,7 @@ class CommandHandler(Handler):
55
50
56
51
Note:
57
52
:attr:`pass_user_data` and :attr:`pass_chat_data` determine whether a ``dict`` you
58
- can use to keep any data in will be sent to the :attr:`callback` function. Related to
53
+ can use to keep any data in will be sent to the :attr:`callback` function.. Related to
59
54
either the user or the chat that the update was sent in. For each update from the same user
60
55
or in the same chat, it will be the same ``dict``.
61
56
@@ -64,8 +59,7 @@ class CommandHandler(Handler):
64
59
65
60
Args:
66
61
command (:obj:`str` | List[:obj:`str`]): The command or list of commands this handler
67
- should listen for. Limitations are the same as described here
68
- https://core.telegram.org/bots#commands
62
+ should listen for.
69
63
callback (:obj:`callable`): The callback function for this handler. Will be called when
70
64
:attr:`check_update` has determined that an update should be processed by this handler.
71
65
Callback signature for context based API:
@@ -102,8 +96,6 @@ class CommandHandler(Handler):
102
96
``chat_data`` will be passed to the callback function. Default is ``False``.
103
97
DEPRECATED: Please switch to context based callbacks.
104
98
105
- Raises:
106
- ValueError - when command is too long or has illegal chars.
107
99
"""
108
100
109
101
def __init__ (self ,
@@ -127,10 +119,6 @@ def __init__(self,
127
119
self .command = [command .lower ()]
128
120
else :
129
121
self .command = [x .lower () for x in command ]
130
- for comm in self .command :
131
- if not re .match (r'^[\da-z_]{1,32}$' , comm ):
132
- raise ValueError ('Command is not a valid bot command' )
133
-
134
122
self .filters = filters
135
123
self .allow_edited = allow_edited
136
124
self .pass_args = pass_args
@@ -147,21 +135,21 @@ def check_update(self, update):
147
135
"""
148
136
if (isinstance (update , Update ) and
149
137
(update .message or update .edited_message and self .allow_edited )):
150
- message = update .effective_message
138
+ message = update .message or update . edited_message
151
139
152
- if ( message .entities and message .entities [ 0 ]. type == MessageEntity . BOT_COMMAND and
153
- message .entities [ 0 ]. offset == 0 ):
154
- command = message . text [ 1 : message . entities [ 0 ]. length ]
155
- args = message . text . split () [1 :]
156
- command = command .split ( '@' )
157
- command . append ( message .bot .username )
140
+ if message .text and message .text . startswith ( '/' ) and len ( message . text ) > 1 :
141
+ first_word = message .text_html . split ( None , 1 )[ 0 ]
142
+ if len ( first_word ) > 1 and first_word . startswith ( '/' ):
143
+ command = first_word [1 :]. split ( '@' )
144
+ command .append (
145
+ message .bot .username ) # in case the command was sent without a username
158
146
159
- if not (command [0 ].lower () in self .command and
160
- command [1 ].lower () == message .bot .username .lower ()):
161
- return None
147
+ if not (command [0 ].lower () in self .command
148
+ and command [1 ].lower () == message .bot .username .lower ()):
149
+ return None
162
150
163
- if self .filters is None or self .filters (message ):
164
- return args
151
+ if self .filters is None or self .filters (message ):
152
+ return message . text . split ()[ 1 :]
165
153
166
154
def collect_optional_args (self , dispatcher , update = None , check_result = None ):
167
155
optional_args = super (CommandHandler , self ).collect_optional_args (dispatcher , update )
@@ -171,149 +159,3 @@ def collect_optional_args(self, dispatcher, update=None, check_result=None):
171
159
172
160
def collect_additional_context (self , context , update , dispatcher , check_result ):
173
161
context .args = check_result
174
-
175
-
176
- class PrefixHandler (CommandHandler ):
177
- """Handler class to handle custom prefix commands
178
-
179
- This is a intermediate handler between :class:`MessageHandler` and :class:`CommandHandler`.
180
- It supports configurable commands with the same options as CommandHandler. It will respond to
181
- every combination of :attr:`prefix` and :attr:`command`. It will add a ``list`` to the
182
- :class:`CallbackContext` named :attr:`CallbackContext.args`. It will contain a list of strings,
183
- which is the text following the command split on single or consecutive whitespace characters.
184
-
185
- Examples::
186
-
187
- Single prefix and command:
188
-
189
- PrefixHandler('!', 'test', callback) will respond to '!test'.
190
-
191
- Multiple prefixes, single command:
192
-
193
- PrefixHandler(['!', '#'], 'test', callback) will respond to '!test' and
194
- '#test'.
195
-
196
- Miltiple prefixes and commands:
197
-
198
- PrefixHandler(['!', '#'], ['test', 'help`], callback) will respond to '!test',
199
- '#test', '!help' and '#help'.
200
-
201
- Attributes:
202
- prefix (:obj:`str` | List[:obj:`str`]): The prefix(es) that will precede :attr:`command`.
203
- command (:obj:`str` | List[:obj:`str`]): The command or list of commands this handler
204
- should listen for.
205
- callback (:obj:`callable`): The callback function for this handler.
206
- filters (:class:`telegram.ext.BaseFilter`): Optional. Only allow updates with these
207
- Filters.
208
- allow_edited (:obj:`bool`): Determines Whether the handler should also accept
209
- edited messages.
210
- pass_args (:obj:`bool`): Determines whether the handler should be passed
211
- ``args``.
212
- pass_update_queue (:obj:`bool`): Determines whether ``update_queue`` will be
213
- passed to the callback function.
214
- pass_job_queue (:obj:`bool`): Determines whether ``job_queue`` will be passed to
215
- the callback function.
216
- pass_user_data (:obj:`bool`): Determines whether ``user_data`` will be passed to
217
- the callback function.
218
- pass_chat_data (:obj:`bool`): Determines whether ``chat_data`` will be passed to
219
- the callback function.
220
-
221
- Note:
222
- :attr:`pass_user_data` and :attr:`pass_chat_data` determine whether a ``dict`` you
223
- can use to keep any data in will be sent to the :attr:`callback` function. Related to
224
- either the user or the chat that the update was sent in. For each update from the same user
225
- or in the same chat, it will be the same ``dict``.
226
-
227
- Note that this is DEPRECATED, and you should use context based callbacks. See
228
- https://git.io/vp113 for more info.
229
-
230
- Args:
231
- prefix (:obj:`str` | List[:obj:`str`]): The prefix(es) that will precede :attr:`command`.
232
- command (:obj:`str` | List[:obj:`str`]): The command or list of commands this handler
233
- should listen for.
234
- callback (:obj:`callable`): The callback function for this handler. Will be called when
235
- :attr:`check_update` has determined that an update should be processed by this handler.
236
- Callback signature for context based API:
237
-
238
- ``def callback(update: Update, context: CallbackContext)``
239
-
240
- The return value of the callback is usually ignored except for the special case of
241
- :class:`telegram.ext.ConversationHandler`.
242
- filters (:class:`telegram.ext.BaseFilter`, optional): A filter inheriting from
243
- :class:`telegram.ext.filters.BaseFilter`. Standard filters can be found in
244
- :class:`telegram.ext.filters.Filters`. Filters can be combined using bitwise
245
- operators (& for and, | for or, ~ for not).
246
- allow_edited (:obj:`bool`, optional): Determines whether the handler should also accept
247
- edited messages. Default is ``False``.
248
- pass_args (:obj:`bool`, optional): Determines whether the handler should be passed the
249
- arguments passed to the command as a keyword argument called ``args``. It will contain
250
- a list of strings, which is the text following the command split on single or
251
- consecutive whitespace characters. Default is ``False``
252
- DEPRECATED: Please switch to context based callbacks.
253
- pass_update_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
254
- ``update_queue`` will be passed to the callback function. It will be the ``Queue``
255
- instance used by the :class:`telegram.ext.Updater` and :class:`telegram.ext.Dispatcher`
256
- that contains new updates which can be used to insert updates. Default is ``False``.
257
- DEPRECATED: Please switch to context based callbacks.
258
- pass_job_queue (:obj:`bool`, optional): If set to ``True``, a keyword argument called
259
- ``job_queue`` will be passed to the callback function. It will be a
260
- :class:`telegram.ext.JobQueue` instance created by the :class:`telegram.ext.Updater`
261
- which can be used to schedule new jobs. Default is ``False``.
262
- DEPRECATED: Please switch to context based callbacks.
263
- pass_user_data (:obj:`bool`, optional): If set to ``True``, a keyword argument called
264
- ``user_data`` will be passed to the callback function. Default is ``False``.
265
- DEPRECATED: Please switch to context based callbacks.
266
- pass_chat_data (:obj:`bool`, optional): If set to ``True``, a keyword argument called
267
- ``chat_data`` will be passed to the callback function. Default is ``False``.
268
- DEPRECATED: Please switch to context based callbacks.
269
-
270
- """
271
-
272
- def __init__ (self ,
273
- prefix ,
274
- command ,
275
- callback ,
276
- filters = None ,
277
- allow_edited = False ,
278
- pass_args = False ,
279
- pass_update_queue = False ,
280
- pass_job_queue = False ,
281
- pass_user_data = False ,
282
- pass_chat_data = False ):
283
-
284
- super (PrefixHandler , self ).__init__ (
285
- 'nocommand' , callback , filters = filters , allow_edited = allow_edited , pass_args = pass_args ,
286
- pass_update_queue = pass_update_queue ,
287
- pass_job_queue = pass_job_queue ,
288
- pass_user_data = pass_user_data ,
289
- pass_chat_data = pass_chat_data )
290
-
291
- if isinstance (prefix , string_types ):
292
- self .prefix = [prefix .lower ()]
293
- else :
294
- self .prefix = prefix
295
- if isinstance (command , string_types ):
296
- self .command = [command .lower ()]
297
- else :
298
- self .command = command
299
- self .command = [x .lower () + y .lower () for x in self .prefix for y in self .command ]
300
-
301
- def check_update (self , update ):
302
- """Determines whether an update should be passed to this handlers :attr:`callback`.
303
-
304
- Args:
305
- update (:class:`telegram.Update`): Incoming telegram update.
306
-
307
- Returns:
308
- :obj:`bool`
309
-
310
- """
311
- if (isinstance (update , Update ) and
312
- (update .message or update .edited_message and self .allow_edited )):
313
- message = update .effective_message
314
-
315
- text_list = message .text .split ()
316
- if text_list [0 ].lower () not in self .command :
317
- return None
318
- if self .filters is None or self .filters (message ):
319
- return text_list [1 :]
0 commit comments