pyTelegramBotAPI 4.22.0__py3-none-any.whl → 4.22.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pyTelegramBotAPI
3
- Version: 4.22.0
3
+ Version: 4.22.1
4
4
  Summary: Python Telegram bot api.
5
5
  Project-URL: Homepage, https://github.com/eternnoir/pyTelegramBotAPI
6
6
  Project-URL: Documentation, https://pytba.readthedocs.org
@@ -23,8 +23,6 @@ Requires-Python: >=3.8
23
23
  Requires-Dist: requests
24
24
  Provides-Extra: aiohttp
25
25
  Requires-Dist: aiohttp; extra == 'aiohttp'
26
- Provides-Extra: aioredis
27
- Requires-Dist: aioredis; extra == 'aioredis'
28
26
  Provides-Extra: coloredlogs
29
27
  Requires-Dist: coloredlogs; extra == 'coloredlogs'
30
28
  Provides-Extra: fastapi
@@ -55,7 +53,7 @@ Description-Content-Type: text/markdown
55
53
  <p align="center">A simple, but extensible Python implementation for the <a href="https://core.telegram.org/bots/api">Telegram Bot API</a>.</p>
56
54
  <p align="center">Both synchronous and asynchronous.</p>
57
55
 
58
- ## <p align="center">Supported Bot API version: <a href="https://core.telegram.org/bots/api-changelog#july-31-2024">7.8</a>!
56
+ ## <p align="center">Supported Bot API version: <a href="https://core.telegram.org/bots/api-changelog#july-31-2024"><img src="https://img.shields.io/badge/Bot%20API-7.8-blue?logo=telegram" alt="Supported Bot API version"></a>
59
57
 
60
58
  <h2><a href='https://pytba.readthedocs.io/en/latest/index.html'>Official documentation</a></h2>
61
59
  <h2><a href='https://pytba.readthedocs.io/ru/latest/index.html'>Official ru documentation</a></h2>
