WPyrogram 2.0.149__py3-none-any.whl → 2.0.151__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.1
2
2
  Name: WPyrogram
3
- Version: 2.0.149
3
+ Version: 2.0.151
4
4
  Summary: Elegant, modern and asynchronous Telegram MTProto API framework in Python for users and bots - Woto's experimental fork
5
5
  Home-page: https://github.com/ALiwoto/WPyrogram
6
6
  Download-URL: https://github.com/ALiwoto/WPyrogram
@@ -1,13 +1,13 @@
1
- pyrogram/__init__.py,sha256=L-6OARe-oYpXLMQHueWSGqR9-I2LOxiaFGRcxtcbFkM,1401
2
- pyrogram/client.py,sha256=cVEv_0pVQVSooQI0fvvfTSOSFRfRwa-rEpK39665RA4,46022
3
- pyrogram/dispatcher.py,sha256=Xf1G216PcJX2rZFYujNGAcPuBKKvnGRNWPNIzJkYwUA,15465
1
+ pyrogram/__init__.py,sha256=BJBfFqukQLDR0zicgiJk09jdtXGOO4gYsccHWtZLBDI,1401
2
+ pyrogram/client.py,sha256=Tgtlw85sYEjgzI8cVPL7FwhiCvUNow7FsQcbn5Gx4nY,50088
3
+ pyrogram/dispatcher.py,sha256=cJV2tUDAfgNAh0aSjRHqiWNUBQ7ipGzBNTyJHunxLxc,13947
4
4
  pyrogram/emoji.py,sha256=ixb3OXR1XpLf3BQpw8kWIpmbQRowRIaFedjdnuzljac,208021
5
5
  pyrogram/file_id.py,sha256=jmMBAt2O_XhLE_AXKffZ4F5gccXJB8GHV7MlFCpiklA,15154
6
- pyrogram/filters.py,sha256=eR_dAl8qwF-h3SZHLhwNtskh1AZIhp_khaNthK3TwxE,28225
6
+ pyrogram/filters.py,sha256=5d7GL7W2OLwg9E8RUHLudQnbhdK7OrtFs2mSFTmoR1s,28802
7
7
  pyrogram/mime_types.py,sha256=JbYF6B-JrxZQNga8dPz2C8Dwp8-2pOrE1uv3KIBbjA0,61915
8
8
  pyrogram/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
9
  pyrogram/sync.py,sha256=cxKmLz9NAJPX2N2n2CogTLXyNo-dWgf6etBRXnqq1XA,3739
10
- pyrogram/utils.py,sha256=5oyowGt07WMsDWvWPMpFal-dIsh1af5Qv9KzduB_KPQ,16372
10
+ pyrogram/utils.py,sha256=HHlPe3CxShGPUidDdvCSXVgye5OeqTvmj-QUu5zyNh0,20125
11
11
  pyrogram/connection/__init__.py,sha256=q7KiWEV6VNDQGoj5s13GPyhRRlafXVPvX1h1VpAsVf8,854
12
12
  pyrogram/connection/connection.py,sha256=X5T7jd_lAXsH86f9gaNd4GDg4XIVnll7wrlVvSfgBJ0,2765
13
13
  pyrogram/connection/transport/__init__.py,sha256=nRpFdumPinBtuLOZkR8hH_vXlN7ChzW1oyJ6na4a8qw,838
@@ -51,12 +51,12 @@ pyrogram/enums/user_status.py,sha256=0WEpJJmjfGsJ3CVEhItO3Zc1VP9CBjgZBpxWUOzoFFg
51
51
  pyrogram/errors/__init__.py,sha256=Td5_TRqn2Ht6R3ZTxrLJaL_HoaugITxNCsiYEfueqCw,2605
52
52
  pyrogram/errors/rpc_error.py,sha256=18YbiYLQ-wKBZJ389SfPpl0pwQMHn4Xzh0leuZ-vuNU,3315
53
53
  pyrogram/errors/exceptions/__init__.py,sha256=z2D3DvbIArXHMWt1--qogk5t7V0uQkhejs8mxqyEQf0,1066
