· 4 years ago · Sep 11, 2021, 03:40 PM
1# -*- coding: utf-8 -*-
2from datetime import datetime
3
4import logging
5import re
6import sys
7import threading
8import time
9import traceback
10from typing import Any, Callable, List, Optional, Union
11
12# this imports are used to avoid circular import error
13import telebot.util
14import telebot.types
15
16
17
18logger = logging.getLogger('TeleBot')
19formatter = logging.Formatter(
20 '%(asctime)s (%(filename)s:%(lineno)d %(threadName)s) %(levelname)s - %(name)s: "%(message)s"'
21)
22
23console_output_handler = logging.StreamHandler(sys.stderr)
24console_output_handler.setFormatter(formatter)
25logger.addHandler(console_output_handler)
26
27logger.setLevel(logging.ERROR)
28
29from telebot import apihelper, util, types
30from telebot.handler_backends import MemoryHandlerBackend, FileHandlerBackend
31
32
33REPLY_MARKUP_TYPES = Union[
34 types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup,
35 types.ReplyKeyboardRemove, types.ForceReply]
36
37
38"""
39Module : telebot
40"""
41
42
43class Handler:
44 """
45 Class for (next step|reply) handlers
46 """
47
48 def __init__(self, callback, *args, **kwargs):
49 self.callback = callback
50 self.args = args
51 self.kwargs = kwargs
52
53 def __getitem__(self, item):
54 return getattr(self, item)
55
56
57class ExceptionHandler:
58 """
59 Class for handling exceptions while Polling
60 """
61
62 # noinspection PyMethodMayBeStatic,PyUnusedLocal
63 def handle(self, exception):
64 return False
65
66
67class TeleBot:
68 """ This is TeleBot Class
69 Methods:
70 getMe
71 logOut
72 close
73 sendMessage
74 forwardMessage
75 copyMessage
76 deleteMessage
77 sendPhoto
78 sendAudio
79 sendDocument
80 sendSticker
81 sendVideo
82 sendVenue
83 sendAnimation
84 sendVideoNote
85 sendLocation
86 sendChatAction
87 sendDice
88 sendContact
89 sendInvoice
90 sendMediaGroup
91 getUserProfilePhotos
92 getUpdates
93 getFile
94 sendPoll
95 stopPoll
96 sendGame
97 setGameScore
98 getGameHighScores
99 editMessageText
100 editMessageCaption
101 editMessageMedia
102 editMessageReplyMarkup
103 editMessageLiveLocation
104 stopMessageLiveLocation
105 banChatMember
106 unbanChatMember
107 restrictChatMember
108 promoteChatMember
109 setChatAdministratorCustomTitle
110 setChatPermissions
111 createChatInviteLink
112 editChatInviteLink
113 revokeChatInviteLink
114 exportChatInviteLink
115 setChatStickerSet
116 deleteChatStickerSet
117 createNewStickerSet
118 addStickerToSet
119 deleteStickerFromSet
120 setStickerPositionInSet
121 uploadStickerFile
122 setStickerSetThumb
123 getStickerSet
124 setChatPhoto
125 deleteChatPhoto
126 setChatTitle
127 setChatDescription
128 pinChatMessage
129 unpinChatMessage
130 leaveChat
131 getChat
132 getChatAdministrators
133 getChatMemberCount
134 getChatMember
135 answerCallbackQuery
136 getMyCommands
137 setMyCommands
138 deleteMyCommands
139 answerInlineQuery
140 answerShippingQuery
141 answerPreCheckoutQuery
142 """
143
144 def __init__(
145 self, token, parse_mode=None, threaded=True, skip_pending=False, num_threads=2,
146 next_step_backend=None, reply_backend=None, exception_handler=None, last_update_id=0,
147 suppress_middleware_excepions=False
148 ):
149 """
150 :param token: bot API token
151 :param parse_mode: default parse_mode
152 :return: Telebot object.
153 """
154
155 self.token = token
156 self.parse_mode = parse_mode
157 self.update_listener = []
158 self.skip_pending = skip_pending
159 self.suppress_middleware_excepions = suppress_middleware_excepions
160
161 self.__stop_polling = threading.Event()
162 self.last_update_id = last_update_id
163 self.exc_info = None
164
165 self.next_step_backend = next_step_backend
166 if not self.next_step_backend:
167 self.next_step_backend = MemoryHandlerBackend()
168
169 self.reply_backend = reply_backend
170 if not self.reply_backend:
171 self.reply_backend = MemoryHandlerBackend()
172
173 self.exception_handler = exception_handler
174
175 self.message_handlers = []
176 self.edited_message_handlers = []
177 self.channel_post_handlers = []
178 self.edited_channel_post_handlers = []
179 self.inline_handlers = []
180 self.chosen_inline_handlers = []
181 self.callback_query_handlers = []
182 self.shipping_query_handlers = []
183 self.pre_checkout_query_handlers = []
184 self.poll_handlers = []
185 self.poll_answer_handlers = []
186 self.my_chat_member_handlers = []
187 self.chat_member_handlers = []
188 self.custom_filters = {}
189
190 if apihelper.ENABLE_MIDDLEWARE:
191 self.typed_middleware_handlers = {
192 'message': [],
193 'edited_message': [],
194 'channel_post': [],
195 'edited_channel_post': [],
196 'inline_query': [],
197 'chosen_inline_result': [],
198 'callback_query': [],
199 'shipping_query': [],
200 'pre_checkout_query': [],
201 'poll': [],
202 'poll_answer': [],
203 'my_chat_member': [],
204 'chat_member': []
205 }
206 self.default_middleware_handlers = []
207
208 self.threaded = threaded
209 if self.threaded:
210 self.worker_pool = util.ThreadPool(num_threads=num_threads)
211
212 def enable_save_next_step_handlers(self, delay=120, filename="./.handler-saves/step.save"):
213 """
214 Enable saving next step handlers (by default saving disabled)
215
216 This function explicitly assigns FileHandlerBackend (instead of Saver) just to keep backward
217 compatibility whose purpose was to enable file saving capability for handlers. And the same
218 implementation is now available with FileHandlerBackend
219
220 Most probably this function should be deprecated in future major releases
221
222 :param delay: Delay between changes in handlers and saving
223 :param filename: Filename of save file
224 """
225 self.next_step_backend = FileHandlerBackend(self.next_step_backend.handlers, filename, delay)
226
227 def enable_save_reply_handlers(self, delay=120, filename="./.handler-saves/reply.save"):
228 """
229 Enable saving reply handlers (by default saving disable)
230
231 This function explicitly assigns FileHandlerBackend (instead of Saver) just to keep backward
232 compatibility whose purpose was to enable file saving capability for handlers. And the same
233 implementation is now available with FileHandlerBackend
234
235 Most probably this function should be deprecated in future major releases
236
237 :param delay: Delay between changes in handlers and saving
238 :param filename: Filename of save file
239 """
240 self.reply_backend = FileHandlerBackend(self.reply_backend.handlers, filename, delay)
241
242 def disable_save_next_step_handlers(self):
243 """
244 Disable saving next step handlers (by default saving disable)
245
246 This function is left to keep backward compatibility whose purpose was to disable file saving capability
247 for handlers. For the same purpose, MemoryHandlerBackend is reassigned as a new next_step_backend backend
248 instead of FileHandlerBackend.
249
250 Most probably this function should be deprecated in future major releases
251 """
252 self.next_step_backend = MemoryHandlerBackend(self.next_step_backend.handlers)
253
254 def disable_save_reply_handlers(self):
255 """
256 Disable saving next step handlers (by default saving disable)
257
258 This function is left to keep backward compatibility whose purpose was to disable file saving capability
259 for handlers. For the same purpose, MemoryHandlerBackend is reassigned as a new reply_backend backend
260 instead of FileHandlerBackend.
261
262 Most probably this function should be deprecated in future major releases
263 """
264 self.reply_backend = MemoryHandlerBackend(self.reply_backend.handlers)
265
266 def load_next_step_handlers(self, filename="./.handler-saves/step.save", del_file_after_loading=True):
267 """
268 Load next step handlers from save file
269
270 This function is left to keep backward compatibility whose purpose was to load handlers from file with the
271 help of FileHandlerBackend and is only recommended to use if next_step_backend was assigned as
272 FileHandlerBackend before entering this function
273
274 Most probably this function should be deprecated in future major releases
275
276 :param filename: Filename of the file where handlers was saved
277 :param del_file_after_loading: Is passed True, after loading save file will be deleted
278 """
279 self.next_step_backend.load_handlers(filename, del_file_after_loading)
280
281 def load_reply_handlers(self, filename="./.handler-saves/reply.save", del_file_after_loading=True):
282 """
283 Load reply handlers from save file
284
285 This function is left to keep backward compatibility whose purpose was to load handlers from file with the
286 help of FileHandlerBackend and is only recommended to use if reply_backend was assigned as
287 FileHandlerBackend before entering this function
288
289 Most probably this function should be deprecated in future major releases
290
291 :param filename: Filename of the file where handlers was saved
292 :param del_file_after_loading: Is passed True, after loading save file will be deleted
293 """
294 self.reply_backend.load_handlers(filename, del_file_after_loading)
295
296 def set_webhook(self, url=None, certificate=None, max_connections=None, allowed_updates=None, ip_address=None,
297 drop_pending_updates = None, timeout=None):
298 """
299 Use this method to specify a url and receive incoming updates via an outgoing webhook. Whenever there is an
300 update for the bot, we will send an HTTPS POST request to the specified url,
301 containing a JSON-serialized Update.
302 In case of an unsuccessful request, we will give up after a reasonable amount of attempts.
303 Returns True on success.
304
305 :param url: HTTPS url to send updates to. Use an empty string to remove webhook integration
306 :param certificate: Upload your public key certificate so that the root certificate in use can be checked.
307 See our self-signed guide for details.
308 :param max_connections: Maximum allowed number of simultaneous HTTPS connections to the webhook
309 for update delivery, 1-100. Defaults to 40. Use lower values to limit the load on your bot's server,
310 and higher values to increase your bot's throughput.
311 :param allowed_updates: A JSON-serialized list of the update types you want your bot to receive.
312 For example, specify [“message”, “edited_channel_post”, “callback_query”] to only receive updates
313 of these types. See Update for a complete list of available update types.
314 Specify an empty list to receive all updates regardless of type (default).
315 If not specified, the previous setting will be used.
316 :param ip_address: The fixed IP address which will be used to send webhook requests instead of the IP address
317 resolved through DNS
318 :param drop_pending_updates: Pass True to drop all pending updates
319 :param timeout: Integer. Request connection timeout
320 :return:
321 """
322 return apihelper.set_webhook(self.token, url, certificate, max_connections, allowed_updates, ip_address,
323 drop_pending_updates, timeout)
324
325 def delete_webhook(self, drop_pending_updates=None, timeout=None):
326 """
327 Use this method to remove webhook integration if you decide to switch back to getUpdates.
328
329 :param drop_pending_updates: Pass True to drop all pending updates
330 :param timeout: Integer. Request connection timeout
331 :return: bool
332 """
333 return apihelper.delete_webhook(self.token, drop_pending_updates, timeout)
334
335 def get_webhook_info(self, timeout=None):
336 """
337 Use this method to get current webhook status. Requires no parameters.
338 If the bot is using getUpdates, will return an object with the url field empty.
339
340 :param timeout: Integer. Request connection timeout
341 :return: On success, returns a WebhookInfo object.
342 """
343 result = apihelper.get_webhook_info(self.token, timeout)
344 return types.WebhookInfo.de_json(result)
345
346 def remove_webhook(self):
347 return self.set_webhook() # No params resets webhook
348
349 def get_updates(self, offset: Optional[int]=None, limit: Optional[int]=None,
350 timeout: Optional[int]=20, allowed_updates: Optional[List[str]]=None,
351 long_polling_timeout: int=20) -> List[types.Update]:
352 """
353 Use this method to receive incoming updates using long polling (wiki). An Array of Update objects is returned.
354 :param allowed_updates: Array of string. List the types of updates you want your bot to receive.
355 :param offset: Integer. Identifier of the first update to be returned.
356 :param limit: Integer. Limits the number of updates to be retrieved.
357 :param timeout: Integer. Request connection timeout
358 :param long_polling_timeout. Timeout in seconds for long polling.
359 :return: array of Updates
360 """
361 json_updates = apihelper.get_updates(self.token, offset, limit, timeout, allowed_updates, long_polling_timeout)
362 return [types.Update.de_json(ju) for ju in json_updates]
363
364 def __skip_updates(self):
365 """
366 Get and discard all pending updates before first poll of the bot
367 :return:
368 """
369 self.get_updates(offset=-1)
370
371 def __retrieve_updates(self, timeout=20, long_polling_timeout=20, allowed_updates=None):
372 """
373 Retrieves any updates from the Telegram API.
374 Registered listeners and applicable message handlers will be notified when a new message arrives.
375 :raises ApiException when a call has failed.
376 """
377 if self.skip_pending:
378 self.__skip_updates()
379 logger.debug('Skipped all pending messages')
380 self.skip_pending = False
381 updates = self.get_updates(offset=(self.last_update_id + 1),
382 allowed_updates=allowed_updates,
383 timeout=timeout, long_polling_timeout=long_polling_timeout)
384 self.process_new_updates(updates)
385
386 def process_new_updates(self, updates):
387 upd_count = len(updates)
388 logger.debug('Received {0} new updates'.format(upd_count))
389 if upd_count == 0: return
390
391 new_messages = None
392 new_edited_messages = None
393 new_channel_posts = None
394 new_edited_channel_posts = None
395 new_inline_queries = None
396 new_chosen_inline_results = None
397 new_callback_queries = None
398 new_shipping_queries = None
399 new_pre_checkout_queries = None
400 new_polls = None
401 new_poll_answers = None
402 new_my_chat_members = None
403 new_chat_members = None
404
405 for update in updates:
406 if apihelper.ENABLE_MIDDLEWARE:
407 try:
408 self.process_middlewares(update)
409 except Exception as e:
410 logger.error(str(e))
411 if not self.suppress_middleware_excepions:
412 raise
413 else:
414 if update.update_id > self.last_update_id: self.last_update_id = update.update_id
415 continue
416
417 if update.update_id > self.last_update_id:
418 self.last_update_id = update.update_id
419 if update.message:
420 if new_messages is None: new_messages = []
421 new_messages.append(update.message)
422 if update.edited_message:
423 if new_edited_messages is None: new_edited_messages = []
424 new_edited_messages.append(update.edited_message)
425 if update.channel_post:
426 if new_channel_posts is None: new_channel_posts = []
427 new_channel_posts.append(update.channel_post)
428 if update.edited_channel_post:
429 if new_edited_channel_posts is None: new_edited_channel_posts = []
430 new_edited_channel_posts.append(update.edited_channel_post)
431 if update.inline_query:
432 if new_inline_queries is None: new_inline_queries = []
433 new_inline_queries.append(update.inline_query)
434 if update.chosen_inline_result:
435 if new_chosen_inline_results is None: new_chosen_inline_results = []
436 new_chosen_inline_results.append(update.chosen_inline_result)
437 if update.callback_query:
438 if new_callback_queries is None: new_callback_queries = []
439 new_callback_queries.append(update.callback_query)
440 if update.shipping_query:
441 if new_shipping_queries is None: new_shipping_queries = []
442 new_shipping_queries.append(update.shipping_query)
443 if update.pre_checkout_query:
444 if new_pre_checkout_queries is None: new_pre_checkout_queries = []
445 new_pre_checkout_queries.append(update.pre_checkout_query)
446 if update.poll:
447 if new_polls is None: new_polls = []
448 new_polls.append(update.poll)
449 if update.poll_answer:
450 if new_poll_answers is None: new_poll_answers = []
451 new_poll_answers.append(update.poll_answer)
452 if update.my_chat_member:
453 if new_my_chat_members is None: new_my_chat_members = []
454 new_my_chat_members.append(update.my_chat_member)
455 if update.chat_member:
456 if new_chat_members is None: new_chat_members = []
457 new_chat_members.append(update.chat_member)
458
459 if new_messages:
460 self.process_new_messages(new_messages)
461 if new_edited_messages:
462 self.process_new_edited_messages(new_edited_messages)
463 if new_channel_posts:
464 self.process_new_channel_posts(new_channel_posts)
465 if new_edited_channel_posts:
466 self.process_new_edited_channel_posts(new_edited_channel_posts)
467 if new_inline_queries:
468 self.process_new_inline_query(new_inline_queries)
469 if new_chosen_inline_results:
470 self.process_new_chosen_inline_query(new_chosen_inline_results)
471 if new_callback_queries:
472 self.process_new_callback_query(new_callback_queries)
473 if new_shipping_queries:
474 self.process_new_shipping_query(new_shipping_queries)
475 if new_pre_checkout_queries:
476 self.process_new_pre_checkout_query(new_pre_checkout_queries)
477 if new_polls:
478 self.process_new_poll(new_polls)
479 if new_poll_answers:
480 self.process_new_poll_answer(new_poll_answers)
481 if new_my_chat_members:
482 self.process_new_my_chat_member(new_my_chat_members)
483 if new_chat_members:
484 self.process_new_chat_member(new_chat_members)
485
486 def process_new_messages(self, new_messages):
487 self._notify_next_handlers(new_messages)
488 self._notify_reply_handlers(new_messages)
489 self.__notify_update(new_messages)
490 self._notify_command_handlers(self.message_handlers, new_messages)
491
492 def process_new_edited_messages(self, edited_message):
493 self._notify_command_handlers(self.edited_message_handlers, edited_message)
494
495 def process_new_channel_posts(self, channel_post):
496 self._notify_command_handlers(self.channel_post_handlers, channel_post)
497
498 def process_new_edited_channel_posts(self, edited_channel_post):
499 self._notify_command_handlers(self.edited_channel_post_handlers, edited_channel_post)
500
501 def process_new_inline_query(self, new_inline_querys):
502 self._notify_command_handlers(self.inline_handlers, new_inline_querys)
503
504 def process_new_chosen_inline_query(self, new_chosen_inline_querys):
505 self._notify_command_handlers(self.chosen_inline_handlers, new_chosen_inline_querys)
506
507 def process_new_callback_query(self, new_callback_querys):
508 self._notify_command_handlers(self.callback_query_handlers, new_callback_querys)
509
510 def process_new_shipping_query(self, new_shipping_querys):
511 self._notify_command_handlers(self.shipping_query_handlers, new_shipping_querys)
512
513 def process_new_pre_checkout_query(self, pre_checkout_querys):
514 self._notify_command_handlers(self.pre_checkout_query_handlers, pre_checkout_querys)
515
516 def process_new_poll(self, polls):
517 self._notify_command_handlers(self.poll_handlers, polls)
518
519 def process_new_poll_answer(self, poll_answers):
520 self._notify_command_handlers(self.poll_answer_handlers, poll_answers)
521
522 def process_new_my_chat_member(self, my_chat_members):
523 self._notify_command_handlers(self.my_chat_member_handlers, my_chat_members)
524
525 def process_new_chat_member(self, chat_members):
526 self._notify_command_handlers(self.chat_member_handlers, chat_members)
527
528 def process_middlewares(self, update):
529 for update_type, middlewares in self.typed_middleware_handlers.items():
530 if getattr(update, update_type) is not None:
531 for typed_middleware_handler in middlewares:
532 try:
533 typed_middleware_handler(self, getattr(update, update_type))
534 except Exception as e:
535 e.args = e.args + (f'Typed middleware handler "{typed_middleware_handler.__qualname__}"',)
536 raise
537
538 if len(self.default_middleware_handlers) > 0:
539 for default_middleware_handler in self.default_middleware_handlers:
540 try:
541 default_middleware_handler(self, update)
542 except Exception as e:
543 e.args = e.args + (f'Default middleware handler "{default_middleware_handler.__qualname__}"',)
544 raise
545
546 def __notify_update(self, new_messages):
547 if len(self.update_listener) == 0:
548 return
549 for listener in self.update_listener:
550 self._exec_task(listener, new_messages)
551
552 def infinity_polling(self, timeout=20, skip_pending=False, long_polling_timeout=20, logger_level=logging.ERROR,
553 allowed_updates=None, *args, **kwargs):
554 """
555 Wrap polling with infinite loop and exception handling to avoid bot stops polling.
556
557 :param timeout: Request connection timeout
558 :param long_polling_timeout: Timeout in seconds for long polling (see API docs)
559 :param skip_pending: skip old updates
560 :param logger_level: Custom logging level for infinity_polling logging.
561 Use logger levels from logging as a value. None/NOTSET = no error logging
562 :param allowed_updates: A list of the update types you want your bot to receive.
563 For example, specify [“message”, “edited_channel_post”, “callback_query”] to only receive updates of these types.
564 See util.update_types for a complete list of available update types.
565 Specify an empty list to receive all update types except chat_member (default).
566 If not specified, the previous setting will be used.
567
568 Please note that this parameter doesn't affect updates created before the call to the get_updates,
569 so unwanted updates may be received for a short period of time.
570 """
571 if skip_pending:
572 self.__skip_updates()
573
574 while not self.__stop_polling.is_set():
575 try:
576 self.polling(none_stop=True, timeout=timeout, long_polling_timeout=long_polling_timeout,
577 allowed_updates=allowed_updates, *args, **kwargs)
578 except Exception as e:
579 if logger_level and logger_level >= logging.ERROR:
580 logger.error("Infinity polling exception: %s", str(e))
581 if logger_level and logger_level >= logging.DEBUG:
582 logger.error("Exception traceback:\n%s", traceback.format_exc())
583 time.sleep(3)
584 continue
585 if logger_level and logger_level >= logging.INFO:
586 logger.error("Infinity polling: polling exited")
587 if logger_level and logger_level >= logging.INFO:
588 logger.error("Break infinity polling")
589
590 def polling(self, non_stop: bool=False, skip_pending=False, interval: int=0, timeout: int=20,
591 long_polling_timeout: int=20, allowed_updates: Optional[List[str]]=None,
592 none_stop: Optional[bool]=None):
593 """
594 This function creates a new Thread that calls an internal __retrieve_updates function.
595 This allows the bot to retrieve Updates automagically and notify listeners and message handlers accordingly.
596
597 Warning: Do not call this function more than once!
598
599 Always get updates.
600 :param interval: Delay between two update retrivals
601 :param non_stop: Do not stop polling when an ApiException occurs.
602 :param timeout: Request connection timeout
603 :param skip_pending: skip old updates
604 :param long_polling_timeout: Timeout in seconds for long polling (see API docs)
605 :param allowed_updates: A list of the update types you want your bot to receive.
606 For example, specify [“message”, “edited_channel_post”, “callback_query”] to only receive updates of these types.
607 See util.update_types for a complete list of available update types.
608 Specify an empty list to receive all update types except chat_member (default).
609 If not specified, the previous setting will be used.
610
611 Please note that this parameter doesn't affect updates created before the call to the get_updates,
612 so unwanted updates may be received for a short period of time.
613 :param none_stop: Deprecated, use non_stop. Old typo f***up compatibility
614 :return:
615 """
616 if none_stop is not None:
617 non_stop = none_stop
618
619 if skip_pending:
620 self.__skip_updates()
621
622 if self.threaded:
623 self.__threaded_polling(non_stop, interval, timeout, long_polling_timeout, allowed_updates)
624 else:
625 self.__non_threaded_polling(non_stop, interval, timeout, long_polling_timeout, allowed_updates)
626
627 def __threaded_polling(self, non_stop=False, interval=0, timeout = None, long_polling_timeout = None, allowed_updates=None):
628 logger.info('Started polling.')
629 self.__stop_polling.clear()
630 error_interval = 0.25
631
632 polling_thread = util.WorkerThread(name="PollingThread")
633 or_event = util.OrEvent(
634 polling_thread.done_event,
635 polling_thread.exception_event,
636 self.worker_pool.exception_event
637 )
638
639 while not self.__stop_polling.wait(interval):
640 or_event.clear()
641 try:
642 polling_thread.put(self.__retrieve_updates, timeout, long_polling_timeout, allowed_updates=allowed_updates)
643 or_event.wait() # wait for polling thread finish, polling thread error or thread pool error
644 polling_thread.raise_exceptions()
645 self.worker_pool.raise_exceptions()
646 error_interval = 0.25
647 except apihelper.ApiException as e:
648 if self.exception_handler is not None:
649 handled = self.exception_handler.handle(e)
650 else:
651 handled = False
652 if not handled:
653 logger.error(e)
654 if not non_stop:
655 self.__stop_polling.set()
656 logger.info("Exception occurred. Stopping.")
657 else:
658 # polling_thread.clear_exceptions()
659 # self.worker_pool.clear_exceptions()
660 logger.info("Waiting for {0} seconds until retry".format(error_interval))
661 time.sleep(error_interval)
662 error_interval *= 2
663 else:
664 # polling_thread.clear_exceptions()
665 # self.worker_pool.clear_exceptions()
666 time.sleep(error_interval)
667 polling_thread.clear_exceptions() #*
668 self.worker_pool.clear_exceptions() #*
669 except KeyboardInterrupt:
670 logger.info("KeyboardInterrupt received.")
671 self.__stop_polling.set()
672 break
673 except Exception as e:
674 if self.exception_handler is not None:
675 handled = self.exception_handler.handle(e)
676 else:
677 handled = False
678 if not handled:
679 polling_thread.stop()
680 polling_thread.clear_exceptions() #*
681 self.worker_pool.clear_exceptions() #*
682 raise e
683 else:
684 polling_thread.clear_exceptions()
685 self.worker_pool.clear_exceptions()
686 time.sleep(error_interval)
687
688 polling_thread.stop()
689 polling_thread.clear_exceptions() #*
690 self.worker_pool.clear_exceptions() #*
691 logger.info('Stopped polling.')
692
693 def __non_threaded_polling(self, non_stop=False, interval=0, timeout=None, long_polling_timeout=None, allowed_updates=None):
694 logger.info('Started polling.')
695 self.__stop_polling.clear()
696 error_interval = 0.25
697
698 while not self.__stop_polling.wait(interval):
699 try:
700 self.__retrieve_updates(timeout, long_polling_timeout, allowed_updates=allowed_updates)
701 error_interval = 0.25
702 except apihelper.ApiException as e:
703 if self.exception_handler is not None:
704 handled = self.exception_handler.handle(e)
705 else:
706 handled = False
707
708 if not handled:
709 logger.error(e)
710 if not non_stop:
711 self.__stop_polling.set()
712 logger.info("Exception occurred. Stopping.")
713 else:
714 logger.info("Waiting for {0} seconds until retry".format(error_interval))
715 time.sleep(error_interval)
716 error_interval *= 2
717 else:
718 time.sleep(error_interval)
719 except KeyboardInterrupt:
720 logger.info("KeyboardInterrupt received.")
721 self.__stop_polling.set()
722 break
723 except Exception as e:
724 if self.exception_handler is not None:
725 handled = self.exception_handler.handle(e)
726 else:
727 handled = False
728 if not handled:
729 raise e
730 else:
731 time.sleep(error_interval)
732
733 logger.info('Stopped polling.')
734
735 def _exec_task(self, task, *args, **kwargs):
736 if self.threaded:
737 self.worker_pool.put(task, *args, **kwargs)
738 else:
739 task(*args, **kwargs)
740
741 def stop_polling(self):
742 self.__stop_polling.set()
743
744 def stop_bot(self):
745 self.stop_polling()
746 if self.threaded and self.worker_pool:
747 self.worker_pool.close()
748
749 def set_update_listener(self, listener):
750 self.update_listener.append(listener)
751
752 def get_me(self) -> types.User:
753 """
754 Returns basic information about the bot in form of a User object.
755 """
756 result = apihelper.get_me(self.token)
757 return types.User.de_json(result)
758
759 def get_file(self, file_id: str) -> types.File:
760 """
761 Use this method to get basic info about a file and prepare it for downloading.
762 For the moment, bots can download files of up to 20MB in size.
763 On success, a File object is returned.
764 It is guaranteed that the link will be valid for at least 1 hour.
765 When the link expires, a new one can be requested by calling get_file again.
766 """
767 return types.File.de_json(apihelper.get_file(self.token, file_id))
768
769 def get_file_url(self, file_id: str) -> str:
770 return apihelper.get_file_url(self.token, file_id)
771
772 def download_file(self, file_path: str) -> bytes:
773 return apihelper.download_file(self.token, file_path)
774
775 def log_out(self) -> bool:
776 """
777 Use this method to log out from the cloud Bot API server before launching the bot locally.
778 You MUST log out the bot before running it locally, otherwise there is no guarantee
779 that the bot will receive updates.
780 After a successful call, you can immediately log in on a local server,
781 but will not be able to log in back to the cloud Bot API server for 10 minutes.
782 Returns True on success.
783 """
784 return apihelper.log_out(self.token)
785
786 def close(self) -> bool:
787 """
788 Use this method to close the bot instance before moving it from one local server to another.
789 You need to delete the webhook before calling this method to ensure that the bot isn't launched again
790 after server restart.
791 The method will return error 429 in the first 10 minutes after the bot is launched.
792 Returns True on success.
793 """
794 return apihelper.close(self.token)
795
796 def get_user_profile_photos(self, user_id: int, offset: Optional[int]=None,
797 limit: Optional[int]=None) -> types.UserProfilePhotos:
798 """
799 Retrieves the user profile photos of the person with 'user_id'
800 See https://core.telegram.org/bots/api#getuserprofilephotos
801 :param user_id:
802 :param offset:
803 :param limit:
804 :return: API reply.
805 """
806 result = apihelper.get_user_profile_photos(self.token, user_id, offset, limit)
807 return types.UserProfilePhotos.de_json(result)
808
809 def get_chat(self, chat_id: Union[int, str]) -> types.Chat:
810 """
811 Use this method to get up to date information about the chat (current name of the user for one-on-one
812 conversations, current username of a user, group or channel, etc.). Returns a Chat object on success.
813 :param chat_id:
814 :return:
815 """
816 result = apihelper.get_chat(self.token, chat_id)
817 return types.Chat.de_json(result)
818
819 def leave_chat(self, chat_id: Union[int, str]) -> bool:
820 """
821 Use this method for your bot to leave a group, supergroup or channel. Returns True on success.
822 :param chat_id:
823 :return:
824 """
825 result = apihelper.leave_chat(self.token, chat_id)
826 return result
827
828 def get_chat_administrators(self, chat_id: Union[int, str]) -> List[types.ChatMember]:
829 """
830 Use this method to get a list of administrators in a chat.
831 On success, returns an Array of ChatMember objects that contains
832 information about all chat administrators except other bots.
833 :param chat_id: Unique identifier for the target chat or username
834 of the target supergroup or channel (in the format @channelusername)
835 :return:
836 """
837 result = apihelper.get_chat_administrators(self.token, chat_id)
838 return [types.ChatMember.de_json(r) for r in result]
839
840 def get_chat_members_count(self, chat_id: Union[int, str]) -> int:
841 """
842 This function is deprecated. Use `get_chat_member_count` instead
843 """
844 logger.info('get_chat_members_count is deprecated. Use get_chat_member_count instead.')
845 result = apihelper.get_chat_member_count(self.token, chat_id)
846 return result
847
848 def get_chat_member_count(self, chat_id: Union[int, str]) -> int:
849 """
850 Use this method to get the number of members in a chat. Returns Int on success.
851 :param chat_id:
852 :return:
853 """
854 result = apihelper.get_chat_member_count(self.token, chat_id)
855 return result
856
857 def set_chat_sticker_set(self, chat_id: Union[int, str], sticker_set_name: str) -> types.StickerSet:
858 """
859 Use this method to set a new group sticker set for a supergroup. The bot must be an administrator
860 in the chat for this to work and must have the appropriate admin rights.
861 Use the field can_set_sticker_set optionally returned in getChat requests to check
862 if the bot can use this method. Returns True on success.
863 :param chat_id: Unique identifier for the target chat or username of the target supergroup
864 (in the format @supergroupusername)
865 :param sticker_set_name: Name of the sticker set to be set as the group sticker set
866 :return:
867 """
868 result = apihelper.set_chat_sticker_set(self.token, chat_id, sticker_set_name)
869 return result
870
871 def delete_chat_sticker_set(self, chat_id: Union[int, str]) -> bool:
872 """
873 Use this method to delete a group sticker set from a supergroup. The bot must be an administrator in the chat
874 for this to work and must have the appropriate admin rights. Use the field can_set_sticker_set
875 optionally returned in getChat requests to check if the bot can use this method. Returns True on success.
876 :param chat_id: Unique identifier for the target chat or username of the target supergroup
877 (in the format @supergroupusername)
878 :return:
879 """
880 result = apihelper.delete_chat_sticker_set(self.token, chat_id)
881 return result
882
883 def get_chat_member(self, chat_id: Union[int, str], user_id: int) -> types.ChatMember:
884 """
885 Use this method to get information about a member of a chat. Returns a ChatMember object on success.
886 :param chat_id:
887 :param user_id:
888 :return:
889 """
890 result = apihelper.get_chat_member(self.token, chat_id, user_id)
891 return types.ChatMember.de_json(result)
892
893 def send_message(
894 self, chat_id: Union[int, str], text: str,
895 disable_web_page_preview: Optional[bool]=None,
896 reply_to_message_id: Optional[int]=None,
897 reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
898 parse_mode: Optional[str]=None,
899 disable_notification: Optional[bool]=None,
900 timeout: Optional[int]=None,
901 entities: Optional[List[types.MessageEntity]]=None,
902 allow_sending_without_reply: Optional[bool]=None) -> types.Message:
903 """
904 Use this method to send text messages.
905
906 Warning: Do not send more than about 4000 characters each message, otherwise you'll risk an HTTP 414 error.
907 If you must send more than 4000 characters,
908 use the `split_string` or `smart_split` function in util.py.
909
910 :param chat_id:
911 :param text:
912 :param disable_web_page_preview:
913 :param reply_to_message_id:
914 :param reply_markup:
915 :param parse_mode:
916 :param disable_notification: Boolean, Optional. Sends the message silently.
917 :param timeout:
918 :param entities:
919 :param allow_sending_without_reply:
920 :return: API reply.
921 """
922 parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
923
924 return types.Message.de_json(
925 apihelper.send_message(
926 self.token, chat_id, text, disable_web_page_preview, reply_to_message_id,
927 reply_markup, parse_mode, disable_notification, timeout,
928 entities, allow_sending_without_reply))
929
930 def forward_message(
931 self, chat_id: Union[int, str], from_chat_id: Union[int, str],
932 message_id: int, disable_notification: Optional[bool]=None,
933 timeout: Optional[int]=None) -> types.Message:
934 """
935 Use this method to forward messages of any kind.
936 :param disable_notification:
937 :param chat_id: which chat to forward
938 :param from_chat_id: which chat message from
939 :param message_id: message id
940 :param timeout:
941 :return: API reply.
942 """
943 return types.Message.de_json(
944 apihelper.forward_message(self.token, chat_id, from_chat_id, message_id, disable_notification, timeout))
945
946 def copy_message(
947 self, chat_id: Union[int, str],
948 from_chat_id: Union[int, str],
949 message_id: int,
950 caption: Optional[str]=None,
951 parse_mode: Optional[str]=None,
952 caption_entities: Optional[List[types.MessageEntity]]=None,
953 disable_notification: Optional[bool]=None,
954 reply_to_message_id: Optional[int]=None,
955 allow_sending_without_reply: Optional[bool]=None,
956 reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
957 timeout: Optional[int]=None) -> int:
958 """
959 Use this method to copy messages of any kind.
960 :param chat_id: which chat to forward
961 :param from_chat_id: which chat message from
962 :param message_id: message id
963 :param caption:
964 :param parse_mode:
965 :param caption_entities:
966 :param disable_notification:
967 :param reply_to_message_id:
968 :param allow_sending_without_reply:
969 :param reply_markup:
970 :param timeout:
971 :return: API reply.
972 """
973 return types.MessageID.de_json(
974 apihelper.copy_message(self.token, chat_id, from_chat_id, message_id, caption, parse_mode, caption_entities,
975 disable_notification, reply_to_message_id, allow_sending_without_reply, reply_markup,
976 timeout))
977
978 def delete_message(self, chat_id: Union[int, str], message_id: int,
979 timeout: Optional[int]=None) -> bool:
980 """
981 Use this method to delete message. Returns True on success.
982 :param chat_id: in which chat to delete
983 :param message_id: which message to delete
984 :param timeout:
985 :return: API reply.
986 """
987 return apihelper.delete_message(self.token, chat_id, message_id, timeout)
988
989 def send_dice(
990 self, chat_id: Union[int, str],
991 emoji: Optional[str]=None, disable_notification: Optional[bool]=None,
992 reply_to_message_id: Optional[int]=None,
993 reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
994 timeout: Optional[int]=None,
995 allow_sending_without_reply: Optional[bool]=None) -> types.Message:
996 """
997 Use this method to send dices.
998 :param chat_id:
999 :param emoji:
1000 :param disable_notification:
1001 :param reply_to_message_id:
1002 :param reply_markup:
1003 :param timeout:
1004 :param allow_sending_without_reply:
1005 :return: Message
1006 """
1007 return types.Message.de_json(
1008 apihelper.send_dice(
1009 self.token, chat_id, emoji, disable_notification, reply_to_message_id,
1010 reply_markup, timeout, allow_sending_without_reply)
1011 )
1012
1013 def send_photo(
1014 self, chat_id: Union[int, str], photo: Union[Any, str],
1015 caption: Optional[str]=None, reply_to_message_id: Optional[int]=None,
1016 reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
1017 parse_mode: Optional[str]=None, disable_notification: Optional[bool]=None,
1018 timeout: Optional[int]=None,
1019 caption_entities: Optional[List[types.MessageEntity]]=None,
1020 allow_sending_without_reply: Optional[bool]=None) -> types.Message:
1021 """
1022 Use this method to send photos.
1023 :param chat_id:
1024 :param photo:
1025 :param caption:
1026 :param parse_mode:
1027 :param disable_notification:
1028 :param reply_to_message_id:
1029 :param reply_markup:
1030 :param timeout:
1031 :param caption_entities:
1032 :param allow_sending_without_reply:
1033 :return: API reply.
1034 """
1035 parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
1036
1037 return types.Message.de_json(
1038 apihelper.send_photo(
1039 self.token, chat_id, photo, caption, reply_to_message_id, reply_markup,
1040 parse_mode, disable_notification, timeout, caption_entities,
1041 allow_sending_without_reply))
1042
1043 def send_audio(
1044 self, chat_id: Union[int, str], audio: Union[Any, str],
1045 caption: Optional[str]=None, duration: Optional[int]=None,
1046 performer: Optional[str]=None, title: Optional[str]=None,
1047 reply_to_message_id: Optional[int]=None,
1048 reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
1049 parse_mode: Optional[str]=None,
1050 disable_notification: Optional[bool]=None,
1051 timeout: Optional[int]=None,
1052 thumb: Optional[Union[Any, str]]=None,
1053 caption_entities: Optional[List[types.MessageEntity]]=None,
1054 allow_sending_without_reply: Optional[bool]=None) -> types.Message:
1055 """
1056 Use this method to send audio files, if you want Telegram clients to display them in the music player.
1057 Your audio must be in the .mp3 format.
1058 :param chat_id:Unique identifier for the message recipient
1059 :param audio:Audio file to send.
1060 :param caption:
1061 :param duration:Duration of the audio in seconds
1062 :param performer:Performer
1063 :param title:Track name
1064 :param reply_to_message_id:If the message is a reply, ID of the original message
1065 :param reply_markup:
1066 :param parse_mode
1067 :param disable_notification:
1068 :param timeout:
1069 :param thumb:
1070 :param caption_entities:
1071 :param allow_sending_without_reply:
1072 :return: Message
1073 """
1074 parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
1075
1076 return types.Message.de_json(
1077 apihelper.send_audio(
1078 self.token, chat_id, audio, caption, duration, performer, title, reply_to_message_id,
1079 reply_markup, parse_mode, disable_notification, timeout, thumb,
1080 caption_entities, allow_sending_without_reply))
1081
1082 def send_voice(
1083 self, chat_id: Union[int, str], voice: Union[Any, str],
1084 caption: Optional[str]=None, duration: Optional[int]=None,
1085 reply_to_message_id: Optional[int]=None,
1086 reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
1087 parse_mode: Optional[str]=None,
1088 disable_notification: Optional[bool]=None,
1089 timeout: Optional[int]=None,
1090 caption_entities: Optional[List[types.MessageEntity]]=None,
1091 allow_sending_without_reply: Optional[bool]=None) -> types.Message:
1092 """
1093 Use this method to send audio files, if you want Telegram clients to display the file
1094 as a playable voice message.
1095 :param chat_id:Unique identifier for the message recipient.
1096 :param voice:
1097 :param caption:
1098 :param duration:Duration of sent audio in seconds
1099 :param reply_to_message_id:
1100 :param reply_markup:
1101 :param parse_mode
1102 :param disable_notification:
1103 :param timeout:
1104 :param caption_entities:
1105 :param allow_sending_without_reply:
1106 :return: Message
1107 """
1108 parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
1109
1110 return types.Message.de_json(
1111 apihelper.send_voice(
1112 self.token, chat_id, voice, caption, duration, reply_to_message_id, reply_markup,
1113 parse_mode, disable_notification, timeout, caption_entities,
1114 allow_sending_without_reply))
1115
1116 def send_document(
1117 self, chat_id: Union[int, str], data: Union[Any, str],
1118 reply_to_message_id: Optional[int]=None,
1119 caption: Optional[str]=None,
1120 reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
1121 parse_mode: Optional[str]=None,
1122 disable_notification: Optional[bool]=None,
1123 timeout: Optional[int]=None,
1124 thumb: Optional[Union[Any, str]]=None,
1125 caption_entities: Optional[List[types.MessageEntity]]=None,
1126 allow_sending_without_reply: Optional[bool]=None,
1127 visible_file_name: Optional[str]=None,
1128 disable_content_type_detection: Optional[bool]=None) -> types.Message:
1129 """
1130 Use this method to send general files.
1131 :param chat_id: Unique identifier for the target chat or username of the target channel (in the format @channelusername)
1132 :param data: (document) File to send. Pass a file_id as String to send a file that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data
1133 :param reply_to_message_id: If the message is a reply, ID of the original message
1134 :param caption: Document caption (may also be used when resending documents by file_id), 0-1024 characters after entities parsing
1135 :param reply_markup:
1136 :param parse_mode: Mode for parsing entities in the document caption
1137 :param disable_notification: Sends the message silently. Users will receive a notification with no sound.
1138 :param timeout:
1139 :param thumb: InputFile or String : Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new file, so you can pass “attach://<file_attach_name>” if the thumbnail was uploaded using multipart/form-data under <file_attach_name>
1140 :param caption_entities:
1141 :param allow_sending_without_reply:
1142 :param visible_file_name: allows to define file name that will be visible in the Telegram instead of original file name
1143 :param disable_content_type_detection: Disables automatic server-side content type detection for files uploaded using multipart/form-data
1144 :return: API reply.
1145 """
1146 parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
1147
1148 return types.Message.de_json(
1149 apihelper.send_data(
1150 self.token, chat_id, data, 'document',
1151 reply_to_message_id = reply_to_message_id, reply_markup = reply_markup, parse_mode = parse_mode,
1152 disable_notification = disable_notification, timeout = timeout, caption = caption, thumb = thumb,
1153 caption_entities = caption_entities, allow_sending_without_reply = allow_sending_without_reply,
1154 disable_content_type_detection = disable_content_type_detection, visible_file_name = visible_file_name))
1155
1156 def send_sticker(
1157 self, chat_id: Union[int, str], data: Union[Any, str],
1158 reply_to_message_id: Optional[int]=None,
1159 reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
1160 disable_notification: Optional[bool]=None,
1161 timeout: Optional[int]=None,
1162 allow_sending_without_reply: Optional[bool]=None) -> types.Message:
1163 """
1164 Use this method to send .webp stickers.
1165 :param chat_id:
1166 :param data:
1167 :param reply_to_message_id:
1168 :param reply_markup:
1169 :param disable_notification: to disable the notification
1170 :param timeout: timeout
1171 :param allow_sending_without_reply:
1172 :return: API reply.
1173 """
1174 return types.Message.de_json(
1175 apihelper.send_data(
1176 self.token, chat_id, data, 'sticker',
1177 reply_to_message_id=reply_to_message_id, reply_markup=reply_markup,
1178 disable_notification=disable_notification, timeout=timeout,
1179 allow_sending_without_reply=allow_sending_without_reply))
1180
1181 def send_video(
1182 self, chat_id: Union[int, str], data: Union[Any, str],
1183 duration: Optional[int]=None,
1184 caption: Optional[str]=None,
1185 reply_to_message_id: Optional[int]=None,
1186 reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
1187 parse_mode: Optional[str]=None,
1188 supports_streaming: Optional[bool]=None,
1189 disable_notification: Optional[bool]=None,
1190 timeout: Optional[int]=None,
1191 thumb: Optional[Union[Any, str]]=None,
1192 width: Optional[int]=None,
1193 height: Optional[int]=None,
1194 caption_entities: Optional[List[types.MessageEntity]]=None,
1195 allow_sending_without_reply: Optional[bool]=None) -> types.Message:
1196 """
1197 Use this method to send video files, Telegram clients support mp4 videos.
1198 :param chat_id: Integer : Unique identifier for the message recipient — User or GroupChat id
1199 :param data: InputFile or String : Video to send. You can either pass a file_id as String to resend
1200 a video that is already on the Telegram server
1201 :param duration: Integer : Duration of sent video in seconds
1202 :param caption: String : Video caption (may also be used when resending videos by file_id).
1203 :param parse_mode:
1204 :param supports_streaming:
1205 :param reply_to_message_id:
1206 :param reply_markup:
1207 :param disable_notification:
1208 :param timeout:
1209 :param thumb: InputFile or String : Thumbnail of the file sent
1210 :param width:
1211 :param height:
1212 :param caption_entities:
1213 :param allow_sending_without_reply:
1214 :return:
1215 """
1216 parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
1217
1218 return types.Message.de_json(
1219 apihelper.send_video(
1220 self.token, chat_id, data, duration, caption, reply_to_message_id, reply_markup,
1221 parse_mode, supports_streaming, disable_notification, timeout, thumb, width, height,
1222 caption_entities, allow_sending_without_reply))
1223
1224 def send_animation(
1225 self, chat_id: Union[int, str], animation: Union[Any, str],
1226 duration: Optional[int]=None,
1227 caption: Optional[str]=None,
1228 reply_to_message_id: Optional[int]=None,
1229 reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
1230 parse_mode: Optional[str]=None,
1231 disable_notification: Optional[bool]=None,
1232 timeout: Optional[int]=None,
1233 thumb: Optional[Union[Any, str]]=None,
1234 caption_entities: Optional[List[types.MessageEntity]]=None,
1235 allow_sending_without_reply: Optional[bool]=None) -> types.Message:
1236 """
1237 Use this method to send animation files (GIF or H.264/MPEG-4 AVC video without sound).
1238 :param chat_id: Integer : Unique identifier for the message recipient — User or GroupChat id
1239 :param animation: InputFile or String : Animation to send. You can either pass a file_id as String to resend an
1240 animation that is already on the Telegram server
1241 :param duration: Integer : Duration of sent video in seconds
1242 :param caption: String : Animation caption (may also be used when resending animation by file_id).
1243 :param parse_mode:
1244 :param reply_to_message_id:
1245 :param reply_markup:
1246 :param disable_notification:
1247 :param timeout:
1248 :param thumb: InputFile or String : Thumbnail of the file sent
1249 :param caption_entities:
1250 :param allow_sending_without_reply:
1251 :return:
1252 """
1253 parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
1254
1255 return types.Message.de_json(
1256 apihelper.send_animation(
1257 self.token, chat_id, animation, duration, caption, reply_to_message_id,
1258 reply_markup, parse_mode, disable_notification, timeout, thumb,
1259 caption_entities, allow_sending_without_reply))
1260
1261 def send_video_note(
1262 self, chat_id: Union[int, str], data: Union[Any, str],
1263 duration: Optional[int]=None,
1264 length: Optional[int]=None,
1265 reply_to_message_id: Optional[int]=None,
1266 reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
1267 disable_notification: Optional[bool]=None,
1268 timeout: Optional[int]=None,
1269 thumb: Optional[Union[Any, str]]=None,
1270 allow_sending_without_reply: Optional[bool]=None) -> types.Message:
1271 """
1272 As of v.4.0, Telegram clients support rounded square mp4 videos of up to 1 minute long. Use this method to send
1273 video messages.
1274 :param chat_id: Integer : Unique identifier for the message recipient — User or GroupChat id
1275 :param data: InputFile or String : Video note to send. You can either pass a file_id as String to resend
1276 a video that is already on the Telegram server
1277 :param duration: Integer : Duration of sent video in seconds
1278 :param length: Integer : Video width and height, Can't be None and should be in range of (0, 640)
1279 :param reply_to_message_id:
1280 :param reply_markup:
1281 :param disable_notification:
1282 :param timeout:
1283 :param thumb: InputFile or String : Thumbnail of the file sent
1284 :param allow_sending_without_reply:
1285 :return:
1286 """
1287 return types.Message.de_json(
1288 apihelper.send_video_note(
1289 self.token, chat_id, data, duration, length, reply_to_message_id, reply_markup,
1290 disable_notification, timeout, thumb, allow_sending_without_reply))
1291
1292 def send_media_group(
1293 self, chat_id: Union[int, str],
1294 media: List[Union[
1295 types.InputMediaAudio, types.InputMediaDocument,
1296 types.InputMediaPhoto, types.InputMediaVideo]],
1297 disable_notification: Optional[bool]=None,
1298 reply_to_message_id: Optional[int]=None,
1299 timeout: Optional[int]=None,
1300 allow_sending_without_reply: Optional[bool]=None) -> List[types.Message]:
1301 """
1302 send a group of photos or videos as an album. On success, an array of the sent Messages is returned.
1303 :param chat_id:
1304 :param media:
1305 :param disable_notification:
1306 :param reply_to_message_id:
1307 :param timeout:
1308 :param allow_sending_without_reply:
1309 :return:
1310 """
1311 result = apihelper.send_media_group(
1312 self.token, chat_id, media, disable_notification, reply_to_message_id, timeout,
1313 allow_sending_without_reply)
1314 return [types.Message.de_json(msg) for msg in result]
1315
1316 def send_location(
1317 self, chat_id: Union[int, str],
1318 latitude: float, longitude: float,
1319 live_period: Optional[int]=None,
1320 reply_to_message_id: Optional[int]=None,
1321 reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
1322 disable_notification: Optional[bool]=None,
1323 timeout: Optional[int]=None,
1324 horizontal_accuracy: Optional[float]=None,
1325 heading: Optional[int]=None,
1326 proximity_alert_radius: Optional[int]=None,
1327 allow_sending_without_reply: Optional[bool]=None) -> types.Message:
1328
1329
1330 """
1331 Use this method to send point on the map.
1332 :param chat_id:
1333 :param latitude:
1334 :param longitude:
1335 :param live_period:
1336 :param reply_to_message_id:
1337 :param reply_markup:
1338 :param disable_notification:
1339 :param timeout:
1340 :param horizontal_accuracy:
1341 :param heading:
1342 :param proximity_alert_radius:
1343 :param allow_sending_without_reply:
1344 :return: API reply.
1345 """
1346 return types.Message.de_json(
1347 apihelper.send_location(
1348 self.token, chat_id, latitude, longitude, live_period,
1349 reply_to_message_id, reply_markup, disable_notification, timeout,
1350 horizontal_accuracy, heading, proximity_alert_radius,
1351 allow_sending_without_reply))
1352
1353 def edit_message_live_location(
1354 self, latitude: float, longitude: float,
1355 chat_id: Optional[Union[int, str]]=None,
1356 message_id: Optional[int]=None,
1357 inline_message_id: Optional[str]=None,
1358 reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
1359 timeout: Optional[int]=None,
1360 horizontal_accuracy: Optional[float]=None,
1361 heading: Optional[int]=None,
1362 proximity_alert_radius: Optional[int]=None) -> types.Message:
1363 """
1364 Use this method to edit live location
1365 :param latitude:
1366 :param longitude:
1367 :param chat_id:
1368 :param message_id:
1369 :param reply_markup:
1370 :param timeout:
1371 :param inline_message_id:
1372 :param horizontal_accuracy:
1373 :param heading:
1374 :param proximity_alert_radius:
1375 :return:
1376 """
1377 return types.Message.de_json(
1378 apihelper.edit_message_live_location(
1379 self.token, latitude, longitude, chat_id, message_id,
1380 inline_message_id, reply_markup, timeout,
1381 horizontal_accuracy, heading, proximity_alert_radius))
1382
1383 def stop_message_live_location(
1384 self, chat_id: Optional[Union[int, str]]=None,
1385 message_id: Optional[int]=None,
1386 inline_message_id: Optional[str]=None,
1387 reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
1388 timeout: Optional[int]=None) -> types.Message:
1389 """
1390 Use this method to stop updating a live location message sent by the bot
1391 or via the bot (for inline bots) before live_period expires
1392 :param chat_id:
1393 :param message_id:
1394 :param inline_message_id:
1395 :param reply_markup:
1396 :param timeout:
1397 :return:
1398 """
1399 return types.Message.de_json(
1400 apihelper.stop_message_live_location(
1401 self.token, chat_id, message_id, inline_message_id, reply_markup, timeout))
1402
1403 def send_venue(
1404 self, chat_id: Union[int, str],
1405 latitude: float, longitude: float,
1406 title: str, address: str,
1407 foursquare_id: Optional[str]=None,
1408 foursquare_type: Optional[str]=None,
1409 disable_notification: Optional[bool]=None,
1410 reply_to_message_id: Optional[int]=None,
1411 reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
1412 timeout: Optional[int]=None,
1413 allow_sending_without_reply: Optional[bool]=None,
1414 google_place_id: Optional[str]=None,
1415 google_place_type: Optional[str]=None) -> types.Message:
1416 """
1417 Use this method to send information about a venue.
1418 :param chat_id: Integer or String : Unique identifier for the target chat or username of the target channel
1419 :param latitude: Float : Latitude of the venue
1420 :param longitude: Float : Longitude of the venue
1421 :param title: String : Name of the venue
1422 :param address: String : Address of the venue
1423 :param foursquare_id: String : Foursquare identifier of the venue
1424 :param foursquare_type: Foursquare type of the venue, if known. (For example, “arts_entertainment/default”,
1425 “arts_entertainment/aquarium” or “food/icecream”.)
1426 :param disable_notification:
1427 :param reply_to_message_id:
1428 :param reply_markup:
1429 :param timeout:
1430 :param allow_sending_without_reply:
1431 :param google_place_id:
1432 :param google_place_type:
1433 :return:
1434 """
1435 return types.Message.de_json(
1436 apihelper.send_venue(
1437 self.token, chat_id, latitude, longitude, title, address, foursquare_id, foursquare_type,
1438 disable_notification, reply_to_message_id, reply_markup, timeout,
1439 allow_sending_without_reply, google_place_id, google_place_type)
1440 )
1441
1442 def send_contact(
1443 self, chat_id: Union[int, str], phone_number: str,
1444 first_name: str, last_name: Optional[str]=None,
1445 vcard: Optional[str]=None,
1446 disable_notification: Optional[bool]=None,
1447 reply_to_message_id: Optional[int]=None,
1448 reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
1449 timeout: Optional[int]=None,
1450 allow_sending_without_reply: Optional[bool]=None) -> types.Message:
1451 return types.Message.de_json(
1452 apihelper.send_contact(
1453 self.token, chat_id, phone_number, first_name, last_name, vcard,
1454 disable_notification, reply_to_message_id, reply_markup, timeout,
1455 allow_sending_without_reply)
1456 )
1457
1458 def send_chat_action(
1459 self, chat_id: Union[int, str], action: str, timeout: Optional[int]=None) -> bool:
1460 """
1461 Use this method when you need to tell the user that something is happening on the bot's side.
1462 The status is set for 5 seconds or less (when a message arrives from your bot, Telegram clients clear
1463 its typing status).
1464 :param chat_id:
1465 :param action: One of the following strings: 'typing', 'upload_photo', 'record_video', 'upload_video',
1466 'record_audio', 'upload_audio', 'upload_document', 'find_location', 'record_video_note',
1467 'upload_video_note'.
1468 :param timeout:
1469 :return: API reply. :type: boolean
1470 """
1471 return apihelper.send_chat_action(self.token, chat_id, action, timeout)
1472
1473 def kick_chat_member(
1474 self, chat_id: Union[int, str], user_id: int,
1475 until_date:Optional[Union[int, datetime]]=None,
1476 revoke_messages: Optional[bool]=None) -> bool:
1477 """
1478 This function is deprecated. Use `ban_chat_member` instead
1479 """
1480 logger.info('kick_chat_member is deprecated. Use ban_chat_member instead.')
1481 return apihelper.ban_chat_member(self.token, chat_id, user_id, until_date, revoke_messages)
1482
1483 def ban_chat_member(
1484 self, chat_id: Union[int, str], user_id: int,
1485 until_date:Optional[Union[int, datetime]]=None,
1486 revoke_messages: Optional[bool]=None) -> bool:
1487 """
1488 Use this method to ban a user in a group, a supergroup or a channel.
1489 In the case of supergroups and channels, the user will not be able to return to the chat on their
1490 own using invite links, etc., unless unbanned first.
1491 Returns True on success.
1492 :param chat_id: Int or string : Unique identifier for the target group or username of the target supergroup
1493 :param user_id: Int : Unique identifier of the target user
1494 :param until_date: Date when the user will be unbanned, unix time. If user is banned for more than 366 days or
1495 less than 30 seconds from the current time they are considered to be banned forever
1496 :param revoke_messages: Bool: Pass True to delete all messages from the chat for the user that is being removed.
1497 If False, the user will be able to see messages in the group that were sent before the user was removed.
1498 Always True for supergroups and channels.
1499 :return: boolean
1500 """
1501 return apihelper.ban_chat_member(self.token, chat_id, user_id, until_date, revoke_messages)
1502
1503 def unban_chat_member(
1504 self, chat_id: Union[int, str], user_id: int,
1505 only_if_banned: Optional[bool]=False) -> bool:
1506 """
1507 Use this method to unban a previously kicked user in a supergroup or channel.
1508 The user will not return to the group or channel automatically, but will be able to join via link, etc.
1509 The bot must be an administrator for this to work. By default, this method guarantees that after the call
1510 the user is not a member of the chat, but will be able to join it. So if the user is a member of the chat
1511 they will also be removed from the chat. If you don't want this, use the parameter only_if_banned.
1512
1513 :param chat_id: Unique identifier for the target group or username of the target supergroup or channel
1514 (in the format @username)
1515 :param user_id: Unique identifier of the target user
1516 :param only_if_banned: Do nothing if the user is not banned
1517 :return: True on success
1518 """
1519 return apihelper.unban_chat_member(self.token, chat_id, user_id, only_if_banned)
1520
1521 def restrict_chat_member(
1522 self, chat_id: Union[int, str], user_id: int,
1523 until_date: Optional[Union[int, datetime]]=None,
1524 can_send_messages: Optional[bool]=None,
1525 can_send_media_messages: Optional[bool]=None,
1526 can_send_polls: Optional[bool]=None,
1527 can_send_other_messages: Optional[bool]=None,
1528 can_add_web_page_previews: Optional[bool]=None,
1529 can_change_info: Optional[bool]=None,
1530 can_invite_users: Optional[bool]=None,
1531 can_pin_messages: Optional[bool]=None) -> bool:
1532 """
1533 Use this method to restrict a user in a supergroup.
1534 The bot must be an administrator in the supergroup for this to work and must have
1535 the appropriate admin rights. Pass True for all boolean parameters to lift restrictions from a user.
1536
1537 :param chat_id: Int or String : Unique identifier for the target group or username of the target supergroup
1538 or channel (in the format @channelusername)
1539 :param user_id: Int : Unique identifier of the target user
1540 :param until_date: Date when restrictions will be lifted for the user, unix time.
1541 If user is restricted for more than 366 days or less than 30 seconds from the current time,
1542 they are considered to be restricted forever
1543 :param can_send_messages: Pass True, if the user can send text messages, contacts, locations and venues
1544 :param can_send_media_messages Pass True, if the user can send audios, documents, photos, videos, video notes
1545 and voice notes, implies can_send_messages
1546 :param can_send_polls: Pass True, if the user is allowed to send polls, implies can_send_messages
1547 :param can_send_other_messages: Pass True, if the user can send animations, games, stickers and
1548 use inline bots, implies can_send_media_messages
1549 :param can_add_web_page_previews: Pass True, if the user may add web page previews to their messages,
1550 implies can_send_media_messages
1551 :param can_change_info: Pass True, if the user is allowed to change the chat title, photo and other settings.
1552 Ignored in public supergroups
1553 :param can_invite_users: Pass True, if the user is allowed to invite new users to the chat,
1554 implies can_invite_users
1555 :param can_pin_messages: Pass True, if the user is allowed to pin messages. Ignored in public supergroups
1556 :return: True on success
1557 """
1558 return apihelper.restrict_chat_member(
1559 self.token, chat_id, user_id, until_date,
1560 can_send_messages, can_send_media_messages,
1561 can_send_polls, can_send_other_messages,
1562 can_add_web_page_previews, can_change_info,
1563 can_invite_users, can_pin_messages)
1564
1565 def promote_chat_member(
1566 self, chat_id: Union[int, str], user_id: int,
1567 can_change_info: Optional[bool]=None,
1568 can_post_messages: Optional[bool]=None,
1569 can_edit_messages: Optional[bool]=None,
1570 can_delete_messages: Optional[bool]=None,
1571 can_invite_users: Optional[bool]=None,
1572 can_restrict_members: Optional[bool]=None,
1573 can_pin_messages: Optional[bool]=None,
1574 can_promote_members: Optional[bool]=None,
1575 is_anonymous: Optional[bool]=None,
1576 can_manage_chat: Optional[bool]=None,
1577 can_manage_voice_chats: Optional[bool]=None) -> bool:
1578 """
1579 Use this method to promote or demote a user in a supergroup or a channel. The bot must be an administrator
1580 in the chat for this to work and must have the appropriate admin rights.
1581 Pass False for all boolean parameters to demote a user.
1582
1583 :param chat_id: Unique identifier for the target chat or username of the target channel (
1584 in the format @channelusername)
1585 :param user_id: Int : Unique identifier of the target user
1586 :param can_change_info: Bool: Pass True, if the administrator can change chat title, photo and other settings
1587 :param can_post_messages: Bool : Pass True, if the administrator can create channel posts, channels only
1588 :param can_edit_messages: Bool : Pass True, if the administrator can edit messages of other users, channels only
1589 :param can_delete_messages: Bool : Pass True, if the administrator can delete messages of other users
1590 :param can_invite_users: Bool : Pass True, if the administrator can invite new users to the chat
1591 :param can_restrict_members: Bool: Pass True, if the administrator can restrict, ban or unban chat members
1592 :param can_pin_messages: Bool: Pass True, if the administrator can pin messages, supergroups only
1593 :param can_promote_members: Bool: Pass True, if the administrator can add new administrators with a subset
1594 of his own privileges or demote administrators that he has promoted, directly or indirectly
1595 (promoted by administrators that were appointed by him)
1596 :param is_anonymous: Bool: Pass True, if the administrator's presence in the chat is hidden
1597 :param can_manage_chat: Bool: Pass True, if the administrator can access the chat event log, chat statistics,
1598 message statistics in channels, see channel members,
1599 see anonymous administrators in supergroups and ignore slow mode.
1600 Implied by any other administrator privilege
1601 :param can_manage_voice_chats: Bool: Pass True, if the administrator can manage voice chats
1602 For now, bots can use this privilege only for passing to other administrators.
1603 :return: True on success.
1604 """
1605 return apihelper.promote_chat_member(
1606 self.token, chat_id, user_id, can_change_info, can_post_messages,
1607 can_edit_messages, can_delete_messages, can_invite_users,
1608 can_restrict_members, can_pin_messages, can_promote_members,
1609 is_anonymous, can_manage_chat, can_manage_voice_chats)
1610
1611 def set_chat_administrator_custom_title(
1612 self, chat_id: Union[int, str], user_id: int, custom_title: str) -> bool:
1613 """
1614 Use this method to set a custom title for an administrator
1615 in a supergroup promoted by the bot.
1616
1617 :param chat_id: Unique identifier for the target chat or username of the target supergroup
1618 (in the format @supergroupusername)
1619 :param user_id: Unique identifier of the target user
1620 :param custom_title: New custom title for the administrator;
1621 0-16 characters, emoji are not allowed
1622 :return: True on success.
1623 """
1624 return apihelper.set_chat_administrator_custom_title(self.token, chat_id, user_id, custom_title)
1625
1626 def set_chat_permissions(
1627 self, chat_id: Union[int, str], permissions: types.ChatPermissions) -> bool:
1628 """
1629 Use this method to set default chat permissions for all members.
1630 The bot must be an administrator in the group or a supergroup for this to work
1631 and must have the can_restrict_members admin rights.
1632
1633 :param chat_id: Unique identifier for the target chat or username of the target supergroup
1634 (in the format @supergroupusername)
1635 :param permissions: New default chat permissions
1636 :return: True on success
1637 """
1638 return apihelper.set_chat_permissions(self.token, chat_id, permissions)
1639
1640 def create_chat_invite_link(
1641 self, chat_id: Union[int, str],
1642 expire_date: Optional[Union[int, datetime]]=None,
1643 member_limit: Optional[int]=None) -> types.ChatInviteLink:
1644 """
1645 Use this method to create an additional invite link for a chat.
1646 The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
1647
1648 :param chat_id: Id: Unique identifier for the target chat or username of the target channel
1649 (in the format @channelusername)
1650 :param expire_date: Point in time (Unix timestamp) when the link will expire
1651 :param member_limit: Maximum number of users that can be members of the chat simultaneously
1652 :return:
1653 """
1654 return types.ChatInviteLink.de_json(
1655 apihelper.create_chat_invite_link(self.token, chat_id, expire_date, member_limit)
1656 )
1657
1658 def edit_chat_invite_link(
1659 self, chat_id: Union[int, str], invite_link: str,
1660 expire_date: Optional[Union[int, datetime]]=None,
1661 member_limit: Optional[int]=None) -> types.ChatInviteLink:
1662 """
1663 Use this method to edit a non-primary invite link created by the bot.
1664 The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
1665
1666 :param invite_link:
1667 :param chat_id: Id: Unique identifier for the target chat or username of the target channel
1668 (in the format @channelusername)
1669 :param invite_link: The invite link to edit
1670 :param expire_date: Point in time (Unix timestamp) when the link will expire
1671 :param member_limit: Maximum number of users that can be members of the chat simultaneously
1672 :return:
1673 """
1674 return types.ChatInviteLink.de_json(
1675 apihelper.edit_chat_invite_link(self.token, chat_id, invite_link, expire_date, member_limit)
1676 )
1677
1678 def revoke_chat_invite_link(
1679 self, chat_id: Union[int, str], invite_link: str) -> types.ChatInviteLink:
1680 """
1681 Use this method to revoke an invite link created by the bot.
1682 Note: If the primary link is revoked, a new link is automatically generated The bot must be an administrator
1683 in the chat for this to work and must have the appropriate admin rights.
1684
1685 :param chat_id: Id: Unique identifier for the target chat or username of the target channel
1686 (in the format @channelusername)
1687 :param invite_link: The invite link to revoke
1688 :return:
1689 """
1690 return types.ChatInviteLink.de_json(
1691 apihelper.revoke_chat_invite_link(self.token, chat_id, invite_link)
1692 )
1693
1694 def export_chat_invite_link(self, chat_id: Union[int, str]) -> str:
1695 """
1696 Use this method to export an invite link to a supergroup or a channel. The bot must be an administrator
1697 in the chat for this to work and must have the appropriate admin rights.
1698
1699 :param chat_id: Id: Unique identifier for the target chat or username of the target channel
1700 (in the format @channelusername)
1701 :return: exported invite link as String on success.
1702 """
1703 return apihelper.export_chat_invite_link(self.token, chat_id)
1704
1705 def set_chat_photo(self, chat_id: Union[int, str], photo: Any) -> bool:
1706 """
1707 Use this method to set a new profile photo for the chat. Photos can't be changed for private chats.
1708 The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
1709 Returns True on success.
1710 Note: In regular groups (non-supergroups), this method will only work if the ‘All Members Are Admins’
1711 setting is off in the target group.
1712 :param chat_id: Int or Str: Unique identifier for the target chat or username of the target channel
1713 (in the format @channelusername)
1714 :param photo: InputFile: New chat photo, uploaded using multipart/form-data
1715 :return:
1716 """
1717 return apihelper.set_chat_photo(self.token, chat_id, photo)
1718
1719 def delete_chat_photo(self, chat_id: Union[int, str]) -> bool:
1720 """
1721 Use this method to delete a chat photo. Photos can't be changed for private chats.
1722 The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
1723 Returns True on success.
1724 Note: In regular groups (non-supergroups), this method will only work if the ‘All Members Are Admins’
1725 setting is off in the target group.
1726 :param chat_id: Int or Str: Unique identifier for the target chat or username of the target channel
1727 (in the format @channelusername)
1728 """
1729 return apihelper.delete_chat_photo(self.token, chat_id)
1730
1731 def get_my_commands(self, scope: Optional[types.BotCommandScope],
1732 language_code: Optional[str]) -> List[types.BotCommand]:
1733 """
1734 Use this method to get the current list of the bot's commands.
1735 Returns List of BotCommand on success.
1736 :param scope: The scope of users for which the commands are relevant.
1737 Defaults to BotCommandScopeDefault.
1738 :param language_code: A two-letter ISO 639-1 language code. If empty,
1739 commands will be applied to all users from the given scope,
1740 for whose language there are no dedicated commands
1741 """
1742 result = apihelper.get_my_commands(self.token, scope, language_code)
1743 return [types.BotCommand.de_json(cmd) for cmd in result]
1744
1745 def set_my_commands(self, commands: List[types.BotCommand],
1746 scope: Optional[types.BotCommandScope]=None,
1747 language_code: Optional[str]=None) -> bool:
1748 """
1749 Use this method to change the list of the bot's commands.
1750 :param commands: List of BotCommand. At most 100 commands can be specified.
1751 :param scope: The scope of users for which the commands are relevant.
1752 Defaults to BotCommandScopeDefault.
1753 :param language_code: A two-letter ISO 639-1 language code. If empty,
1754 commands will be applied to all users from the given scope,
1755 for whose language there are no dedicated commands
1756 :return:
1757 """
1758 return apihelper.set_my_commands(self.token, commands, scope, language_code)
1759
1760 def delete_my_commands(self, scope: Optional[types.BotCommandScope]=None,
1761 language_code: Optional[int]=None) -> bool:
1762 """
1763 Use this method to delete the list of the bot's commands for the given scope and user language.
1764 After deletion, higher level commands will be shown to affected users.
1765 Returns True on success.
1766 :param scope: The scope of users for which the commands are relevant.
1767 Defaults to BotCommandScopeDefault.
1768 :param language_code: A two-letter ISO 639-1 language code. If empty,
1769 commands will be applied to all users from the given scope,
1770 for whose language there are no dedicated commands
1771 """
1772 return apihelper.delete_my_commands(self.token, scope, language_code)
1773
1774 def set_chat_title(self, chat_id: Union[int, str], title: str) -> bool:
1775 """
1776 Use this method to change the title of a chat. Titles can't be changed for private chats.
1777 The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
1778 Returns True on success.
1779 Note: In regular groups (non-supergroups), this method will only work if the ‘All Members Are Admins’
1780 setting is off in the target group.
1781 :param chat_id: Int or Str: Unique identifier for the target chat or username of the target channel
1782 (in the format @channelusername)
1783 :param title: New chat title, 1-255 characters
1784 :return:
1785 """
1786 return apihelper.set_chat_title(self.token, chat_id, title)
1787
1788 def set_chat_description(self, chat_id: Union[int, str], description: Optional[str]=None) -> bool:
1789 """
1790 Use this method to change the description of a supergroup or a channel.
1791 The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
1792
1793 :param chat_id: Int or Str: Unique identifier for the target chat or username of the target channel
1794 (in the format @channelusername)
1795 :param description: Str: New chat description, 0-255 characters
1796 :return: True on success.
1797 """
1798 return apihelper.set_chat_description(self.token, chat_id, description)
1799
1800 def pin_chat_message(
1801 self, chat_id: Union[int, str], message_id: int,
1802 disable_notification: Optional[bool]=False) -> bool:
1803 """
1804 Use this method to pin a message in a supergroup.
1805 The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
1806 Returns True on success.
1807 :param chat_id: Int or Str: Unique identifier for the target chat or username of the target channel
1808 (in the format @channelusername)
1809 :param message_id: Int: Identifier of a message to pin
1810 :param disable_notification: Bool: Pass True, if it is not necessary to send a notification
1811 to all group members about the new pinned message
1812 :return:
1813 """
1814 return apihelper.pin_chat_message(self.token, chat_id, message_id, disable_notification)
1815
1816 def unpin_chat_message(self, chat_id: Union[int, str], message_id: Optional[int]=None) -> bool:
1817 """
1818 Use this method to unpin specific pinned message in a supergroup chat.
1819 The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
1820 Returns True on success.
1821 :param chat_id: Int or Str: Unique identifier for the target chat or username of the target channel
1822 (in the format @channelusername)
1823 :param message_id: Int: Identifier of a message to unpin
1824 :return:
1825 """
1826 return apihelper.unpin_chat_message(self.token, chat_id, message_id)
1827
1828 def unpin_all_chat_messages(self, chat_id: Union[int, str]) -> bool:
1829 """
1830 Use this method to unpin a all pinned messages in a supergroup chat.
1831 The bot must be an administrator in the chat for this to work and must have the appropriate admin rights.
1832 Returns True on success.
1833 :param chat_id: Int or Str: Unique identifier for the target chat or username of the target channel
1834 (in the format @channelusername)
1835 :return:
1836 """
1837 return apihelper.unpin_all_chat_messages(self.token, chat_id)
1838
1839 def edit_message_text(
1840 self, text: str,
1841 chat_id: Optional[Union[int, str]]=None,
1842 message_id: Optional[int]=None,
1843 inline_message_id: Optional[str]=None,
1844 parse_mode: Optional[str]=None,
1845 entities: Optional[List[types.MessageEntity]]=None,
1846 disable_web_page_preview: Optional[bool]=None,
1847 reply_markup: Optional[REPLY_MARKUP_TYPES]=None) -> Union[types.Message, bool]:
1848 """
1849 Use this method to edit text and game messages.
1850 :param text:
1851 :param chat_id:
1852 :param message_id:
1853 :param inline_message_id:
1854 :param parse_mode:
1855 :param entities:
1856 :param disable_web_page_preview:
1857 :param reply_markup:
1858 :return:
1859 """
1860 parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
1861
1862 result = apihelper.edit_message_text(self.token, text, chat_id, message_id, inline_message_id, parse_mode,
1863 entities, disable_web_page_preview, reply_markup)
1864 if type(result) == bool: # if edit inline message return is bool not Message.
1865 return result
1866 return types.Message.de_json(result)
1867
1868 def edit_message_media(
1869 self, media: Any, chat_id: Optional[Union[int, str]]=None,
1870 message_id: Optional[int]=None,
1871 inline_message_id: Optional[str]=None,
1872 reply_markup: Optional[REPLY_MARKUP_TYPES]=None) -> Union[types.Message, bool]:
1873 """
1874 Use this method to edit animation, audio, document, photo, or video messages.
1875 If a message is a part of a message album, then it can be edited only to a photo or a video.
1876 Otherwise, message type can be changed arbitrarily. When inline message is edited, new file can't be uploaded.
1877 Use previously uploaded file via its file_id or specify a URL.
1878 :param media:
1879 :param chat_id:
1880 :param message_id:
1881 :param inline_message_id:
1882 :param reply_markup:
1883 :return:
1884 """
1885 result = apihelper.edit_message_media(self.token, media, chat_id, message_id, inline_message_id, reply_markup)
1886 if type(result) == bool: # if edit inline message return is bool not Message.
1887 return result
1888 return types.Message.de_json(result)
1889
1890 def edit_message_reply_markup(
1891 self, chat_id: Optional[Union[int, str]]=None,
1892 message_id: Optional[int]=None,
1893 inline_message_id: Optional[str]=None,
1894 reply_markup: Optional[REPLY_MARKUP_TYPES]=None) -> Union[types.Message, bool]:
1895 """
1896 Use this method to edit only the reply markup of messages.
1897 :param chat_id:
1898 :param message_id:
1899 :param inline_message_id:
1900 :param reply_markup:
1901 :return:
1902 """
1903 result = apihelper.edit_message_reply_markup(self.token, chat_id, message_id, inline_message_id, reply_markup)
1904 if type(result) == bool:
1905 return result
1906 return types.Message.de_json(result)
1907
1908 def send_game(
1909 self, chat_id: Union[int, str], game_short_name: str,
1910 disable_notification: Optional[bool]=None,
1911 reply_to_message_id: Optional[int]=None,
1912 reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
1913 timeout: Optional[int]=None,
1914 allow_sending_without_reply: Optional[bool]=None) -> types.Message:
1915 """
1916 Used to send the game
1917 :param chat_id:
1918 :param game_short_name:
1919 :param disable_notification:
1920 :param reply_to_message_id:
1921 :param reply_markup:
1922 :param timeout:
1923 :param allow_sending_without_reply:
1924 :return:
1925 """
1926 result = apihelper.send_game(
1927 self.token, chat_id, game_short_name, disable_notification,
1928 reply_to_message_id, reply_markup, timeout,
1929 allow_sending_without_reply)
1930 return types.Message.de_json(result)
1931
1932 def set_game_score(
1933 self, user_id: Union[int, str], score: int,
1934 force: Optional[bool]=None,
1935 chat_id: Optional[Union[int, str]]=None,
1936 message_id: Optional[int]=None,
1937 inline_message_id: Optional[str]=None,
1938 disable_edit_message: Optional[bool]=None) -> Union[types.Message, bool]:
1939 """
1940 Sets the value of points in the game to a specific user
1941 :param user_id:
1942 :param score:
1943 :param force:
1944 :param chat_id:
1945 :param message_id:
1946 :param inline_message_id:
1947 :param disable_edit_message:
1948 :return:
1949 """
1950 result = apihelper.set_game_score(self.token, user_id, score, force, disable_edit_message, chat_id,
1951 message_id, inline_message_id)
1952 if type(result) == bool:
1953 return result
1954 return types.Message.de_json(result)
1955
1956 def get_game_high_scores(
1957 self, user_id: int, chat_id: Optional[Union[int, str]]=None,
1958 message_id: Optional[int]=None,
1959 inline_message_id: Optional[str]=None) -> List[types.GameHighScore]:
1960 """
1961 Gets top points and game play
1962 :param user_id:
1963 :param chat_id:
1964 :param message_id:
1965 :param inline_message_id:
1966 :return:
1967 """
1968 result = apihelper.get_game_high_scores(self.token, user_id, chat_id, message_id, inline_message_id)
1969 return [types.GameHighScore.de_json(r) for r in result]
1970
1971 def send_invoice(
1972 self, chat_id: Union[int, str], title: str, description: str,
1973 invoice_payload: str, provider_token: str, currency: str,
1974 prices: List[types.LabeledPrice], start_parameter: Optional[str]=None,
1975 photo_url: Optional[str]=None, photo_size: Optional[int]=None,
1976 photo_width: Optional[int]=None, photo_height: Optional[int]=None,
1977 need_name: Optional[bool]=None, need_phone_number: Optional[bool]=None,
1978 need_email: Optional[bool]=None, need_shipping_address: Optional[bool]=None,
1979 send_phone_number_to_provider: Optional[bool]=None,
1980 send_email_to_provider: Optional[bool]=None,
1981 is_flexible: Optional[bool]=None,
1982 disable_notification: Optional[bool]=None,
1983 reply_to_message_id: Optional[int]=None,
1984 reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
1985 provider_data: Optional[str]=None,
1986 timeout: Optional[int]=None,
1987 allow_sending_without_reply: Optional[bool]=None,
1988 max_tip_amount: Optional[int] = None,
1989 suggested_tip_amounts: Optional[List[int]]=None) -> types.Message:
1990 """
1991 Sends invoice
1992 :param chat_id: Unique identifier for the target private chat
1993 :param title: Product name
1994 :param description: Product description
1995 :param invoice_payload: Bot-defined invoice payload, 1-128 bytes. This will not be displayed to the user,
1996 use for your internal processes.
1997 :param provider_token: Payments provider token, obtained via @Botfather
1998 :param currency: Three-letter ISO 4217 currency code,
1999 see https://core.telegram.org/bots/payments#supported-currencies
2000 :param prices: Price breakdown, a list of components
2001 (e.g. product price, tax, discount, delivery cost, delivery tax, bonus, etc.)
2002 :param start_parameter: Unique deep-linking parameter that can be used to generate this invoice
2003 when used as a start parameter
2004 :param photo_url: URL of the product photo for the invoice. Can be a photo of the goods
2005 or a marketing image for a service. People like it better when they see what they are paying for.
2006 :param photo_size: Photo size
2007 :param photo_width: Photo width
2008 :param photo_height: Photo height
2009 :param need_name: Pass True, if you require the user's full name to complete the order
2010 :param need_phone_number: Pass True, if you require the user's phone number to complete the order
2011 :param need_email: Pass True, if you require the user's email to complete the order
2012 :param need_shipping_address: Pass True, if you require the user's shipping address to complete the order
2013 :param is_flexible: Pass True, if the final price depends on the shipping method
2014 :param send_phone_number_to_provider: Pass True, if user's phone number should be sent to provider
2015 :param send_email_to_provider: Pass True, if user's email address should be sent to provider
2016 :param disable_notification: Sends the message silently. Users will receive a notification with no sound.
2017 :param reply_to_message_id: If the message is a reply, ID of the original message
2018 :param reply_markup: A JSON-serialized object for an inline keyboard. If empty,
2019 one 'Pay total price' button will be shown. If not empty, the first button must be a Pay button
2020 :param provider_data: A JSON-serialized data about the invoice, which will be shared with the payment provider.
2021 A detailed description of required fields should be provided by the payment provider.
2022 :param timeout:
2023 :param allow_sending_without_reply:
2024 :param max_tip_amount: The maximum accepted amount for tips in the smallest units of the currency
2025 :param suggested_tip_amounts: A JSON-serialized array of suggested amounts of tips in the smallest
2026 units of the currency. At most 4 suggested tip amounts can be specified. The suggested tip
2027 amounts must be positive, passed in a strictly increased order and must not exceed max_tip_amount.
2028 :return:
2029 """
2030 result = apihelper.send_invoice(
2031 self.token, chat_id, title, description, invoice_payload, provider_token,
2032 currency, prices, start_parameter, photo_url, photo_size, photo_width,
2033 photo_height, need_name, need_phone_number, need_email, need_shipping_address,
2034 send_phone_number_to_provider, send_email_to_provider, is_flexible, disable_notification,
2035 reply_to_message_id, reply_markup, provider_data, timeout, allow_sending_without_reply,
2036 max_tip_amount, suggested_tip_amounts)
2037 return types.Message.de_json(result)
2038
2039 # noinspection PyShadowingBuiltins
2040 def send_poll(
2041 self, chat_id: Union[int, str], question: str, options: List[str],
2042 is_anonymous: Optional[bool]=None, type: Optional[str]=None,
2043 allows_multiple_answers: Optional[bool]=None,
2044 correct_option_id: Optional[int]=None,
2045 explanation: Optional[str]=None,
2046 explanation_parse_mode: Optional[str]=None,
2047 open_period: Optional[int]=None,
2048 close_date: Optional[Union[int, datetime]]=None,
2049 is_closed: Optional[bool]=None,
2050 disable_notification: Optional[bool]=False,
2051 reply_to_message_id: Optional[int]=None,
2052 reply_markup: Optional[REPLY_MARKUP_TYPES]=None,
2053 allow_sending_without_reply: Optional[bool]=None,
2054 timeout: Optional[int]=None,
2055 explanation_entities: Optional[List[types.MessageEntity]]=None) -> types.Message:
2056 """
2057 Send polls
2058 :param chat_id:
2059 :param question:
2060 :param options: array of str with answers
2061 :param is_anonymous:
2062 :param type:
2063 :param allows_multiple_answers:
2064 :param correct_option_id:
2065 :param explanation:
2066 :param explanation_parse_mode:
2067 :param open_period:
2068 :param close_date:
2069 :param is_closed:
2070 :param disable_notification:
2071 :param reply_to_message_id:
2072 :param allow_sending_without_reply:
2073 :param reply_markup:
2074 :param timeout:
2075 :param explanation_entities:
2076 :return:
2077 """
2078
2079 if isinstance(question, types.Poll):
2080 raise RuntimeError("The send_poll signature was changed, please see send_poll function details.")
2081
2082 return types.Message.de_json(
2083 apihelper.send_poll(
2084 self.token, chat_id,
2085 question, options,
2086 is_anonymous, type, allows_multiple_answers, correct_option_id,
2087 explanation, explanation_parse_mode, open_period, close_date, is_closed,
2088 disable_notification, reply_to_message_id, allow_sending_without_reply,
2089 reply_markup, timeout, explanation_entities))
2090
2091 def stop_poll(
2092 self, chat_id: Union[int, str], message_id: int,
2093 reply_markup: Optional[REPLY_MARKUP_TYPES]=None) -> types.Poll:
2094 """
2095 Stops poll
2096 :param chat_id:
2097 :param message_id:
2098 :param reply_markup:
2099 :return:
2100 """
2101 return types.Poll.de_json(apihelper.stop_poll(self.token, chat_id, message_id, reply_markup))
2102
2103 def answer_shipping_query(
2104 self, shipping_query_id: str, ok: bool,
2105 shipping_options: Optional[List[types.ShippingOption]]=None,
2106 error_message: Optional[str]=None) -> bool:
2107 """
2108 Asks for an answer to a shipping question
2109 :param shipping_query_id:
2110 :param ok:
2111 :param shipping_options:
2112 :param error_message:
2113 :return:
2114 """
2115 return apihelper.answer_shipping_query(self.token, shipping_query_id, ok, shipping_options, error_message)
2116
2117 def answer_pre_checkout_query(
2118 self, pre_checkout_query_id: int, ok: bool,
2119 error_message: Optional[str]=None) -> bool:
2120 """
2121 Response to a request for pre-inspection
2122 :param pre_checkout_query_id:
2123 :param ok:
2124 :param error_message:
2125 :return:
2126 """
2127 return apihelper.answer_pre_checkout_query(self.token, pre_checkout_query_id, ok, error_message)
2128
2129 def edit_message_caption(
2130 self, caption: str, chat_id: Optional[Union[int, str]]=None,
2131 message_id: Optional[int]=None,
2132 inline_message_id: Optional[str]=None,
2133 parse_mode: Optional[str]=None,
2134 caption_entities: Optional[List[types.MessageEntity]]=None,
2135 reply_markup: Optional[REPLY_MARKUP_TYPES]=None) -> Union[types.Message, bool]:
2136 """
2137 Use this method to edit captions of messages
2138 :param caption:
2139 :param chat_id:
2140 :param message_id:
2141 :param inline_message_id:
2142 :param parse_mode:
2143 :param caption_entities:
2144 :param reply_markup:
2145 :return:
2146 """
2147 parse_mode = self.parse_mode if (parse_mode is None) else parse_mode
2148
2149 result = apihelper.edit_message_caption(self.token, caption, chat_id, message_id, inline_message_id,
2150 parse_mode, caption_entities, reply_markup)
2151 if type(result) == bool:
2152 return result
2153 return types.Message.de_json(result)
2154
2155 def reply_to(self, message: types.Message, text: str, **kwargs) -> types.Message:
2156 """
2157 Convenience function for `send_message(message.chat.id, text, reply_to_message_id=message.message_id, **kwargs)`
2158 :param message:
2159 :param text:
2160 :param kwargs:
2161 :return:
2162 """
2163 return self.send_message(message.chat.id, text, reply_to_message_id=message.message_id, **kwargs)
2164
2165 def answer_inline_query(
2166 self, inline_query_id: str,
2167 results: List[Any],
2168 cache_time: Optional[int]=None,
2169 is_personal: Optional[bool]=None,
2170 next_offset: Optional[str]=None,
2171 switch_pm_text: Optional[str]=None,
2172 switch_pm_parameter: Optional[str]=None) -> bool:
2173 """
2174 Use this method to send answers to an inline query. On success, True is returned.
2175 No more than 50 results per query are allowed.
2176 :param inline_query_id: Unique identifier for the answered query
2177 :param results: Array of results for the inline query
2178 :param cache_time: The maximum amount of time in seconds that the result of the inline query
2179 may be cached on the server.
2180 :param is_personal: Pass True, if results may be cached on the server side only for
2181 the user that sent the query.
2182 :param next_offset: Pass the offset that a client should send in the next query with the same text
2183 to receive more results.
2184 :param switch_pm_parameter: If passed, clients will display a button with specified text that switches the user
2185 to a private chat with the bot and sends the bot a start message with the parameter switch_pm_parameter
2186 :param switch_pm_text: Parameter for the start message sent to the bot when user presses the switch button
2187 :return: True means success.
2188 """
2189 return apihelper.answer_inline_query(self.token, inline_query_id, results, cache_time, is_personal, next_offset,
2190 switch_pm_text, switch_pm_parameter)
2191
2192 def answer_callback_query(
2193 self, callback_query_id: int,
2194 text: Optional[str]=None, show_alert: Optional[bool]=None,
2195 url: Optional[str]=None, cache_time: Optional[int]=None) -> bool:
2196 """
2197 Use this method to send answers to callback queries sent from inline keyboards. The answer will be displayed to
2198 the user as a notification at the top of the chat screen or as an alert.
2199 :param callback_query_id:
2200 :param text:
2201 :param show_alert:
2202 :param url:
2203 :param cache_time:
2204 :return:
2205 """
2206 return apihelper.answer_callback_query(self.token, callback_query_id, text, show_alert, url, cache_time)
2207
2208 def set_sticker_set_thumb(
2209 self, name: str, user_id: int, thumb: Union[Any, str]=None):
2210 """
2211 Use this method to set the thumbnail of a sticker set.
2212 Animated thumbnails can be set for animated sticker sets only. Returns True on success.
2213 """
2214 return apihelper.set_sticker_set_thumb(self.token, name, user_id, thumb)
2215
2216 def get_sticker_set(self, name: str) -> types.StickerSet:
2217 """
2218 Use this method to get a sticker set. On success, a StickerSet object is returned.
2219 :param name:
2220 :return:
2221 """
2222 result = apihelper.get_sticker_set(self.token, name)
2223 return types.StickerSet.de_json(result)
2224
2225 def upload_sticker_file(self, user_id: int, png_sticker: Union[Any, str]) -> types.File:
2226 """
2227 Use this method to upload a .png file with a sticker for later use in createNewStickerSet and addStickerToSet
2228 methods (can be used multiple times). Returns the uploaded File on success.
2229 :param user_id:
2230 :param png_sticker:
2231 :return:
2232 """
2233 result = apihelper.upload_sticker_file(self.token, user_id, png_sticker)
2234 return types.File.de_json(result)
2235
2236 def create_new_sticker_set(
2237 self, user_id: int, name: str, title: str,
2238 emojis: str,
2239 png_sticker: Union[Any, str],
2240 tgs_sticker: Union[Any, str],
2241 contains_masks: Optional[bool]=None,
2242 mask_position: Optional[types.MaskPosition]=None) -> bool:
2243 """
2244 Use this method to create new sticker set owned by a user.
2245 The bot will be able to edit the created sticker set.
2246 Returns True on success.
2247 :param user_id:
2248 :param name:
2249 :param title:
2250 :param emojis:
2251 :param png_sticker:
2252 :param tgs_sticker:
2253 :param contains_masks:
2254 :param mask_position:
2255 :return:
2256 """
2257 return apihelper.create_new_sticker_set(
2258 self.token, user_id, name, title, emojis, png_sticker, tgs_sticker,
2259 contains_masks, mask_position)
2260
2261
2262 def add_sticker_to_set(
2263 self, user_id: int, name: str, emojis: str,
2264 png_sticker: Optional[Union[Any, str]]=None,
2265 tgs_sticker: Optional[Union[Any, str]]=None,
2266 mask_position: Optional[types.MaskPosition]=None) -> bool:
2267 """
2268 Use this method to add a new sticker to a set created by the bot.
2269 It's required to pass `png_sticker` or `tgs_sticker`.
2270 Returns True on success.
2271 :param user_id:
2272 :param name:
2273 :param emojis:
2274 :param png_sticker: Required if `tgs_sticker` is None
2275 :param tgs_sticker: Required if `png_sticker` is None
2276 :param mask_position:
2277 :return:
2278 """
2279 return apihelper.add_sticker_to_set(
2280 self.token, user_id, name, emojis, png_sticker, tgs_sticker, mask_position)
2281
2282
2283 def set_sticker_position_in_set(self, sticker: str, position: int) -> bool:
2284 """
2285 Use this method to move a sticker in a set created by the bot to a specific position . Returns True on success.
2286 :param sticker:
2287 :param position:
2288 :return:
2289 """
2290 return apihelper.set_sticker_position_in_set(self.token, sticker, position)
2291
2292 def delete_sticker_from_set(self, sticker: str) -> bool:
2293 """
2294 Use this method to delete a sticker from a set created by the bot. Returns True on success.
2295 :param sticker:
2296 :return:
2297 """
2298 return apihelper.delete_sticker_from_set(self.token, sticker)
2299
2300 def register_for_reply(
2301 self, message: types.Message, callback: Callable, *args, **kwargs) -> None:
2302 """
2303 Registers a callback function to be notified when a reply to `message` arrives.
2304
2305 Warning: In case `callback` as lambda function, saving reply handlers will not work.
2306
2307 :param message: The message for which we are awaiting a reply.
2308 :param callback: The callback function to be called when a reply arrives. Must accept one `message`
2309 parameter, which will contain the replied message.
2310 """
2311 message_id = message.message_id
2312 self.register_for_reply_by_message_id(message_id, callback, *args, **kwargs)
2313
2314 def register_for_reply_by_message_id(
2315 self, message_id: int, callback: Callable, *args, **kwargs) -> None:
2316 """
2317 Registers a callback function to be notified when a reply to `message` arrives.
2318
2319 Warning: In case `callback` as lambda function, saving reply handlers will not work.
2320
2321 :param message_id: The id of the message for which we are awaiting a reply.
2322 :param callback: The callback function to be called when a reply arrives. Must accept one `message`
2323 parameter, which will contain the replied message.
2324 """
2325 self.reply_backend.register_handler(message_id, Handler(callback, *args, **kwargs))
2326
2327 def _notify_reply_handlers(self, new_messages) -> None:
2328 """
2329 Notify handlers of the answers
2330 :param new_messages:
2331 :return:
2332 """
2333 for message in new_messages:
2334 if hasattr(message, "reply_to_message") and message.reply_to_message is not None:
2335 handlers = self.reply_backend.get_handlers(message.reply_to_message.message_id)
2336 if handlers:
2337 for handler in handlers:
2338 self._exec_task(handler["callback"], message, *handler["args"], **handler["kwargs"])
2339
2340 def register_next_step_handler(
2341 self, message: types.Message, callback: Callable, *args, **kwargs) -> None:
2342 """
2343 Registers a callback function to be notified when new message arrives after `message`.
2344
2345 Warning: In case `callback` as lambda function, saving next step handlers will not work.
2346
2347 :param message: The message for which we want to handle new message in the same chat.
2348 :param callback: The callback function which next new message arrives.
2349 :param args: Args to pass in callback func
2350 :param kwargs: Args to pass in callback func
2351 """
2352 chat_id = message.chat.id
2353 self.register_next_step_handler_by_chat_id(chat_id, callback, *args, **kwargs)
2354
2355 def register_next_step_handler_by_chat_id(
2356 self, chat_id: Union[int, str], callback: Callable, *args, **kwargs) -> None:
2357 """
2358 Registers a callback function to be notified when new message arrives after `message`.
2359
2360 Warning: In case `callback` as lambda function, saving next step handlers will not work.
2361
2362 :param chat_id: The chat for which we want to handle new message.
2363 :param callback: The callback function which next new message arrives.
2364 :param args: Args to pass in callback func
2365 :param kwargs: Args to pass in callback func
2366 """
2367 self.next_step_backend.register_handler(chat_id, Handler(callback, *args, **kwargs))
2368
2369 def clear_step_handler(self, message: types.Message) -> None:
2370 """
2371 Clears all callback functions registered by register_next_step_handler().
2372
2373 :param message: The message for which we want to handle new message after that in same chat.
2374 """
2375 chat_id = message.chat.id
2376 self.clear_step_handler_by_chat_id(chat_id)
2377
2378 def clear_step_handler_by_chat_id(self, chat_id: Union[int, str]) -> None:
2379 """
2380 Clears all callback functions registered by register_next_step_handler().
2381
2382 :param chat_id: The chat for which we want to clear next step handlers
2383 """
2384 self.next_step_backend.clear_handlers(chat_id)
2385
2386 def clear_reply_handlers(self, message: types.Message) -> None:
2387 """
2388 Clears all callback functions registered by register_for_reply() and register_for_reply_by_message_id().
2389
2390 :param message: The message for which we want to clear reply handlers
2391 """
2392 message_id = message.message_id
2393 self.clear_reply_handlers_by_message_id(message_id)
2394
2395 def clear_reply_handlers_by_message_id(self, message_id: int) -> None:
2396 """
2397 Clears all callback functions registered by register_for_reply() and register_for_reply_by_message_id().
2398
2399 :param message_id: The message id for which we want to clear reply handlers
2400 """
2401 self.reply_backend.clear_handlers(message_id)
2402
2403 def _notify_next_handlers(self, new_messages):
2404 """
2405 Description: TBD
2406 :param new_messages:
2407 :return:
2408 """
2409 for i, message in enumerate(new_messages):
2410 need_pop = False
2411 handlers = self.next_step_backend.get_handlers(message.chat.id)
2412 if handlers:
2413 for handler in handlers:
2414 need_pop = True
2415 self._exec_task(handler["callback"], message, *handler["args"], **handler["kwargs"])
2416 if need_pop:
2417 new_messages.pop(i) # removing message that was detected with next_step_handler
2418
2419 @staticmethod
2420 def _build_handler_dict(handler, **filters):
2421 """
2422 Builds a dictionary for a handler
2423 :param handler:
2424 :param filters:
2425 :return:
2426 """
2427 return {
2428 'function': handler,
2429 'filters': filters
2430 }
2431
2432 def middleware_handler(self, update_types=None):
2433 """
2434 Middleware handler decorator.
2435
2436 This decorator can be used to decorate functions that must be handled as middlewares before entering any other
2437 message handlers
2438 But, be careful and check type of the update inside the handler if more than one update_type is given
2439
2440 Example:
2441
2442 bot = TeleBot('TOKEN')
2443
2444 # Print post message text before entering to any post_channel handlers
2445 @bot.middleware_handler(update_types=['channel_post', 'edited_channel_post'])
2446 def print_channel_post_text(bot_instance, channel_post):
2447 print(channel_post.text)
2448
2449 # Print update id before entering to any handlers
2450 @bot.middleware_handler()
2451 def print_channel_post_text(bot_instance, update):
2452 print(update.update_id)
2453
2454 :param update_types: Optional list of update types that can be passed into the middleware handler.
2455
2456 """
2457
2458 def decorator(handler):
2459 self.add_middleware_handler(handler, update_types)
2460 return handler
2461
2462 return decorator
2463
2464 def add_middleware_handler(self, handler, update_types=None):
2465 """
2466 Add middleware handler
2467 :param handler:
2468 :param update_types:
2469 :return:
2470 """
2471 if not apihelper.ENABLE_MIDDLEWARE:
2472 raise RuntimeError("Middleware is not enabled. Use apihelper.ENABLE_MIDDLEWARE.")
2473
2474 if update_types:
2475 for update_type in update_types:
2476 self.typed_middleware_handlers[update_type].append(handler)
2477 else:
2478 self.default_middleware_handlers.append(handler)
2479
2480 def message_handler(self, commands=None, regexp=None, func=None, content_types=None, chat_types=None, **kwargs):
2481 """
2482 Message handler decorator.
2483 This decorator can be used to decorate functions that must handle certain types of messages.
2484 All message handlers are tested in the order they were added.
2485
2486 Example:
2487
2488 bot = TeleBot('TOKEN')
2489
2490 # Handles all messages which text matches regexp.
2491 @bot.message_handler(regexp='someregexp')
2492 def command_help(message):
2493 bot.send_message(message.chat.id, 'Did someone call for help?')
2494
2495 # Handles messages in private chat
2496 @bot.message_handler(chat_types=['private']) # You can add more chat types
2497 def command_help(message):
2498 bot.send_message(message.chat.id, 'Private chat detected, sir!')
2499
2500 # Handle all sent documents of type 'text/plain'.
2501 @bot.message_handler(func=lambda message: message.document.mime_type == 'text/plain',
2502 content_types=['document'])
2503 def command_handle_document(message):
2504 bot.send_message(message.chat.id, 'Document received, sir!')
2505
2506 # Handle all other messages.
2507 @bot.message_handler(func=lambda message: True, content_types=['audio', 'photo', 'voice', 'video', 'document',
2508 'text', 'location', 'contact', 'sticker'])
2509 def default_command(message):
2510 bot.send_message(message.chat.id, "This is the default command handler.")
2511
2512 :param commands: Optional list of strings (commands to handle).
2513 :param regexp: Optional regular expression.
2514 :param func: Optional lambda function. The lambda receives the message to test as the first parameter.
2515 It must return True if the command should handle the message.
2516 :param content_types: Supported message content types. Must be a list. Defaults to ['text'].
2517 :param chat_types: list of chat types
2518 """
2519
2520 if content_types is None:
2521 content_types = ["text"]
2522
2523 def decorator(handler):
2524 handler_dict = self._build_handler_dict(handler,
2525 content_types=content_types,
2526 commands=commands,
2527 regexp=regexp,
2528 chat_types=chat_types,
2529 func=func,
2530 **kwargs)
2531 self.add_message_handler(handler_dict)
2532 return handler
2533
2534 return decorator
2535
2536 def add_message_handler(self, handler_dict):
2537 """
2538 Adds a message handler
2539 :param handler_dict:
2540 :return:
2541 """
2542 self.message_handlers.append(handler_dict)
2543
2544 def register_message_handler(self, callback, content_types=None, commands=None, regexp=None, func=None, chat_types=None, **kwargs):
2545 """
2546 Registers message handler.
2547 :param callback: function to be called
2548 :param content_types: list of content_types
2549 :param commands: list of commands
2550 :param regexp:
2551 :param func:
2552 :param chat_types: True for private chat
2553 :return: decorated function
2554 """
2555 handler_dict = self._build_handler_dict(callback,
2556 content_types=content_types,
2557 commands=commands,
2558 regexp=regexp,
2559 func=func,
2560 chat_types=chat_types,
2561 **kwargs)
2562 self.add_message_handler(handler_dict)
2563 def edited_message_handler(self, commands=None, regexp=None, func=None, content_types=None, chat_types=None, **kwargs):
2564 """
2565 Edit message handler decorator
2566 :param commands:
2567 :param regexp:
2568 :param func:
2569 :param content_types:
2570 :param chat_types: list of chat types
2571 :param kwargs:
2572 :return:
2573 """
2574
2575 if content_types is None:
2576 content_types = ["text"]
2577
2578 def decorator(handler):
2579 handler_dict = self._build_handler_dict(handler,
2580 commands=commands,
2581 regexp=regexp,
2582 func=func,
2583 content_types=content_types,
2584 chat_types=chat_types,
2585 **kwargs)
2586 self.add_edited_message_handler(handler_dict)
2587 return handler
2588
2589 return decorator
2590
2591 def add_edited_message_handler(self, handler_dict):
2592 """
2593 Adds the edit message handler
2594 :param handler_dict:
2595 :return:
2596 """
2597 self.edited_message_handlers.append(handler_dict)
2598
2599 def register_edited_message_handler(self, callback, content_types=None, commands=None, regexp=None, func=None, chat_types=None, **kwargs):
2600 """
2601 Registers edited message handler.
2602 :param callback: function to be called
2603 :param content_types: list of content_types
2604 :param commands: list of commands
2605 :param regexp:
2606 :param func:
2607 :param chat_types: True for private chat
2608 :return: decorated function
2609 """
2610 handler_dict = self._build_handler_dict(callback,
2611 content_types=content_types,
2612 commands=commands,
2613 regexp=regexp,
2614 func=func,
2615 chat_types=chat_types,
2616 **kwargs)
2617 self.add_edited_message_handler(handler_dict)
2618 def channel_post_handler(self, commands=None, regexp=None, func=None, content_types=None, **kwargs):
2619 """
2620 Channel post handler decorator
2621 :param commands:
2622 :param regexp:
2623 :param func:
2624 :param content_types:
2625 :param kwargs:
2626 :return:
2627 """
2628
2629 if content_types is None:
2630 content_types = ["text"]
2631
2632 def decorator(handler):
2633 handler_dict = self._build_handler_dict(handler,
2634 commands=commands,
2635 regexp=regexp,
2636 func=func,
2637 content_types=content_types,
2638 **kwargs)
2639 self.add_channel_post_handler(handler_dict)
2640 return handler
2641
2642 return decorator
2643
2644 def add_channel_post_handler(self, handler_dict):
2645 """
2646 Adds channel post handler
2647 :param handler_dict:
2648 :return:
2649 """
2650 self.channel_post_handlers.append(handler_dict)
2651
2652 def register_channel_post_handler(self, callback, content_types=None, commands=None, regexp=None, func=None, **kwargs):
2653 """
2654 Registers channel post message handler.
2655 :param callback: function to be called
2656 :param content_types: list of content_types
2657 :param commands: list of commands
2658 :param regexp:
2659 :param func:
2660 :return: decorated function
2661 """
2662 handler_dict = self._build_handler_dict(callback,
2663 content_types=content_types,
2664 commands=commands,
2665 regexp=regexp,
2666 func=func,
2667 **kwargs)
2668 self.add_channel_post_handler(handler_dict)
2669 def edited_channel_post_handler(self, commands=None, regexp=None, func=None, content_types=None, **kwargs):
2670 """
2671 Edit channel post handler decorator
2672 :param commands:
2673 :param regexp:
2674 :param func:
2675 :param content_types:
2676 :param kwargs:
2677 :return:
2678 """
2679
2680 if content_types is None:
2681 content_types = ["text"]
2682
2683 def decorator(handler):
2684 handler_dict = self._build_handler_dict(handler,
2685 commands=commands,
2686 regexp=regexp,
2687 func=func,
2688 content_types=content_types,
2689 **kwargs)
2690 self.add_edited_channel_post_handler(handler_dict)
2691 return handler
2692
2693 return decorator
2694
2695 def add_edited_channel_post_handler(self, handler_dict):
2696 """
2697 Adds the edit channel post handler
2698 :param handler_dict:
2699 :return:
2700 """
2701 self.edited_channel_post_handlers.append(handler_dict)
2702
2703 def register_edited_channel_post_handler(self, callback, content_types=None, commands=None, regexp=None, func=None, **kwargs):
2704 """
2705 Registers edited channel post message handler.
2706 :param callback: function to be called
2707 :param content_types: list of content_types
2708 :param commands: list of commands
2709 :param regexp:
2710 :param func:
2711 :return: decorated function
2712 """
2713 handler_dict = self._build_handler_dict(callback,
2714 content_types=content_types,
2715 commands=commands,
2716 regexp=regexp,
2717 func=func,
2718 **kwargs)
2719 self.add_edited_channel_post_handler(handler_dict)
2720
2721 def inline_handler(self, func, **kwargs):
2722 """
2723 Inline call handler decorator
2724 :param func:
2725 :param kwargs:
2726 :return:
2727 """
2728
2729 def decorator(handler):
2730 handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
2731 self.add_inline_handler(handler_dict)
2732 return handler
2733
2734 return decorator
2735
2736 def add_inline_handler(self, handler_dict):
2737 """
2738 Adds inline call handler
2739 :param handler_dict:
2740 :return:
2741 """
2742 self.inline_handlers.append(handler_dict)
2743
2744 def register_inline_handler(self, callback, func, **kwargs):
2745 """
2746 Registers inline handler.
2747 :param callback: function to be called
2748 :param func:
2749 :return: decorated function
2750 """
2751 handler_dict = self._build_handler_dict(callback, func=func, **kwargs)
2752 self.add_inline_handler(handler_dict)
2753
2754 def chosen_inline_handler(self, func, **kwargs):
2755 """
2756 Description: TBD
2757 :param func:
2758 :param kwargs:
2759 :return:
2760 """
2761
2762 def decorator(handler):
2763 handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
2764 self.add_chosen_inline_handler(handler_dict)
2765 return handler
2766
2767 return decorator
2768
2769 def add_chosen_inline_handler(self, handler_dict):
2770 """
2771 Description: TBD
2772 :param handler_dict:
2773 :return:
2774 """
2775 self.chosen_inline_handlers.append(handler_dict)
2776
2777 def register_chosen_inline_handler(self, callback, func, **kwargs):
2778 """
2779 Registers chosen inline handler.
2780 :param callback: function to be called
2781 :param func:
2782 :return: decorated function
2783 """
2784 handler_dict = self._build_handler_dict(callback, func=func, **kwargs)
2785 self.add_chosen_inline_handler(handler_dict)
2786
2787
2788 def callback_query_handler(self, func, **kwargs):
2789 """
2790 Callback request handler decorator
2791 :param func:
2792 :param kwargs:
2793 :return:
2794 """
2795
2796 def decorator(handler):
2797 handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
2798 self.add_callback_query_handler(handler_dict)
2799 return handler
2800
2801 return decorator
2802
2803 def add_callback_query_handler(self, handler_dict):
2804 """
2805 Adds a callback request handler
2806 :param handler_dict:
2807 :return:
2808 """
2809 self.callback_query_handlers.append(handler_dict)
2810
2811 def register_callback_query_handler(self, callback, func, **kwargs):
2812 """
2813 Registers callback query handler..
2814 :param callback: function to be called
2815 :param func:
2816 :return: decorated function
2817 """
2818 handler_dict = self._build_handler_dict(callback, func=func, **kwargs)
2819 self.add_callback_query_handler(handler_dict)
2820
2821 def shipping_query_handler(self, func, **kwargs):
2822 """
2823 Shipping request handler
2824 :param func:
2825 :param kwargs:
2826 :return:
2827 """
2828
2829 def decorator(handler):
2830 handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
2831 self.add_shipping_query_handler(handler_dict)
2832 return handler
2833
2834 return decorator
2835
2836 def add_shipping_query_handler(self, handler_dict):
2837 """
2838 Adds a shipping request handler
2839 :param handler_dict:
2840 :return:
2841 """
2842 self.shipping_query_handlers.append(handler_dict)
2843
2844 def register_shipping_query_handler(self, callback, func, **kwargs):
2845 """
2846 Registers shipping query handler.
2847 :param callback: function to be called
2848 :param func:
2849 :return: decorated function
2850 """
2851 handler_dict = self._build_handler_dict(callback, func=func, **kwargs)
2852 self.add_shipping_query_handler(handler_dict)
2853
2854 def pre_checkout_query_handler(self, func, **kwargs):
2855 """
2856 Pre-checkout request handler
2857 :param func:
2858 :param kwargs:
2859 :return:
2860 """
2861
2862 def decorator(handler):
2863 handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
2864 self.add_pre_checkout_query_handler(handler_dict)
2865 return handler
2866
2867 return decorator
2868
2869 def add_pre_checkout_query_handler(self, handler_dict):
2870 """
2871 Adds a pre-checkout request handler
2872 :param handler_dict:
2873 :return:
2874 """
2875 self.pre_checkout_query_handlers.append(handler_dict)
2876
2877 def register_pre_checkout_query_handler(self, callback, func, **kwargs):
2878 """
2879 Registers pre-checkout request handler.
2880 :param callback: function to be called
2881 :param func:
2882 :return: decorated function
2883 """
2884 handler_dict = self._build_handler_dict(callback, func=func, **kwargs)
2885 self.add_pre_checkout_query_handler(handler_dict)
2886
2887 def poll_handler(self, func, **kwargs):
2888 """
2889 Poll request handler
2890 :param func:
2891 :param kwargs:
2892 :return:
2893 """
2894
2895 def decorator(handler):
2896 handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
2897 self.add_poll_handler(handler_dict)
2898 return handler
2899
2900 return decorator
2901
2902 def add_poll_handler(self, handler_dict):
2903 """
2904 Adds a poll request handler
2905 :param handler_dict:
2906 :return:
2907 """
2908 self.poll_handlers.append(handler_dict)
2909
2910 def register_poll_handler(self, callback, func, **kwargs):
2911 """
2912 Registers poll handler.
2913 :param callback: function to be called
2914 :param func:
2915 :return: decorated function
2916 """
2917 handler_dict = self._build_handler_dict(callback,
2918 func=func,
2919 **kwargs)
2920 self.add_poll_handler(handler_dict)
2921
2922 def poll_answer_handler(self, func=None, **kwargs):
2923 """
2924 Poll_answer request handler
2925 :param func:
2926 :param kwargs:
2927 :return:
2928 """
2929
2930 def decorator(handler):
2931 handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
2932 self.add_poll_answer_handler(handler_dict)
2933 return handler
2934
2935 return decorator
2936
2937 def add_poll_answer_handler(self, handler_dict):
2938 """
2939 Adds a poll_answer request handler
2940 :param handler_dict:
2941 :return:
2942 """
2943 self.poll_answer_handlers.append(handler_dict)
2944
2945 def register_poll_answer_handler(self, callback, func, **kwargs):
2946 """
2947 Registers poll answer handler.
2948 :param callback: function to be called
2949 :param func:
2950 :return: decorated function
2951 """
2952 handler_dict = self._build_handler_dict(callback,
2953 func=func,
2954 **kwargs)
2955 self.add_poll_answer_handler(handler_dict)
2956
2957 def my_chat_member_handler(self, func=None, **kwargs):
2958 """
2959 my_chat_member handler
2960 :param func:
2961 :param kwargs:
2962 :return:
2963 """
2964
2965 def decorator(handler):
2966 handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
2967 self.add_my_chat_member_handler(handler_dict)
2968 return handler
2969
2970 return decorator
2971
2972 def add_my_chat_member_handler(self, handler_dict):
2973 """
2974 Adds a my_chat_member handler
2975 :param handler_dict:
2976 :return:
2977 """
2978 self.my_chat_member_handlers.append(handler_dict)
2979
2980 def register_my_chat_member_handler(self, callback, func=None, **kwargs):
2981 """
2982 Registers my chat member handler.
2983 :param callback: function to be called
2984 :param func:
2985 :return: decorated function
2986 """
2987 handler_dict = self._build_handler_dict(callback,
2988 func=func,
2989 **kwargs)
2990 self.add_my_chat_member_handler(handler_dict)
2991
2992 def chat_member_handler(self, func=None, **kwargs):
2993 """
2994 chat_member handler
2995 :param func:
2996 :param kwargs:
2997 :return:
2998 """
2999
3000 def decorator(handler):
3001 handler_dict = self._build_handler_dict(handler, func=func, **kwargs)
3002 self.add_chat_member_handler(handler_dict)
3003 return handler
3004
3005 return decorator
3006
3007 def add_chat_member_handler(self, handler_dict):
3008 """
3009 Adds a chat_member handler
3010 :param handler_dict:
3011 :return:
3012 """
3013 self.chat_member_handlers.append(handler_dict)
3014
3015 def register_chat_member_handler(self, callback, func=None, **kwargs):
3016 """
3017 Registers chat member handler.
3018 :param callback: function to be called
3019 :param func:
3020 :return: decorated function
3021 """
3022 handler_dict = self._build_handler_dict(callback, func=func, **kwargs)
3023 self.add_chat_member_handler(handler_dict)
3024
3025 def _test_message_handler(self, message_handler, message):
3026 """
3027 Test message handler
3028 :param message_handler:
3029 :param message:
3030 :return:
3031 """
3032 for message_filter, filter_value in message_handler['filters'].items():
3033 if filter_value is None:
3034 continue
3035
3036 if not self._test_filter(message_filter, filter_value, message):
3037 return False
3038
3039 return True
3040
3041 def create_filter(self, filter: util.CustomFilter):
3042 self.custom_filters[filter.key] = filter
3043
3044 def _test_filter(self, message_filter, filter_value, message):
3045 """
3046 Test filters
3047 :param message_filter: Filter type passed in handler
3048 :param filter_value: Filter value passed in handler
3049 :param message: Message to test
3050 :return: True if filter conforms
3051 """
3052 # test_cases = {
3053 # 'content_types': lambda msg: msg.content_type in filter_value,
3054 # 'regexp': lambda msg: msg.content_type == 'text' and re.search(filter_value, msg.text, re.IGNORECASE),
3055 # 'commands': lambda msg: msg.content_type == 'text' and util.extract_command(msg.text) in filter_value,
3056 # 'func': lambda msg: filter_value(msg)
3057 # }
3058 # return test_cases.get(message_filter, lambda msg: False)(message)
3059
3060 if message_filter == 'content_types':
3061 return message.content_type in filter_value
3062 elif message_filter == 'regexp':
3063 return message.content_type == 'text' and re.search(filter_value, message.text, re.IGNORECASE)
3064 elif message_filter == 'commands':
3065 return message.content_type == 'text' and util.extract_command(message.text) in filter_value
3066 elif message_filter == 'chat_types':
3067 return message.chat.type in filter_value
3068 elif message_filter == 'func':
3069 if type(filter_value) is not type:
3070 return filter_value(message)
3071 else:
3072 return filter_value.check(message)
3073 else:
3074 if message_filter in self._check_filter(message_filter):
3075 pass
3076
3077
3078 def _check_filter(self, filter):
3079 if filter in self.custom_filters:
3080 return self.custom_filters
3081 else:
3082 return False
3083
3084
3085 def _notify_command_handlers(self, handlers, new_messages):
3086 """
3087 Notifies command handlers
3088 :param handlers:
3089 :param new_messages:
3090 :return:
3091 """
3092 if len(handlers) == 0:
3093 return
3094 for message in new_messages:
3095 for message_handler in handlers:
3096 if self._test_message_handler(message_handler, message):
3097 self._exec_task(message_handler['function'], message)
3098 break
3099
3100
3101class AsyncTeleBot(TeleBot):
3102 def __init__(self, *args, **kwargs):
3103 TeleBot.__init__(self, *args, **kwargs)
3104
3105 # I'm not sure if `get_updates` should be added here too
3106
3107 @util.async_dec()
3108 def enable_save_next_step_handlers(self, delay=120, filename="./.handler-saves/step.save"):
3109 return TeleBot.enable_save_next_step_handlers(self, delay, filename)
3110
3111 @util.async_dec()
3112 def enable_save_reply_handlers(self, delay=120, filename="./.handler-saves/reply.save"):
3113 return TeleBot.enable_save_reply_handlers(self, delay, filename)
3114
3115 @util.async_dec()
3116 def disable_save_next_step_handlers(self):
3117 return TeleBot.disable_save_next_step_handlers(self)
3118
3119 @util.async_dec()
3120 def disable_save_reply_handlers(self):
3121 return TeleBot.enable_save_reply_handlers(self)
3122
3123 @util.async_dec()
3124 def load_next_step_handlers(self, filename="./.handler-saves/step.save", del_file_after_loading=True):
3125 return TeleBot.load_next_step_handlers(self, filename, del_file_after_loading)
3126
3127 @util.async_dec()
3128 def load_reply_handlers(self, filename="./.handler-saves/reply.save", del_file_after_loading=True):
3129 return TeleBot.load_reply_handlers(self, filename, del_file_after_loading)
3130
3131 @util.async_dec()
3132 def get_me(self):
3133 return TeleBot.get_me(self)
3134
3135 @util.async_dec()
3136 def log_out(self):
3137 return TeleBot.log_out(self)
3138
3139 @util.async_dec()
3140 def close(self):
3141 return TeleBot.close(self)
3142
3143 @util.async_dec()
3144 def get_my_commands(self, *args, **kwargs): # needed args because new scope and language_code
3145 return TeleBot.get_my_commands(self, *args, **kwargs)
3146
3147 @util.async_dec()
3148 def set_my_commands(self, *args, **kwargs):
3149 return TeleBot.set_my_commands(self, *args, **kwargs)
3150
3151 @util.async_dec()
3152 def delete_my_commands(self, *args, **kwargs):
3153 return TeleBot.delete_my_commands(self, *args, **kwargs)
3154
3155 @util.async_dec()
3156 def get_file(self, *args):
3157 return TeleBot.get_file(self, *args)
3158
3159 @util.async_dec()
3160 def download_file(self, *args):
3161 return TeleBot.download_file(self, *args)
3162
3163 @util.async_dec()
3164 def get_user_profile_photos(self, *args, **kwargs):
3165 return TeleBot.get_user_profile_photos(self, *args, **kwargs)
3166
3167 @util.async_dec()
3168 def get_chat(self, *args):
3169 return TeleBot.get_chat(self, *args)
3170
3171 @util.async_dec()
3172 def leave_chat(self, *args):
3173 return TeleBot.leave_chat(self, *args)
3174
3175 @util.async_dec()
3176 def get_chat_administrators(self, *args):
3177 return TeleBot.get_chat_administrators(self, *args)
3178
3179 @util.async_dec()
3180 def get_chat_members_count(self, *args):
3181 logger.info('get_chat_members_count is deprecated. Use get_chat_member_count instead')
3182 return TeleBot.get_chat_member_count(self, *args)
3183
3184 @util.async_dec()
3185 def get_chat_member_count(self, *args):
3186 return TeleBot.get_chat_member_count(self, *args)
3187
3188 @util.async_dec()
3189 def set_chat_sticker_set(self, *args):
3190 return TeleBot.set_chat_sticker_set(self, *args)
3191
3192 @util.async_dec()
3193 def delete_chat_sticker_set(self, *args):
3194 return TeleBot.delete_chat_sticker_set(self, *args)
3195
3196 @util.async_dec()
3197 def get_chat_member(self, *args):
3198 return TeleBot.get_chat_member(self, *args)
3199
3200 @util.async_dec()
3201 def send_message(self, *args, **kwargs):
3202 return TeleBot.send_message(self, *args, **kwargs)
3203
3204 @util.async_dec()
3205 def send_dice(self, *args, **kwargs):
3206 return TeleBot.send_dice(self, *args, **kwargs)
3207
3208 @util.async_dec()
3209 def send_animation(self, *args, **kwargs):
3210 return TeleBot.send_animation(self, *args, **kwargs)
3211
3212 @util.async_dec()
3213 def forward_message(self, *args, **kwargs):
3214 return TeleBot.forward_message(self, *args, **kwargs)
3215
3216 @util.async_dec()
3217 def copy_message(self, *args, **kwargs):
3218 return TeleBot.copy_message(self, *args, **kwargs)
3219
3220 @util.async_dec()
3221 def delete_message(self, *args):
3222 return TeleBot.delete_message(self, *args)
3223
3224 @util.async_dec()
3225 def send_photo(self, *args, **kwargs):
3226 return TeleBot.send_photo(self, *args, **kwargs)
3227
3228 @util.async_dec()
3229 def send_audio(self, *args, **kwargs):
3230 return TeleBot.send_audio(self, *args, **kwargs)
3231
3232 @util.async_dec()
3233 def send_voice(self, *args, **kwargs):
3234 return TeleBot.send_voice(self, *args, **kwargs)
3235
3236 @util.async_dec()
3237 def send_document(self, *args, **kwargs):
3238 return TeleBot.send_document(self, *args, **kwargs)
3239
3240 @util.async_dec()
3241 def send_sticker(self, *args, **kwargs):
3242 return TeleBot.send_sticker(self, *args, **kwargs)
3243
3244 @util.async_dec()
3245 def send_video(self, *args, **kwargs):
3246 return TeleBot.send_video(self, *args, **kwargs)
3247
3248 @util.async_dec()
3249 def send_video_note(self, *args, **kwargs):
3250 return TeleBot.send_video_note(self, *args, **kwargs)
3251
3252 @util.async_dec()
3253 def send_media_group(self, *args, **kwargs):
3254 return TeleBot.send_media_group(self, *args, **kwargs)
3255
3256 @util.async_dec()
3257 def send_location(self, *args, **kwargs):
3258 return TeleBot.send_location(self, *args, **kwargs)
3259
3260 @util.async_dec()
3261 def edit_message_live_location(self, *args, **kwargs):
3262 return TeleBot.edit_message_live_location(self, *args, **kwargs)
3263
3264 @util.async_dec()
3265 def stop_message_live_location(self, *args, **kwargs):
3266 return TeleBot.stop_message_live_location(self, *args, **kwargs)
3267
3268 @util.async_dec()
3269 def send_venue(self, *args, **kwargs):
3270 return TeleBot.send_venue(self, *args, **kwargs)
3271
3272 @util.async_dec()
3273 def send_contact(self, *args, **kwargs):
3274 return TeleBot.send_contact(self, *args, **kwargs)
3275
3276 @util.async_dec()
3277 def send_chat_action(self, *args, **kwargs):
3278 return TeleBot.send_chat_action(self, *args, **kwargs)
3279
3280 @util.async_dec()
3281 def kick_chat_member(self, *args, **kwargs):
3282 logger.info('kick_chat_member is deprecated. Use ban_chat_member instead.')
3283 return TeleBot.ban_chat_member(self, *args, **kwargs)
3284
3285 @util.async_dec()
3286 def ban_chat_member(self, *args, **kwargs):
3287 return TeleBot.ban_chat_member(self, *args, **kwargs)
3288
3289 @util.async_dec()
3290 def unban_chat_member(self, *args, **kwargs):
3291 return TeleBot.unban_chat_member(self, *args, **kwargs)
3292
3293 @util.async_dec()
3294 def restrict_chat_member(self, *args, **kwargs):
3295 return TeleBot.restrict_chat_member(self, *args, **kwargs)
3296
3297 @util.async_dec()
3298 def promote_chat_member(self, *args, **kwargs):
3299 return TeleBot.promote_chat_member(self, *args, **kwargs)
3300
3301 @util.async_dec()
3302 def set_chat_administrator_custom_title(self, *args, **kwargs):
3303 return TeleBot.set_chat_administrator_custom_title(self, *args, **kwargs)
3304
3305 @util.async_dec()
3306 def set_chat_permissions(self, *args, **kwargs):
3307 return TeleBot.set_chat_permissions(self, *args, **kwargs)
3308
3309 @util.async_dec()
3310 def create_chat_invite_link(self, *args, **kwargs):
3311 return TeleBot.create_chat_invite_link(self, *args, **kwargs)
3312
3313 @util.async_dec()
3314 def edit_chat_invite_link(self, *args, **kwargs):
3315 return TeleBot.edit_chat_invite_link(self, *args, **kwargs)
3316
3317 @util.async_dec()
3318 def revoke_chat_invite_link(self, *args, **kwargs):
3319 return TeleBot.revoke_chat_invite_link(self, *args, **kwargs)
3320
3321 @util.async_dec()
3322 def export_chat_invite_link(self, *args):
3323 return TeleBot.export_chat_invite_link(self, *args)
3324
3325 @util.async_dec()
3326 def set_chat_photo(self, *args):
3327 return TeleBot.set_chat_photo(self, *args)
3328
3329 @util.async_dec()
3330 def delete_chat_photo(self, *args):
3331 return TeleBot.delete_chat_photo(self, *args)
3332
3333 @util.async_dec()
3334 def set_chat_title(self, *args):
3335 return TeleBot.set_chat_title(self, *args)
3336
3337 @util.async_dec()
3338 def set_chat_description(self, *args):
3339 return TeleBot.set_chat_description(self, *args)
3340
3341 @util.async_dec()
3342 def pin_chat_message(self, *args, **kwargs):
3343 return TeleBot.pin_chat_message(self, *args, **kwargs)
3344
3345 @util.async_dec()
3346 def unpin_chat_message(self, *args):
3347 return TeleBot.unpin_chat_message(self, *args)
3348
3349 @util.async_dec()
3350 def unpin_all_chat_messages(self, *args):
3351 return TeleBot.unpin_all_chat_messages(self, *args)
3352
3353 @util.async_dec()
3354 def edit_message_text(self, *args, **kwargs):
3355 return TeleBot.edit_message_text(self, *args, **kwargs)
3356
3357 @util.async_dec()
3358 def edit_message_media(self, *args, **kwargs):
3359 return TeleBot.edit_message_media(self, *args, **kwargs)
3360
3361 @util.async_dec()
3362 def edit_message_reply_markup(self, *args, **kwargs):
3363 return TeleBot.edit_message_reply_markup(self, *args, **kwargs)
3364
3365 @util.async_dec()
3366 def send_game(self, *args, **kwargs):
3367 return TeleBot.send_game(self, *args, **kwargs)
3368
3369 @util.async_dec()
3370 def set_game_score(self, *args, **kwargs):
3371 return TeleBot.set_game_score(self, *args, **kwargs)
3372
3373 @util.async_dec()
3374 def get_game_high_scores(self, *args, **kwargs):
3375 return TeleBot.get_game_high_scores(self, *args, **kwargs)
3376
3377 @util.async_dec()
3378 def send_invoice(self, *args, **kwargs):
3379 return TeleBot.send_invoice(self, *args, **kwargs)
3380
3381 @util.async_dec()
3382 def answer_shipping_query(self, *args, **kwargs):
3383 return TeleBot.answer_shipping_query(self, *args, **kwargs)
3384
3385 @util.async_dec()
3386 def answer_pre_checkout_query(self, *args, **kwargs):
3387 return TeleBot.answer_pre_checkout_query(self, *args, **kwargs)
3388
3389 @util.async_dec()
3390 def edit_message_caption(self, *args, **kwargs):
3391 return TeleBot.edit_message_caption(self, *args, **kwargs)
3392
3393 @util.async_dec()
3394 def answer_inline_query(self, *args, **kwargs):
3395 return TeleBot.answer_inline_query(self, *args, **kwargs)
3396
3397 @util.async_dec()
3398 def answer_callback_query(self, *args, **kwargs):
3399 return TeleBot.answer_callback_query(self, *args, **kwargs)
3400
3401 @util.async_dec()
3402 def get_sticker_set(self, *args, **kwargs):
3403 return TeleBot.get_sticker_set(self, *args, **kwargs)
3404
3405 @util.async_dec()
3406 def upload_sticker_file(self, *args, **kwargs):
3407 return TeleBot.upload_sticker_file(self, *args, **kwargs)
3408
3409 @util.async_dec()
3410 def create_new_sticker_set(self, *args, **kwargs):
3411 return TeleBot.create_new_sticker_set(self, *args, **kwargs)
3412
3413 @util.async_dec()
3414 def add_sticker_to_set(self, *args, **kwargs):
3415 return TeleBot.add_sticker_to_set(self, *args, **kwargs)
3416
3417 @util.async_dec()
3418 def set_sticker_position_in_set(self, *args, **kwargs):
3419 return TeleBot.set_sticker_position_in_set(self, *args, **kwargs)
3420
3421 @util.async_dec()
3422 def delete_sticker_from_set(self, *args, **kwargs):
3423 return TeleBot.delete_sticker_from_set(self, *args, **kwargs)
3424
3425 @util.async_dec()
3426 def set_sticker_set_thumb(self, *args, **kwargs):
3427 return TeleBot.set_sticker_set_thumb(self, *args, **kwargs)
3428
3429 @util.async_dec()
3430 def send_poll(self, *args, **kwargs):
3431 return TeleBot.send_poll(self, *args, **kwargs)
3432
3433 @util.async_dec()
3434 def stop_poll(self, *args, **kwargs):
3435 return TeleBot.stop_poll(self, *args, **kwargs)
3436