@@ -0,0 +1,41 @@
1
+ telebot/__init__.py,sha256=ty7WzdASNMWG_cqdg4o3A-kagN9aVIGkc0j93R9reT4,412119
2
+ telebot/apihelper.py,sha256=FJwcuzZXK54GqNmUiziobpbgrN5pwk_LcPBbkhlINf4,94286
3
+ telebot/async_telebot.py,sha256=N5vCHak84CCjxZJCehus8eRt1TaSmUlRyzzAw_ONqYk,385225
4
+ telebot/asyncio_filters.py,sha256=0bnF-CPOX-IZUIjViTk5lxa5OR_UxB8Z5ng0kfDq5nM,12856
5
+ telebot/asyncio_handler_backends.py,sha256=BWS7zr93FJNZJmPHBoXo4i_PIHGlmrEoWy1miXax9aI,2785
6
+ telebot/asyncio_helper.py,sha256=Wvd8i8KFqGizkyaL7xZfb4Woan1yphoQGFYHvdErKyw,95049
7
+ telebot/callback_data.py,sha256=k4Rz3lAONG5J2M9TESKMIjqXoBNJMfEy9nnrmJAyi3Q,5358
8
+ telebot/custom_filters.py,sha256=0NX8hR5EMGjOnl11sLPYwl9gwIxd9APTsxqBhxCASLM,12977
9
+ telebot/formatting.py,sha256=_y8M5KOv9UOXfF9z7Et4fPVgh9JnzI1cr4un9sfdlc0,15176
10
+ telebot/handler_backends.py,sha256=lyKu0PaH2c4y5FfyQS3M9tOyBJ8ATjxHZkATzu01XpE,7969
11
+ telebot/service_utils.py,sha256=xLmlZLTVs34UOdQtMvwduor8hnLxQCx8iJ92wDGl2Mw,2053
12
+ telebot/types.py,sha256=KiKe3WnBAGCN_65Uxe104IGG77cvpUthTzlEjwnc0r4,459391
13
+ telebot/util.py,sha256=YLSNl9LYEmj7PxNgZN5OO3IvtR5YESvVfTsReuxZ9Zw,21361
14
+ telebot/version.py,sha256=dvJgb3UnEA3MSfEPGopCGapphKRx6FGNQqRhsbEch3o,99
15
+ telebot/asyncio_storage/__init__.py,sha256=fraOWJby1ddJmPAXf1oXWmZJXRodSpING17MF875NPI,433
16
+ telebot/asyncio_storage/base_storage.py,sha256=I-NII9ZMCxCHStPc-73qSyQhjBtkhNzb2IcZPhjR1Eg,3243
17
+ telebot/asyncio_storage/memory_storage.py,sha256=h8yc2xpfLmbcBjPmKkqNhZtUtpNQ7EuKIfMGue61e7w,5849
18
+ telebot/asyncio_storage/pickle_storage.py,sha256=3uaQGw6jF1kF7x-qLq1VIGjya2hcEY1J9HAouDuXH4U,7647
19
+ telebot/asyncio_storage/redis_storage.py,sha256=ruhh1jPUf0YHQWfg_QAHPEn8Vm9cvBwkybD5R7GSUDw,9897
20
+ telebot/ext/__init__.py,sha256=_mSeNU1cib3cWSZ6Kb6nKy9znEYwEzGNRCYZsD61rLk,66
21
+ telebot/ext/reloader.py,sha256=vzmJxCsA_COHF-bpmyddDuUXroxNih051IYRMiR21LY,826
22
+ telebot/ext/aio/__init__.py,sha256=2yi7jtvEIH1DqAseFevfujNYi7ZSh5aPMOKGrxIgqsw,143
23
+ telebot/ext/aio/webhooks.py,sha256=tf4DMXkKWvM_Uko_lpLRc0uDwttyZGvsvDLNNbwmO_Y,3788
24
+ telebot/ext/sync/__init__.py,sha256=Lj-15dj1TYkf11d0vY14_2mssnoFR5Uk320huWa_rGc,140
25
+ telebot/ext/sync/webhooks.py,sha256=XMMhXnDuFs7CWJ7iDi11H0dwf6fRA4pbAjFjNgNJ18Y,3513
26
+ telebot/states/__init__.py,sha256=ggLBEJyMoh3i_IDpUE_jvtP7NiC7IwIR4QJXmI1BFGc,4401
27
+ telebot/states/asyncio/__init__.py,sha256=vomgAmaY590Ul0U-oovN7-Vjf6CwrchmjAZS8PX-lqY,132
28
+ telebot/states/asyncio/context.py,sha256=LeH1uD3NSkQ6EJ-rsSfJfA1SaQ_FnoPRWg746SwOhFI,4952
29
+ telebot/states/asyncio/middleware.py,sha256=UZgd4Ty8JwOcj50zdI8eJ0tfPCmgiymxyaX-dR2tpVg,730
30
+ telebot/states/sync/__init__.py,sha256=FqxubuunwknusMEAkaUwgFdIBmTZtEhRUaRZE18bzzs,131
31
+ telebot/states/sync/context.py,sha256=mw19DPMSqPsg8e-i3ZVsp-YxZSfHfn1rpisn5smvfrM,4731
32
+ telebot/states/sync/middleware.py,sha256=7mGC0xEQt7vjfCgmJWOKn7BXHxjQyLFoyZ1rL0blm4Q,680
33
+ telebot/storage/__init__.py,sha256=Uagoo-sNYA0PX-hICKSaXtr4YRUOp2GPwlK1vlap9O8,401
34
+ telebot/storage/base_storage.py,sha256=WzGgSflKzcn2ENsgz1Q-D_v-ZKCtnMOURGOHIwNJ0WU,2986
35
+ telebot/storage/memory_storage.py,sha256=-r1vuIt1YHq9btkr6E7BCu4Do-wUDlNcttG22SSgEYo,5799
36
+ telebot/storage/pickle_storage.py,sha256=dqw7syOJuTWyU0KK8XwbJvQ9PMyDHhZQG-MevZImEak,7121
37
+ telebot/storage/redis_storage.py,sha256=DReU2lc8cI0f3XMIT1N9-suGZ6jE8H9I_mapK3A-lyE,9450
38
+ pytelegrambotapi-4.22.1.dist-info/METADATA,sha256=ECBI-3IKxlXtRMzbmXv11FBTUOlP67NghcrAvQArhTk,48162
39
+ pytelegrambotapi-4.22.1.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
40
+ pytelegrambotapi-4.22.1.dist-info/licenses/LICENSE,sha256=qz_jTTxi4zSAFaTdASiwml2iAk0UZ6R4MRADNzwYo_A,18387
41
+ pytelegrambotapi-4.22.1.dist-info/RECORD,,
telebot/__init__.py CHANGED
@@ -7,7 +7,7 @@ import sys
7
7
  import threading
8
8
  import time
9
9
  import traceback
10
- from typing import Any, Callable, List, Optional, Union
10
+ from typing import Any, Callable, List, Optional, Union, Dict
11
11
 
12
12
  # these imports are used to avoid circular import error
13
13
  import telebot.util