54
- pyrogram/errors/exceptions/all.py,sha256=vR5xjc31cDUVc6EEa-A_A0HSG-tPjQvZNpJpa85e1Z4,37189
55
- pyrogram/errors/exceptions/bad_request_400.py,sha256=JrgYlD-pZzsxHTFZQgFY5DqCdiLw0FMfr0mhJhkZFEQ,96235
56
- pyrogram/errors/exceptions/flood_420.py,sha256=f2hM-HvNtBaXkfvEPG_kOLc9hyMonTjPAmrxjYr-rGM,2476
57
- pyrogram/errors/exceptions/forbidden_403.py,sha256=fvUYMt7nxRbLiLKffBb-GNLyB2pYy7khkI7E_ce0ceg,9912
54
+ pyrogram/errors/exceptions/all.py,sha256=J6JhFMErFJbrxnNgoUy8e2EcDKCJR5l_pGJ58us7-IE,40114
55
+ pyrogram/errors/exceptions/bad_request_400.py,sha256=FSvaHcBq5SGRIE7M1ndzgvqiTYqtTJHfspLS30mFmrM,106605
56
+ pyrogram/errors/exceptions/flood_420.py,sha256=0G9dgyuvbmc0dW0dWLFM_EJTH1qNFEVaqUeCKMqWHUc,2641
57
+ pyrogram/errors/exceptions/forbidden_403.py,sha256=Vp-KW1WQjz312sGExePrMPqfTBxx_0jAwVlgZ4GJ-UQ,10671
58
58
  pyrogram/errors/exceptions/internal_server_error_500.py,sha256=I2pr1HS-F81uI4ZRP8oE5RoP4-quIZZJaguZvrQFiKg,12166
59
- pyrogram/errors/exceptions/not_acceptable_406.py,sha256=RBZqq-H6FiPFSXdkJinCg0edUeho00lgzzC9LsBHizA,7063
59
+ pyrogram/errors/exceptions/not_acceptable_406.py,sha256=OLIqzk4wcuty2vCN20Rb4D5ahaLCOE6ZyJzHlqJaYBs,7638
60
60
  pyrogram/errors/exceptions/see_other_303.py,sha256=_-P2lSLpLky-e5L17DLWneEponf5uw2sUGY2FabD-KI,1952
61
61
  pyrogram/errors/exceptions/service_unavailable_503.py,sha256=nGlK_dCJKwW3adMSWp2dV8cfo5b7SytlNlAyNBYYtp8,1535
62
62
  pyrogram/errors/exceptions/unauthorized_401.py,sha256=-b6fglrqn1EZ_lQP56dcuK7pfhH5wPeT9nh8cyMOjZQ,2672
@@ -169,7 +169,7 @@ pyrogram/methods/chats/get_dialogs.py,sha256=SXRoCp0BoPXR9Qf9LeaL0rA5mmI-nOOhtcv
169
169
  pyrogram/methods/chats/get_dialogs_count.py,sha256=jKZyseU8sTYDhhflyw9paalsdXyXkqorQ63_ljxn8vE,2491
170
170
  pyrogram/methods/chats/get_folders.py,sha256=YGMNvjrbqipEUJuSpVFDi5GsUv-ucBgEe5adXH2Nokw,3603
171
171
  pyrogram/methods/chats/get_forum_topics.py,sha256=AjY3EzZohPtm2ollJVXEn7VGQc-3oICsjdXoDBuTrHY,3284
172
- pyrogram/methods/chats/get_forum_topics_by_id.py,sha256=q2zOyoLKEvGBIxkCVOZEXw4oH4-9Wb1ulri5t7xgu8U,3798
172
+ pyrogram/methods/chats/get_forum_topics_by_id.py,sha256=m8R_YuUAK3sbKVgJ8UE1vWqKz5AZYuFoJUURaDttE2A,3813
173
173
  pyrogram/methods/chats/get_nearby_chats.py,sha256=sOoNjQ9qHKzD4UYoVusMM5G65KnqzqpzzwLwByJf6tc,2401
174
174
  pyrogram/methods/chats/get_personal_channels.py,sha256=_2PqL64zXjR9DgzajeStIWkrgyS7lEdJjQwoLSvySUk,1653
175
175
  pyrogram/methods/chats/get_send_as_chats.py,sha256=bY6VQnm3J6nezq5lhaBtPxu5-Co-Ti2sZki2XW5Q8JI,2151
