Rubka 5.2.0__py3-none-any.whl → 6.4.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rubka/api.py +410 -20
- rubka/asynco.py +402 -33
- rubka/button.py +32 -1
- rubka/context.py +4 -0
- rubka/update.py +489 -0
- {rubka-5.2.0.dist-info → rubka-6.4.4.dist-info}/METADATA +1 -1
- {rubka-5.2.0.dist-info → rubka-6.4.4.dist-info}/RECORD +9 -8
- {rubka-5.2.0.dist-info → rubka-6.4.4.dist-info}/WHEEL +0 -0
- {rubka-5.2.0.dist-info → rubka-6.4.4.dist-info}/top_level.txt +0 -0
rubka/api.py
CHANGED
|
@@ -169,7 +169,326 @@ class Robot:
|
|
|
169
169
|
"""b"""
|
|
170
170
|
if self.get_me()['status'] != "OK":
|
|
171
171
|
raise InvalidTokenError("The provided bot token is invalid or expired.")
|
|
172
|
-
|
|
172
|
+
def on_message_private(
|
|
173
|
+
self,
|
|
174
|
+
chat_id: Optional[Union[str, List[str]]] = None,
|
|
175
|
+
commands: Optional[List[str]] = None,
|
|
176
|
+
filters: Optional[Callable[[Message], bool]] = None,
|
|
177
|
+
sender_id: Optional[Union[str, List[str]]] = None,
|
|
178
|
+
sender_type: Optional[str] = None,
|
|
179
|
+
allow_forwarded: bool = True,
|
|
180
|
+
allow_files: bool = True,
|
|
181
|
+
allow_stickers: bool = True,
|
|
182
|
+
allow_polls: bool = True,
|
|
183
|
+
allow_contacts: bool = True,
|
|
184
|
+
allow_locations: bool = True,
|
|
185
|
+
min_text_length: Optional[int] = None,
|
|
186
|
+
max_text_length: Optional[int] = None,
|
|
187
|
+
contains: Optional[str] = None,
|
|
188
|
+
startswith: Optional[str] = None,
|
|
189
|
+
endswith: Optional[str] = None,
|
|
190
|
+
case_sensitive: bool = False
|
|
191
|
+
):
|
|
192
|
+
"""
|
|
193
|
+
Sync decorator for handling only private messages with extended filters.
|
|
194
|
+
"""
|
|
195
|
+
|
|
196
|
+
def decorator(func: Callable[[Any, Message], None]):
|
|
197
|
+
def wrapper(bot, message: Message):
|
|
198
|
+
|
|
199
|
+
if not message.is_private:
|
|
200
|
+
return
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
if chat_id:
|
|
204
|
+
if isinstance(chat_id, str) and message.chat_id != chat_id:
|
|
205
|
+
return
|
|
206
|
+
if isinstance(chat_id, list) and message.chat_id not in chat_id:
|
|
207
|
+
return
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
if sender_id:
|
|
211
|
+
if isinstance(sender_id, str) and message.sender_id != sender_id:
|
|
212
|
+
return
|
|
213
|
+
if isinstance(sender_id, list) and message.sender_id not in sender_id:
|
|
214
|
+
return
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
if sender_type and message.sender_type != sender_type:
|
|
218
|
+
return
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
if not allow_forwarded and message.forwarded_from:
|
|
222
|
+
return
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
if not allow_files and message.file:
|
|
226
|
+
return
|
|
227
|
+
if not allow_stickers and message.sticker:
|
|
228
|
+
return
|
|
229
|
+
if not allow_polls and message.poll:
|
|
230
|
+
return
|
|
231
|
+
if not allow_contacts and message.contact_message:
|
|
232
|
+
return
|
|
233
|
+
if not allow_locations and (message.location or message.live_location):
|
|
234
|
+
return
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
if message.text:
|
|
238
|
+
text = message.text if case_sensitive else message.text.lower()
|
|
239
|
+
if min_text_length and len(message.text) < min_text_length:
|
|
240
|
+
return
|
|
241
|
+
if max_text_length and len(message.text) > max_text_length:
|
|
242
|
+
return
|
|
243
|
+
if contains and (contains if case_sensitive else contains.lower()) not in text:
|
|
244
|
+
return
|
|
245
|
+
if startswith and not text.startswith(startswith if case_sensitive else startswith.lower()):
|
|
246
|
+
return
|
|
247
|
+
if endswith and not text.endswith(endswith if case_sensitive else endswith.lower()):
|
|
248
|
+
return
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
if commands:
|
|
252
|
+
if not message.text:
|
|
253
|
+
return
|
|
254
|
+
parts = message.text.strip().split()
|
|
255
|
+
cmd = parts[0].lstrip("/")
|
|
256
|
+
if cmd not in commands:
|
|
257
|
+
return
|
|
258
|
+
message.args = parts[1:]
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
if filters and not filters(message):
|
|
262
|
+
return
|
|
263
|
+
|
|
264
|
+
return func(bot, message)
|
|
265
|
+
|
|
266
|
+
self._message_handlers.append({
|
|
267
|
+
"func": wrapper,
|
|
268
|
+
"filters": filters,
|
|
269
|
+
"commands": commands,
|
|
270
|
+
"chat_id": chat_id,
|
|
271
|
+
"private_only": True,
|
|
272
|
+
"sender_id": sender_id,
|
|
273
|
+
"sender_type": sender_type
|
|
274
|
+
})
|
|
275
|
+
return wrapper
|
|
276
|
+
|
|
277
|
+
return decorator
|
|
278
|
+
def on_message_channel(
|
|
279
|
+
self,
|
|
280
|
+
chat_id: Optional[Union[str, List[str]]] = None,
|
|
281
|
+
commands: Optional[List[str]] = None,
|
|
282
|
+
filters: Optional[Callable[[Message], bool]] = None,
|
|
283
|
+
sender_id: Optional[Union[str, List[str]]] = None,
|
|
284
|
+
sender_type: Optional[str] = None,
|
|
285
|
+
allow_forwarded: bool = True,
|
|
286
|
+
allow_files: bool = True,
|
|
287
|
+
allow_stickers: bool = True,
|
|
288
|
+
allow_polls: bool = True,
|
|
289
|
+
allow_contacts: bool = True,
|
|
290
|
+
allow_locations: bool = True,
|
|
291
|
+
min_text_length: Optional[int] = None,
|
|
292
|
+
max_text_length: Optional[int] = None,
|
|
293
|
+
contains: Optional[str] = None,
|
|
294
|
+
startswith: Optional[str] = None,
|
|
295
|
+
endswith: Optional[str] = None,
|
|
296
|
+
case_sensitive: bool = False
|
|
297
|
+
):
|
|
298
|
+
"""
|
|
299
|
+
Sync decorator for handling only private messages with extended filters.
|
|
300
|
+
"""
|
|
301
|
+
|
|
302
|
+
def decorator(func: Callable[[Any, Message], None]):
|
|
303
|
+
def wrapper(bot, message: Message):
|
|
304
|
+
|
|
305
|
+
if not message.is_channel:
|
|
306
|
+
return
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
if chat_id:
|
|
310
|
+
if isinstance(chat_id, str) and message.chat_id != chat_id:
|
|
311
|
+
return
|
|
312
|
+
if isinstance(chat_id, list) and message.chat_id not in chat_id:
|
|
313
|
+
return
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
if sender_id:
|
|
317
|
+
if isinstance(sender_id, str) and message.sender_id != sender_id:
|
|
318
|
+
return
|
|
319
|
+
if isinstance(sender_id, list) and message.sender_id not in sender_id:
|
|
320
|
+
return
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
if sender_type and message.sender_type != sender_type:
|
|
324
|
+
return
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
if not allow_forwarded and message.forwarded_from:
|
|
328
|
+
return
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
if not allow_files and message.file:
|
|
332
|
+
return
|
|
333
|
+
if not allow_stickers and message.sticker:
|
|
334
|
+
return
|
|
335
|
+
if not allow_polls and message.poll:
|
|
336
|
+
return
|
|
337
|
+
if not allow_contacts and message.contact_message:
|
|
338
|
+
return
|
|
339
|
+
if not allow_locations and (message.location or message.live_location):
|
|
340
|
+
return
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
if message.text:
|
|
344
|
+
text = message.text if case_sensitive else message.text.lower()
|
|
345
|
+
if min_text_length and len(message.text) < min_text_length:
|
|
346
|
+
return
|
|
347
|
+
if max_text_length and len(message.text) > max_text_length:
|
|
348
|
+
return
|
|
349
|
+
if contains and (contains if case_sensitive else contains.lower()) not in text:
|
|
350
|
+
return
|
|
351
|
+
if startswith and not text.startswith(startswith if case_sensitive else startswith.lower()):
|
|
352
|
+
return
|
|
353
|
+
if endswith and not text.endswith(endswith if case_sensitive else endswith.lower()):
|
|
354
|
+
return
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
if commands:
|
|
358
|
+
if not message.text:
|
|
359
|
+
return
|
|
360
|
+
parts = message.text.strip().split()
|
|
361
|
+
cmd = parts[0].lstrip("/")
|
|
362
|
+
if cmd not in commands:
|
|
363
|
+
return
|
|
364
|
+
message.args = parts[1:]
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
if filters and not filters(message):
|
|
368
|
+
return
|
|
369
|
+
|
|
370
|
+
return func(bot, message)
|
|
371
|
+
|
|
372
|
+
self._message_handlers.append({
|
|
373
|
+
"func": wrapper,
|
|
374
|
+
"filters": filters,
|
|
375
|
+
"commands": commands,
|
|
376
|
+
"chat_id": chat_id,
|
|
377
|
+
"private_only": True,
|
|
378
|
+
"sender_id": sender_id,
|
|
379
|
+
"sender_type": sender_type
|
|
380
|
+
})
|
|
381
|
+
return wrapper
|
|
382
|
+
|
|
383
|
+
return decorator
|
|
384
|
+
|
|
385
|
+
def on_message_group(
|
|
386
|
+
self,
|
|
387
|
+
chat_id: Optional[Union[str, List[str]]] = None,
|
|
388
|
+
commands: Optional[List[str]] = None,
|
|
389
|
+
filters: Optional[Callable[[Message], bool]] = None,
|
|
390
|
+
sender_id: Optional[Union[str, List[str]]] = None,
|
|
391
|
+
sender_type: Optional[str] = None,
|
|
392
|
+
allow_forwarded: bool = True,
|
|
393
|
+
allow_files: bool = True,
|
|
394
|
+
allow_stickers: bool = True,
|
|
395
|
+
allow_polls: bool = True,
|
|
396
|
+
allow_contacts: bool = True,
|
|
397
|
+
allow_locations: bool = True,
|
|
398
|
+
min_text_length: Optional[int] = None,
|
|
399
|
+
max_text_length: Optional[int] = None,
|
|
400
|
+
contains: Optional[str] = None,
|
|
401
|
+
startswith: Optional[str] = None,
|
|
402
|
+
endswith: Optional[str] = None,
|
|
403
|
+
case_sensitive: bool = False
|
|
404
|
+
):
|
|
405
|
+
"""
|
|
406
|
+
Sync decorator for handling only group messages with extended filters.
|
|
407
|
+
"""
|
|
408
|
+
|
|
409
|
+
def decorator(func: Callable[[Any, Message], None]):
|
|
410
|
+
def wrapper(bot, message: Message):
|
|
411
|
+
|
|
412
|
+
if not message.is_group:
|
|
413
|
+
return
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
if chat_id:
|
|
417
|
+
if isinstance(chat_id, str) and message.chat_id != chat_id:
|
|
418
|
+
return
|
|
419
|
+
if isinstance(chat_id, list) and message.chat_id not in chat_id:
|
|
420
|
+
return
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
if sender_id:
|
|
424
|
+
if isinstance(sender_id, str) and message.sender_id != sender_id:
|
|
425
|
+
return
|
|
426
|
+
if isinstance(sender_id, list) and message.sender_id not in sender_id:
|
|
427
|
+
return
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
if sender_type and message.sender_type != sender_type:
|
|
431
|
+
return
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
if not allow_forwarded and message.forwarded_from:
|
|
435
|
+
return
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
if not allow_files and message.file:
|
|
439
|
+
return
|
|
440
|
+
if not allow_stickers and message.sticker:
|
|
441
|
+
return
|
|
442
|
+
if not allow_polls and message.poll:
|
|
443
|
+
return
|
|
444
|
+
if not allow_contacts and message.contact_message:
|
|
445
|
+
return
|
|
446
|
+
if not allow_locations and (message.location or message.live_location):
|
|
447
|
+
return
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
if message.text:
|
|
451
|
+
text = message.text if case_sensitive else message.text.lower()
|
|
452
|
+
if min_text_length and len(message.text) < min_text_length:
|
|
453
|
+
return
|
|
454
|
+
if max_text_length and len(message.text) > max_text_length:
|
|
455
|
+
return
|
|
456
|
+
if contains and (contains if case_sensitive else contains.lower()) not in text:
|
|
457
|
+
return
|
|
458
|
+
if startswith and not text.startswith(startswith if case_sensitive else startswith.lower()):
|
|
459
|
+
return
|
|
460
|
+
if endswith and not text.endswith(endswith if case_sensitive else endswith.lower()):
|
|
461
|
+
return
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
if commands:
|
|
465
|
+
if not message.text:
|
|
466
|
+
return
|
|
467
|
+
parts = message.text.strip().split()
|
|
468
|
+
cmd = parts[0].lstrip("/")
|
|
469
|
+
if cmd not in commands:
|
|
470
|
+
return
|
|
471
|
+
message.args = parts[1:]
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
if filters and not filters(message):
|
|
475
|
+
return
|
|
476
|
+
|
|
477
|
+
return func(bot, message)
|
|
478
|
+
|
|
479
|
+
self._message_handlers.append({
|
|
480
|
+
"func": wrapper,
|
|
481
|
+
"filters": filters,
|
|
482
|
+
"commands": commands,
|
|
483
|
+
"chat_id": chat_id,
|
|
484
|
+
"group_only": True,
|
|
485
|
+
"sender_id": sender_id,
|
|
486
|
+
"sender_type": sender_type
|
|
487
|
+
})
|
|
488
|
+
return wrapper
|
|
489
|
+
|
|
490
|
+
return decorator
|
|
491
|
+
|
|
173
492
|
def on_message(self, filters: Optional[Callable[[Message], bool]] = None, commands: Optional[List[str]] = None):
|
|
174
493
|
def decorator(func: Callable[[Any, Message], None]):
|
|
175
494
|
self._message_handlers.append({
|
|
@@ -302,7 +621,7 @@ class Robot:
|
|
|
302
621
|
continue
|
|
303
622
|
|
|
304
623
|
threading.Thread(target=handler["func"], args=(self, context), daemon=True).start()
|
|
305
|
-
|
|
624
|
+
continue
|
|
306
625
|
|
|
307
626
|
def get_updates(
|
|
308
627
|
self,
|
|
@@ -762,39 +1081,110 @@ class Robot:
|
|
|
762
1081
|
data = response.json()
|
|
763
1082
|
return data.get('data', {}).get('file_id')
|
|
764
1083
|
|
|
765
|
-
def send_button_join(
|
|
1084
|
+
def send_button_join(
|
|
1085
|
+
self,
|
|
1086
|
+
chat_id,
|
|
1087
|
+
title_button : Union[str, list],
|
|
1088
|
+
username : Union[str, list],
|
|
1089
|
+
text,
|
|
1090
|
+
reply_to_message_id=None,
|
|
1091
|
+
id="None"
|
|
1092
|
+
):
|
|
766
1093
|
from .button import InlineBuilder
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
1094
|
+
builder = InlineBuilder()
|
|
1095
|
+
|
|
1096
|
+
|
|
1097
|
+
if isinstance(username, (list, tuple)) and isinstance(title_button, (list, tuple)):
|
|
1098
|
+
for t, u in zip(title_button, username):
|
|
1099
|
+
builder = builder.row(
|
|
1100
|
+
InlineBuilder().button_join_channel(
|
|
1101
|
+
text=t,
|
|
1102
|
+
id=id,
|
|
1103
|
+
username=u
|
|
1104
|
+
)
|
|
1105
|
+
)
|
|
1106
|
+
|
|
1107
|
+
|
|
1108
|
+
elif isinstance(username, (list, tuple)) and isinstance(title_button, str):
|
|
1109
|
+
for u in username:
|
|
1110
|
+
builder = builder.row(
|
|
1111
|
+
InlineBuilder().button_join_channel(
|
|
1112
|
+
text=title_button,
|
|
1113
|
+
id=id,
|
|
1114
|
+
username=u
|
|
1115
|
+
)
|
|
1116
|
+
)
|
|
1117
|
+
|
|
1118
|
+
|
|
1119
|
+
else:
|
|
1120
|
+
builder = builder.row(
|
|
1121
|
+
InlineBuilder().button_join_channel(
|
|
774
1122
|
text=title_button,
|
|
775
1123
|
id=id,
|
|
776
1124
|
username=username
|
|
777
1125
|
)
|
|
778
|
-
)
|
|
779
|
-
|
|
780
|
-
)
|
|
781
|
-
def send_button_url(self, chat_id, title_button, url, text, reply_to_message_id=None, id="None"):
|
|
782
|
-
from .button import InlineBuilder
|
|
1126
|
+
)
|
|
1127
|
+
|
|
783
1128
|
return self.send_message(
|
|
784
1129
|
chat_id=chat_id,
|
|
785
1130
|
text=text,
|
|
786
|
-
inline_keypad=
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
1131
|
+
inline_keypad=builder.build(),
|
|
1132
|
+
reply_to_message_id=reply_to_message_id
|
|
1133
|
+
)
|
|
1134
|
+
|
|
1135
|
+
|
|
1136
|
+
def send_button_url(
|
|
1137
|
+
self,
|
|
1138
|
+
chat_id,
|
|
1139
|
+
title_button : Union[str, list],
|
|
1140
|
+
url : Union[str, list],
|
|
1141
|
+
text,
|
|
1142
|
+
reply_to_message_id=None,
|
|
1143
|
+
id="None"
|
|
1144
|
+
):
|
|
1145
|
+
from .button import InlineBuilder
|
|
1146
|
+
builder = InlineBuilder()
|
|
1147
|
+
|
|
1148
|
+
|
|
1149
|
+
if isinstance(url, (list, tuple)) and isinstance(title_button, (list, tuple)):
|
|
1150
|
+
for t, u in zip(title_button, url):
|
|
1151
|
+
builder = builder.row(
|
|
1152
|
+
InlineBuilder().button_url_link(
|
|
1153
|
+
text=t,
|
|
1154
|
+
id=id,
|
|
1155
|
+
url=u
|
|
1156
|
+
)
|
|
1157
|
+
)
|
|
1158
|
+
|
|
1159
|
+
|
|
1160
|
+
elif isinstance(url, (list, tuple)) and isinstance(title_button, str):
|
|
1161
|
+
for u in url:
|
|
1162
|
+
builder = builder.row(
|
|
1163
|
+
InlineBuilder().button_url_link(
|
|
1164
|
+
text=title_button,
|
|
1165
|
+
id=id,
|
|
1166
|
+
url=u
|
|
1167
|
+
)
|
|
1168
|
+
)
|
|
1169
|
+
|
|
1170
|
+
|
|
1171
|
+
else:
|
|
1172
|
+
builder = builder.row(
|
|
1173
|
+
InlineBuilder().button_url_link(
|
|
790
1174
|
text=title_button,
|
|
791
1175
|
id=id,
|
|
792
1176
|
url=url
|
|
793
1177
|
)
|
|
794
|
-
)
|
|
1178
|
+
)
|
|
1179
|
+
|
|
1180
|
+
return self.send_message(
|
|
1181
|
+
chat_id=chat_id,
|
|
1182
|
+
text=text,
|
|
1183
|
+
inline_keypad=builder.build(),
|
|
795
1184
|
reply_to_message_id=reply_to_message_id
|
|
796
1185
|
)
|
|
797
1186
|
|
|
1187
|
+
|
|
798
1188
|
def get_upload_url(self, media_type: Literal['File', 'Image', 'Voice', 'Music', 'Gif','Video']) -> str:
|
|
799
1189
|
allowed = ['File', 'Image', 'Voice', 'Music', 'Gif','Video']
|
|
800
1190
|
if media_type not in allowed:
|