@@ -20,7 +20,6 @@ from telebot.storage import StatePickleStorage, StateMemoryStorage, StateStorage
20
20
  # random module to generate random string
21
21
  import random
22
22
  import string
23
- import copy
24
23
 
25
24
  import ssl
26
25
 
@@ -153,9 +152,14 @@ class TeleBot:
153
152
  :param allow_sending_without_reply: Default value for allow_sending_without_reply, defaults to None
154
153
  :type allow_sending_without_reply: :obj:`bool`, optional
155
154
 
156
-
157
155
  :param colorful_logs: Outputs colorful logs
158
156
  :type colorful_logs: :obj:`bool`, optional
157
+
158
+ :param validate_token: Validate token, defaults to True;
159
+ :type validate_token: :obj:`bool`, optional
160
+
161
+ :raises ImportError: If coloredlogs module is not installed and colorful_logs is True
162
+ :raises ValueError: If token is invalid
159
163
  """
160
164
 
161
165
  def __init__(
@@ -169,7 +173,8 @@ class TeleBot:
169
173
  disable_notification: Optional[bool]=None,
170
174
  protect_content: Optional[bool]=None,
171
175
  allow_sending_without_reply: Optional[bool]=None,
172
- colorful_logs: Optional[bool]=False
176
+ colorful_logs: Optional[bool]=False,
177
+ validate_token: Optional[bool]=True
173
178
  ):
174
179
 
175
180
  # update-related
@@ -187,6 +192,11 @@ class TeleBot:
187
192
  self.webhook_listener = None
188
193
  self._user = None
189
194
 
195
+ if validate_token:
196
+ util.validate_token(self.token)
197
+
198
+ self.bot_id: Union[int, None] = util.extract_bot_id(self.token) # subject to change in future, unspecified
199
+
190
200
  # logs-related
191
201
  if colorful_logs:
192
202
  try:
@@ -281,7 +291,7 @@ class TeleBot:
281
291
  self.threaded = threaded
282
292
  if self.threaded:
283
293
  self.worker_pool = util.ThreadPool(self, num_threads=num_threads)
284
-
294
+
285
295
  @property
286
296
  def user(self) -> types.User:
287
297
  """
@@ -6642,7 +6652,9 @@ class TeleBot:
6642
6652
  self.middlewares.append(middleware)
6643
6653
 
6644
6654
 
6645
- def set_state(self, user_id: int, state: Union[int, str, State], chat_id: Optional[int]=None) -> None:
6655
+ def set_state(self, user_id: int, state: Union[str, State], chat_id: Optional[int]=None,
6656
+ business_connection_id: Optional[str]=None, message_thread_id: Optional[int]=None,
6657
+ bot_id: Optional[int]=None) -> bool:
6646
6658
  """
6647
6659
  Sets a new state of a user.
6648
6660
 
@@ -6652,25 +6664,49 @@ class TeleBot:
6652
6664
  Otherwise, if you only set user_id, chat_id will equal to user_id, this means that
6653
6665
  state will be set for the user in his private chat with a bot.
6654
6666
 
6667
+ .. versionchanged:: 4.23.0
6668
+
6669
+ Added additional parameters to support topics, business connections, and message threads.
6670
+
6671
+ .. seealso::
6672
+
6673
+ For more details, visit the `custom_states.py example <https://github.com/eternnoir/pyTelegramBotAPI/blob/master/examples/custom_states.py>`_.
6674
+
6655
6675
  :param user_id: User's identifier
6656
6676
  :type user_id: :obj:`int`
6657
6677
 
6658
- :param state: new state. can be string, integer, or :class:`telebot.types.State`
6678
+ :param state: new state. can be string, or :class:`telebot.types.State`
6659
6679
  :type state: :obj:`int` or :obj:`str` or :class:`telebot.types.State`
6660
6680
 
6661
6681
  :param chat_id: Chat's identifier
6662
6682
  :type chat_id: :obj:`int`
6663
6683
 
6664
- :return: None
6684
+ :param bot_id: Bot's identifier, defaults to current bot id
6685
+ :type bot_id: :obj:`int`
6686
+
6687
+ :param business_connection_id: Business identifier
6688
+ :type business_connection_id: :obj:`str`
6689
+
6690
+ :param message_thread_id: Identifier of the message thread
6691
+ :type message_thread_id: :obj:`int`
6692
+
6693
+ :return: True on success
6694
+ :rtype: :obj:`bool`
6665
6695
  """
6666
6696
  if chat_id is None:
6667
6697
  chat_id = user_id