@@ -3316,10 +3316,10 @@ pyrogram/types/user_and_chats/video_chat_ended.py,sha256=J5xTIAMSGDz8_z-EGrKwkoJ
3316
3316
  pyrogram/types/user_and_chats/video_chat_members_invited.py,sha256=9QhonApJd1XjOeJu9fqx2_u6nIOTZhfXZw_tX9XXxd8,1610
3317
3317
  pyrogram/types/user_and_chats/video_chat_scheduled.py,sha256=rUvDXF8r-2MfsAZKAcaWb_UZt5VoHebPjeJXWRDHGSo,1531
3318
3318
  pyrogram/types/user_and_chats/video_chat_started.py,sha256=WOAuM_CnkRA-W_Iedx0fIHB9RJ-AsvJIiSF05HzLRdA,1043
3319
- WPyrogram-2.0.149.dist-info/COPYING,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
3320
- WPyrogram-2.0.149.dist-info/COPYING.lesser,sha256=pWgb-bBdsU2Gd2kwAXxketnm5W_2u8_fIeWEgojfrxs,7651
3321
- WPyrogram-2.0.149.dist-info/METADATA,sha256=RMMZapyMNYHNe1aDLXUJJgfB0FWgopZpk_HRwfpeKek,4922
3322
- WPyrogram-2.0.149.dist-info/NOTICE,sha256=QL3iJdeVh_ZqRZZchyruQic5bYUWdx3yl0OkSUC2PQc,774
3323
- WPyrogram-2.0.149.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
3324
- WPyrogram-2.0.149.dist-info/top_level.txt,sha256=vS2-tKX7dJ1uKjistE5CoOVbv4yqglA95SK0KFEDwl0,9
3325
- WPyrogram-2.0.149.dist-info/RECORD,,
3319
+ WPyrogram-2.0.151.dist-info/COPYING,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
3320
+ WPyrogram-2.0.151.dist-info/COPYING.lesser,sha256=pWgb-bBdsU2Gd2kwAXxketnm5W_2u8_fIeWEgojfrxs,7651
3321
+ WPyrogram-2.0.151.dist-info/METADATA,sha256=cO3ivKchXGiMFDNBWChjgJFxNjeGHIBLOtqCNSExl38,4922
3322
+ WPyrogram-2.0.151.dist-info/NOTICE,sha256=QL3iJdeVh_ZqRZZchyruQic5bYUWdx3yl0OkSUC2PQc,774
3323
+ WPyrogram-2.0.151.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
3324
+ WPyrogram-2.0.151.dist-info/top_level.txt,sha256=vS2-tKX7dJ1uKjistE5CoOVbv4yqglA95SK0KFEDwl0,9
3325
+ WPyrogram-2.0.151.dist-info/RECORD,,
pyrogram/__init__.py CHANGED
@@ -16,7 +16,7 @@
16
16
  # You should have received a copy of the GNU Lesser General Public License
17
17
  # along with Pyrogram. If not, see <http://www.gnu.org/licenses/>.
18
18
 
19
- __version__ = "2.0.149"
19
+ __version__ = "2.0.151"
20
20
  __license__ = "GNU Lesser General Public License v3.0 (LGPL-3.0)"
21
21
  __copyright__ = "Copyright (C) 2017-present Dan <https://github.com/delivrance>"
22
22
 
pyrogram/client.py CHANGED
@@ -32,7 +32,7 @@ from importlib import import_module
32
32
  from io import StringIO, BytesIO
33
33
  from mimetypes import MimeTypes
34
34
  from pathlib import Path
35
- from typing import Union, List, Optional, Callable, AsyncGenerator
35
+ from typing import Union, List, Optional, Callable, AsyncGenerator, Type, Tuple
36
36
 
37
37
  import pyrogram
38
38
  from pyrogram import __version__, __license__
@@ -45,7 +45,8 @@ from pyrogram.errors import (
45
45
  SessionPasswordNeeded,
46
46
  VolumeLocNotFound, ChannelPrivate,
47
47
  BadRequest, AuthBytesInvalid,
48
- FloodWait, FloodPremiumWait
48
+ FloodWait, FloodPremiumWait,
49
+ ChannelInvalid, PersistentTimestampInvalid, PersistentTimestampOutdated
49
50
  )
