mirror of
https://github.com/eternnoir/pyTelegramBotAPI.git
synced 2023-08-10 21:12:57 +03:00
Completed docstrings for all files except types.py
This commit is contained in:
parent
7c12162576
commit
b0e06253ff
@ -84,10 +84,13 @@ class TeleBot:
|
|||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python3
|
||||||
|
:caption: Creating instance of TeleBot
|
||||||
|
|
||||||
from telebot import TeleBot
|
from telebot import TeleBot
|
||||||
bot = TeleBot('token') # get token from @BotFather
|
bot = TeleBot('token') # get token from @BotFather
|
||||||
|
# now you can register other handlers/update listeners,
|
||||||
|
# and use bot methods.
|
||||||
|
|
||||||
See more examples in examples/ directory:
|
See more examples in examples/ directory:
|
||||||
https://github.com/eternnoir/pyTelegramBotAPI/tree/master/examples
|
https://github.com/eternnoir/pyTelegramBotAPI/tree/master/examples
|
||||||
@ -243,7 +246,7 @@ class TeleBot:
|
|||||||
Enable saving states (by default saving disabled)
|
Enable saving states (by default saving disabled)
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
It is recommended to pass a :class:`~telebot.storage.StateMemoryStorage` instance as state_storage
|
It is recommended to pass a :class:`~telebot.storage.StatePickleStorage` instance as state_storage
|
||||||
to TeleBot class.
|
to TeleBot class.
|
||||||
|
|
||||||
:param filename: Filename of saving file, defaults to "./.state-save/states.pkl"
|
:param filename: Filename of saving file, defaults to "./.state-save/states.pkl"
|
||||||
@ -547,8 +550,6 @@ class TeleBot:
|
|||||||
|
|
||||||
Telegram documentation: https://core.telegram.org/bots/api#getupdates
|
Telegram documentation: https://core.telegram.org/bots/api#getupdates
|
||||||
|
|
||||||
:param allowed_updates: Array of string. List the types of updates you want your bot to receive.
|
|
||||||
:type allowed_updates: :obj:`list`, optional
|
|
||||||
|
|
||||||
:param offset: Identifier of the first update to be returned. Must be greater by one than the highest among the identifiers of previously received updates.
|
:param offset: Identifier of the first update to be returned. Must be greater by one than the highest among the identifiers of previously received updates.
|
||||||
By default, updates starting with the earliest unconfirmed update are returned. An update is considered confirmed as soon as getUpdates is called with an offset
|
By default, updates starting with the earliest unconfirmed update are returned. An update is considered confirmed as soon as getUpdates is called with an offset
|
||||||
@ -562,6 +563,9 @@ class TeleBot:
|
|||||||
:param timeout: Request connection timeout
|
:param timeout: Request connection timeout
|
||||||
:type timeout: :obj:`int`, optional
|
:type timeout: :obj:`int`, optional
|
||||||
|
|
||||||
|
:param allowed_updates: Array of string. List the types of updates you want your bot to receive.
|
||||||
|
:type allowed_updates: :obj:`list`, optional
|
||||||
|
|
||||||
:param long_polling_timeout: Timeout in seconds for long polling.
|
:param long_polling_timeout: Timeout in seconds for long polling.
|
||||||
:type long_polling_timeout: :obj:`int`, optional
|
:type long_polling_timeout: :obj:`int`, optional
|
||||||
|
|
||||||
@ -604,6 +608,9 @@ class TeleBot:
|
|||||||
Processes new updates. Just pass list of subclasses of Update to this method.
|
Processes new updates. Just pass list of subclasses of Update to this method.
|
||||||
|
|
||||||
:param updates: List of :class:`telebot.types.Update` objects.
|
:param updates: List of :class:`telebot.types.Update` objects.
|
||||||
|
:type updates: :obj:`list` of :class:`telebot.types.Update`
|
||||||
|
|
||||||
|
:return None:
|
||||||
"""
|
"""
|
||||||
upd_count = len(updates)
|
upd_count = len(updates)
|
||||||
logger.debug('Received {0} new updates'.format(upd_count))
|
logger.debug('Received {0} new updates'.format(upd_count))
|
||||||
@ -885,11 +892,11 @@ class TeleBot:
|
|||||||
none_stop: Optional[bool]=None):
|
none_stop: Optional[bool]=None):
|
||||||
"""
|
"""
|
||||||
This function creates a new Thread that calls an internal __retrieve_updates function.
|
This function creates a new Thread that calls an internal __retrieve_updates function.
|
||||||
This allows the bot to retrieve Updates automagically and notify listeners and message handlers accordingly.
|
This allows the bot to retrieve Updates automatically and notify listeners and message handlers accordingly.
|
||||||
|
|
||||||
Warning: Do not call this function more than once!
|
Warning: Do not call this function more than once!
|
||||||
|
|
||||||
Always get updates.
|
Always gets updates.
|
||||||
|
|
||||||
.. deprecated:: 4.1.1
|
.. deprecated:: 4.1.1
|
||||||
Use :meth:`infinity_polling` instead.
|
Use :meth:`infinity_polling` instead.
|
||||||
@ -921,7 +928,7 @@ class TeleBot:
|
|||||||
|
|
||||||
Please note that this parameter doesn't affect updates created before the call to the get_updates,
|
Please note that this parameter doesn't affect updates created before the call to the get_updates,
|
||||||
so unwanted updates may be received for a short period of time.
|
so unwanted updates may be received for a short period of time.
|
||||||
:type allowed_updates: :obj:`list`] of :obj:`str`
|
:type allowed_updates: :obj:`list` of :obj:`str`
|
||||||
|
|
||||||
:param none_stop: Deprecated, use non_stop. Old typo, kept for backward compatibility.
|
:param none_stop: Deprecated, use non_stop. Old typo, kept for backward compatibility.
|
||||||
:type none_stop: :obj:`bool`
|
:type none_stop: :obj:`bool`
|
||||||
@ -1104,6 +1111,8 @@ class TeleBot:
|
|||||||
def stop_polling(self):
|
def stop_polling(self):
|
||||||
"""
|
"""
|
||||||
Stops polling.
|
Stops polling.
|
||||||
|
|
||||||
|
Does not accept any arguments.
|
||||||
"""
|
"""
|
||||||
self.__stop_polling.set()
|
self.__stop_polling.set()
|
||||||
|
|
||||||
@ -1170,6 +1179,15 @@ class TeleBot:
|
|||||||
|
|
||||||
|
|
||||||
def download_file(self, file_path: str) -> bytes:
|
def download_file(self, file_path: str) -> bytes:
|
||||||
|
"""
|
||||||
|
Downloads file.
|
||||||
|
|
||||||
|
:param file_path: Path where the file should be downloaded.
|
||||||
|
:type file_path: str
|
||||||
|
|
||||||
|
:return: bytes
|
||||||
|
:rtype: :obj:`bytes`
|
||||||
|
"""
|
||||||
return apihelper.download_file(self.token, file_path)
|
return apihelper.download_file(self.token, file_path)
|
||||||
|
|
||||||
|
|
||||||
@ -1209,7 +1227,7 @@ class TeleBot:
|
|||||||
limit: Optional[int]=None) -> types.UserProfilePhotos:
|
limit: Optional[int]=None) -> types.UserProfilePhotos:
|
||||||
"""
|
"""
|
||||||
Use this method to get a list of profile pictures for a user.
|
Use this method to get a list of profile pictures for a user.
|
||||||
Returns a UserProfilePhotos object.
|
Returns a :class:`telebot.types.UserProfilePhotos` object.
|
||||||
|
|
||||||
Telegram documentation: https://core.telegram.org/bots/api#getuserprofilephotos
|
Telegram documentation: https://core.telegram.org/bots/api#getuserprofilephotos
|
||||||
|
|
||||||
@ -1240,7 +1258,7 @@ class TeleBot:
|
|||||||
:param chat_id: Unique identifier for the target chat or username of the target supergroup or channel (in the format @channelusername)
|
:param chat_id: Unique identifier for the target chat or username of the target supergroup or channel (in the format @channelusername)
|
||||||
:type chat_id: :obj:`int` or :obj:`str`
|
:type chat_id: :obj:`int` or :obj:`str`
|
||||||
|
|
||||||
:return: :class:`telebot.types.Chat`
|
:return: Chat information
|
||||||
:rtype: :class:`telebot.types.Chat`
|
:rtype: :class:`telebot.types.Chat`
|
||||||
"""
|
"""
|
||||||
result = apihelper.get_chat(self.token, chat_id)
|
result = apihelper.get_chat(self.token, chat_id)
|
||||||
@ -1384,8 +1402,8 @@ class TeleBot:
|
|||||||
"""
|
"""
|
||||||
Use this method to send text messages.
|
Use this method to send text messages.
|
||||||
|
|
||||||
Warning: Do not send more than about 4000 characters each message, otherwise you'll risk an HTTP 414 error.
|
Warning: Do not send more than about 4096 characters each message, otherwise you'll risk an HTTP 414 error.
|
||||||
If you must send more than 4000 characters,
|
If you must send more than 4096 characters,
|
||||||
use the `split_string` or `smart_split` function in util.py.
|
use the `split_string` or `smart_split` function in util.py.
|
||||||
|
|
||||||
Telegram documentation: https://core.telegram.org/bots/api#sendmessage
|
Telegram documentation: https://core.telegram.org/bots/api#sendmessage
|
||||||
@ -3552,7 +3570,12 @@ class TeleBot:
|
|||||||
message_id: Optional[int]=None,
|
message_id: Optional[int]=None,
|
||||||
inline_message_id: Optional[str]=None) -> List[types.GameHighScore]:
|
inline_message_id: Optional[str]=None) -> List[types.GameHighScore]:
|
||||||
"""
|
"""
|
||||||
Gets top points and game play.
|
Use this method to get data for high score tables. Will return the score of the specified user and several of
|
||||||
|
their neighbors in a game. On success, returns an Array of GameHighScore objects.
|
||||||
|
|
||||||
|
This method will currently return scores for the target user, plus two of their closest neighbors on each side.
|
||||||
|
Will also return the top three users if the user and their neighbors are not among them.
|
||||||
|
Please note that this behavior is subject to change.
|
||||||
|
|
||||||
Telegram documentation: https://core.telegram.org/bots/api#getgamehighscores
|
Telegram documentation: https://core.telegram.org/bots/api#getgamehighscores
|
||||||
|
|
||||||
@ -4430,10 +4453,16 @@ class TeleBot:
|
|||||||
|
|
||||||
self.middlewares.append(middleware)
|
self.middlewares.append(middleware)
|
||||||
|
|
||||||
def set_state(self, user_id: int, state: Union[int, str, State], chat_id: int=None) -> None:
|
def set_state(self, user_id: int, state: Union[int, str, State], chat_id: Optional[int]=None) -> None:
|
||||||
"""
|
"""
|
||||||
Sets a new state of a user.
|
Sets a new state of a user.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
You should set both user id and chat id in order to set state for a user in a chat.
|
||||||
|
Otherwise, if you only set user_id, chat_id will equal to user_id, this means that
|
||||||
|
state will be set for the user in his private chat with a bot.
|
||||||
|
|
||||||
:param user_id: User's identifier
|
:param user_id: User's identifier
|
||||||
:type user_id: :obj:`int`
|
:type user_id: :obj:`int`
|
||||||
|
|
||||||
@ -4449,7 +4478,7 @@ class TeleBot:
|
|||||||
chat_id = user_id
|
chat_id = user_id
|
||||||
self.current_states.set_state(chat_id, user_id, state)
|
self.current_states.set_state(chat_id, user_id, state)
|
||||||
|
|
||||||
def reset_data(self, user_id: int, chat_id: int=None):
|
def reset_data(self, user_id: int, chat_id: Optional[int]=None):
|
||||||
"""
|
"""
|
||||||
Reset data for a user in chat.
|
Reset data for a user in chat.
|
||||||
|
|
||||||
@ -4465,7 +4494,7 @@ class TeleBot:
|
|||||||
chat_id = user_id
|
chat_id = user_id
|
||||||
self.current_states.reset_data(chat_id, user_id)
|
self.current_states.reset_data(chat_id, user_id)
|
||||||
|
|
||||||
def delete_state(self, user_id: int, chat_id: int=None) -> None:
|
def delete_state(self, user_id: int, chat_id: Optional[int]=None) -> None:
|
||||||
"""
|
"""
|
||||||
Delete the current state of a user.
|
Delete the current state of a user.
|
||||||
|
|
||||||
@ -4481,12 +4510,24 @@ class TeleBot:
|
|||||||
chat_id = user_id
|
chat_id = user_id
|
||||||
self.current_states.delete_state(chat_id, user_id)
|
self.current_states.delete_state(chat_id, user_id)
|
||||||
|
|
||||||
def retrieve_data(self, user_id: int, chat_id: int=None) -> Optional[Any]:
|
def retrieve_data(self, user_id: int, chat_id: Optional[int]=None) -> Optional[Any]:
|
||||||
|
"""
|
||||||
|
Returns context manager with data for a user in chat.
|
||||||
|
|
||||||
|
:param user_id: User identifier
|
||||||
|
:type user_id: int
|
||||||
|
|
||||||
|
:param chat_id: Chat's unique identifier, defaults to user_id
|
||||||
|
:type chat_id: int, optional
|
||||||
|
|
||||||
|
:return: Context manager with data for a user in chat
|
||||||
|
:rtype: Optional[Any]
|
||||||
|
"""
|
||||||
if chat_id is None:
|
if chat_id is None:
|
||||||
chat_id = user_id
|
chat_id = user_id
|
||||||
return self.current_states.get_interactive_data(chat_id, user_id)
|
return self.current_states.get_interactive_data(chat_id, user_id)
|
||||||
|
|
||||||
def get_state(self, user_id: int, chat_id: int=None) -> Optional[Union[int, str, State]]:
|
def get_state(self, user_id: int, chat_id: Optional[int]=None) -> Optional[Union[int, str, State]]:
|
||||||
"""
|
"""
|
||||||
Gets current state of a user.
|
Gets current state of a user.
|
||||||
Not recommended to use this method. But it is ok for debugging.
|
Not recommended to use this method. But it is ok for debugging.
|
||||||
@ -4504,7 +4545,7 @@ class TeleBot:
|
|||||||
chat_id = user_id
|
chat_id = user_id
|
||||||
return self.current_states.get_state(chat_id, user_id)
|
return self.current_states.get_state(chat_id, user_id)
|
||||||
|
|
||||||
def add_data(self, user_id: int, chat_id:int=None, **kwargs):
|
def add_data(self, user_id: int, chat_id: Optional[int]=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Add data to states.
|
Add data to states.
|
||||||
|
|
||||||
@ -4635,6 +4676,7 @@ class TeleBot:
|
|||||||
Example:
|
Example:
|
||||||
|
|
||||||
.. code-block:: python3
|
.. code-block:: python3
|
||||||
|
:caption: Usage of middleware_handler
|
||||||
|
|
||||||
bot = TeleBot('TOKEN')
|
bot = TeleBot('TOKEN')
|
||||||
|
|
||||||
@ -4728,13 +4770,14 @@ class TeleBot:
|
|||||||
def message_handler(self, commands: Optional[List[str]]=None, regexp: Optional[str]=None, func: Optional[Callable]=None,
|
def message_handler(self, commands: Optional[List[str]]=None, regexp: Optional[str]=None, func: Optional[Callable]=None,
|
||||||
content_types: Optional[List[str]]=None, chat_types: Optional[List[str]]=None, **kwargs):
|
content_types: Optional[List[str]]=None, chat_types: Optional[List[str]]=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Message handler decorator.
|
Handles New incoming message of any kind - text, photo, sticker, etc.
|
||||||
This decorator can be used to decorate functions that must handle certain types of messages.
|
As a parameter to the decorator function, it passes :class:`telebot.types.Message` object.
|
||||||
All message handlers are tested in the order they were added.
|
All message handlers are tested in the order they were added.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python3
|
||||||
|
:caption: Usage of message_handler
|
||||||
|
|
||||||
bot = TeleBot('TOKEN')
|
bot = TeleBot('TOKEN')
|
||||||
|
|
||||||
@ -4768,8 +4811,17 @@ class TeleBot:
|
|||||||
|
|
||||||
:param func: Optional lambda function. The lambda receives the message to test as the first parameter.
|
:param func: Optional lambda function. The lambda receives the message to test as the first parameter.
|
||||||
It must return True if the command should handle the message.
|
It must return True if the command should handle the message.
|
||||||
|
:type func: :obj:`lambda`
|
||||||
|
|
||||||
:param content_types: Supported message content types. Must be a list. Defaults to ['text'].
|
:param content_types: Supported message content types. Must be a list. Defaults to ['text'].
|
||||||
|
:type content_types: :obj:`list` of :obj:`str`
|
||||||
|
|
||||||
:param chat_types: list of chat types
|
:param chat_types: list of chat types
|
||||||
|
:type chat_types: :obj:`list` of :obj:`str`
|
||||||
|
|
||||||
|
:param kwargs: Optional keyword arguments(custom filters)
|
||||||
|
|
||||||
|
:return: decorated function
|
||||||
"""
|
"""
|
||||||
if content_types is None:
|
if content_types is None:
|
||||||
content_types = ["text"]
|
content_types = ["text"]
|
||||||
@ -4871,7 +4923,8 @@ class TeleBot:
|
|||||||
|
|
||||||
def edited_message_handler(self, commands=None, regexp=None, func=None, content_types=None, chat_types=None, **kwargs):
|
def edited_message_handler(self, commands=None, regexp=None, func=None, content_types=None, chat_types=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Edit message handler decorator
|
Handles new version of a message that is known to the bot and was edited.
|
||||||
|
As a parameter to the decorator function, it passes :class:`telebot.types.Message` object.
|
||||||
|
|
||||||
:param commands: Optional list of strings (commands to handle).
|
:param commands: Optional list of strings (commands to handle).
|
||||||
:type commands: :obj:`list` of :obj:`str`
|
:type commands: :obj:`list` of :obj:`str`
|
||||||
@ -4889,6 +4942,7 @@ class TeleBot:
|
|||||||
:type chat_types: :obj:`list` of :obj:`str`
|
:type chat_types: :obj:`list` of :obj:`str`
|
||||||
|
|
||||||
:param kwargs: Optional keyword arguments(custom filters)
|
:param kwargs: Optional keyword arguments(custom filters)
|
||||||
|
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
if content_types is None:
|
if content_types is None:
|
||||||
@ -4960,6 +5014,8 @@ class TeleBot:
|
|||||||
:param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
|
:param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
|
||||||
:type pass_bot: :obj:`bool`
|
:type pass_bot: :obj:`bool`
|
||||||
|
|
||||||
|
:param kwargs: Optional keyword arguments(custom filters)
|
||||||
|
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
method_name = "register_edited_message_handler"
|
method_name = "register_edited_message_handler"
|
||||||
@ -4988,7 +5044,8 @@ class TeleBot:
|
|||||||
|
|
||||||
def channel_post_handler(self, commands=None, regexp=None, func=None, content_types=None, **kwargs):
|
def channel_post_handler(self, commands=None, regexp=None, func=None, content_types=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Channel post handler decorator.
|
Handles new incoming channel post of any kind - text, photo, sticker, etc.
|
||||||
|
As a parameter to the decorator function, it passes :class:`telebot.types.Message` object.
|
||||||
|
|
||||||
:param commands: Optional list of strings (commands to handle).
|
:param commands: Optional list of strings (commands to handle).
|
||||||
:type commands: :obj:`list` of :obj:`str`
|
:type commands: :obj:`list` of :obj:`str`
|
||||||
@ -5003,6 +5060,7 @@ class TeleBot:
|
|||||||
:type content_types: :obj:`list` of :obj:`str`
|
:type content_types: :obj:`list` of :obj:`str`
|
||||||
|
|
||||||
:param kwargs: Optional keyword arguments(custom filters)
|
:param kwargs: Optional keyword arguments(custom filters)
|
||||||
|
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
if content_types is None:
|
if content_types is None:
|
||||||
@ -5069,6 +5127,8 @@ class TeleBot:
|
|||||||
:param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
|
:param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
|
||||||
:type pass_bot: :obj:`bool`
|
:type pass_bot: :obj:`bool`
|
||||||
|
|
||||||
|
:param kwargs: Optional keyword arguments(custom filters)
|
||||||
|
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
method_name = "register_channel_post_handler"
|
method_name = "register_channel_post_handler"
|
||||||
@ -5096,7 +5156,8 @@ class TeleBot:
|
|||||||
|
|
||||||
def edited_channel_post_handler(self, commands=None, regexp=None, func=None, content_types=None, **kwargs):
|
def edited_channel_post_handler(self, commands=None, regexp=None, func=None, content_types=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Edit channel post handler decorator
|
Handles new version of a channel post that is known to the bot and was edited.
|
||||||
|
As a parameter to the decorator function, it passes :class:`telebot.types.Message` object.
|
||||||
|
|
||||||
:param commands: Optional list of strings (commands to handle).
|
:param commands: Optional list of strings (commands to handle).
|
||||||
:type commands: :obj:`list` of :obj:`str`
|
:type commands: :obj:`list` of :obj:`str`
|
||||||
@ -5178,6 +5239,8 @@ class TeleBot:
|
|||||||
:param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
|
:param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
|
||||||
:type pass_bot: :obj:`bool`
|
:type pass_bot: :obj:`bool`
|
||||||
|
|
||||||
|
:param kwargs: Optional keyword arguments(custom filters)
|
||||||
|
|
||||||
:return: decorated function
|
:return: decorated function
|
||||||
"""
|
"""
|
||||||
method_name = "register_edited_channel_post_handler"
|
method_name = "register_edited_channel_post_handler"
|
||||||
@ -5205,7 +5268,8 @@ class TeleBot:
|
|||||||
|
|
||||||
def inline_handler(self, func, **kwargs):
|
def inline_handler(self, func, **kwargs):
|
||||||
"""
|
"""
|
||||||
Inline call handler decorator
|
Handles new incoming inline query.
|
||||||
|
As a parameter to the decorator function, it passes :class:`telebot.types.InlineQuery` object.
|
||||||
|
|
||||||
:param func: Function executed as a filter
|
:param func: Function executed as a filter
|
||||||
:type func: :obj:`function`
|
:type func: :obj:`function`
|
||||||
@ -5246,6 +5310,8 @@ class TeleBot:
|
|||||||
:param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
|
:param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
|
||||||
:type pass_bot: :obj:`bool`
|
:type pass_bot: :obj:`bool`
|
||||||
|
|
||||||
|
:param kwargs: Optional keyword arguments(custom filters)
|
||||||
|
|
||||||
:return: decorated function
|
:return: decorated function
|
||||||
"""
|
"""
|
||||||
handler_dict = self._build_handler_dict(callback, func=func, pass_bot=pass_bot, **kwargs)
|
handler_dict = self._build_handler_dict(callback, func=func, pass_bot=pass_bot, **kwargs)
|
||||||
@ -5253,7 +5319,9 @@ class TeleBot:
|
|||||||
|
|
||||||
def chosen_inline_handler(self, func, **kwargs):
|
def chosen_inline_handler(self, func, **kwargs):
|
||||||
"""
|
"""
|
||||||
Description: The result of an inline query that was chosen by a user and sent to their chat partner.
|
Handles the result of an inline query that was chosen by a user and sent to their chat partner.
|
||||||
|
Please see our documentation on the feedback collecting for details on how to enable these updates for your bot.
|
||||||
|
As a parameter to the decorator function, it passes :class:`telebot.types.ChosenInlineResult` object.
|
||||||
|
|
||||||
:param func: Function executed as a filter
|
:param func: Function executed as a filter
|
||||||
:type func: :obj:`function`
|
:type func: :obj:`function`
|
||||||
@ -5294,6 +5362,8 @@ class TeleBot:
|
|||||||
:param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
|
:param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
|
||||||
:type pass_bot: :obj:`bool`
|
:type pass_bot: :obj:`bool`
|
||||||
|
|
||||||
|
:param kwargs: Optional keyword arguments(custom filters)
|
||||||
|
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
handler_dict = self._build_handler_dict(callback, func=func, pass_bot=pass_bot, **kwargs)
|
handler_dict = self._build_handler_dict(callback, func=func, pass_bot=pass_bot, **kwargs)
|
||||||
@ -5301,7 +5371,8 @@ class TeleBot:
|
|||||||
|
|
||||||
def callback_query_handler(self, func, **kwargs):
|
def callback_query_handler(self, func, **kwargs):
|
||||||
"""
|
"""
|
||||||
Callback request handler decorator
|
Handles new incoming callback query.
|
||||||
|
As a parameter to the decorator function, it passes :class:`telebot.types.CallbackQuery` object.
|
||||||
|
|
||||||
:param func: Function executed as a filter
|
:param func: Function executed as a filter
|
||||||
:type func: :obj:`function`
|
:type func: :obj:`function`
|
||||||
@ -5342,6 +5413,8 @@ class TeleBot:
|
|||||||
:param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
|
:param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
|
||||||
:type pass_bot: :obj:`bool`
|
:type pass_bot: :obj:`bool`
|
||||||
|
|
||||||
|
:param kwargs: Optional keyword arguments(custom filters)
|
||||||
|
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
handler_dict = self._build_handler_dict(callback, func=func, pass_bot=pass_bot, **kwargs)
|
handler_dict = self._build_handler_dict(callback, func=func, pass_bot=pass_bot, **kwargs)
|
||||||
@ -5349,7 +5422,8 @@ class TeleBot:
|
|||||||
|
|
||||||
def shipping_query_handler(self, func, **kwargs):
|
def shipping_query_handler(self, func, **kwargs):
|
||||||
"""
|
"""
|
||||||
Shipping request handler
|
Handles new incoming shipping query. Only for invoices with flexible price.
|
||||||
|
As a parameter to the decorator function, it passes :class:`telebot.types.ShippingQuery` object.
|
||||||
|
|
||||||
:param func: Function executed as a filter
|
:param func: Function executed as a filter
|
||||||
:type func: :obj:`function`
|
:type func: :obj:`function`
|
||||||
@ -5390,6 +5464,8 @@ class TeleBot:
|
|||||||
:param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
|
:param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
|
||||||
:type pass_bot: :obj:`bool`
|
:type pass_bot: :obj:`bool`
|
||||||
|
|
||||||
|
:param kwargs: Optional keyword arguments(custom filters)
|
||||||
|
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
handler_dict = self._build_handler_dict(callback, func=func, pass_bot=pass_bot, **kwargs)
|
handler_dict = self._build_handler_dict(callback, func=func, pass_bot=pass_bot, **kwargs)
|
||||||
@ -5397,7 +5473,8 @@ class TeleBot:
|
|||||||
|
|
||||||
def pre_checkout_query_handler(self, func, **kwargs):
|
def pre_checkout_query_handler(self, func, **kwargs):
|
||||||
"""
|
"""
|
||||||
Pre-checkout request handler
|
New incoming pre-checkout query. Contains full information about checkout.
|
||||||
|
As a parameter to the decorator function, it passes :class:`telebot.types.PreCheckoutQuery` object.
|
||||||
|
|
||||||
:param func: Function executed as a filter
|
:param func: Function executed as a filter
|
||||||
:type func: :obj:`function`
|
:type func: :obj:`function`
|
||||||
@ -5437,6 +5514,8 @@ class TeleBot:
|
|||||||
:param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
|
:param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
|
||||||
:type pass_bot: :obj:`bool`
|
:type pass_bot: :obj:`bool`
|
||||||
|
|
||||||
|
:param kwargs: Optional keyword arguments(custom filters)
|
||||||
|
|
||||||
:return: decorated function
|
:return: decorated function
|
||||||
"""
|
"""
|
||||||
handler_dict = self._build_handler_dict(callback, func=func, pass_bot=pass_bot, **kwargs)
|
handler_dict = self._build_handler_dict(callback, func=func, pass_bot=pass_bot, **kwargs)
|
||||||
@ -5444,7 +5523,8 @@ class TeleBot:
|
|||||||
|
|
||||||
def poll_handler(self, func, **kwargs):
|
def poll_handler(self, func, **kwargs):
|
||||||
"""
|
"""
|
||||||
Poll request handler
|
Handles new state of a poll. Bots receive only updates about stopped polls and polls, which are sent by the bot
|
||||||
|
As a parameter to the decorator function, it passes :class:`telebot.types.Poll` object.
|
||||||
|
|
||||||
:param func: Function executed as a filter
|
:param func: Function executed as a filter
|
||||||
:type func: :obj:`function`
|
:type func: :obj:`function`
|
||||||
@ -5484,6 +5564,8 @@ class TeleBot:
|
|||||||
:param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
|
:param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
|
||||||
:type pass_bot: :obj:`bool`
|
:type pass_bot: :obj:`bool`
|
||||||
|
|
||||||
|
:param kwargs: Optional keyword arguments(custom filters)
|
||||||
|
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
handler_dict = self._build_handler_dict(callback, func=func, pass_bot=pass_bot, **kwargs)
|
handler_dict = self._build_handler_dict(callback, func=func, pass_bot=pass_bot, **kwargs)
|
||||||
@ -5491,7 +5573,9 @@ class TeleBot:
|
|||||||
|
|
||||||
def poll_answer_handler(self, func=None, **kwargs):
|
def poll_answer_handler(self, func=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Poll_answer request handler
|
Handles change of user's answer in a non-anonymous poll(when user changes the vote).
|
||||||
|
Bots receive new votes only in polls that were sent by the bot itself.
|
||||||
|
As a parameter to the decorator function, it passes :class:`telebot.types.PollAnswer` object.
|
||||||
|
|
||||||
:param func: Function executed as a filter
|
:param func: Function executed as a filter
|
||||||
:type func: :obj:`function`
|
:type func: :obj:`function`
|
||||||
@ -5532,6 +5616,8 @@ class TeleBot:
|
|||||||
:param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
|
:param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
|
||||||
:type pass_bot: :obj:`bool`
|
:type pass_bot: :obj:`bool`
|
||||||
|
|
||||||
|
:param kwargs: Optional keyword arguments(custom filters)
|
||||||
|
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
handler_dict = self._build_handler_dict(callback, func=func, pass_bot=pass_bot, **kwargs)
|
handler_dict = self._build_handler_dict(callback, func=func, pass_bot=pass_bot, **kwargs)
|
||||||
@ -5539,8 +5625,9 @@ class TeleBot:
|
|||||||
|
|
||||||
def my_chat_member_handler(self, func=None, **kwargs):
|
def my_chat_member_handler(self, func=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
The bot's chat member status was updated in a chat. For private chats,
|
Handles update in a status of a bot. For private chats,
|
||||||
this update is received only when the bot is blocked or unblocked by the user.
|
this update is received only when the bot is blocked or unblocked by the user.
|
||||||
|
As a parameter to the decorator function, it passes :class:`telebot.types.ChatMemberUpdated` object.
|
||||||
|
|
||||||
:param func: Function executed as a filter
|
:param func: Function executed as a filter
|
||||||
:type func: :obj:`function`
|
:type func: :obj:`function`
|
||||||
@ -5581,6 +5668,8 @@ class TeleBot:
|
|||||||
:param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
|
:param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
|
||||||
:type pass_bot: :obj:`bool`
|
:type pass_bot: :obj:`bool`
|
||||||
|
|
||||||
|
:param kwargs: Optional keyword arguments(custom filters)
|
||||||
|
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
handler_dict = self._build_handler_dict(callback, func=func, pass_bot=pass_bot, **kwargs)
|
handler_dict = self._build_handler_dict(callback, func=func, pass_bot=pass_bot, **kwargs)
|
||||||
@ -5588,8 +5677,10 @@ class TeleBot:
|
|||||||
|
|
||||||
def chat_member_handler(self, func=None, **kwargs):
|
def chat_member_handler(self, func=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
A chat member's status was updated in a chat. The bot must be an administrator
|
Handles update in a status of a user in a chat.
|
||||||
in the chat and must explicitly specify “chat_member” in the list of allowed_updates to receive these updates.
|
The bot must be an administrator in the chat and must explicitly specify “chat_member”
|
||||||
|
in the list of allowed_updates to receive these updates.
|
||||||
|
As a parameter to the decorator function, it passes :class:`telebot.types.ChatMemberUpdated` object.
|
||||||
|
|
||||||
:param func: Function executed as a filter
|
:param func: Function executed as a filter
|
||||||
:type func: :obj:`function`
|
:type func: :obj:`function`
|
||||||
@ -5639,8 +5730,9 @@ class TeleBot:
|
|||||||
|
|
||||||
def chat_join_request_handler(self, func=None, **kwargs):
|
def chat_join_request_handler(self, func=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
A request to join the chat has been sent. The bot must have the can_invite_users
|
Handles a request to join the chat has been sent. The bot must have the can_invite_users
|
||||||
administrator right in the chat to receive these updates.
|
administrator right in the chat to receive these updates.
|
||||||
|
As a parameter to the decorator function, it passes :class:`telebot.types.ChatJoinRequest` object.
|
||||||
|
|
||||||
:param func: Function executed as a filter
|
:param func: Function executed as a filter
|
||||||
:type func: :obj:`function`
|
:type func: :obj:`function`
|
||||||
@ -5681,6 +5773,8 @@ class TeleBot:
|
|||||||
:param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
|
:param pass_bot: True if you need to pass TeleBot instance to handler(useful for separating handlers into different files)
|
||||||
:type pass_bot: :obj:`bool`
|
:type pass_bot: :obj:`bool`
|
||||||
|
|
||||||
|
:param kwargs: Optional keyword arguments(custom filters)
|
||||||
|
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
handler_dict = self._build_handler_dict(callback, func=func, pass_bot=pass_bot, **kwargs)
|
handler_dict = self._build_handler_dict(callback, func=func, pass_bot=pass_bot, **kwargs)
|
||||||
@ -5707,6 +5801,15 @@ class TeleBot:
|
|||||||
"""
|
"""
|
||||||
Create custom filter.
|
Create custom filter.
|
||||||
|
|
||||||
|
.. code-block:: python3
|
||||||
|
:caption: Example on checking the text of a message
|
||||||
|
|
||||||
|
class TextMatchFilter(AdvancedCustomFilter):
|
||||||
|
key = 'text'
|
||||||
|
|
||||||
|
async def check(self, message, text):
|
||||||
|
return text == message.text
|
||||||
|
|
||||||
:param custom_filter: Class with check(message) method.
|
:param custom_filter: Class with check(message) method.
|
||||||
:param custom_filter: Custom filter class with key.
|
:param custom_filter: Custom filter class with key.
|
||||||
"""
|
"""
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -12,6 +12,17 @@ class SimpleCustomFilter(ABC):
|
|||||||
Accepts only message, returns bool value, that is compared with given in handler.
|
Accepts only message, returns bool value, that is compared with given in handler.
|
||||||
|
|
||||||
Child classes should have .key property.
|
Child classes should have .key property.
|
||||||
|
|
||||||
|
.. code-block:: python3
|
||||||
|
:caption: Example on creating a simple custom filter.
|
||||||
|
|
||||||
|
class ForwardFilter(SimpleCustomFilter):
|
||||||
|
# Check whether message was forwarded from channel or group.
|
||||||
|
key = 'is_forwarded'
|
||||||
|
|
||||||
|
def check(self, message):
|
||||||
|
return message.forward_date is not None
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
key: str = None
|
key: str = None
|
||||||
@ -25,13 +36,23 @@ class SimpleCustomFilter(ABC):
|
|||||||
|
|
||||||
class AdvancedCustomFilter(ABC):
|
class AdvancedCustomFilter(ABC):
|
||||||
"""
|
"""
|
||||||
Simple Custom Filter base class.
|
Advanced Custom Filter base class.
|
||||||
Create child class with check() method.
|
Create child class with check() method.
|
||||||
Accepts two parameters, returns bool: True - filter passed, False - filter failed.
|
Accepts two parameters, returns bool: True - filter passed, False - filter failed.
|
||||||
message: Message class
|
message: Message class
|
||||||
text: Filter value given in handler
|
text: Filter value given in handler
|
||||||
|
|
||||||
Child classes should have .key property.
|
Child classes should have .key property.
|
||||||
|
|
||||||
|
.. code-block:: python3
|
||||||
|
:caption: Example on creating an advanced custom filter.
|
||||||
|
|
||||||
|
class TextStartsFilter(AdvancedCustomFilter):
|
||||||
|
# Filter to check whether message starts with some text.
|
||||||
|
key = 'text_startswith'
|
||||||
|
|
||||||
|
def check(self, message, text):
|
||||||
|
return message.text.startswith(text)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
key: str = None
|
key: str = None
|
||||||
@ -48,6 +69,25 @@ class TextFilter:
|
|||||||
Advanced text filter to check (types.Message, types.CallbackQuery, types.InlineQuery, types.Poll)
|
Advanced text filter to check (types.Message, types.CallbackQuery, types.InlineQuery, types.Poll)
|
||||||
|
|
||||||
example of usage is in examples/asynchronous_telebot/custom_filters/advanced_text_filter.py
|
example of usage is in examples/asynchronous_telebot/custom_filters/advanced_text_filter.py
|
||||||
|
|
||||||
|
:param equals: string, True if object's text is equal to passed string
|
||||||
|
:type equals: :obj:`str`
|
||||||
|
|
||||||
|
:param contains: list[str] or tuple[str], True if any string element of iterable is in text
|
||||||
|
:type contains: list[str] or tuple[str]
|
||||||
|
|
||||||
|
:param starts_with: string, True if object's text starts with passed string
|
||||||
|
:type starts_with: :obj:`str`
|
||||||
|
|
||||||
|
:param ends_with: string, True if object's text starts with passed string
|
||||||
|
:type ends_with: :obj:`str`
|
||||||
|
|
||||||
|
:param ignore_case: bool (default False), case insensitive
|
||||||
|
:type ignore_case: :obj:`bool`
|
||||||
|
|
||||||
|
:raises ValueError: if incorrect value for a parameter was supplied
|
||||||
|
|
||||||
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
@ -56,13 +96,25 @@ class TextFilter:
|
|||||||
starts_with: Optional[Union[str, list, tuple]] = None,
|
starts_with: Optional[Union[str, list, tuple]] = None,
|
||||||
ends_with: Optional[Union[str, list, tuple]] = None,
|
ends_with: Optional[Union[str, list, tuple]] = None,
|
||||||
ignore_case: bool = False):
|
ignore_case: bool = False):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
:param equals: string, True if object's text is equal to passed string
|
:param equals: string, True if object's text is equal to passed string
|
||||||
|
:type equals: :obj:`str`
|
||||||
|
|
||||||
:param contains: list[str] or tuple[str], True if any string element of iterable is in text
|
:param contains: list[str] or tuple[str], True if any string element of iterable is in text
|
||||||
|
:type contains: list[str] or tuple[str]
|
||||||
|
|
||||||
:param starts_with: string, True if object's text starts with passed string
|
:param starts_with: string, True if object's text starts with passed string
|
||||||
|
:type starts_with: :obj:`str`
|
||||||
|
|
||||||
:param ends_with: string, True if object's text starts with passed string
|
:param ends_with: string, True if object's text starts with passed string
|
||||||
|
:type ends_with: :obj:`str`
|
||||||
|
|
||||||
:param ignore_case: bool (default False), case insensitive
|
:param ignore_case: bool (default False), case insensitive
|
||||||
|
:type ignore_case: :obj:`bool`
|
||||||
|
|
||||||
|
:raises ValueError: if incorrect value for a parameter was supplied
|
||||||
|
|
||||||
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
to_check = sum((pattern is not None for pattern in (equals, contains, starts_with, ends_with)))
|
to_check = sum((pattern is not None for pattern in (equals, contains, starts_with, ends_with)))
|
||||||
@ -87,7 +139,9 @@ class TextFilter:
|
|||||||
return iterable
|
return iterable
|
||||||
|
|
||||||
async def check(self, obj: Union[types.Message, types.CallbackQuery, types.InlineQuery, types.Poll]):
|
async def check(self, obj: Union[types.Message, types.CallbackQuery, types.InlineQuery, types.Poll]):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
if isinstance(obj, types.Poll):
|
if isinstance(obj, types.Poll):
|
||||||
text = obj.question
|
text = obj.question
|
||||||
elif isinstance(obj, types.Message):
|
elif isinstance(obj, types.Message):
|
||||||
@ -135,15 +189,20 @@ class TextFilter:
|
|||||||
class TextMatchFilter(AdvancedCustomFilter):
|
class TextMatchFilter(AdvancedCustomFilter):
|
||||||
"""
|
"""
|
||||||
Filter to check Text message.
|
Filter to check Text message.
|
||||||
key: text
|
|
||||||
|
|
||||||
Example:
|
.. code-block:: python3
|
||||||
|
:caption: Example on using this filter:
|
||||||
|
|
||||||
@bot.message_handler(text=['account'])
|
@bot.message_handler(text=['account'])
|
||||||
|
# your function
|
||||||
"""
|
"""
|
||||||
|
|
||||||
key = 'text'
|
key = 'text'
|
||||||
|
|
||||||
async def check(self, message, text):
|
async def check(self, message, text):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
if isinstance(text, TextFilter):
|
if isinstance(text, TextFilter):
|
||||||
return await text.check(message)
|
return await text.check(message)
|
||||||
elif type(text) is list:
|
elif type(text) is list:
|
||||||
@ -157,14 +216,21 @@ class TextContainsFilter(AdvancedCustomFilter):
|
|||||||
Filter to check Text message.
|
Filter to check Text message.
|
||||||
key: text
|
key: text
|
||||||
|
|
||||||
Example:
|
|
||||||
|
.. code-block:: python3
|
||||||
|
:caption: Example on using this filter:
|
||||||
|
|
||||||
# Will respond if any message.text contains word 'account'
|
# Will respond if any message.text contains word 'account'
|
||||||
@bot.message_handler(text_contains=['account'])
|
@bot.message_handler(text_contains=['account'])
|
||||||
|
# your function
|
||||||
"""
|
"""
|
||||||
|
|
||||||
key = 'text_contains'
|
key = 'text_contains'
|
||||||
|
|
||||||
async def check(self, message, text):
|
async def check(self, message, text):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
if not isinstance(text, str) and not isinstance(text, list) and not isinstance(text, tuple):
|
if not isinstance(text, str) and not isinstance(text, list) and not isinstance(text, tuple):
|
||||||
raise ValueError("Incorrect text_contains value")
|
raise ValueError("Incorrect text_contains value")
|
||||||
elif isinstance(text, str):
|
elif isinstance(text, str):
|
||||||
@ -179,14 +245,20 @@ class TextStartsFilter(AdvancedCustomFilter):
|
|||||||
"""
|
"""
|
||||||
Filter to check whether message starts with some text.
|
Filter to check whether message starts with some text.
|
||||||
|
|
||||||
Example:
|
.. code-block:: python3
|
||||||
# Will work if message.text starts with 'Sir'.
|
:caption: Example on using this filter:
|
||||||
@bot.message_handler(text_startswith='Sir')
|
|
||||||
|
# Will work if message.text starts with 'sir'.
|
||||||
|
@bot.message_handler(text_startswith='sir')
|
||||||
|
# your function
|
||||||
"""
|
"""
|
||||||
|
|
||||||
key = 'text_startswith'
|
key = 'text_startswith'
|
||||||
|
|
||||||
async def check(self, message, text):
|
async def check(self, message, text):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
return message.text.startswith(text)
|
return message.text.startswith(text)
|
||||||
|
|
||||||
|
|
||||||
@ -194,13 +266,19 @@ class ChatFilter(AdvancedCustomFilter):
|
|||||||
"""
|
"""
|
||||||
Check whether chat_id corresponds to given chat_id.
|
Check whether chat_id corresponds to given chat_id.
|
||||||
|
|
||||||
Example:
|
.. code-block:: python3
|
||||||
|
:caption: Example on using this filter:
|
||||||
|
|
||||||
@bot.message_handler(chat_id=[99999])
|
@bot.message_handler(chat_id=[99999])
|
||||||
|
# your function
|
||||||
"""
|
"""
|
||||||
|
|
||||||
key = 'chat_id'
|
key = 'chat_id'
|
||||||
|
|
||||||
async def check(self, message, text):
|
async def check(self, message, text):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
if isinstance(message, types.CallbackQuery):
|
if isinstance(message, types.CallbackQuery):
|
||||||
return message.message.chat.id in text
|
return message.message.chat.id in text
|
||||||
return message.chat.id in text
|
return message.chat.id in text
|
||||||
@ -210,14 +288,19 @@ class ForwardFilter(SimpleCustomFilter):
|
|||||||
"""
|
"""
|
||||||
Check whether message was forwarded from channel or group.
|
Check whether message was forwarded from channel or group.
|
||||||
|
|
||||||
Example:
|
.. code-block:: python3
|
||||||
|
:caption: Example on using this filter:
|
||||||
|
|
||||||
@bot.message_handler(is_forwarded=True)
|
@bot.message_handler(is_forwarded=True)
|
||||||
|
# your function
|
||||||
"""
|
"""
|
||||||
|
|
||||||
key = 'is_forwarded'
|
key = 'is_forwarded'
|
||||||
|
|
||||||
async def check(self, message):
|
async def check(self, message):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
return message.forward_date is not None
|
return message.forward_date is not None
|
||||||
|
|
||||||
|
|
||||||
@ -225,14 +308,19 @@ class IsReplyFilter(SimpleCustomFilter):
|
|||||||
"""
|
"""
|
||||||
Check whether message is a reply.
|
Check whether message is a reply.
|
||||||
|
|
||||||
Example:
|
.. code-block:: python3
|
||||||
|
:caption: Example on using this filter:
|
||||||
|
|
||||||
@bot.message_handler(is_reply=True)
|
@bot.message_handler(is_reply=True)
|
||||||
|
# your function
|
||||||
"""
|
"""
|
||||||
|
|
||||||
key = 'is_reply'
|
key = 'is_reply'
|
||||||
|
|
||||||
async def check(self, message):
|
async def check(self, message):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
if isinstance(message, types.CallbackQuery):
|
if isinstance(message, types.CallbackQuery):
|
||||||
return message.message.reply_to_message is not None
|
return message.message.reply_to_message is not None
|
||||||
return message.reply_to_message is not None
|
return message.reply_to_message is not None
|
||||||
@ -242,14 +330,19 @@ class LanguageFilter(AdvancedCustomFilter):
|
|||||||
"""
|
"""
|
||||||
Check users language_code.
|
Check users language_code.
|
||||||
|
|
||||||
Example:
|
.. code-block:: python3
|
||||||
|
:caption: Example on using this filter:
|
||||||
|
|
||||||
@bot.message_handler(language_code=['ru'])
|
@bot.message_handler(language_code=['ru'])
|
||||||
|
# your function
|
||||||
"""
|
"""
|
||||||
|
|
||||||
key = 'language_code'
|
key = 'language_code'
|
||||||
|
|
||||||
async def check(self, message, text):
|
async def check(self, message, text):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
if type(text) is list:
|
if type(text) is list:
|
||||||
return message.from_user.language_code in text
|
return message.from_user.language_code in text
|
||||||
else:
|
else:
|
||||||
@ -260,8 +353,11 @@ class IsAdminFilter(SimpleCustomFilter):
|
|||||||
"""
|
"""
|
||||||
Check whether the user is administrator / owner of the chat.
|
Check whether the user is administrator / owner of the chat.
|
||||||
|
|
||||||
Example:
|
.. code-block:: python3
|
||||||
|
:caption: Example on using this filter:
|
||||||
|
|
||||||
@bot.message_handler(chat_types=['supergroup'], is_chat_admin=True)
|
@bot.message_handler(chat_types=['supergroup'], is_chat_admin=True)
|
||||||
|
# your function
|
||||||
"""
|
"""
|
||||||
|
|
||||||
key = 'is_chat_admin'
|
key = 'is_chat_admin'
|
||||||
@ -270,6 +366,9 @@ class IsAdminFilter(SimpleCustomFilter):
|
|||||||
self._bot = bot
|
self._bot = bot
|
||||||
|
|
||||||
async def check(self, message):
|
async def check(self, message):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
if isinstance(message, types.CallbackQuery):
|
if isinstance(message, types.CallbackQuery):
|
||||||
result = await self._bot.get_chat_member(message.message.chat.id, message.from_user.id)
|
result = await self._bot.get_chat_member(message.message.chat.id, message.from_user.id)
|
||||||
return result.status ('creator', 'administrator')
|
return result.status ('creator', 'administrator')
|
||||||
@ -281,8 +380,11 @@ class StateFilter(AdvancedCustomFilter):
|
|||||||
"""
|
"""
|
||||||
Filter to check state.
|
Filter to check state.
|
||||||
|
|
||||||
Example:
|
.. code-block:: python3
|
||||||
|
:caption: Example on using this filter:
|
||||||
|
|
||||||
@bot.message_handler(state=1)
|
@bot.message_handler(state=1)
|
||||||
|
# your function
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
@ -291,6 +393,9 @@ class StateFilter(AdvancedCustomFilter):
|
|||||||
key = 'state'
|
key = 'state'
|
||||||
|
|
||||||
async def check(self, message, text):
|
async def check(self, message, text):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
if text == '*': return True
|
if text == '*': return True
|
||||||
|
|
||||||
# needs to work with callbackquery
|
# needs to work with callbackquery
|
||||||
@ -334,10 +439,16 @@ class IsDigitFilter(SimpleCustomFilter):
|
|||||||
"""
|
"""
|
||||||
Filter to check whether the string is made up of only digits.
|
Filter to check whether the string is made up of only digits.
|
||||||
|
|
||||||
Example:
|
.. code-block:: python3
|
||||||
|
:caption: Example on using this filter:
|
||||||
|
|
||||||
@bot.message_handler(is_digit=True)
|
@bot.message_handler(is_digit=True)
|
||||||
|
# your function
|
||||||
"""
|
"""
|
||||||
key = 'is_digit'
|
key = 'is_digit'
|
||||||
|
|
||||||
async def check(self, message):
|
async def check(self, message):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
return message.text.isdigit()
|
return message.text.isdigit()
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
"""
|
||||||
|
File with all middleware classes, states.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class BaseMiddleware:
|
class BaseMiddleware:
|
||||||
"""
|
"""
|
||||||
Base class for middleware.
|
Base class for middleware.
|
||||||
@ -9,23 +16,25 @@ class BaseMiddleware:
|
|||||||
so on. Same applies to post_process.
|
so on. Same applies to post_process.
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
:caption: Example of class-based middlewares
|
||||||
|
|
||||||
class MyMiddleware(BaseMiddleware):
|
class MyMiddleware(BaseMiddleware):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.update_sensitive = True
|
self.update_sensitive = True
|
||||||
self.update_types = ['message', 'edited_message']
|
self.update_types = ['message', 'edited_message']
|
||||||
|
|
||||||
def pre_process_message(self, message, data):
|
async def pre_process_message(self, message, data):
|
||||||
# only message update here
|
# only message update here
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def post_process_message(self, message, data, exception):
|
async def post_process_message(self, message, data, exception):
|
||||||
pass # only message update here for post_process
|
pass # only message update here for post_process
|
||||||
|
|
||||||
def pre_process_edited_message(self, message, data):
|
async def pre_process_edited_message(self, message, data):
|
||||||
# only edited_message update here
|
# only edited_message update here
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def post_process_edited_message(self, message, data, exception):
|
async def post_process_edited_message(self, message, data, exception):
|
||||||
pass # only edited_message update here for post_process
|
pass # only edited_message update here for post_process
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -42,6 +51,14 @@ class BaseMiddleware:
|
|||||||
|
|
||||||
|
|
||||||
class State:
|
class State:
|
||||||
|
"""
|
||||||
|
Class representing a state.
|
||||||
|
|
||||||
|
.. code-block:: python3
|
||||||
|
|
||||||
|
class MyStates(StatesGroup):
|
||||||
|
my_state = State() # returns my_state:State string.
|
||||||
|
"""
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.name = None
|
self.name = None
|
||||||
|
|
||||||
@ -50,6 +67,14 @@ class State:
|
|||||||
|
|
||||||
|
|
||||||
class StatesGroup:
|
class StatesGroup:
|
||||||
|
"""
|
||||||
|
Class representing common states.
|
||||||
|
|
||||||
|
.. code-block:: python3
|
||||||
|
|
||||||
|
class MyStates(StatesGroup):
|
||||||
|
my_state = State() # returns my_state:State string.
|
||||||
|
"""
|
||||||
def __init_subclass__(cls) -> None:
|
def __init_subclass__(cls) -> None:
|
||||||
|
|
||||||
for name, value in cls.__dict__.items():
|
for name, value in cls.__dict__.items():
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
"""
|
||||||
|
Callback data factory's file.
|
||||||
|
"""
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2017-2018 Alex Root Junior
|
Copyright (c) 2017-2018 Alex Root Junior
|
||||||
|
|
||||||
@ -29,17 +33,23 @@ import typing
|
|||||||
|
|
||||||
|
|
||||||
class CallbackDataFilter:
|
class CallbackDataFilter:
|
||||||
|
"""
|
||||||
|
Filter for CallbackData.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, factory, config: typing.Dict[str, str]):
|
def __init__(self, factory, config: typing.Dict[str, str]):
|
||||||
self.config = config
|
self.config = config
|
||||||
self.factory = factory
|
self.factory = factory
|
||||||
|
|
||||||
def check(self, query):
|
def check(self, query) -> bool:
|
||||||
"""
|
"""
|
||||||
Checks if query.data appropriates to specified config
|
Checks if query.data appropriates to specified config
|
||||||
|
|
||||||
:param query: telebot.types.CallbackQuery
|
:param query: telebot.types.CallbackQuery
|
||||||
:return: bool
|
:type query: telebot.types.CallbackQuery
|
||||||
|
|
||||||
|
:return: True if query.data appropriates to specified config
|
||||||
|
:rtype: bool
|
||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -135,7 +145,7 @@ class CallbackData:
|
|||||||
"""
|
"""
|
||||||
Generate filter
|
Generate filter
|
||||||
|
|
||||||
:param config: specified named parameters will be checked with CallbackQury.data
|
:param config: specified named parameters will be checked with CallbackQuery.data
|
||||||
:return: CallbackDataFilter class
|
:return: CallbackDataFilter class
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -14,6 +14,17 @@ class SimpleCustomFilter(ABC):
|
|||||||
Accepts only message, returns bool value, that is compared with given in handler.
|
Accepts only message, returns bool value, that is compared with given in handler.
|
||||||
|
|
||||||
Child classes should have .key property.
|
Child classes should have .key property.
|
||||||
|
|
||||||
|
.. code-block:: python3
|
||||||
|
:caption: Example on creating a simple custom filter.
|
||||||
|
|
||||||
|
class ForwardFilter(SimpleCustomFilter):
|
||||||
|
# Check whether message was forwarded from channel or group.
|
||||||
|
key = 'is_forwarded'
|
||||||
|
|
||||||
|
def check(self, message):
|
||||||
|
return message.forward_date is not None
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
key: str = None
|
key: str = None
|
||||||
@ -27,13 +38,23 @@ class SimpleCustomFilter(ABC):
|
|||||||
|
|
||||||
class AdvancedCustomFilter(ABC):
|
class AdvancedCustomFilter(ABC):
|
||||||
"""
|
"""
|
||||||
Simple Custom Filter base class.
|
Advanced Custom Filter base class.
|
||||||
Create child class with check() method.
|
Create child class with check() method.
|
||||||
Accepts two parameters, returns bool: True - filter passed, False - filter failed.
|
Accepts two parameters, returns bool: True - filter passed, False - filter failed.
|
||||||
message: Message class
|
message: Message class
|
||||||
text: Filter value given in handler
|
text: Filter value given in handler
|
||||||
|
|
||||||
Child classes should have .key property.
|
Child classes should have .key property.
|
||||||
|
|
||||||
|
.. code-block:: python3
|
||||||
|
:caption: Example on creating an advanced custom filter.
|
||||||
|
|
||||||
|
class TextStartsFilter(AdvancedCustomFilter):
|
||||||
|
# Filter to check whether message starts with some text.
|
||||||
|
key = 'text_startswith'
|
||||||
|
|
||||||
|
def check(self, message, text):
|
||||||
|
return message.text.startswith(text)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
key: str = None
|
key: str = None
|
||||||
@ -50,6 +71,25 @@ class TextFilter:
|
|||||||
Advanced text filter to check (types.Message, types.CallbackQuery, types.InlineQuery, types.Poll)
|
Advanced text filter to check (types.Message, types.CallbackQuery, types.InlineQuery, types.Poll)
|
||||||
|
|
||||||
example of usage is in examples/custom_filters/advanced_text_filter.py
|
example of usage is in examples/custom_filters/advanced_text_filter.py
|
||||||
|
|
||||||
|
:param equals: string, True if object's text is equal to passed string
|
||||||
|
:type equals: :obj:`str`
|
||||||
|
|
||||||
|
:param contains: list[str] or tuple[str], True if any string element of iterable is in text
|
||||||
|
:type contains: list[str] or tuple[str]
|
||||||
|
|
||||||
|
:param starts_with: string, True if object's text starts with passed string
|
||||||
|
:type starts_with: :obj:`str`
|
||||||
|
|
||||||
|
:param ends_with: string, True if object's text starts with passed string
|
||||||
|
:type ends_with: :obj:`str`
|
||||||
|
|
||||||
|
:param ignore_case: bool (default False), case insensitive
|
||||||
|
:type ignore_case: :obj:`bool`
|
||||||
|
|
||||||
|
:raises ValueError: if incorrect value for a parameter was supplied
|
||||||
|
|
||||||
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
@ -58,13 +98,25 @@ class TextFilter:
|
|||||||
starts_with: Optional[Union[str, list, tuple]] = None,
|
starts_with: Optional[Union[str, list, tuple]] = None,
|
||||||
ends_with: Optional[Union[str, list, tuple]] = None,
|
ends_with: Optional[Union[str, list, tuple]] = None,
|
||||||
ignore_case: bool = False):
|
ignore_case: bool = False):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
:param equals: string, True if object's text is equal to passed string
|
:param equals: string, True if object's text is equal to passed string
|
||||||
|
:type equals: :obj:`str`
|
||||||
|
|
||||||
:param contains: list[str] or tuple[str], True if any string element of iterable is in text
|
:param contains: list[str] or tuple[str], True if any string element of iterable is in text
|
||||||
|
:type contains: list[str] or tuple[str]
|
||||||
|
|
||||||
:param starts_with: string, True if object's text starts with passed string
|
:param starts_with: string, True if object's text starts with passed string
|
||||||
|
:type starts_with: :obj:`str`
|
||||||
|
|
||||||
:param ends_with: string, True if object's text starts with passed string
|
:param ends_with: string, True if object's text starts with passed string
|
||||||
|
:type ends_with: :obj:`str`
|
||||||
|
|
||||||
:param ignore_case: bool (default False), case insensitive
|
:param ignore_case: bool (default False), case insensitive
|
||||||
|
:type ignore_case: :obj:`bool`
|
||||||
|
|
||||||
|
:raises ValueError: if incorrect value for a parameter was supplied
|
||||||
|
|
||||||
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
to_check = sum((pattern is not None for pattern in (equals, contains, starts_with, ends_with)))
|
to_check = sum((pattern is not None for pattern in (equals, contains, starts_with, ends_with)))
|
||||||
@ -89,6 +141,9 @@ class TextFilter:
|
|||||||
return iterable
|
return iterable
|
||||||
|
|
||||||
def check(self, obj: Union[types.Message, types.CallbackQuery, types.InlineQuery, types.Poll]):
|
def check(self, obj: Union[types.Message, types.CallbackQuery, types.InlineQuery, types.Poll]):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
|
|
||||||
if isinstance(obj, types.Poll):
|
if isinstance(obj, types.Poll):
|
||||||
text = obj.question
|
text = obj.question
|
||||||
@ -142,15 +197,20 @@ class TextFilter:
|
|||||||
class TextMatchFilter(AdvancedCustomFilter):
|
class TextMatchFilter(AdvancedCustomFilter):
|
||||||
"""
|
"""
|
||||||
Filter to check Text message.
|
Filter to check Text message.
|
||||||
key: text
|
|
||||||
|
|
||||||
Example:
|
.. code-block:: python3
|
||||||
|
:caption: Example on using this filter:
|
||||||
|
|
||||||
@bot.message_handler(text=['account'])
|
@bot.message_handler(text=['account'])
|
||||||
|
# your function
|
||||||
"""
|
"""
|
||||||
|
|
||||||
key = 'text'
|
key = 'text'
|
||||||
|
|
||||||
def check(self, message, text):
|
def check(self, message, text):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
if isinstance(text, TextFilter):
|
if isinstance(text, TextFilter):
|
||||||
return text.check(message)
|
return text.check(message)
|
||||||
elif type(text) is list:
|
elif type(text) is list:
|
||||||
@ -164,14 +224,21 @@ class TextContainsFilter(AdvancedCustomFilter):
|
|||||||
Filter to check Text message.
|
Filter to check Text message.
|
||||||
key: text
|
key: text
|
||||||
|
|
||||||
Example:
|
|
||||||
|
.. code-block:: python3
|
||||||
|
:caption: Example on using this filter:
|
||||||
|
|
||||||
# Will respond if any message.text contains word 'account'
|
# Will respond if any message.text contains word 'account'
|
||||||
@bot.message_handler(text_contains=['account'])
|
@bot.message_handler(text_contains=['account'])
|
||||||
|
# your function
|
||||||
"""
|
"""
|
||||||
|
|
||||||
key = 'text_contains'
|
key = 'text_contains'
|
||||||
|
|
||||||
def check(self, message, text):
|
def check(self, message, text):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
if not isinstance(text, str) and not isinstance(text, list) and not isinstance(text, tuple):
|
if not isinstance(text, str) and not isinstance(text, list) and not isinstance(text, tuple):
|
||||||
raise ValueError("Incorrect text_contains value")
|
raise ValueError("Incorrect text_contains value")
|
||||||
elif isinstance(text, str):
|
elif isinstance(text, str):
|
||||||
@ -186,14 +253,20 @@ class TextStartsFilter(AdvancedCustomFilter):
|
|||||||
"""
|
"""
|
||||||
Filter to check whether message starts with some text.
|
Filter to check whether message starts with some text.
|
||||||
|
|
||||||
Example:
|
.. code-block:: python3
|
||||||
# Will work if message.text starts with 'Sir'.
|
:caption: Example on using this filter:
|
||||||
@bot.message_handler(text_startswith='Sir')
|
|
||||||
|
# Will work if message.text starts with 'sir'.
|
||||||
|
@bot.message_handler(text_startswith='sir')
|
||||||
|
# your function
|
||||||
"""
|
"""
|
||||||
|
|
||||||
key = 'text_startswith'
|
key = 'text_startswith'
|
||||||
|
|
||||||
def check(self, message, text):
|
def check(self, message, text):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
return message.text.startswith(text)
|
return message.text.startswith(text)
|
||||||
|
|
||||||
|
|
||||||
@ -201,13 +274,19 @@ class ChatFilter(AdvancedCustomFilter):
|
|||||||
"""
|
"""
|
||||||
Check whether chat_id corresponds to given chat_id.
|
Check whether chat_id corresponds to given chat_id.
|
||||||
|
|
||||||
Example:
|
.. code-block:: python3
|
||||||
|
:caption: Example on using this filter:
|
||||||
|
|
||||||
@bot.message_handler(chat_id=[99999])
|
@bot.message_handler(chat_id=[99999])
|
||||||
|
# your function
|
||||||
"""
|
"""
|
||||||
|
|
||||||
key = 'chat_id'
|
key = 'chat_id'
|
||||||
|
|
||||||
def check(self, message, text):
|
def check(self, message, text):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
if isinstance(message, types.CallbackQuery):
|
if isinstance(message, types.CallbackQuery):
|
||||||
return message.message.chat.id in text
|
return message.message.chat.id in text
|
||||||
return message.chat.id in text
|
return message.chat.id in text
|
||||||
@ -217,14 +296,19 @@ class ForwardFilter(SimpleCustomFilter):
|
|||||||
"""
|
"""
|
||||||
Check whether message was forwarded from channel or group.
|
Check whether message was forwarded from channel or group.
|
||||||
|
|
||||||
Example:
|
.. code-block:: python3
|
||||||
|
:caption: Example on using this filter:
|
||||||
|
|
||||||
@bot.message_handler(is_forwarded=True)
|
@bot.message_handler(is_forwarded=True)
|
||||||
|
# your function
|
||||||
"""
|
"""
|
||||||
|
|
||||||
key = 'is_forwarded'
|
key = 'is_forwarded'
|
||||||
|
|
||||||
def check(self, message):
|
def check(self, message):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
return message.forward_date is not None
|
return message.forward_date is not None
|
||||||
|
|
||||||
|
|
||||||
@ -232,14 +316,19 @@ class IsReplyFilter(SimpleCustomFilter):
|
|||||||
"""
|
"""
|
||||||
Check whether message is a reply.
|
Check whether message is a reply.
|
||||||
|
|
||||||
Example:
|
.. code-block:: python3
|
||||||
|
:caption: Example on using this filter:
|
||||||
|
|
||||||
@bot.message_handler(is_reply=True)
|
@bot.message_handler(is_reply=True)
|
||||||
|
# your function
|
||||||
"""
|
"""
|
||||||
|
|
||||||
key = 'is_reply'
|
key = 'is_reply'
|
||||||
|
|
||||||
def check(self, message):
|
def check(self, message):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
if isinstance(message, types.CallbackQuery):
|
if isinstance(message, types.CallbackQuery):
|
||||||
return message.message.reply_to_message is not None
|
return message.message.reply_to_message is not None
|
||||||
return message.reply_to_message is not None
|
return message.reply_to_message is not None
|
||||||
@ -249,14 +338,19 @@ class LanguageFilter(AdvancedCustomFilter):
|
|||||||
"""
|
"""
|
||||||
Check users language_code.
|
Check users language_code.
|
||||||
|
|
||||||
Example:
|
.. code-block:: python3
|
||||||
|
:caption: Example on using this filter:
|
||||||
|
|
||||||
@bot.message_handler(language_code=['ru'])
|
@bot.message_handler(language_code=['ru'])
|
||||||
|
# your function
|
||||||
"""
|
"""
|
||||||
|
|
||||||
key = 'language_code'
|
key = 'language_code'
|
||||||
|
|
||||||
def check(self, message, text):
|
def check(self, message, text):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
if type(text) is list:
|
if type(text) is list:
|
||||||
return message.from_user.language_code in text
|
return message.from_user.language_code in text
|
||||||
else:
|
else:
|
||||||
@ -267,8 +361,11 @@ class IsAdminFilter(SimpleCustomFilter):
|
|||||||
"""
|
"""
|
||||||
Check whether the user is administrator / owner of the chat.
|
Check whether the user is administrator / owner of the chat.
|
||||||
|
|
||||||
Example:
|
.. code-block:: python3
|
||||||
|
:caption: Example on using this filter:
|
||||||
|
|
||||||
@bot.message_handler(chat_types=['supergroup'], is_chat_admin=True)
|
@bot.message_handler(chat_types=['supergroup'], is_chat_admin=True)
|
||||||
|
# your function
|
||||||
"""
|
"""
|
||||||
|
|
||||||
key = 'is_chat_admin'
|
key = 'is_chat_admin'
|
||||||
@ -277,6 +374,9 @@ class IsAdminFilter(SimpleCustomFilter):
|
|||||||
self._bot = bot
|
self._bot = bot
|
||||||
|
|
||||||
def check(self, message):
|
def check(self, message):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
if isinstance(message, types.CallbackQuery):
|
if isinstance(message, types.CallbackQuery):
|
||||||
return self._bot.get_chat_member(message.message.chat.id, message.from_user.id).status in ['creator', 'administrator']
|
return self._bot.get_chat_member(message.message.chat.id, message.from_user.id).status in ['creator', 'administrator']
|
||||||
return self._bot.get_chat_member(message.chat.id, message.from_user.id).status in ['creator', 'administrator']
|
return self._bot.get_chat_member(message.chat.id, message.from_user.id).status in ['creator', 'administrator']
|
||||||
@ -286,8 +386,11 @@ class StateFilter(AdvancedCustomFilter):
|
|||||||
"""
|
"""
|
||||||
Filter to check state.
|
Filter to check state.
|
||||||
|
|
||||||
Example:
|
.. code-block:: python3
|
||||||
|
:caption: Example on using this filter:
|
||||||
|
|
||||||
@bot.message_handler(state=1)
|
@bot.message_handler(state=1)
|
||||||
|
# your function
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, bot):
|
def __init__(self, bot):
|
||||||
@ -296,6 +399,9 @@ class StateFilter(AdvancedCustomFilter):
|
|||||||
key = 'state'
|
key = 'state'
|
||||||
|
|
||||||
def check(self, message, text):
|
def check(self, message, text):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
if text == '*': return True
|
if text == '*': return True
|
||||||
|
|
||||||
# needs to work with callbackquery
|
# needs to work with callbackquery
|
||||||
@ -341,10 +447,16 @@ class IsDigitFilter(SimpleCustomFilter):
|
|||||||
"""
|
"""
|
||||||
Filter to check whether the string is made up of only digits.
|
Filter to check whether the string is made up of only digits.
|
||||||
|
|
||||||
Example:
|
.. code-block:: python3
|
||||||
|
:caption: Example on using this filter:
|
||||||
|
|
||||||
@bot.message_handler(is_digit=True)
|
@bot.message_handler(is_digit=True)
|
||||||
|
# your function
|
||||||
"""
|
"""
|
||||||
key = 'is_digit'
|
key = 'is_digit'
|
||||||
|
|
||||||
def check(self, message):
|
def check(self, message):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
return message.text.isdigit()
|
return message.text.isdigit()
|
||||||
|
@ -34,14 +34,34 @@ class AsyncWebhookListener:
|
|||||||
"""
|
"""
|
||||||
Aynchronous implementation of webhook listener
|
Aynchronous implementation of webhook listener
|
||||||
for asynchronous version of telebot.
|
for asynchronous version of telebot.
|
||||||
|
Not supposed to be used manually by user.
|
||||||
|
Use AsyncTeleBot.run_webhooks() instead.
|
||||||
|
|
||||||
|
:param bot: AsyncTeleBot instance.
|
||||||
|
:type bot: telebot.async_telebot.AsyncTeleBot
|
||||||
|
|
||||||
:param bot: TeleBot instance
|
|
||||||
:param secret_token: Telegram secret token
|
:param secret_token: Telegram secret token
|
||||||
|
:type secret_token: str
|
||||||
|
|
||||||
:param host: Webhook host
|
:param host: Webhook host
|
||||||
|
:type host: str
|
||||||
|
|
||||||
:param port: Webhook port
|
:param port: Webhook port
|
||||||
|
:type port: int
|
||||||
|
|
||||||
:param ssl_context: SSL context
|
:param ssl_context: SSL context
|
||||||
|
:type ssl_context: tuple
|
||||||
|
|
||||||
:param url_path: Webhook url path
|
:param url_path: Webhook url path
|
||||||
|
:type url_path: str
|
||||||
|
|
||||||
:param debug: Debug mode
|
:param debug: Debug mode
|
||||||
|
:type debug: bool
|
||||||
|
|
||||||
|
:raises ImportError: If FastAPI or uvicorn is not installed.
|
||||||
|
:raises ImportError: If Starlette version is too old.
|
||||||
|
|
||||||
|
:return: None
|
||||||
"""
|
"""
|
||||||
self._check_dependencies()
|
self._check_dependencies()
|
||||||
|
|
||||||
@ -73,6 +93,8 @@ class AsyncWebhookListener:
|
|||||||
async def process_update(self, request: Request, update: dict):
|
async def process_update(self, request: Request, update: dict):
|
||||||
"""
|
"""
|
||||||
Processes updates.
|
Processes updates.
|
||||||
|
|
||||||
|
:meta private:
|
||||||
"""
|
"""
|
||||||
# header containsX-Telegram-Bot-Api-Secret-Token
|
# header containsX-Telegram-Bot-Api-Secret-Token
|
||||||
if request.headers.get('X-Telegram-Bot-Api-Secret-Token') != self._secret_token:
|
if request.headers.get('X-Telegram-Bot-Api-Secret-Token') != self._secret_token:
|
||||||
@ -88,7 +110,10 @@ class AsyncWebhookListener:
|
|||||||
|
|
||||||
async def run_app(self):
|
async def run_app(self):
|
||||||
"""
|
"""
|
||||||
Run app with the given parameters.
|
Run app with the given parameters to init.
|
||||||
|
Not supposed to be used manually by user.
|
||||||
|
|
||||||
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
config = Config(app=self.app,
|
config = Config(app=self.app,
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
"""
|
"""
|
||||||
This file is used by TeleBot.run_webhooks() &
|
This file is used by TeleBot.run_webhooks() function.
|
||||||
AsyncTeleBot.run_webhooks() functions.
|
|
||||||
|
|
||||||
Flask/fastapi is required to run this script.
|
Fastapi is required to run this script.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# modules required for running this script
|
# modules required for running this script
|
||||||
@ -34,16 +33,36 @@ class SyncWebhookListener:
|
|||||||
debug: Optional[bool]=False
|
debug: Optional[bool]=False
|
||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Synchronous implementation of webhook listener
|
Aynchronous implementation of webhook listener
|
||||||
for synchronous version of telebot.
|
for asynchronous version of telebot.
|
||||||
|
Not supposed to be used manually by user.
|
||||||
|
Use AsyncTeleBot.run_webhooks() instead.
|
||||||
|
|
||||||
|
:param bot: AsyncTeleBot instance.
|
||||||
|
:type bot: telebot.async_telebot.AsyncTeleBot
|
||||||
|
|
||||||
:param bot: TeleBot instance
|
|
||||||
:param secret_token: Telegram secret token
|
:param secret_token: Telegram secret token
|
||||||
|
:type secret_token: str
|
||||||
|
|
||||||
:param host: Webhook host
|
:param host: Webhook host
|
||||||
|
:type host: str
|
||||||
|
|
||||||
:param port: Webhook port
|
:param port: Webhook port
|
||||||
|
:type port: int
|
||||||
|
|
||||||
:param ssl_context: SSL context
|
:param ssl_context: SSL context
|
||||||
|
:type ssl_context: tuple
|
||||||
|
|
||||||
:param url_path: Webhook url path
|
:param url_path: Webhook url path
|
||||||
|
:type url_path: str
|
||||||
|
|
||||||
:param debug: Debug mode
|
:param debug: Debug mode
|
||||||
|
:type debug: bool
|
||||||
|
|
||||||
|
:raises ImportError: If FastAPI or uvicorn is not installed.
|
||||||
|
:raises ImportError: If Starlette version is too old.
|
||||||
|
|
||||||
|
:return: None
|
||||||
"""
|
"""
|
||||||
self._check_dependencies()
|
self._check_dependencies()
|
||||||
|
|
||||||
@ -75,6 +94,8 @@ class SyncWebhookListener:
|
|||||||
def process_update(self, request: Request, update: dict):
|
def process_update(self, request: Request, update: dict):
|
||||||
"""
|
"""
|
||||||
Processes updates.
|
Processes updates.
|
||||||
|
|
||||||
|
:meta private:
|
||||||
"""
|
"""
|
||||||
# header containsX-Telegram-Bot-Api-Secret-Token
|
# header containsX-Telegram-Bot-Api-Secret-Token
|
||||||
if request.headers.get('X-Telegram-Bot-Api-Secret-Token') != self._secret_token:
|
if request.headers.get('X-Telegram-Bot-Api-Secret-Token') != self._secret_token:
|
||||||
@ -89,7 +110,10 @@ class SyncWebhookListener:
|
|||||||
|
|
||||||
def run_app(self):
|
def run_app(self):
|
||||||
"""
|
"""
|
||||||
Run app with the given parameters.
|
Run app with the given parameters to init.
|
||||||
|
Not supposed to be used manually by user.
|
||||||
|
|
||||||
|
:return: None
|
||||||
"""
|
"""
|
||||||
|
|
||||||
uvicorn.run(app=self.app,
|
uvicorn.run(app=self.app,
|
||||||
|
@ -5,14 +5,17 @@ Markdown & HTML formatting functions.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import html
|
import html
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
|
||||||
def format_text(*args, separator="\n"):
|
def format_text(*args, separator="\n"):
|
||||||
"""
|
"""
|
||||||
Formats a list of strings into a single string.
|
Formats a list of strings into a single string.
|
||||||
|
|
||||||
.. code:: python
|
.. code:: python3
|
||||||
|
|
||||||
format_text( # just an example
|
format_text( # just an example
|
||||||
mbold('Hello'),
|
mbold('Hello'),
|
||||||
@ -20,7 +23,13 @@ def format_text(*args, separator="\n"):
|
|||||||
)
|
)
|
||||||
|
|
||||||
:param args: Strings to format.
|
:param args: Strings to format.
|
||||||
|
:type args: :obj:`str`
|
||||||
|
|
||||||
:param separator: The separator to use between each string.
|
:param separator: The separator to use between each string.
|
||||||
|
:type separator: :obj:`str`
|
||||||
|
|
||||||
|
:return: The formatted string.
|
||||||
|
:rtype: :obj:`str`
|
||||||
"""
|
"""
|
||||||
return separator.join(args)
|
return separator.join(args)
|
||||||
|
|
||||||
@ -31,6 +40,10 @@ def escape_html(content: str) -> str:
|
|||||||
Escapes HTML characters in a string of HTML.
|
Escapes HTML characters in a string of HTML.
|
||||||
|
|
||||||
:param content: The string of HTML to escape.
|
:param content: The string of HTML to escape.
|
||||||
|
:type content: :obj:`str`
|
||||||
|
|
||||||
|
:return: The escaped string.
|
||||||
|
:rtype: :obj:`str`
|
||||||
"""
|
"""
|
||||||
return html.escape(content)
|
return html.escape(content)
|
||||||
|
|
||||||
@ -39,9 +52,13 @@ def escape_markdown(content: str) -> str:
|
|||||||
"""
|
"""
|
||||||
Escapes Markdown characters in a string of Markdown.
|
Escapes Markdown characters in a string of Markdown.
|
||||||
|
|
||||||
Credits: simonsmh
|
Credits to: simonsmh
|
||||||
|
|
||||||
:param content: The string of Markdown to escape.
|
:param content: The string of Markdown to escape.
|
||||||
|
:type content: :obj:`str`
|
||||||
|
|
||||||
|
:return: The escaped string.
|
||||||
|
:rtype: :obj:`str`
|
||||||
"""
|
"""
|
||||||
|
|
||||||
parse = re.sub(r"([_*\[\]()~`>\#\+\-=|\.!])", r"\\\1", content)
|
parse = re.sub(r"([_*\[\]()~`>\#\+\-=|\.!])", r"\\\1", content)
|
||||||
@ -49,154 +66,249 @@ def escape_markdown(content: str) -> str:
|
|||||||
return reparse
|
return reparse
|
||||||
|
|
||||||
|
|
||||||
def mbold(content: str, escape: bool=True) -> str:
|
def mbold(content: str, escape: Optional[bool]=True) -> str:
|
||||||
"""
|
"""
|
||||||
Returns a Markdown-formatted bold string.
|
Returns a Markdown-formatted bold string.
|
||||||
|
|
||||||
:param content: The string to bold.
|
:param content: The string to bold.
|
||||||
:param escape: True if you need to escape special characters.
|
:type content: :obj:`str`
|
||||||
|
|
||||||
|
:param escape: True if you need to escape special characters. Defaults to True.
|
||||||
|
:type escape: :obj:`bool`
|
||||||
|
|
||||||
|
:return: The formatted string.
|
||||||
|
:rtype: :obj:`str`
|
||||||
"""
|
"""
|
||||||
return '*{}*'.format(escape_markdown(content) if escape else content)
|
return '*{}*'.format(escape_markdown(content) if escape else content)
|
||||||
|
|
||||||
|
|
||||||
def hbold(content: str, escape: bool=True) -> str:
|
def hbold(content: str, escape: Optional[bool]=True) -> str:
|
||||||
"""
|
"""
|
||||||
Returns an HTML-formatted bold string.
|
Returns an HTML-formatted bold string.
|
||||||
|
|
||||||
:param content: The string to bold.
|
:param content: The string to bold.
|
||||||
:param escape: True if you need to escape special characters.
|
:type content: :obj:`str`
|
||||||
|
|
||||||
|
:param escape: True if you need to escape special characters. Defaults to True.
|
||||||
|
:type escape: :obj:`bool`
|
||||||
|
|
||||||
|
:return: The formatted string.
|
||||||
|
:rtype: :obj:`str`
|
||||||
"""
|
"""
|
||||||
return '<b>{}</b>'.format(escape_html(content) if escape else content)
|
return '<b>{}</b>'.format(escape_html(content) if escape else content)
|
||||||
|
|
||||||
|
|
||||||
def mitalic(content: str, escape: bool=True) -> str:
|
def mitalic(content: str, escape: Optional[bool]=True) -> str:
|
||||||
"""
|
"""
|
||||||
Returns a Markdown-formatted italic string.
|
Returns a Markdown-formatted italic string.
|
||||||
|
|
||||||
:param content: The string to italicize.
|
:param content: The string to italicize.
|
||||||
:param escape: True if you need to escape special characters.
|
:type content: :obj:`str`
|
||||||
|
|
||||||
|
:param escape: True if you need to escape special characters. Defaults to True.
|
||||||
|
:type escape: :obj:`bool`
|
||||||
|
|
||||||
|
:return: The formatted string.
|
||||||
|
:rtype: :obj:`str`
|
||||||
"""
|
"""
|
||||||
return '_{}_\r'.format(escape_markdown(content) if escape else content)
|
return '_{}_\r'.format(escape_markdown(content) if escape else content)
|
||||||
|
|
||||||
|
|
||||||
def hitalic(content: str, escape: bool=True) -> str:
|
def hitalic(content: str, escape: Optional[bool]=True) -> str:
|
||||||
"""
|
"""
|
||||||
Returns an HTML-formatted italic string.
|
Returns an HTML-formatted italic string.
|
||||||
|
|
||||||
:param content: The string to italicize.
|
:param content: The string to italicize.
|
||||||
:param escape: True if you need to escape special characters.
|
:type content: :obj:`str`
|
||||||
|
|
||||||
|
:param escape: True if you need to escape special characters. Defaults to True.
|
||||||
|
:type escape: :obj:`bool`
|
||||||
|
|
||||||
|
:return: The formatted string.
|
||||||
|
:rtype: :obj:`str`
|
||||||
"""
|
"""
|
||||||
return '<i>{}</i>'.format(escape_html(content) if escape else content)
|
return '<i>{}</i>'.format(escape_html(content) if escape else content)
|
||||||
|
|
||||||
|
|
||||||
def munderline(content: str, escape: bool=True) -> str:
|
def munderline(content: str, escape: Optional[bool]=True) -> str:
|
||||||
"""
|
"""
|
||||||
Returns a Markdown-formatted underline string.
|
Returns a Markdown-formatted underline string.
|
||||||
|
|
||||||
:param content: The string to underline.
|
:param content: The string to underline.
|
||||||
:param escape: True if you need to escape special characters.
|
:type content: :obj:`str`
|
||||||
|
|
||||||
|
:param escape: True if you need to escape special characters. Defaults to True.
|
||||||
|
:type escape: :obj:`bool`
|
||||||
|
|
||||||
|
:return: The formatted string.
|
||||||
|
:rtype: :obj:`str`
|
||||||
"""
|
"""
|
||||||
return '__{}__'.format(escape_markdown(content) if escape else content)
|
return '__{}__'.format(escape_markdown(content) if escape else content)
|
||||||
|
|
||||||
|
|
||||||
def hunderline(content: str, escape: bool=True) -> str:
|
def hunderline(content: str, escape: Optional[bool]=True) -> str:
|
||||||
"""
|
"""
|
||||||
Returns an HTML-formatted underline string.
|
Returns an HTML-formatted underline string.
|
||||||
|
|
||||||
:param content: The string to underline.
|
:param content: The string to underline.
|
||||||
:param escape: True if you need to escape special characters.
|
:type content: :obj:`str`
|
||||||
|
|
||||||
|
:param escape: True if you need to escape special characters. Defaults to True.
|
||||||
|
:type escape: :obj:`bool`
|
||||||
|
|
||||||
|
:return: The formatted string.
|
||||||
|
:rtype: :obj:`str`
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return '<u>{}</u>'.format(escape_html(content) if escape else content)
|
return '<u>{}</u>'.format(escape_html(content) if escape else content)
|
||||||
|
|
||||||
|
|
||||||
def mstrikethrough(content: str, escape: bool=True) -> str:
|
def mstrikethrough(content: str, escape: Optional[bool]=True) -> str:
|
||||||
"""
|
"""
|
||||||
Returns a Markdown-formatted strikethrough string.
|
Returns a Markdown-formatted strikethrough string.
|
||||||
|
|
||||||
:param content: The string to strikethrough.
|
:param content: The string to strikethrough.
|
||||||
:param escape: True if you need to escape special characters.
|
:type content: :obj:`str`
|
||||||
|
|
||||||
|
:param escape: True if you need to escape special characters. Defaults to True.
|
||||||
|
:type escape: :obj:`bool`
|
||||||
|
|
||||||
|
:return: The formatted string.
|
||||||
|
:rtype: :obj:`str`
|
||||||
"""
|
"""
|
||||||
return '~{}~'.format(escape_markdown(content) if escape else content)
|
return '~{}~'.format(escape_markdown(content) if escape else content)
|
||||||
|
|
||||||
|
|
||||||
def hstrikethrough(content: str, escape: bool=True) -> str:
|
def hstrikethrough(content: str, escape: Optional[bool]=True) -> str:
|
||||||
"""
|
"""
|
||||||
Returns an HTML-formatted strikethrough string.
|
Returns an HTML-formatted strikethrough string.
|
||||||
|
|
||||||
:param content: The string to strikethrough.
|
:param content: The string to strikethrough.
|
||||||
:param escape: True if you need to escape special characters.
|
:type content: :obj:`str`
|
||||||
|
|
||||||
|
:param escape: True if you need to escape special characters. Defaults to True.
|
||||||
|
:type escape: :obj:`bool`
|
||||||
|
|
||||||
|
:return: The formatted string.
|
||||||
|
:rtype: :obj:`str`
|
||||||
"""
|
"""
|
||||||
return '<s>{}</s>'.format(escape_html(content) if escape else content)
|
return '<s>{}</s>'.format(escape_html(content) if escape else content)
|
||||||
|
|
||||||
|
|
||||||
def mspoiler(content: str, escape: bool=True) -> str:
|
def mspoiler(content: str, escape: Optional[bool]=True) -> str:
|
||||||
"""
|
"""
|
||||||
Returns a Markdown-formatted spoiler string.
|
Returns a Markdown-formatted spoiler string.
|
||||||
|
|
||||||
:param content: The string to spoiler.
|
:param content: The string to spoiler.
|
||||||
:param escape: True if you need to escape special characters.
|
:type content: :obj:`str`
|
||||||
|
|
||||||
|
:param escape: True if you need to escape special characters. Defaults to True.
|
||||||
|
:type escape: :obj:`bool`
|
||||||
|
|
||||||
|
:return: The formatted string.
|
||||||
|
:rtype: :obj:`str`
|
||||||
"""
|
"""
|
||||||
return '||{}||'.format(escape_markdown(content) if escape else content)
|
return '||{}||'.format(escape_markdown(content) if escape else content)
|
||||||
|
|
||||||
|
|
||||||
def hspoiler(content: str, escape: bool=True) -> str:
|
def hspoiler(content: str, escape: Optional[bool]=True) -> str:
|
||||||
"""
|
"""
|
||||||
Returns an HTML-formatted spoiler string.
|
Returns an HTML-formatted spoiler string.
|
||||||
|
|
||||||
:param content: The string to spoiler.
|
:param content: The string to spoiler.
|
||||||
:param escape: True if you need to escape special characters.
|
:type content: :obj:`str`
|
||||||
|
|
||||||
|
:param escape: True if you need to escape special characters. Defaults to True.
|
||||||
|
:type escape: :obj:`bool`
|
||||||
|
|
||||||
|
:return: The formatted string.
|
||||||
|
:rtype: :obj:`str`
|
||||||
"""
|
"""
|
||||||
return '<tg-spoiler>{}</tg-spoiler>'.format(escape_html(content) if escape else content)
|
return '<tg-spoiler>{}</tg-spoiler>'.format(escape_html(content) if escape else content)
|
||||||
|
|
||||||
|
|
||||||
def mlink(content: str, url: str, escape: bool=True) -> str:
|
def mlink(content: str, url: str, escape: Optional[bool]=True) -> str:
|
||||||
"""
|
"""
|
||||||
Returns a Markdown-formatted link string.
|
Returns a Markdown-formatted link string.
|
||||||
|
|
||||||
:param content: The string to link.
|
:param content: The string to link.
|
||||||
|
:type content: :obj:`str`
|
||||||
|
|
||||||
:param url: The URL to link to.
|
:param url: The URL to link to.
|
||||||
:param escape: True if you need to escape special characters.
|
:type url: str
|
||||||
|
|
||||||
|
:param escape: True if you need to escape special characters. Defaults to True.
|
||||||
|
:type escape: :obj:`bool`
|
||||||
|
|
||||||
|
:return: The formatted string.
|
||||||
|
:rtype: :obj:`str`
|
||||||
"""
|
"""
|
||||||
return '[{}]({})'.format(escape_markdown(content), escape_markdown(url) if escape else content)
|
return '[{}]({})'.format(escape_markdown(content), escape_markdown(url) if escape else content)
|
||||||
|
|
||||||
|
|
||||||
def hlink(content: str, url: str, escape: bool=True) -> str:
|
def hlink(content: str, url: str, escape: Optional[bool]=True) -> str:
|
||||||
"""
|
"""
|
||||||
Returns an HTML-formatted link string.
|
Returns an HTML-formatted link string.
|
||||||
|
|
||||||
:param content: The string to link.
|
:param content: The string to link.
|
||||||
|
:type content: :obj:`str`
|
||||||
|
|
||||||
:param url: The URL to link to.
|
:param url: The URL to link to.
|
||||||
:param escape: True if you need to escape special characters.
|
:type url: :obj:`str`
|
||||||
|
|
||||||
|
:param escape: True if you need to escape special characters. Defaults to True.
|
||||||
|
:type escape: :obj:`bool`
|
||||||
|
|
||||||
|
:return: The formatted string.
|
||||||
|
:rtype: :obj:`str`
|
||||||
"""
|
"""
|
||||||
return '<a href="{}">{}</a>'.format(escape_html(url), escape_html(content) if escape else content)
|
return '<a href="{}">{}</a>'.format(escape_html(url), escape_html(content) if escape else content)
|
||||||
|
|
||||||
|
|
||||||
def mcode(content: str, language: str="", escape: bool=True) -> str:
|
def mcode(content: str, language: str="", escape: Optional[bool]=True) -> str:
|
||||||
"""
|
"""
|
||||||
Returns a Markdown-formatted code string.
|
Returns a Markdown-formatted code string.
|
||||||
|
|
||||||
:param content: The string to code.
|
:param content: The string to code.
|
||||||
:param escape: True if you need to escape special characters.
|
:type content: :obj:`str`
|
||||||
|
|
||||||
|
:param escape: True if you need to escape special characters. Defaults to True.
|
||||||
|
:type escape: :obj:`bool`
|
||||||
|
|
||||||
|
:return: The formatted string.
|
||||||
|
:rtype: :obj:`str`
|
||||||
"""
|
"""
|
||||||
return '```{}\n{}```'.format(language, escape_markdown(content) if escape else content)
|
return '```{}\n{}```'.format(language, escape_markdown(content) if escape else content)
|
||||||
|
|
||||||
|
|
||||||
def hcode(content: str, escape: bool=True) -> str:
|
def hcode(content: str, escape: Optional[bool]=True) -> str:
|
||||||
"""
|
"""
|
||||||
Returns an HTML-formatted code string.
|
Returns an HTML-formatted code string.
|
||||||
|
|
||||||
:param content: The string to code.
|
:param content: The string to code.
|
||||||
:param escape: True if you need to escape special characters.
|
:type content: :obj:`str`
|
||||||
|
|
||||||
|
:param escape: True if you need to escape special characters. Defaults to True.
|
||||||
|
:type escape: :obj:`bool`
|
||||||
|
|
||||||
|
:return: The formatted string.
|
||||||
|
:rtype: :obj:`str`
|
||||||
"""
|
"""
|
||||||
return '<code>{}</code>'.format(escape_html(content) if escape else content)
|
return '<code>{}</code>'.format(escape_html(content) if escape else content)
|
||||||
|
|
||||||
|
|
||||||
def hpre(content: str, escape: bool=True, language: str="") -> str:
|
def hpre(content: str, escape: Optional[bool]=True, language: str="") -> str:
|
||||||
"""
|
"""
|
||||||
Returns an HTML-formatted preformatted string.
|
Returns an HTML-formatted preformatted string.
|
||||||
|
|
||||||
:param content: The string to preformatted.
|
:param content: The string to preformatted.
|
||||||
:param escape: True if you need to escape special characters.
|
:type content: :obj:`str`
|
||||||
|
|
||||||
|
:param escape: True if you need to escape special characters. Defaults to True.
|
||||||
|
:type escape: :obj:`bool`
|
||||||
|
|
||||||
|
:return: The formatted string.
|
||||||
|
:rtype: :obj:`str`
|
||||||
"""
|
"""
|
||||||
return '<pre><code class="{}">{}</code></pre>'.format(language, escape_html(content) if escape else content)
|
return '<pre><code class="{}">{}</code></pre>'.format(language, escape_html(content) if escape else content)
|
||||||
|
|
||||||
@ -205,7 +317,10 @@ def hide_link(url: str) -> str:
|
|||||||
"""
|
"""
|
||||||
Hide url of an image.
|
Hide url of an image.
|
||||||
|
|
||||||
:param url:
|
:param url: The url of the image.
|
||||||
:return: str
|
:type url: :obj:`str`
|
||||||
|
|
||||||
|
:return: The hidden url.
|
||||||
|
:rtype: :obj:`str`
|
||||||
"""
|
"""
|
||||||
return f'<a href="{url}">⁠</a>'
|
return f'<a href="{url}">⁠</a>'
|
@ -12,7 +12,9 @@ except:
|
|||||||
|
|
||||||
class HandlerBackend(object):
|
class HandlerBackend(object):
|
||||||
"""
|
"""
|
||||||
Class for saving (next step|reply) handlers
|
Class for saving (next step|reply) handlers.
|
||||||
|
|
||||||
|
:meta private:
|
||||||
"""
|
"""
|
||||||
def __init__(self, handlers=None):
|
def __init__(self, handlers=None):
|
||||||
if handlers is None:
|
if handlers is None:
|
||||||
@ -30,6 +32,9 @@ class HandlerBackend(object):
|
|||||||
|
|
||||||
|
|
||||||
class MemoryHandlerBackend(HandlerBackend):
|
class MemoryHandlerBackend(HandlerBackend):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
def register_handler(self, handler_group_id, handler):
|
def register_handler(self, handler_group_id, handler):
|
||||||
if handler_group_id in self.handlers:
|
if handler_group_id in self.handlers:
|
||||||
self.handlers[handler_group_id].append(handler)
|
self.handlers[handler_group_id].append(handler)
|
||||||
@ -47,6 +52,9 @@ class MemoryHandlerBackend(HandlerBackend):
|
|||||||
|
|
||||||
|
|
||||||
class FileHandlerBackend(HandlerBackend):
|
class FileHandlerBackend(HandlerBackend):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
def __init__(self, handlers=None, filename='./.handler-saves/handlers.save', delay=120):
|
def __init__(self, handlers=None, filename='./.handler-saves/handlers.save', delay=120):
|
||||||
super(FileHandlerBackend, self).__init__(handlers)
|
super(FileHandlerBackend, self).__init__(handlers)
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
@ -119,6 +127,9 @@ class FileHandlerBackend(HandlerBackend):
|
|||||||
|
|
||||||
|
|
||||||
class RedisHandlerBackend(HandlerBackend):
|
class RedisHandlerBackend(HandlerBackend):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
def __init__(self, handlers=None, host='localhost', port=6379, db=0, prefix='telebot', password=None):
|
def __init__(self, handlers=None, host='localhost', port=6379, db=0, prefix='telebot', password=None):
|
||||||
super(RedisHandlerBackend, self).__init__(handlers)
|
super(RedisHandlerBackend, self).__init__(handlers)
|
||||||
if not redis_installed:
|
if not redis_installed:
|
||||||
@ -150,6 +161,14 @@ class RedisHandlerBackend(HandlerBackend):
|
|||||||
|
|
||||||
|
|
||||||
class State:
|
class State:
|
||||||
|
"""
|
||||||
|
Class representing a state.
|
||||||
|
|
||||||
|
.. code-block:: python3
|
||||||
|
|
||||||
|
class MyStates(StatesGroup):
|
||||||
|
my_state = State() # returns my_state:State string.
|
||||||
|
"""
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.name = None
|
self.name = None
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
@ -158,6 +177,14 @@ class State:
|
|||||||
|
|
||||||
|
|
||||||
class StatesGroup:
|
class StatesGroup:
|
||||||
|
"""
|
||||||
|
Class representing common states.
|
||||||
|
|
||||||
|
.. code-block:: python3
|
||||||
|
|
||||||
|
class MyStates(StatesGroup):
|
||||||
|
my_state = State() # returns my_state:State string.
|
||||||
|
"""
|
||||||
def __init_subclass__(cls) -> None:
|
def __init_subclass__(cls) -> None:
|
||||||
for name, value in cls.__dict__.items():
|
for name, value in cls.__dict__.items():
|
||||||
if not name.startswith('__') and not callable(value) and isinstance(value, State):
|
if not name.startswith('__') and not callable(value) and isinstance(value, State):
|
||||||
@ -179,7 +206,12 @@ class BaseMiddleware:
|
|||||||
message update, then you will have to create pre_process_message function, and
|
message update, then you will have to create pre_process_message function, and
|
||||||
so on. Same applies to post_process.
|
so on. Same applies to post_process.
|
||||||
|
|
||||||
.. code-block:: python
|
.. note::
|
||||||
|
If you want to use middleware, you have to set use_class_middlewares=True in your
|
||||||
|
TeleBot instance.
|
||||||
|
|
||||||
|
.. code-block:: python3
|
||||||
|
:caption: Example of class-based middlewares.
|
||||||
|
|
||||||
class MyMiddleware(BaseMiddleware):
|
class MyMiddleware(BaseMiddleware):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -20,6 +20,7 @@ class JsonSerializable(object):
|
|||||||
"""
|
"""
|
||||||
Subclasses of this class are guaranteed to be able to be converted to JSON format.
|
Subclasses of this class are guaranteed to be able to be converted to JSON format.
|
||||||
All subclasses of this class must override to_json.
|
All subclasses of this class must override to_json.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def to_json(self):
|
def to_json(self):
|
||||||
@ -36,6 +37,7 @@ class Dictionaryable(object):
|
|||||||
"""
|
"""
|
||||||
Subclasses of this class are guaranteed to be able to be converted to dictionary.
|
Subclasses of this class are guaranteed to be able to be converted to dictionary.
|
||||||
All subclasses of this class must override to_dict.
|
All subclasses of this class must override to_dict.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
@ -90,6 +92,65 @@ class JsonDeserializable(object):
|
|||||||
|
|
||||||
|
|
||||||
class Update(JsonDeserializable):
|
class Update(JsonDeserializable):
|
||||||
|
"""
|
||||||
|
This object represents an incoming update.
|
||||||
|
|
||||||
|
https://core.telegram.org/bots/api#update
|
||||||
|
|
||||||
|
:attribute update_id: The update's unique identifier. Update identifiers start from a certain positive number and increase sequentially.
|
||||||
|
This ID becomes especially handy if you're using webhooks, since it allows you to ignore repeated updates or to restore the correct
|
||||||
|
update sequence, should they get out of order. If there are no new updates for at least a week, then identifier of the next update will
|
||||||
|
be chosen randomly instead of sequentially.
|
||||||
|
:type update_id: int
|
||||||
|
|
||||||
|
:attribute message: New incoming message of any kind — text, photo, sticker, etc.
|
||||||
|
:type message: :class:`telebot.types.Message`
|
||||||
|
|
||||||
|
:attribute edited_message: New version of a message that is known to the bot and was edited.
|
||||||
|
:type edited_message: :class:`telebot.types.Message`
|
||||||
|
|
||||||
|
:attribute channel_post: New incoming channel post of any kind — text, photo, sticker, etc.
|
||||||
|
:type channel_post: :class:`telebot.types.Message`
|
||||||
|
|
||||||
|
:attribute edited_channel_post: New version of a channel post that is known to the bot and was edited.
|
||||||
|
:type edited_channel_post: :class:`telebot.types.Message`
|
||||||
|
|
||||||
|
:attribute inline_query: New incoming query from a user, which is answered by a bot and can be further processed.
|
||||||
|
:type inline_query: :class:`telebot.types.InlineQuery`
|
||||||
|
|
||||||
|
:attribute chosen_inline_result: New incoming result of an inline query that was chosen by a user and sent to their chat partner.
|
||||||
|
:type chosen_inline_result: :class:`telebot.types.ChosenInlineResult`
|
||||||
|
|
||||||
|
:attribute callback_query: New incoming callback query from a user.
|
||||||
|
:type callback_query: :class:`telebot.types.CallbackQuery`
|
||||||
|
|
||||||
|
:attribute shipping_query: New incoming shipping query. Only for invoices with flexible price
|
||||||
|
:type shipping_query: :class:`telebot.types.ShippingQuery`
|
||||||
|
|
||||||
|
:attribute pre_checkout_query: New incoming pre-checkout query. Contains full information about checkout
|
||||||
|
:type pre_checkout_query: :class:`telebot.types.PreCheckoutQuery`
|
||||||
|
|
||||||
|
:attribute poll: New poll state. Bots receive only updates about stopped polls and polls, which are sent by the bot
|
||||||
|
:type poll: :class:`telebot.types.Poll`
|
||||||
|
|
||||||
|
:attribute poll_answer: A user changed their answer in a non-anonymous poll. Bots receive new votes only in polls that were sent by the bot itself.
|
||||||
|
:type poll_answer: :class:`telebot.types.PollAnswer`
|
||||||
|
|
||||||
|
:attribute my_chat_member: The bot's chat member status was updated in a chat. For private chats,
|
||||||
|
this update is received only when the bot is blocked or unblocked by the user.
|
||||||
|
:type my_chat_member: :class:`telebot.types.ChatMember`
|
||||||
|
|
||||||
|
:attribute chat_member: A chat member's status was updated in a chat. The bot must be an administrator in the chat and must
|
||||||
|
explicitly specify “chat_member” in the list of allowed_updates to receive these updates.
|
||||||
|
:type chat_member: :class:`telebot.types.ChatMember`
|
||||||
|
|
||||||
|
:attribute chat_join_request: A request to join the chat has been sent. The bot must have the can_invite_users
|
||||||
|
administrator right in the chat to receive these updates.
|
||||||
|
:type chat_join_request: :class:`telebot.types.ChatJoinRequest`
|
||||||
|
|
||||||
|
:return: An Update object.
|
||||||
|
:rtype: :class:`telebot.types.Update`
|
||||||
|
"""
|
||||||
@classmethod
|
@classmethod
|
||||||
def de_json(cls, json_string):
|
def de_json(cls, json_string):
|
||||||
if json_string is None: return None
|
if json_string is None: return None
|
||||||
|
191
telebot/util.py
191
telebot/util.py
@ -35,11 +35,13 @@ logger = logging.getLogger('TeleBot')
|
|||||||
|
|
||||||
thread_local = threading.local()
|
thread_local = threading.local()
|
||||||
|
|
||||||
|
#: Contains all media content types.
|
||||||
content_type_media = [
|
content_type_media = [
|
||||||
'text', 'audio', 'animation', 'document', 'photo', 'sticker', 'video', 'video_note', 'voice', 'contact', 'dice', 'poll',
|
'text', 'audio', 'animation', 'document', 'photo', 'sticker', 'video', 'video_note', 'voice', 'contact', 'dice', 'poll',
|
||||||
'venue', 'location'
|
'venue', 'location'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
#: Contains all service content types such as `User joined the group`.
|
||||||
content_type_service = [
|
content_type_service = [
|
||||||
'new_chat_members', 'left_chat_member', 'new_chat_title', 'new_chat_photo', 'delete_chat_photo', 'group_chat_created',
|
'new_chat_members', 'left_chat_member', 'new_chat_title', 'new_chat_photo', 'delete_chat_photo', 'group_chat_created',
|
||||||
'supergroup_chat_created', 'channel_chat_created', 'migrate_to_chat_id', 'migrate_from_chat_id', 'pinned_message',
|
'supergroup_chat_created', 'channel_chat_created', 'migrate_to_chat_id', 'migrate_from_chat_id', 'pinned_message',
|
||||||
@ -47,6 +49,7 @@ content_type_service = [
|
|||||||
'video_chat_participants_invited', 'message_auto_delete_timer_changed'
|
'video_chat_participants_invited', 'message_auto_delete_timer_changed'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
#: All update types, should be used for allowed_updates parameter in polling.
|
||||||
update_types = [
|
update_types = [
|
||||||
"message", "edited_message", "channel_post", "edited_channel_post", "inline_query",
|
"message", "edited_message", "channel_post", "edited_channel_post", "inline_query",
|
||||||
"chosen_inline_result", "callback_query", "shipping_query", "pre_checkout_query", "poll", "poll_answer",
|
"chosen_inline_result", "callback_query", "shipping_query", "pre_checkout_query", "poll", "poll_answer",
|
||||||
@ -55,6 +58,9 @@ update_types = [
|
|||||||
|
|
||||||
|
|
||||||
class WorkerThread(threading.Thread):
|
class WorkerThread(threading.Thread):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
count = 0
|
count = 0
|
||||||
|
|
||||||
def __init__(self, exception_callback=None, queue=None, name=None):
|
def __init__(self, exception_callback=None, queue=None, name=None):
|
||||||
@ -118,7 +124,9 @@ class WorkerThread(threading.Thread):
|
|||||||
|
|
||||||
|
|
||||||
class ThreadPool:
|
class ThreadPool:
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
def __init__(self, telebot, num_threads=2):
|
def __init__(self, telebot, num_threads=2):
|
||||||
self.telebot = telebot
|
self.telebot = telebot
|
||||||
self.tasks = Queue.Queue()
|
self.tasks = Queue.Queue()
|
||||||
@ -156,6 +164,9 @@ class ThreadPool:
|
|||||||
|
|
||||||
|
|
||||||
class AsyncTask:
|
class AsyncTask:
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
def __init__(self, target, *args, **kwargs):
|
def __init__(self, target, *args, **kwargs):
|
||||||
self.target = target
|
self.target = target
|
||||||
self.args = args
|
self.args = args
|
||||||
@ -182,6 +193,9 @@ class AsyncTask:
|
|||||||
|
|
||||||
|
|
||||||
class CustomRequestResponse():
|
class CustomRequestResponse():
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
def __init__(self, json_text, status_code = 200, reason = ""):
|
def __init__(self, json_text, status_code = 200, reason = ""):
|
||||||
self.status_code = status_code
|
self.status_code = status_code
|
||||||
self.text = json_text
|
self.text = json_text
|
||||||
@ -192,6 +206,9 @@ class CustomRequestResponse():
|
|||||||
|
|
||||||
|
|
||||||
def async_dec():
|
def async_dec():
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
def decorator(fn):
|
def decorator(fn):
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
return AsyncTask(fn, *args, **kwargs)
|
return AsyncTask(fn, *args, **kwargs)
|
||||||
@ -201,19 +218,49 @@ def async_dec():
|
|||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
def is_string(var):
|
def is_string(var) -> bool:
|
||||||
|
"""
|
||||||
|
Returns True if the given object is a string.
|
||||||
|
"""
|
||||||
return isinstance(var, str)
|
return isinstance(var, str)
|
||||||
|
|
||||||
|
|
||||||
def is_dict(var):
|
def is_dict(var) -> bool:
|
||||||
|
"""
|
||||||
|
Returns True if the given object is a dictionary.
|
||||||
|
|
||||||
|
:param var: object to be checked
|
||||||
|
:type var: :obj:`object`
|
||||||
|
|
||||||
|
:return: True if the given object is a dictionary.
|
||||||
|
:rtype: :obj:`bool`
|
||||||
|
"""
|
||||||
return isinstance(var, dict)
|
return isinstance(var, dict)
|
||||||
|
|
||||||
|
|
||||||
def is_bytes(var):
|
def is_bytes(var) -> bool:
|
||||||
|
"""
|
||||||
|
Returns True if the given object is a bytes object.
|
||||||
|
|
||||||
|
:param var: object to be checked
|
||||||
|
:type var: :obj:`object`
|
||||||
|
|
||||||
|
:return: True if the given object is a bytes object.
|
||||||
|
:rtype: :obj:`bool`
|
||||||
|
"""
|
||||||
return isinstance(var, bytes)
|
return isinstance(var, bytes)
|
||||||
|
|
||||||
|
|
||||||
def is_pil_image(var):
|
def is_pil_image(var) -> bool:
|
||||||
|
"""
|
||||||
|
Returns True if the given object is a PIL.Image.Image object.
|
||||||
|
|
||||||
|
:param var: object to be checked
|
||||||
|
:type var: :obj:`object`
|
||||||
|
|
||||||
|
:return: True if the given object is a PIL.Image.Image object.
|
||||||
|
:rtype: :obj:`bool`
|
||||||
|
"""
|
||||||
return pil_imported and isinstance(var, Image.Image)
|
return pil_imported and isinstance(var, Image.Image)
|
||||||
|
|
||||||
|
|
||||||
@ -233,7 +280,10 @@ def is_command(text: str) -> bool:
|
|||||||
Checks if `text` is a command. Telegram chat commands start with the '/' character.
|
Checks if `text` is a command. Telegram chat commands start with the '/' character.
|
||||||
|
|
||||||
:param text: Text to check.
|
:param text: Text to check.
|
||||||
|
:type text: :obj:`str`
|
||||||
|
|
||||||
:return: True if `text` is a command, else False.
|
:return: True if `text` is a command, else False.
|
||||||
|
:rtype: :obj:`bool`
|
||||||
"""
|
"""
|
||||||
if text is None: return False
|
if text is None: return False
|
||||||
return text.startswith('/')
|
return text.startswith('/')
|
||||||
@ -244,30 +294,40 @@ def extract_command(text: str) -> Union[str, None]:
|
|||||||
Extracts the command from `text` (minus the '/') if `text` is a command (see is_command).
|
Extracts the command from `text` (minus the '/') if `text` is a command (see is_command).
|
||||||
If `text` is not a command, this function returns None.
|
If `text` is not a command, this function returns None.
|
||||||
|
|
||||||
Examples:
|
.. code-block:: python3
|
||||||
|
:caption: Examples:
|
||||||
|
|
||||||
extract_command('/help'): 'help'
|
extract_command('/help'): 'help'
|
||||||
extract_command('/help@BotName'): 'help'
|
extract_command('/help@BotName'): 'help'
|
||||||
extract_command('/search black eyed peas'): 'search'
|
extract_command('/search black eyed peas'): 'search'
|
||||||
extract_command('Good day to you'): None
|
extract_command('Good day to you'): None
|
||||||
|
|
||||||
:param text: String to extract the command from
|
:param text: String to extract the command from
|
||||||
|
:type text: :obj:`str`
|
||||||
|
|
||||||
:return: the command if `text` is a command (according to is_command), else None.
|
:return: the command if `text` is a command (according to is_command), else None.
|
||||||
|
:rtype: :obj:`str` or :obj:`None`
|
||||||
"""
|
"""
|
||||||
if text is None: return None
|
if text is None: return None
|
||||||
return text.split()[0].split('@')[0][1:] if is_command(text) else None
|
return text.split()[0].split('@')[0][1:] if is_command(text) else None
|
||||||
|
|
||||||
|
|
||||||
def extract_arguments(text: str) -> str:
|
def extract_arguments(text: str) -> str or None:
|
||||||
"""
|
"""
|
||||||
Returns the argument after the command.
|
Returns the argument after the command.
|
||||||
|
|
||||||
Examples:
|
.. code-block:: python3
|
||||||
|
:caption: Examples:
|
||||||
|
|
||||||
extract_arguments("/get name"): 'name'
|
extract_arguments("/get name"): 'name'
|
||||||
extract_arguments("/get"): ''
|
extract_arguments("/get"): ''
|
||||||
extract_arguments("/get@botName name"): 'name'
|
extract_arguments("/get@botName name"): 'name'
|
||||||
|
|
||||||
:param text: String to extract the arguments from a command
|
:param text: String to extract the arguments from a command
|
||||||
|
:type text: :obj:`str`
|
||||||
|
|
||||||
:return: the arguments if `text` is a command (according to is_command), else None.
|
:return: the arguments if `text` is a command (according to is_command), else None.
|
||||||
|
:rtype: :obj:`str` or :obj:`None`
|
||||||
"""
|
"""
|
||||||
regexp = re.compile(r"/\w*(@\w*)*\s*([\s\S]*)", re.IGNORECASE)
|
regexp = re.compile(r"/\w*(@\w*)*\s*([\s\S]*)", re.IGNORECASE)
|
||||||
result = regexp.match(text)
|
result = regexp.match(text)
|
||||||
@ -280,8 +340,13 @@ def split_string(text: str, chars_per_string: int) -> List[str]:
|
|||||||
This is very useful for splitting one giant message into multiples.
|
This is very useful for splitting one giant message into multiples.
|
||||||
|
|
||||||
:param text: The text to split
|
:param text: The text to split
|
||||||
|
:type text: :obj:`str`
|
||||||
|
|
||||||
:param chars_per_string: The number of characters per line the text is split into.
|
:param chars_per_string: The number of characters per line the text is split into.
|
||||||
|
:type chars_per_string: :obj:`int`
|
||||||
|
|
||||||
:return: The splitted text as a list of strings.
|
:return: The splitted text as a list of strings.
|
||||||
|
:rtype: :obj:`list` of :obj:`str`
|
||||||
"""
|
"""
|
||||||
return [text[i:i + chars_per_string] for i in range(0, len(text), chars_per_string)]
|
return [text[i:i + chars_per_string] for i in range(0, len(text), chars_per_string)]
|
||||||
|
|
||||||
@ -294,8 +359,13 @@ def smart_split(text: str, chars_per_string: int=MAX_MESSAGE_LENGTH) -> List[str
|
|||||||
Splits by '\n', '. ' or ' ' in exactly this priority.
|
Splits by '\n', '. ' or ' ' in exactly this priority.
|
||||||
|
|
||||||
:param text: The text to split
|
:param text: The text to split
|
||||||
|
:type text: :obj:`str`
|
||||||
|
|
||||||
:param chars_per_string: The number of maximum characters per part the text is split to.
|
:param chars_per_string: The number of maximum characters per part the text is split to.
|
||||||
|
:type chars_per_string: :obj:`int`
|
||||||
|
|
||||||
:return: The splitted text as a list of strings.
|
:return: The splitted text as a list of strings.
|
||||||
|
:rtype: :obj:`list` of :obj:`str`
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _text_before_last(substr: str) -> str:
|
def _text_before_last(substr: str) -> str:
|
||||||
@ -336,12 +406,25 @@ def user_link(user: types.User, include_id: bool=False) -> str:
|
|||||||
Returns an HTML user link. This is useful for reports.
|
Returns an HTML user link. This is useful for reports.
|
||||||
Attention: Don't forget to set parse_mode to 'HTML'!
|
Attention: Don't forget to set parse_mode to 'HTML'!
|
||||||
|
|
||||||
Example:
|
|
||||||
|
.. code-block:: python3
|
||||||
|
:caption: Example:
|
||||||
|
|
||||||
bot.send_message(your_user_id, user_link(message.from_user) + ' started the bot!', parse_mode='HTML')
|
bot.send_message(your_user_id, user_link(message.from_user) + ' started the bot!', parse_mode='HTML')
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
You can use formatting.* for all other formatting options(bold, italic, links, and etc.)
|
||||||
|
This method is kept for backward compatibility, and it is recommended to use formatting.* for
|
||||||
|
more options.
|
||||||
|
|
||||||
:param user: the user (not the user_id)
|
:param user: the user (not the user_id)
|
||||||
|
:type user: :obj:`telebot.types.User`
|
||||||
|
|
||||||
:param include_id: include the user_id
|
:param include_id: include the user_id
|
||||||
|
:type include_id: :obj:`bool`
|
||||||
|
|
||||||
:return: HTML user link
|
:return: HTML user link
|
||||||
|
:rtype: :obj:`str`
|
||||||
"""
|
"""
|
||||||
name = escape(user.first_name)
|
name = escape(user.first_name)
|
||||||
return (f"<a href='tg://user?id={user.id}'>{name}</a>"
|
return (f"<a href='tg://user?id={user.id}'>{name}</a>"
|
||||||
@ -355,7 +438,8 @@ def quick_markup(values: Dict[str, Dict[str, Any]], row_width: int=2) -> types.I
|
|||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python3
|
||||||
|
:caption: Using quick_markup:
|
||||||
|
|
||||||
quick_markup({
|
quick_markup({
|
||||||
'Twitter': {'url': 'https://twitter.com'},
|
'Twitter': {'url': 'https://twitter.com'},
|
||||||
@ -378,8 +462,13 @@ def quick_markup(values: Dict[str, Dict[str, Any]], row_width: int=2) -> types.I
|
|||||||
}
|
}
|
||||||
|
|
||||||
:param values: a dict containing all buttons to create in this format: {text: kwargs} {str:}
|
:param values: a dict containing all buttons to create in this format: {text: kwargs} {str:}
|
||||||
|
:type values: :obj:`dict`
|
||||||
|
|
||||||
:param row_width: int row width
|
:param row_width: int row width
|
||||||
|
:type row_width: :obj:`int`
|
||||||
|
|
||||||
:return: InlineKeyboardMarkup
|
:return: InlineKeyboardMarkup
|
||||||
|
:rtype: :obj:`types.InlineKeyboardMarkup`
|
||||||
"""
|
"""
|
||||||
markup = types.InlineKeyboardMarkup(row_width=row_width)
|
markup = types.InlineKeyboardMarkup(row_width=row_width)
|
||||||
buttons = [
|
buttons = [
|
||||||
@ -392,16 +481,25 @@ def quick_markup(values: Dict[str, Dict[str, Any]], row_width: int=2) -> types.I
|
|||||||
|
|
||||||
# CREDITS TO http://stackoverflow.com/questions/12317940#answer-12320352
|
# CREDITS TO http://stackoverflow.com/questions/12317940#answer-12320352
|
||||||
def or_set(self):
|
def or_set(self):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
self._set()
|
self._set()
|
||||||
self.changed()
|
self.changed()
|
||||||
|
|
||||||
|
|
||||||
def or_clear(self):
|
def or_clear(self):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
self._clear()
|
self._clear()
|
||||||
self.changed()
|
self.changed()
|
||||||
|
|
||||||
|
|
||||||
def orify(e, changed_callback):
|
def orify(e, changed_callback):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
if not hasattr(e, "_set"):
|
if not hasattr(e, "_set"):
|
||||||
e._set = e.set
|
e._set = e.set
|
||||||
if not hasattr(e, "_clear"):
|
if not hasattr(e, "_clear"):
|
||||||
@ -412,6 +510,9 @@ def orify(e, changed_callback):
|
|||||||
|
|
||||||
|
|
||||||
def OrEvent(*events):
|
def OrEvent(*events):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
or_event = threading.Event()
|
or_event = threading.Event()
|
||||||
|
|
||||||
def changed():
|
def changed():
|
||||||
@ -435,6 +536,9 @@ def OrEvent(*events):
|
|||||||
|
|
||||||
|
|
||||||
def per_thread(key, construct_value, reset=False):
|
def per_thread(key, construct_value, reset=False):
|
||||||
|
"""
|
||||||
|
:meta private:
|
||||||
|
"""
|
||||||
if reset or not hasattr(thread_local, key):
|
if reset or not hasattr(thread_local, key):
|
||||||
value = construct_value()
|
value = construct_value()
|
||||||
setattr(thread_local, key, value)
|
setattr(thread_local, key, value)
|
||||||
@ -449,7 +553,13 @@ def chunks(lst, n):
|
|||||||
yield lst[i:i + n]
|
yield lst[i:i + n]
|
||||||
|
|
||||||
|
|
||||||
def generate_random_token():
|
def generate_random_token() -> str:
|
||||||
|
"""
|
||||||
|
Generates a random token consisting of letters and digits, 16 characters long.
|
||||||
|
|
||||||
|
:return: a random token
|
||||||
|
:rtype: :obj:`str`
|
||||||
|
"""
|
||||||
return ''.join(random.sample(string.ascii_letters, 16))
|
return ''.join(random.sample(string.ascii_letters, 16))
|
||||||
|
|
||||||
|
|
||||||
@ -458,9 +568,18 @@ def deprecated(warn: bool=True, alternative: Optional[Callable]=None, deprecatio
|
|||||||
Use this decorator to mark functions as deprecated.
|
Use this decorator to mark functions as deprecated.
|
||||||
When the function is used, an info (or warning if `warn` is True) is logged.
|
When the function is used, an info (or warning if `warn` is True) is logged.
|
||||||
|
|
||||||
|
:meta private:
|
||||||
|
|
||||||
:param warn: If True a warning is logged else an info
|
:param warn: If True a warning is logged else an info
|
||||||
|
:type warn: :obj:`bool`
|
||||||
|
|
||||||
:param alternative: The new function to use instead
|
:param alternative: The new function to use instead
|
||||||
|
:type alternative: :obj:`Callable`
|
||||||
|
|
||||||
:param deprecation_text: Custom deprecation text
|
:param deprecation_text: Custom deprecation text
|
||||||
|
:type deprecation_text: :obj:`str`
|
||||||
|
|
||||||
|
:return: The decorated function
|
||||||
"""
|
"""
|
||||||
def decorator(function):
|
def decorator(function):
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
@ -480,7 +599,17 @@ def deprecated(warn: bool=True, alternative: Optional[Callable]=None, deprecatio
|
|||||||
|
|
||||||
# Cloud helpers
|
# Cloud helpers
|
||||||
def webhook_google_functions(bot, request):
|
def webhook_google_functions(bot, request):
|
||||||
"""A webhook endpoint for Google Cloud Functions FaaS."""
|
"""
|
||||||
|
A webhook endpoint for Google Cloud Functions FaaS.
|
||||||
|
|
||||||
|
:param bot: The bot instance
|
||||||
|
:type bot: :obj:`telebot.TeleBot` or :obj:`telebot.async_telebot.AsyncTeleBot`
|
||||||
|
|
||||||
|
:param request: The request object
|
||||||
|
:type request: :obj:`flask.Request`
|
||||||
|
|
||||||
|
:return: The response object
|
||||||
|
"""
|
||||||
if request.is_json:
|
if request.is_json:
|
||||||
try:
|
try:
|
||||||
request_json = request.get_json()
|
request_json = request.get_json()
|
||||||
@ -494,7 +623,7 @@ def webhook_google_functions(bot, request):
|
|||||||
return 'Bot ON'
|
return 'Bot ON'
|
||||||
|
|
||||||
|
|
||||||
def antiflood(function, *args, **kwargs):
|
def antiflood(function: Callable, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Use this function inside loops in order to avoid getting TooManyRequests error.
|
Use this function inside loops in order to avoid getting TooManyRequests error.
|
||||||
Example:
|
Example:
|
||||||
@ -505,9 +634,15 @@ def antiflood(function, *args, **kwargs):
|
|||||||
for chat_id in chat_id_list:
|
for chat_id in chat_id_list:
|
||||||
msg = antiflood(bot.send_message, chat_id, text)
|
msg = antiflood(bot.send_message, chat_id, text)
|
||||||
|
|
||||||
:param function:
|
:param function: The function to call
|
||||||
:param args:
|
:type function: :obj:`Callable`
|
||||||
:param kwargs:
|
|
||||||
|
:param args: The arguments to pass to the function
|
||||||
|
:type args: :obj:`tuple`
|
||||||
|
|
||||||
|
:param kwargs: The keyword arguments to pass to the function
|
||||||
|
:type kwargs: :obj:`dict`
|
||||||
|
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
from telebot.apihelper import ApiTelegramException
|
from telebot.apihelper import ApiTelegramException
|
||||||
@ -524,6 +659,17 @@ def antiflood(function, *args, **kwargs):
|
|||||||
|
|
||||||
|
|
||||||
def parse_web_app_data(token: str, raw_init_data: str):
|
def parse_web_app_data(token: str, raw_init_data: str):
|
||||||
|
"""
|
||||||
|
Parses web app data.
|
||||||
|
|
||||||
|
:param token: The bot token
|
||||||
|
:type token: :obj:`str`
|
||||||
|
|
||||||
|
:param raw_init_data: The raw init data
|
||||||
|
:type raw_init_data: :obj:`str`
|
||||||
|
|
||||||
|
:return: The parsed init data
|
||||||
|
"""
|
||||||
is_valid = validate_web_app_data(token, raw_init_data)
|
is_valid = validate_web_app_data(token, raw_init_data)
|
||||||
if not is_valid:
|
if not is_valid:
|
||||||
return False
|
return False
|
||||||
@ -539,7 +685,18 @@ def parse_web_app_data(token: str, raw_init_data: str):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def validate_web_app_data(token, raw_init_data):
|
def validate_web_app_data(token: str, raw_init_data: str):
|
||||||
|
"""
|
||||||
|
Validates web app data.
|
||||||
|
|
||||||
|
:param token: The bot token
|
||||||
|
:type token: :obj:`str`
|
||||||
|
|
||||||
|
:param raw_init_data: The raw init data
|
||||||
|
:type raw_init_data: :obj:`str`
|
||||||
|
|
||||||
|
:return: The parsed init data
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
parsed_data = dict(parse_qsl(raw_init_data))
|
parsed_data = dict(parse_qsl(raw_init_data))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
Loading…
Reference in New Issue
Block a user