6668
- self.current_states.set_state(chat_id, user_id, state)
6698
+ if bot_id is None:
6699
+ bot_id = self.bot_id
6700
+ return self.current_states.set_state(
6701
+ chat_id=chat_id, user_id=user_id, state=state, bot_id=bot_id,
6702
+ business_connection_id=business_connection_id, message_thread_id=message_thread_id)
6669
6703
 
6670
6704
 
6671
- def reset_data(self, user_id: int, chat_id: Optional[int]=None):
6705
+ def reset_data(self, user_id: int, chat_id: Optional[int]=None,
6706
+ business_connection_id: Optional[str]=None,
6707
+ message_thread_id: Optional[int]=None, bot_id: Optional[int]=None) -> bool:
6672
6708
  """
6673
- Reset data for a user in chat.
6709
+ Reset data for a user in chat: sets the 'data' field to an empty dictionary.
6674
6710
 
6675
6711
  :param user_id: User's identifier
6676
6712
  :type user_id: :obj:`int`
@@ -6678,16 +6714,34 @@ class TeleBot:
6678
6714
  :param chat_id: Chat's identifier
6679
6715
  :type chat_id: :obj:`int`
6680
6716
 
6681
- :return: None
6717
+ :param bot_id: Bot's identifier, defaults to current bot id
6718
+ :type bot_id: :obj:`int`
6719
+
6720
+ :param business_connection_id: Business identifier
6721
+ :type business_connection_id: :obj:`str`
6722
+
6723
+ :param message_thread_id: Identifier of the message thread
6724
+ :type message_thread_id: :obj:`int`
6725
+
6726
+ :return: True on success
6727
+ :rtype: :obj:`bool`
6682
6728
  """
6683
6729
  if chat_id is None:
6684
6730
  chat_id = user_id
6685
- self.current_states.reset_data(chat_id, user_id)
6731
+ if bot_id is None:
6732
+ bot_id = self.bot_id
6733
+ return self.current_states.reset_data(chat_id=chat_id, user_id=user_id, bot_id=bot_id,
6734
+ business_connection_id=business_connection_id, message_thread_id=message_thread_id)
6686
6735
 
6687
6736
 
6688
- def delete_state(self, user_id: int, chat_id: Optional[int]=None) -> None:
6737
+ def delete_state(self, user_id: int, chat_id: Optional[int]=None, business_connection_id: Optional[str]=None,
6738
+ message_thread_id: Optional[int]=None, bot_id: Optional[int]=None) -> bool:
6689
6739
  """
6690
- Delete the current state of a user.
6740
+ Fully deletes the storage record of a user in chat.
6741
+
6742
+ .. warning::
6743
+
6744
+ This does NOT set state to None, but deletes the object from storage.
6691
6745
 
6692
6746
  :param user_id: User's identifier
6693
6747
  :type user_id: :obj:`int`
@@ -6695,14 +6749,19 @@ class TeleBot:
6695
6749
  :param chat_id: Chat's identifier
6696
6750
  :type chat_id: :obj:`int`
6697
6751
 
6698
- :return: None
6752
+ :return: True on success
6753
+ :rtype: :obj:`bool`
6699
6754
  """
6700
6755
  if chat_id is None:
6701
6756
  chat_id = user_id
6702
- self.current_states.delete_state(chat_id, user_id)
6757
+ if bot_id is None:
6758
+ bot_id = self.bot_id
6759
+ return self.current_states.delete_state(chat_id=chat_id, user_id=user_id, bot_id=bot_id,
6760
+ business_connection_id=business_connection_id, message_thread_id=message_thread_id)
6703
6761
 
6704
6762
 
6705
- def retrieve_data(self, user_id: int, chat_id: Optional[int]=None) -> Optional[Any]:
6763
+ def retrieve_data(self, user_id: int, chat_id: Optional[int]=None, business_connection_id: Optional[str]=None,
6764
+ message_thread_id: Optional[int]=None, bot_id: Optional[int]=None) -> Optional[Dict[str, Any]]:
6706
6765
  """
6707
6766
  Returns context manager with data for a user in chat.
6708
6767
 
@@ -6712,34 +6771,70 @@ class TeleBot:
6712
6771
  :param chat_id: Chat's unique identifier, defaults to user_id
6713
6772
  :type chat_id: int, optional
6714
6773
 
6774
+ :param bot_id: Bot's identifier, defaults to current bot id
6775
+ :type bot_id: int, optional
6776
+
6777
+ :param business_connection_id: Business identifier
6778
+ :type business_connection_id: str, optional
6779
+
6780
+ :param message_thread_id: Identifier of the message thread
6781
+ :type message_thread_id: int, optional
6782
+
6715
6783
  :return: Context manager with data for a user in chat
6716
6784
  :rtype: Optional[Any]
6717
6785
  """