50
51
  from pyrogram.handlers.handler import Handler
51
52
  from pyrogram.methods import Methods
@@ -53,6 +54,8 @@ from pyrogram.session import Auth, Session
53
54
  from pyrogram.storage import Storage, FileStorage, MemoryStorage
54
55
  from pyrogram.types import User, TermsOfService
55
56
  from pyrogram.utils import ainput
57
+ from .connection import Connection
58
+ from .connection.transport import TCP, TCPAbridged
56
59
  from .dispatcher import Dispatcher
57
60
  from .file_id import FileId, FileType, ThumbnailSource
58
61
  from .mime_types import mime_types
@@ -264,7 +267,9 @@ class Client(Methods):
264
267
  max_message_cache_size: int = MAX_MESSAGE_CACHE_SIZE,
265
268
  storage_engine: Optional[Storage] = None,
266
269
  client_platform: "enums.ClientPlatform" = enums.ClientPlatform.OTHER,
267
- init_connection_params: Optional["raw.base.JSONValue"] = None
270
+ init_connection_params: Optional["raw.base.JSONValue"] = None,
271
+ connection_factory: Type[Connection] = Connection,
272
+ protocol_factory: Type[TCP] = TCPAbridged
268
273
  ):
269
274
  super().__init__()
270
275
 
@@ -299,6 +304,8 @@ class Client(Methods):
299
304
  self.max_message_cache_size = max_message_cache_size
300
305
  self.client_platform = client_platform
301
306
  self.init_connection_params = init_connection_params
307
+ self.connection_factory = connection_factory
308
+ self.protocol_factory = protocol_factory
302
309
 
303
310
  self.executor = ThreadPoolExecutor(self.workers, thread_name_prefix="Handler")
304
311
 
@@ -541,25 +548,26 @@ class Client(Methods):
541
548
  async def fetch_peers(self, peers: List[Union[raw.types.User, raw.types.Chat, raw.types.Channel]]) -> bool:
542
549
  is_min = False
543
550
  parsed_peers = []
551
+ parsed_usernames = []
544
552
 
545
553
  for peer in peers:
546
554
  if getattr(peer, "min", False):
547
555
  is_min = True
548
556
  continue
549
557
 
550
- usernames = None
558
+ usernames = []
551
559
  phone_number = None
552
560
 
553
561
  if isinstance(peer, raw.types.User):
554
562
  peer_id = peer.id
555
563
  access_hash = peer.access_hash
556
- usernames = (
557
- [peer.username.lower()] if peer.username
558
- else [username.username.lower() for username in peer.usernames] if peer.usernames
559
- else None
560
- )
561
564
  phone_number = peer.phone
562
565
  peer_type = "bot" if peer.bot else "user"
566
+
567
+ if peer.username:
568
+ usernames.append(peer.username.lower())
569
+ elif peer.usernames:
570
+ usernames.extend(username.username.lower() for username in peer.usernames)
563
571
  elif isinstance(peer, (raw.types.Chat, raw.types.ChatForbidden)):
564
572
  peer_id = -peer.id
565
573
  access_hash = 0
@@ -567,12 +575,12 @@ class Client(Methods):
567
575
  elif isinstance(peer, raw.types.Channel):
568
576
  peer_id = utils.get_channel_id(peer.id)
569
577
  access_hash = peer.access_hash
570
- usernames = (
571
- [peer.username.lower()] if peer.username
572
- else [username.username.lower() for username in peer.usernames] if peer.usernames
573
- else None
574
- )
575
578
  peer_type = "channel" if peer.broadcast else "supergroup"
579
+
580
+ if peer.username:
581
+ usernames.append(peer.username.lower())
582
+ elif peer.usernames:
583
+ usernames.extend(username.username.lower() for username in peer.usernames)
576
584
  elif isinstance(peer, raw.types.ChannelForbidden):
577
585
  peer_id = utils.get_channel_id(peer.id)
578
586
  access_hash = peer.access_hash
@@ -580,9 +588,11 @@ class Client(Methods):
580
588
  else:
581
589
  continue
582
590
 
583
- parsed_peers.append((peer_id, access_hash, peer_type, usernames, phone_number))
591
+ parsed_peers.append((peer_id, access_hash, peer_type, phone_number))
592
+ parsed_usernames.append((peer_id, usernames))
584
593
 
585
594
  await self.storage.update_peers(parsed_peers)
595
+ await self.storage.update_usernames(parsed_usernames)
586
596
 
587
597
  return is_min
588
598
 
@@ -639,10 +649,11 @@ class Client(Methods):
639
649
  )]
640
650
  ),
641
651
  pts=pts - pts_count,
642
- limit=pts
652
+ limit=pts,
653
+ force=False
643
654
  )
644
655
  )
645
- except ChannelPrivate:
656
+ except (ChannelPrivate, PersistentTimestampOutdated, PersistentTimestampInvalid):
646
657
  pass
647
658
  else:
648
659
  if not isinstance(diff, raw.types.updates.ChannelDifferenceEmpty):
@@ -688,6 +699,92 @@ class Client(Methods):
688
699
  elif isinstance(updates, raw.types.UpdatesTooLong):
689
700
  log.info(updates)
690
701
 
702
+ async def recover_gaps(self) -> Tuple[int, int]:
703
+ states = await self.storage.update_state()
704
+
705
+ message_updates_counter = 0
706
+ other_updates_counter = 0
707
+
708
+ if not states:
709
+ log.info("No states found, skipping recovery.")
710
+ return (message_updates_counter, other_updates_counter)
711
+
712
+ for state in states:
713
+ id, local_pts, _, local_date, _ = state
714
+
715
+ prev_pts = 0
716
+
717
+ while True:
718
+ try:
719
+ diff = await self.invoke(
720
+ raw.functions.updates.GetChannelDifference(
721
+ channel=await self.resolve_peer(id),
722
+ filter=raw.types.ChannelMessagesFilterEmpty(),
723
+ pts=local_pts,
724
+ limit=10000,
725
+ force=False
726
+ ) if id < 0 else
727
+ raw.functions.updates.GetDifference(
728
+ pts=local_pts,
729
+ date=local_date,
730
+ qts=0
731
+ )
732
+ )
733
+ except (ChannelPrivate, ChannelInvalid, PersistentTimestampOutdated, PersistentTimestampInvalid):
734
+ break
735
+
736
+ if isinstance(diff, raw.types.updates.DifferenceEmpty):
737
+ break
738
+ elif isinstance(diff, raw.types.updates.DifferenceTooLong):
739
+ break
740
+ elif isinstance(diff, raw.types.updates.Difference):
741
+ local_pts = diff.state.pts
742
+ elif isinstance(diff, raw.types.updates.DifferenceSlice):
743
+ local_pts = diff.intermediate_state.pts
744
+ local_date = diff.intermediate_state.date
745
+
746
+ if prev_pts == local_pts:
747
+ break
748
+
749
+ prev_pts = local_pts
750
+ elif isinstance(diff, raw.types.updates.ChannelDifferenceEmpty):
751
+ break
752
+ elif isinstance(diff, raw.types.updates.ChannelDifferenceTooLong):
753
+ break
754
+ elif isinstance(diff, raw.types.updates.ChannelDifference):
755
+ local_pts = diff.pts
756
+
757
+ users = {i.id: i for i in diff.users}
758
+ chats = {i.id: i for i in diff.chats}
759
+
760
+ for message in diff.new_messages:
761
+ message_updates_counter += 1
762
+ self.dispatcher.updates_queue.put_nowait(
763
+ (
764
+ raw.types.UpdateNewMessage(
765
+ message=message,
766
+ pts=local_pts,
767
+ pts_count=-1
768
+ ),
769
+ users,
770
+ chats
771
+ )
772
+ )
773
+
774
+ for update in diff.other_updates:
775
+ other_updates_counter += 1
776
+ self.dispatcher.updates_queue.put_nowait(
777
+ (update, users, chats)
778
+ )
779
+
780
+ if isinstance(diff, (raw.types.updates.Difference, raw.types.updates.ChannelDifference)):
781
+ break
782
+
783
+ await self.storage.update_state(id)
784
+
785
+ log.info("Recovered %s messages and %s updates.", message_updates_counter, other_updates_counter)
786
+ return (message_updates_counter, other_updates_counter)
787
+
691
788
  async def load_session(self):