6718
6786
  if chat_id is None:
6719
6787
  chat_id = user_id
6720
- return self.current_states.get_interactive_data(chat_id, user_id)
6788
+ if bot_id is None:
6789
+ bot_id = self.bot_id
6790
+ return self.current_states.get_interactive_data(chat_id=chat_id, user_id=user_id, bot_id=bot_id,
6791
+ business_connection_id=business_connection_id,
6792
+ message_thread_id=message_thread_id)
6721
6793
 
6722
6794
 
6723
- def get_state(self, user_id: int, chat_id: Optional[int]=None) -> Optional[Union[int, str, State]]:
6795
+ def get_state(self, user_id: int, chat_id: Optional[int]=None,
6796
+ business_connection_id: Optional[str]=None,
6797
+ message_thread_id: Optional[int]=None, bot_id: Optional[int]=None) -> str:
6724
6798
  """
6725
6799
  Gets current state of a user.
6726
6800
  Not recommended to use this method. But it is ok for debugging.
6727
6801
 
6802
+ .. warning::
6803
+
6804
+ Even if you are using :class:`telebot.types.State`, this method will return a string.
6805
+ When comparing(not recommended), you should compare this string with :class:`telebot.types.State`.name
6806
+
6728
6807
  :param user_id: User's identifier
6729
6808
  :type user_id: :obj:`int`
6730
6809
 
6731
6810
  :param chat_id: Chat's identifier
6732
6811
  :type chat_id: :obj:`int`
6733
6812
 
6813
+ :param bot_id: Bot's identifier, defaults to current bot id
6814
+ :type bot_id: :obj:`int`
6815
+
6816
+ :param business_connection_id: Business identifier
6817
+ :type business_connection_id: :obj:`str`
6818
+
6819
+ :param message_thread_id: Identifier of the message thread
6820
+ :type message_thread_id: :obj:`int`
6821
+
6734
6822
  :return: state of a user
6735
6823
  :rtype: :obj:`int` or :obj:`str` or :class:`telebot.types.State`
6736
6824
  """
6737
6825
  if chat_id is None:
6738
6826
  chat_id = user_id
6739
- return self.current_states.get_state(chat_id, user_id)
6827
+ if bot_id is None:
6828
+ bot_id = self.bot_id
6829
+ return self.current_states.get_state(chat_id=chat_id, user_id=user_id, bot_id=bot_id,
6830
+ business_connection_id=business_connection_id, message_thread_id=message_thread_id)
6740
6831
 
6741
6832
 
6742
- def add_data(self, user_id: int, chat_id: Optional[int]=None, **kwargs):
6833
+ def add_data(self, user_id: int, chat_id: Optional[int]=None,
6834
+ business_connection_id: Optional[str]=None,
6835
+ message_thread_id: Optional[int]=None,
6836
+ bot_id: Optional[int]=None,
6837
+ **kwargs) -> None:
6743
6838
  """
6744
6839
  Add data to states.
6745
6840
 
@@ -6749,13 +6844,25 @@ class TeleBot:
6749
6844
  :param chat_id: Chat's identifier
6750
6845
  :type chat_id: :obj:`int`
6751
6846
 
6847
+ :param bot_id: Bot's identifier, defaults to current bot id
6848
+ :type bot_id: :obj:`int`
6849
+
6850
+ :param business_connection_id: Business identifier
6851
+ :type business_connection_id: :obj:`str`
6852
+
6853
+ :param message_thread_id: Identifier of the message thread
6854
+ :type message_thread_id: :obj:`int`
6855
+
6752
6856
  :param kwargs: Data to add
6753
6857
  :return: None
6754
6858
  """
6755
6859
  if chat_id is None:
6756
6860
  chat_id = user_id
6861
+ if bot_id is None:
6862
+ bot_id = self.bot_id
6757
6863
  for key, value in kwargs.items():
6758
- self.current_states.set_data(chat_id, user_id, key, value)
6864
+ self.current_states.set_data(chat_id=chat_id, user_id=user_id, key=key, value=value, bot_id=bot_id,
6865
+ business_connection_id=business_connection_id, message_thread_id=message_thread_id)
6759
6866
 
6760
6867
 
6761
6868
  def register_next_step_handler_by_chat_id(
@@ -8757,7 +8864,7 @@ class TeleBot:
8757
8864
  logger.error("It is not allowed to pass data and values inside data to the handler. Check your handler: {}".format(handler['function']))
8758
8865
  return
8759
8866
  else:
8760
- data_copy = copy.deepcopy(data)
8867
+ data_copy = data.copy()
8761
8868
  for key in list(data_copy):
8762
8869
  # remove data from data_copy if handler does not accept it
8763
8870
  if key not in params:
telebot/async_telebot.py CHANGED
@@ -4,7 +4,7 @@ from datetime import datetime
4
4
  import logging
5
5
  import re
6
6
  import traceback
7
- from typing import Any, Awaitable, Callable, List, Optional, Union
7
+ from typing import Any, Awaitable, Callable, List, Optional, Union, Dict
8
8
  import sys
9
9
 
10
10
  # this imports are used to avoid circular import error
@@ -32,7 +32,7 @@ REPLY_MARKUP_TYPES = Union[
32
32
  import string
33
33
  import random
34
34
  import ssl
35
- import copy
35
+
36
36
 
37
37
  """
38
38
  Module : telebot
@@ -117,6 +117,11 @@ class AsyncTeleBot:
117
117
  :param colorful_logs: Outputs colorful logs
118
118
  :type colorful_logs: :obj:`bool`, optional
119
119
 
120
+ :param validate_token: Validate token, defaults to True;
121
+ :type validate_token: :obj:`bool`, optional
122
+
123
+ :raises ImportError: If coloredlogs module is not installed and colorful_logs is True
124
+ :raises ValueError: If token is invalid
120
125
  """
121
126
 
122
127
  def __init__(self, token: str, parse_mode: Optional[str]=None, offset: Optional[int]=None,
@@ -126,7 +131,8 @@ class AsyncTeleBot:
126
131
  disable_notification: Optional[bool]=None,
127
132
  protect_content: Optional[bool]=None,
128
133
  allow_sending_without_reply: Optional[bool]=None,
129
- colorful_logs: Optional[bool]=False) -> None:
134
+ colorful_logs: Optional[bool]=False,
135
+ validate_token: Optional[bool]=True) -> None:
130
136
 
131
137
  # update-related
132
138
  self.token = token
@@ -184,6 +190,12 @@ class AsyncTeleBot:
184
190
 
185
191
  self._user = None # set during polling
186
192
 
193
+ if validate_token:
194
+ util.validate_token(self.token)
195
+
196
+ self.bot_id: Union[int, None] = util.extract_bot_id(self.token) # subject to change, unspecified
197
+
198
+
187
199
  @property
188
200
  def user(self):
189
201
  return self._user
@@ -558,7 +570,7 @@ class AsyncTeleBot:
558
570
  logger.error("It is not allowed to pass data and values inside data to the handler. Check your handler: {}".format(handler['function']))
559
571
  return
560
572
  else:
561
- data_copy = copy.deepcopy(data)
573
+ data_copy = data.copy()
562
574
  for key in list(data_copy):
563
575
  # remove data from data_copy if handler does not accept it
564
576
  if key not in params:
@@ -7837,7 +7849,10 @@ class AsyncTeleBot:
7837
7849
  """
7838
7850
  return await asyncio_helper.get_forum_topic_icon_stickers(self.token)
7839
7851
 
7840
- async def set_state(self, user_id: int, state: Union[State, int, str], chat_id: Optional[int]=None):
7852
+
7853
+ async def set_state(self, user_id: int, state: Union[int, str, State], chat_id: Optional[int]=None,
7854
+ business_connection_id: Optional[str]=None, message_thread_id: Optional[int]=None,
7855
+ bot_id: Optional[int]=None) -> bool:
7841
7856
  """
7842
7857
  Sets a new state of a user.
7843
7858
 
@@ -7847,22 +7862,47 @@ class AsyncTeleBot:
7847
7862
  Otherwise, if you only set user_id, chat_id will equal to user_id, this means that
7848
7863
  state will be set for the user in his private chat with a bot.
7849
7864
 
7865
+ .. versionchanged:: 4.23.0
7866
+
7867
+ Added additional parameters to support topics, business connections, and message threads.
7868
+
7869
+ .. seealso::
7870
+
7871
+ For more details, visit the `custom_states.py example <https://github.com/eternnoir/pyTelegramBotAPI/blob/master/examples/asynchronous_telebot/custom_states.py>`_.
7872
+
7850
7873
  :param user_id: User's identifier
7851
7874
  :type user_id: :obj:`int`
7852
7875
 
7853
- :param state: new state. can be string, integer, or :class:`telebot.types.State`
7876
+ :param state: new state. can be string, or :class:`telebot.types.State`
7854
7877
  :type state: :obj:`int` or :obj:`str` or :class:`telebot.types.State`
7855
7878
 
7856
7879
  :param chat_id: Chat's identifier
7857
7880
  :type chat_id: :obj:`int`
7858
7881
 
7859
- :return: None
7882
+ :param bot_id: Bot's identifier, defaults to current bot id
7883
+ :type bot_id: :obj:`int`
7884
+
7885
+ :param business_connection_id: Business identifier
7886
+ :type business_connection_id: :obj:`str`
7887
+
7888
+ :param message_thread_id: Identifier of the message thread
7889
+ :type message_thread_id: :obj:`int`
7890
+
7891
+ :return: True on success
7892
+ :rtype: :obj:`bool`
7860
7893
  """
7861
- if not chat_id:
7894
+ if chat_id is None:
7862
7895
  chat_id = user_id
7863
- await self.current_states.set_state(chat_id, user_id, state)
7896
+ if bot_id is None:
7897
+ bot_id = self.bot_id
7898
+ return await self.current_states.set_state(
7899
+ chat_id=chat_id, user_id=user_id, state=state, bot_id=bot_id,
7900
+ business_connection_id=business_connection_id, message_thread_id=message_thread_id)
7901
+
7864
7902
 
7865
- async def reset_data(self, user_id: int, chat_id: Optional[int]=None):
7903
+ async def reset_data(self, user_id: int, chat_id: Optional[int]=None,
7904
+ business_connection_id: Optional[str]=None,
7905
+ message_thread_id: Optional[int]=None, bot_id: Optional[int]=None) -> bool:
7866
7906
  """
7867
7907
  Reset data for a user in chat.
7868
7908
 
@@ -7872,13 +7912,28 @@ class AsyncTeleBot:
7872
7912
  :param chat_id: Chat's identifier
7873
7913
  :type chat_id: :obj:`int`
7874
7914
 
7875
- :return: None
7915
+ :param bot_id: Bot's identifier, defaults to current bot id
7916
+ :type bot_id: :obj:`int`
7917
+
7918
+ :param business_connection_id: Business identifier
7919
+ :type business_connection_id: :obj:`str`
7920
+
7921
+ :param message_thread_id: Identifier of the message thread
7922
+ :type message_thread_id: :obj:`int`
7923
+
7924
+ :return: True on success
7925
+ :rtype: :obj:`bool`
7876
7926
  """
7877
7927
  if chat_id is None:
7878
7928
  chat_id = user_id
7879
- await self.current_states.reset_data(chat_id, user_id)
7929
+ if bot_id is None:
7930
+ bot_id = self.bot_id
7931
+ return await self.current_states.reset_data(chat_id=chat_id, user_id=user_id, bot_id=bot_id,
7932
+ business_connection_id=business_connection_id, message_thread_id=message_thread_id)
7933
+
7880
7934
 
7881
- async def delete_state(self, user_id: int, chat_id: Optional[int]=None):
7935
+ async def delete_state(self, user_id: int, chat_id: Optional[int]=None, business_connection_id: Optional[str]=None,
7936
+ message_thread_id: Optional[int]=None, bot_id: Optional[int]=None) -> bool:
7882
7937
  """
7883
7938
  Delete the current state of a user.
7884
7939
 
@@ -7890,11 +7945,16 @@ class AsyncTeleBot:
7890
7945
 
7891
7946
  :return: None
7892
7947
  """
7893
- if not chat_id:
7948
+ if chat_id is None:
7894
7949
  chat_id = user_id
7895
- await self.current_states.delete_state(chat_id, user_id)
7950
+ if bot_id is None:
7951
+ bot_id = self.bot_id
7952
+ return await self.current_states.delete_state(chat_id=chat_id, user_id=user_id, bot_id=bot_id,
7953
+ business_connection_id=business_connection_id, message_thread_id=message_thread_id)
7954
+
7896
7955
 
7897
- def retrieve_data(self, user_id: int, chat_id: Optional[int]=None):
7956
+ def retrieve_data(self, user_id: int, chat_id: Optional[int]=None, business_connection_id: Optional[str]=None,
7957
+ message_thread_id: Optional[int]=None, bot_id: Optional[int]=None) -> Optional[Dict[str, Any]]:
7898
7958
  """
7899
7959
  Returns context manager with data for a user in chat.
7900
7960
 
@@ -7904,32 +7964,70 @@ class AsyncTeleBot:
7904
7964
  :param chat_id: Chat's unique identifier, defaults to user_id
7905
7965
  :type chat_id: int, optional
7906
7966
 
7967
+ :param bot_id: Bot's identifier, defaults to current bot id
7968
+ :type bot_id: int, optional
7969
+
7970
+ :param business_connection_id: Business identifier
7971
+ :type business_connection_id: str, optional
7972
+
7973
+ :param message_thread_id: Identifier of the message thread
7974
+ :type message_thread_id: int, optional
7975
+
7907
7976
  :return: Context manager with data for a user in chat
7908
- :rtype: Optional[Any]
7977
+ :rtype: :obj:`dict`
7909
7978
  """
7910
- if not chat_id:
7979
+ if chat_id is None:
7911
7980
  chat_id = user_id
7912
- return self.current_states.get_interactive_data(chat_id, user_id)
7981
+ if bot_id is None:
7982
+ bot_id = self.bot_id
7983
+ return self.current_states.get_interactive_data(chat_id=chat_id, user_id=user_id, bot_id=bot_id,
7984
+ business_connection_id=business_connection_id,
7985
+ message_thread_id=message_thread_id)
7986
+
7913
7987
 
7914
- async def get_state(self, user_id, chat_id: Optional[int]=None):
7988
+ async def get_state(self, user_id: int, chat_id: Optional[int]=None,
7989
+ business_connection_id: Optional[str]=None,
7990
+ message_thread_id: Optional[int]=None, bot_id: Optional[int]=None) -> str:
7915
7991
  """
7916
7992
  Gets current state of a user.
7917
7993
  Not recommended to use this method. But it is ok for debugging.
7918
7994
 
7995
+ .. warning::
7996
+
7997
+ Even if you are using :class:`telebot.types.State`, this method will return a string.
7998
+ When comparing(not recommended), you should compare this string with :class:`telebot.types.State`.name
7999
+
7919
8000
  :param user_id: User's identifier
7920
8001
  :type user_id: :obj:`int`
7921
8002
 
7922
8003
  :param chat_id: Chat's identifier
7923
8004
  :type chat_id: :obj:`int`
7924
8005
 
8006
+ :param bot_id: Bot's identifier, defaults to current bot id
8007
+ :type bot_id: :obj:`int`
8008
+
8009
+ :param business_connection_id: Business identifier
8010
+ :type business_connection_id: :obj:`str`
8011
+
8012
+ :param message_thread_id: Identifier of the message thread
8013
+ :type message_thread_id: :obj:`int`
8014
+
7925
8015
  :return: state of a user
7926
- :rtype: :obj:`int` or :obj:`str` or :class:`telebot.types.State`
8016
+ :rtype: :obj:`str`
7927
8017
  """
7928
- if not chat_id:
8018
+ if chat_id is None:
7929
8019
  chat_id = user_id
7930
- return await self.current_states.get_state(chat_id, user_id)
8020
+ if bot_id is None:
8021
+ bot_id = self.bot_id
8022
+ return await self.current_states.get_state(chat_id=chat_id, user_id=user_id, bot_id=bot_id,
8023
+ business_connection_id=business_connection_id, message_thread_id=message_thread_id)
8024
+
7931
8025
 
7932
- async def add_data(self, user_id: int, chat_id: Optional[int]=None, **kwargs):
8026
+ async def add_data(self, user_id: int, chat_id: Optional[int]=None,
8027
+ business_connection_id: Optional[str]=None,
8028
+ message_thread_id: Optional[int]=None,
8029
+ bot_id: Optional[int]=None,
8030
+ **kwargs) -> None:
7933
8031
  """
7934
8032
  Add data to states.
7935
8033
 
@@ -7939,10 +8037,22 @@ class AsyncTeleBot:
7939
8037
  :param chat_id: Chat's identifier
7940
8038
  :type chat_id: :obj:`int`
7941
8039
 
8040
+ :param bot_id: Bot's identifier, defaults to current bot id
8041
+ :type bot_id: :obj:`int`
8042
+
8043
+ :param business_connection_id: Business identifier
8044
+ :type business_connection_id: :obj:`str`
8045
+
8046
+ :param message_thread_id: Identifier of the message thread
8047
+ :type message_thread_id: :obj:`int`
8048
+
7942
8049
  :param kwargs: Data to add
7943
8050
  :return: None
7944
8051
  """
7945
- if not chat_id:
8052
+ if chat_id is None:
7946
8053
  chat_id = user_id
8054
+ if bot_id is None:
8055
+ bot_id = self.bot_id
7947
8056
  for key, value in kwargs.items():
7948
- await self.current_states.set_data(chat_id, user_id, key, value)
8057
+ await self.current_states.set_data(chat_id=chat_id, user_id=user_id, key=key, value=value, bot_id=bot_id,
8058
+ business_connection_id=business_connection_id, message_thread_id=message_thread_id)