692
789
  await self.storage.open()
693
790
 
pyrogram/dispatcher.py CHANGED
@@ -22,13 +22,12 @@ import logging
22
22
  from collections import OrderedDict
23
23
 
24
24
  import pyrogram
25
- from pyrogram import errors
26
25
  from pyrogram import utils
27
- from pyrogram import raw
28
26
  from pyrogram.handlers import (
29
27
  CallbackQueryHandler, MessageHandler, EditedMessageHandler, DeletedMessagesHandler,
30
28
  UserStatusHandler, RawUpdateHandler, InlineQueryHandler, PollHandler, PreCheckoutQueryHandler,
31
- ChosenInlineResultHandler, ChatMemberUpdatedHandler, ChatJoinRequestHandler, StoryHandler
29
+ ChosenInlineResultHandler, ChatMemberUpdatedHandler, ChatJoinRequestHandler, StoryHandler,
30
+ ShippingQueryHandler, MessageReactionHandler, MessageReactionCountHandler, ChatBoostHandler
32
31
  )
33
32
  from pyrogram.raw.types import (
34
33
  UpdateNewMessage, UpdateNewChannelMessage, UpdateNewScheduledMessage,
@@ -38,7 +37,9 @@ from pyrogram.raw.types import (
38
37
  UpdateBotCallbackQuery, UpdateInlineBotCallbackQuery, UpdateBotPrecheckoutQuery,
39
38
  UpdateUserStatus, UpdateBotInlineQuery, UpdateMessagePoll,
40
39
  UpdateBotInlineSend, UpdateChatParticipant, UpdateChannelParticipant,
41
- UpdateBotChatInviteRequester, UpdateStory
40
+ UpdateBotChatInviteRequester, UpdateStory, UpdateBotShippingQuery, UpdateBotMessageReaction,
41
+ UpdateBotMessageReactions, UpdateBotChatBoost, UpdateBusinessBotCallbackQuery,
42
+ UpdateBotPurchasedPaidMedia, UpdateMessagePollVote
42
43
  )
43
44
 
44
45
  log = logging.getLogger(__name__)
@@ -48,15 +49,20 @@ class Dispatcher:
48
49
  NEW_MESSAGE_UPDATES = (UpdateNewMessage, UpdateNewChannelMessage, UpdateNewScheduledMessage, UpdateBotNewBusinessMessage)
49
50
  EDIT_MESSAGE_UPDATES = (UpdateEditMessage, UpdateEditChannelMessage, UpdateBotEditBusinessMessage)
50
51
  DELETE_MESSAGES_UPDATES = (UpdateDeleteMessages, UpdateDeleteChannelMessages, UpdateBotDeleteBusinessMessage)
51
- CALLBACK_QUERY_UPDATES = (UpdateBotCallbackQuery, UpdateInlineBotCallbackQuery)
52
+ CALLBACK_QUERY_UPDATES = (UpdateBotCallbackQuery, UpdateInlineBotCallbackQuery, UpdateBusinessBotCallbackQuery)
52
53
  CHAT_MEMBER_UPDATES = (UpdateChatParticipant, UpdateChannelParticipant)
53
54
  USER_STATUS_UPDATES = (UpdateUserStatus,)
54
55
  BOT_INLINE_QUERY_UPDATES = (UpdateBotInlineQuery,)
55
- POLL_UPDATES = (UpdateMessagePoll,)
56
+ POLL_UPDATES = (UpdateMessagePoll, UpdateMessagePollVote)
56
57
  CHOSEN_INLINE_RESULT_UPDATES = (UpdateBotInlineSend,)
57
58
  CHAT_JOIN_REQUEST_UPDATES = (UpdateBotChatInviteRequester,)
58
59
  NEW_STORY_UPDATES = (UpdateStory,)
59
60
  PRE_CHECKOUT_QUERY_UPDATES = (UpdateBotPrecheckoutQuery,)
61
+ SHIPPING_QUERY_UPDATES = (UpdateBotShippingQuery,)
62
+ MESSAGE_REACTION_UPDATES = (UpdateBotMessageReaction,)
63
+ MESSAGE_REACTION_COUNT_UPDATES = (UpdateBotMessageReactions,)
64
+ CHAT_BOOST_UPDATES = (UpdateBotChatBoost,)
65
+ PURCHASED_PAID_MEDIA_UPDATES = (UpdateBotPurchasedPaidMedia,)
60
66
 
61
67
  def __init__(self, client: "pyrogram.Client"):
62
68
  self.client = client
@@ -69,6 +75,8 @@ class Dispatcher:
69
75
  self.groups = OrderedDict()
70
76
 
71
77
  async def message_parser(update, users, chats):
78
+ connection_id = getattr(update, "connection_id", None)
79
+
72
80
  return (
73
81
  await pyrogram.types.Message._parse(
74
82
  self.client,
@@ -76,8 +84,9 @@ class Dispatcher:
76
84
  users,
77
85
  chats,
78
86
  is_scheduled=isinstance(update, UpdateNewScheduledMessage),
79
- business_connection_id=getattr(update, "connection_id", None),
80
- reply_to_message=getattr(update, "reply_to_message", None)
87
+ replies=0 if getattr(update, "connection_id", None) else 1,
88
+ business_connection_id=connection_id,
89
+ raw_reply_to_message=getattr(update, "reply_to_message", None)
81
90
  ),
82
91
  MessageHandler
83
92
  )
@@ -99,7 +108,7 @@ class Dispatcher:
99
108
 
100
109
  async def callback_query_parser(update, users, chats):
101
110
  return (
102
- await pyrogram.types.CallbackQuery._parse(self.client, update, users),
111
+ await pyrogram.types.CallbackQuery._parse(self.client, update, users, chats),
103
112
  CallbackQueryHandler
104
113
  )
105
114
 
@@ -117,7 +126,7 @@ class Dispatcher:
117
126
 
118
127
  async def poll_parser(update, users, chats):
119
128
  return (
120
- pyrogram.types.Poll._parse_update(self.client, update),
129
+ pyrogram.types.Poll._parse_update(self.client, update, users),
121
130
  PollHandler
122
131
  )
123
132
 
@@ -151,6 +160,36 @@ class Dispatcher:
151
160
  PreCheckoutQueryHandler
152
161
  )
153
162
 
163
+ async def shipping_query_parser(update, users, chats):
164
+ return (
165
+ await pyrogram.types.ShippingQuery._parse(self.client, update, users),
166
+ ShippingQueryHandler
167
+ )
168
+
169
+ async def message_reaction_parser(update, users, chats):
170
+ return (
171
+ pyrogram.types.MessageReactionUpdated._parse(self.client, update, users, chats),
172
+ MessageReactionHandler
173
+ )
174
+
175
+ async def message_reaction_count_parser(update, users, chats):
176
+ return (
177
+ pyrogram.types.MessageReactionCountUpdated._parse(self.client, update, users, chats),
178
+ MessageReactionCountHandler
179
+ )
180
+
181
+ async def chat_boost_parser(update, users, chats):
182
+ return (
183
+ pyrogram.types.ChatBoostUpdated._parse(self.client, update, users, chats),
184
+ ChatBoostHandler
185
+ )
186
+
187
+ async def purchased_paid_media_parser(update, users, chats):
188
+ return (
189
+ pyrogram.types.PurchasedPaidMedia._parse(self.client, update, users),
190
+ ChatBoostHandler
191
+ )
192
+
154
193
  self.update_parsers = {
155
194
  Dispatcher.NEW_MESSAGE_UPDATES: message_parser,
156
195
  Dispatcher.EDIT_MESSAGE_UPDATES: edited_message_parser,
@@ -163,7 +202,12 @@ class Dispatcher:
163
202
  Dispatcher.CHAT_MEMBER_UPDATES: chat_member_updated_parser,
164
203
  Dispatcher.CHAT_JOIN_REQUEST_UPDATES: chat_join_request_parser,
165
204
  Dispatcher.NEW_STORY_UPDATES: story_parser,
166
- Dispatcher.PRE_CHECKOUT_QUERY_UPDATES: pre_checkout_query_parser
205
+ Dispatcher.PRE_CHECKOUT_QUERY_UPDATES: pre_checkout_query_parser,
206
+ Dispatcher.SHIPPING_QUERY_UPDATES: shipping_query_parser,
207
+ Dispatcher.MESSAGE_REACTION_UPDATES: message_reaction_parser,
208
+ Dispatcher.MESSAGE_REACTION_COUNT_UPDATES: message_reaction_count_parser,
209
+ Dispatcher.CHAT_BOOST_UPDATES: chat_boost_parser,
210
+ Dispatcher.PURCHASED_PAID_MEDIA_UPDATES: purchased_paid_media_parser,
167
211
  }
168
212
 
169
213
  self.update_parsers = {key: value for key_tuple, value in self.update_parsers.items() for key in key_tuple}
@@ -180,93 +224,7 @@ class Dispatcher:
180
224
  log.info("Started %s HandlerTasks", self.client.workers)
181
225
 
182
226
  if not self.client.skip_updates:
183
- states = await self.client.storage.update_state()
184
-
185
- if not states:
186
- log.info("No states found, skipping recovery.")
187
- return
188
-
189
- message_updates_counter = 0
190
- other_updates_counter = 0
191
-
192
- for state in states:
193
- id, local_pts, _, local_date, _ = state
194
-
195
- prev_pts = 0
196
-
197
- while True:
198
- try:
199
- diff = await self.client.invoke(
200
- raw.functions.updates.GetChannelDifference(
201
- channel=await self.client.resolve_peer(id),
202
- filter=raw.types.ChannelMessagesFilterEmpty(),
203
- pts=local_pts,
204
- limit=10000
205
- ) if id < 0 else
206
- raw.functions.updates.GetDifference(
207
- pts=local_pts,
208
- date=local_date,
209
- qts=0
210
- )
211
- )
212
- except (errors.ChannelPrivate, errors.ChannelInvalid):
213
- break
214
-
215
- if isinstance(diff, raw.types.updates.DifferenceEmpty):
216
- break
217
- elif isinstance(diff, raw.types.updates.DifferenceTooLong):
218
- break
219
- elif isinstance(diff, raw.types.updates.Difference):
220
- local_pts = diff.state.pts
221
- elif isinstance(diff, raw.types.updates.DifferenceSlice):
222
- local_pts = diff.intermediate_state.pts
223
- local_date = diff.intermediate_state.date
224
-
225
- if prev_pts == local_pts:
226
- break
227
-
228
- prev_pts = local_pts
229
- elif isinstance(diff, raw.types.updates.ChannelDifferenceEmpty):
230
- break
231
- elif isinstance(diff, raw.types.updates.ChannelDifferenceTooLong):
232
- break
233
- elif isinstance(diff, raw.types.updates.ChannelDifference):
234
- local_pts = diff.pts
235
-
236
- users = {i.id: i for i in getattr(diff, "users", [])}
237
- chats = {i.id: i for i in getattr(diff, "chats", [])}
238
-
239
- for message in diff.new_messages:
240
- message_updates_counter += 1
241
- self.updates_queue.put_nowait(
242
- (
243
- raw.types.UpdateNewMessage(
244
- message=message,
245
- pts=local_pts,
246
- pts_count=-1
247
- ) if id == self.client.me.id else
248
- raw.types.UpdateNewChannelMessage(
249
- message=message,
250
- pts=local_pts,
251
- pts_count=-1
252
- ),
253
- users,
254
- chats
255
- )
256
- )
257
-
258
- for update in diff.other_updates:
259
- other_updates_counter += 1
260
- self.updates_queue.put_nowait(
261
- (update, users, chats)
262
- )
263
-
264
- if isinstance(diff, (raw.types.updates.Difference, raw.types.updates.ChannelDifference)):
265
- break
266
-
267
- await self.client.storage.update_state(id)
268
-
269
- log.info("Recovered %s messages and %s updates.", message_updates_counter, other_updates_counter)
227
+ await self.client.recover_gaps()
270
228
 
271
229
  async def stop(self):
272
230
  if not self.client.no_updates:
@@ -345,7 +303,12 @@ class Dispatcher:
345
303
  continue
346
304
 
347
305
  elif isinstance(handler, RawUpdateHandler):
348
- args = (update, users, chats)
306
+ try:
307
+ if await handler.check(self.client, update):
308
+ args = (update, users, chats)
309
+ except Exception as e:
310
+ log.exception(e)
311
+ continue
349
312
 
350
313
  if args is None:
351
314
  continue