diff --git a/Makefile b/Makefile index 3e6debe6..6b64c03c 100644 --- a/Makefile +++ b/Makefile @@ -60,3 +60,22 @@ tag: dtag: git tag -d $(TAG) git push origin -d $(TAG) + +tagall: + echo "Creating automatic tags for all version bumps..." + for hash in $$(git log --grep="Bump version\|Version bump\|v[0-9]\+\.[0-9]\+\.[0-9]\+" --format="%H"); do \ + msg=$$(git log -1 --format="%s" $$hash); \ + versions=$$(echo "$$msg" | grep -o "v[0-9]\+\.[0-9]\+\.[0-9]\+"); \ + for version in $$versions; do \ + if [ -n "$$version" ]; then \ + if git show-ref --tags --quiet --verify "refs/tags/$$version"; then \ + echo "Tag $$version already exists, skipping."; \ + else \ + echo "Creating tag $$version for commit $$hash"; \ + git tag -a "$$version" "$$hash" -m "Automatic tag $$version"; \ + fi; \ + fi; \ + done; \ + done + echo "Pushing all tags to the remote..." + git push origin --tags \ No newline at end of file diff --git a/compiler/api/compiler.py b/compiler/api/compiler.py index 75378ad7..cac08b1d 100644 --- a/compiler/api/compiler.py +++ b/compiler/api/compiler.py @@ -100,6 +100,19 @@ def camel(s: str): return "".join([i[0].upper() + i[1:] for i in s.split("_")]) +# noinspection PyShadowingBuiltins, PyShadowingNames +def get_return_type_hint(qualtype: str) -> str: + """Get return type hint for generic TLObject""" + if qualtype.startswith("Vector"): + # Extract inner type from Vector + inner = qualtype.split("<")[1][:-1] + ns, name = inner.split(".") if "." in inner else ("", inner) + return f'"List[raw.base.{".".join([ns, name]).strip(".")}]"' + else: + ns, name = qualtype.split(".") if "." in qualtype else ("", qualtype) + return f'"raw.base.{".".join([ns, name]).strip(".")}"' + + # noinspection PyShadowingBuiltins, PyShadowingNames def get_type_hint(type: str) -> str: is_flag = FLAGS_RE.match(type) @@ -301,7 +314,7 @@ def start(format: bool = False): d[qualtype].append(c.qualname) if c.section == "types": - key = c.namespace + key = c.typespace if len(c.namespace) == 0 else c.namespace if key not in namespaces_to_types: namespaces_to_types[key] = [] @@ -548,6 +561,12 @@ def start(format: bool = False): slots = ", ".join([f'"{i[0]}"' for i in sorted_args]) return_arguments = ", ".join([f"{i[0]}={i[0]}" for i in sorted_args]) + # Generate generic type hint for functions + if c.section == "functions": + generic_type = f"[{get_return_type_hint(c.qualtype)}]" + else: + generic_type = "" + compiled_combinator = combinator_tmpl.format( notice=notice, warning=WARNING, @@ -560,7 +579,8 @@ def start(format: bool = False): fields=fields, read_types=read_types, write_types=write_types, - return_arguments=return_arguments + return_arguments=return_arguments, + generic_type=generic_type ) directory = "types" if c.section == "types" else c.section diff --git a/compiler/api/source/main_api.tl b/compiler/api/source/main_api.tl index e31022ec..ada10419 100644 --- a/compiler/api/source/main_api.tl +++ b/compiler/api/source/main_api.tl @@ -8,7 +8,7 @@ // This file is auto-generated by TLExtractor -// Copyright (C) 2025 Laky-64 +// Copyright (C) 2026 Laky-64 ---types--- @@ -36,18 +36,18 @@ inputUserSelf#f7c1b13f = InputUser; inputUser#f21158c6 user_id:long access_hash:long = InputUser; inputUserFromMessage#1da448e2 peer:InputPeer msg_id:int user_id:long = InputUser; -inputPhoneContact#f392b7f4 client_id:long phone:string first_name:string last_name:string = InputContact; +inputPhoneContact#6a1dc4be flags:# client_id:long phone:string first_name:string last_name:string note:flags.0?TextWithEntities = InputContact; inputFile#f52ff27f id:long parts:int name:string md5_checksum:string = InputFile; inputFileBig#fa4f0bb5 id:long parts:int name:string = InputFile; inputFileStoryDocument#62dc8b48 id:InputDocument = InputFile; inputMediaEmpty#9664f57f = InputMedia; -inputMediaUploadedPhoto#1e287d04 flags:# spoiler:flags.2?true file:InputFile stickers:flags.0?Vector ttl_seconds:flags.1?int = InputMedia; -inputMediaPhoto#b3ba0635 flags:# spoiler:flags.1?true id:InputPhoto ttl_seconds:flags.0?int = InputMedia; +inputMediaUploadedPhoto#7d8375da flags:# spoiler:flags.2?true live_photo:flags.3?true file:InputFile stickers:flags.0?Vector ttl_seconds:flags.1?int video:flags.3?InputDocument = InputMedia; +inputMediaPhoto#e3af4434 flags:# spoiler:flags.1?true id:InputPhoto ttl_seconds:flags.0?int video:flags.2?InputDocument = InputMedia; inputMediaGeoPoint#f9c44144 geo_point:InputGeoPoint = InputMedia; inputMediaContact#f8ab7dfb phone_number:string first_name:string last_name:string vcard:string = InputMedia; -inputMediaUploadedDocument#37c9330 flags:# nosound_video:flags.3?true force_file:flags.4?true spoiler:flags.5?true file:InputFile thumb:flags.2?InputFile mime_type:string attributes:Vector stickers:flags.0?Vector video_cover:flags.6?InputPhoto video_timestamp:flags.7?int ttl_seconds:flags.1?int = InputMedia; +inputMediaUploadedDocument#37c9330 flags:# nosound_video:flags.3?true force_file:flags.4?true spoiler:flags.5?true live_photo:flags.8?true file:InputFile thumb:flags.2?InputFile mime_type:string attributes:Vector stickers:flags.0?Vector video_cover:flags.6?InputPhoto video_timestamp:flags.7?int ttl_seconds:flags.1?int = InputMedia; inputMediaDocument#a8763ab5 flags:# spoiler:flags.2?true id:InputDocument video_cover:flags.3?InputPhoto video_timestamp:flags.4?int ttl_seconds:flags.0?int query:flags.1?string = InputMedia; inputMediaVenue#c13d1c11 geo_point:InputGeoPoint title:string address:string provider:string venue_id:string venue_type:string = InputMedia; inputMediaPhotoExternal#e5bbfe1a flags:# spoiler:flags.1?true url:string ttl_seconds:flags.0?int = InputMedia; @@ -55,12 +55,13 @@ inputMediaDocumentExternal#779600f9 flags:# spoiler:flags.1?true url:string ttl_ inputMediaGame#d33f43f3 id:InputGame = InputMedia; inputMediaInvoice#405fef0d flags:# title:string description:string photo:flags.0?InputWebDocument invoice:Invoice payload:bytes provider:flags.3?string provider_data:DataJSON start_param:flags.1?string extended_media:flags.2?InputMedia = InputMedia; inputMediaGeoLive#971fa843 flags:# stopped:flags.0?true geo_point:InputGeoPoint heading:flags.2?int period:flags.1?int proximity_notification_radius:flags.3?int = InputMedia; -inputMediaPoll#f94e5f1 flags:# poll:Poll correct_answers:flags.0?Vector solution:flags.1?string solution_entities:flags.1?Vector = InputMedia; +inputMediaPoll#883a4108 flags:# poll:Poll correct_answers:flags.0?Vector attached_media:flags.3?InputMedia solution:flags.1?string solution_entities:flags.1?Vector solution_media:flags.2?InputMedia = InputMedia; inputMediaDice#e66fbf7b emoticon:string = InputMedia; inputMediaStory#89fdd778 peer:InputPeer id:int = InputMedia; inputMediaWebPage#c21b8849 flags:# force_large_media:flags.0?true force_small_media:flags.1?true optional:flags.2?true url:string = InputMedia; inputMediaPaidMedia#c4103386 flags:# stars_amount:long extended_media:Vector payload:flags.0?string = InputMedia; inputMediaTodo#9fc55fde todo:TodoList = InputMedia; +inputMediaStakeDice#f3a9244a game_hash:string ton_amount:long client_seed:bytes = InputMedia; inputChatPhotoEmpty#1ca48f57 = InputChatPhoto; inputChatUploadedPhoto#bdcdaec0 flags:# file:flags.0?InputFile video:flags.1?InputFile video_start_ts:flags.2?double video_emoji_markup:flags.3?VideoSize = InputChatPhoto; @@ -99,7 +100,7 @@ storage.fileMp4#b3cea0e4 = storage.FileType; storage.fileWebp#1081464c = storage.FileType; userEmpty#d3bc4b7a id:long = User; -user#20b1422 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true apply_min_photo:flags.25?true fake:flags.26?true bot_attach_menu:flags.27?true premium:flags.28?true attach_menu_enabled:flags.29?true flags2:# bot_can_edit:flags2.1?true close_friend:flags2.2?true stories_hidden:flags2.3?true stories_unavailable:flags2.4?true contact_require_premium:flags2.10?true bot_business:flags2.11?true bot_has_main_app:flags2.13?true bot_forum_view:flags2.16?true id:long access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector bot_inline_placeholder:flags.19?string lang_code:flags.22?string emoji_status:flags.30?EmojiStatus usernames:flags2.0?Vector stories_max_id:flags2.5?int color:flags2.8?PeerColor profile_color:flags2.9?PeerColor bot_active_users:flags2.12?int bot_verification_icon:flags2.14?long send_paid_messages_stars:flags2.15?long = User; +user#31774388 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true apply_min_photo:flags.25?true fake:flags.26?true bot_attach_menu:flags.27?true premium:flags.28?true attach_menu_enabled:flags.29?true flags2:# bot_can_edit:flags2.1?true close_friend:flags2.2?true stories_hidden:flags2.3?true stories_unavailable:flags2.4?true contact_require_premium:flags2.10?true bot_business:flags2.11?true bot_has_main_app:flags2.13?true bot_forum_view:flags2.16?true bot_forum_can_manage_topics:flags2.17?true bot_can_manage_bots:flags2.18?true id:long access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector bot_inline_placeholder:flags.19?string lang_code:flags.22?string emoji_status:flags.30?EmojiStatus usernames:flags2.0?Vector stories_max_id:flags2.5?RecentStory color:flags2.8?PeerColor profile_color:flags2.9?PeerColor bot_active_users:flags2.12?int bot_verification_icon:flags2.14?long send_paid_messages_stars:flags2.15?long = User; userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto; userProfilePhoto#82d1f706 flags:# has_video:flags.0?true personal:flags.2?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = UserProfilePhoto; @@ -115,15 +116,15 @@ userStatusHidden#cf7d64b1 = UserStatus; chatEmpty#29562865 id:long = Chat; chat#41cbf256 flags:# creator:flags.0?true kicked:flags.1?true left:flags.2?true deactivated:flags.5?true call_active:flags.23?true call_not_empty:flags.24?true noforwards:flags.25?true id:long title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel admin_rights:flags.14?ChatAdminRights default_banned_rights:flags.18?ChatBannedRights = Chat; chatForbidden#6592a1a7 id:long title:string = Chat; -channel#fe685355 flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true has_geo:flags.21?true slowmode_enabled:flags.22?true call_active:flags.23?true call_not_empty:flags.24?true fake:flags.25?true gigagroup:flags.26?true noforwards:flags.27?true join_to_send:flags.28?true join_request:flags.29?true forum:flags.30?true flags2:# stories_hidden:flags2.1?true stories_hidden_min:flags2.2?true stories_unavailable:flags2.3?true signature_profiles:flags2.12?true autotranslation:flags2.15?true broadcast_messages_allowed:flags2.16?true monoforum:flags2.17?true forum_tabs:flags2.19?true id:long access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int restriction_reason:flags.9?Vector admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int usernames:flags2.0?Vector stories_max_id:flags2.4?int color:flags2.7?PeerColor profile_color:flags2.8?PeerColor emoji_status:flags2.9?EmojiStatus level:flags2.10?int subscription_until_date:flags2.11?int bot_verification_icon:flags2.13?long send_paid_messages_stars:flags2.14?long linked_monoforum_id:flags2.18?long = Chat; -channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true id:long access_hash:long title:string until_date:flags.16?int = Chat; +channel#1c32b11c flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true has_geo:flags.21?true slowmode_enabled:flags.22?true call_active:flags.23?true call_not_empty:flags.24?true fake:flags.25?true gigagroup:flags.26?true noforwards:flags.27?true join_to_send:flags.28?true join_request:flags.29?true forum:flags.30?true flags2:# stories_hidden:flags2.1?true stories_hidden_min:flags2.2?true stories_unavailable:flags2.3?true signature_profiles:flags2.12?true autotranslation:flags2.15?true broadcast_messages_allowed:flags2.16?true monoforum:flags2.17?true forum_tabs:flags2.19?true id:long access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int restriction_reason:flags.9?Vector admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int usernames:flags2.0?Vector stories_max_id:flags2.4?RecentStory color:flags2.7?PeerColor profile_color:flags2.8?PeerColor emoji_status:flags2.9?EmojiStatus level:flags2.10?int subscription_until_date:flags2.11?int bot_verification_icon:flags2.13?long send_paid_messages_stars:flags2.14?long linked_monoforum_id:flags2.18?long = Chat; +channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true monoforum:flags.10?true id:long access_hash:long title:string until_date:flags.16?int = Chat; -chatFull#2633421b flags:# can_set_username:flags.7?true has_scheduled:flags.8?true translations_disabled:flags.19?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector available_reactions:flags.18?ChatReactions reactions_limit:flags.20?int = ChatFull; +chatFull#2633421b flags:# can_set_username:flags.7?true has_scheduled:flags.8?true translations_disabled:flags.19?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ChatInviteExported bot_info:flags.3?Vector pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector available_reactions:flags.18?ChatReactions reactions_limit:flags.20?int = ChatFull; channelFull#e4e0b29d flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true antispam:flags2.1?true participants_hidden:flags2.2?true translations_disabled:flags2.3?true stories_pinned_available:flags2.5?true view_forum_as_messages:flags2.6?true restricted_sponsored:flags2.11?true can_view_revenue:flags2.12?true paid_media_allowed:flags2.14?true can_view_stars_revenue:flags2.15?true paid_reactions_available:flags2.16?true stargifts_available:flags2.19?true paid_messages_available:flags2.20?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions reactions_limit:flags2.13?int stories:flags2.4?PeerStories wallpaper:flags2.7?WallPaper boosts_applied:flags2.8?int boosts_unrestrict:flags2.9?int emojiset:flags2.10?StickerSet bot_verification:flags2.17?BotVerification stargifts_count:flags2.18?int send_paid_messages_stars:flags2.21?long main_tab:flags2.22?ProfileTab = ChatFull; -chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant; -chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant; -chatParticipantAdmin#a0933f5b user_id:long inviter_id:long date:int = ChatParticipant; +chatParticipant#38e79fde flags:# user_id:long inviter_id:long date:int rank:flags.0?string = ChatParticipant; +chatParticipantCreator#e1f867b8 flags:# user_id:long rank:flags.0?string = ChatParticipant; +chatParticipantAdmin#360d5d2 flags:# user_id:long inviter_id:long date:int rank:flags.0?string = ChatParticipant; chatParticipantsForbidden#8763d3e1 flags:# chat_id:long self_participant:flags.0?ChatParticipant = ChatParticipants; chatParticipants#3cbc93f8 chat_id:long participants:Vector version:int = ChatParticipants; @@ -132,27 +133,28 @@ chatPhotoEmpty#37c1011c = ChatPhoto; chatPhoto#1c6e1c11 flags:# has_video:flags.0?true photo_id:long stripped_thumb:flags.1?bytes dc_id:int = ChatPhoto; messageEmpty#90a6ca84 flags:# id:int peer_id:flags.0?Peer = Message; -message#9815cec8 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true pinned:flags.24?true noforwards:flags.26?true invert_media:flags.27?true flags2:# offline:flags2.1?true video_processing_pending:flags2.4?true paid_suggested_post_stars:flags2.8?true paid_suggested_post_ton:flags2.9?true id:int from_id:flags.8?Peer from_boosts_applied:flags.29?int peer_id:Peer saved_peer_id:flags.28?Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?long via_business_bot_id:flags2.0?long reply_to:flags.3?MessageReplyHeader date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector views:flags.10?int forwards:flags.10?int replies:flags.23?MessageReplies edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long reactions:flags.20?MessageReactions restriction_reason:flags.22?Vector ttl_period:flags.25?int quick_reply_shortcut_id:flags.30?int effect:flags2.2?long factcheck:flags2.3?FactCheck report_delivery_until_date:flags2.5?int paid_message_stars:flags2.6?long suggested_post:flags2.7?SuggestedPost = Message; +message#3ae56482 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true pinned:flags.24?true noforwards:flags.26?true invert_media:flags.27?true flags2:# offline:flags2.1?true video_processing_pending:flags2.4?true paid_suggested_post_stars:flags2.8?true paid_suggested_post_ton:flags2.9?true id:int from_id:flags.8?Peer from_boosts_applied:flags.29?int from_rank:flags2.12?string peer_id:Peer saved_peer_id:flags.28?Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?long via_business_bot_id:flags2.0?long reply_to:flags.3?MessageReplyHeader date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector views:flags.10?int forwards:flags.10?int replies:flags.23?MessageReplies edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long reactions:flags.20?MessageReactions restriction_reason:flags.22?Vector ttl_period:flags.25?int quick_reply_shortcut_id:flags.30?int effect:flags2.2?long factcheck:flags2.3?FactCheck report_delivery_until_date:flags2.5?int paid_message_stars:flags2.6?long suggested_post:flags2.7?SuggestedPost schedule_repeat_period:flags2.10?int summary_from_language:flags2.11?string = Message; messageService#7a800e0a flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true reactions_are_possible:flags.9?true silent:flags.13?true post:flags.14?true legacy:flags.19?true id:int from_id:flags.8?Peer peer_id:Peer saved_peer_id:flags.28?Peer reply_to:flags.3?MessageReplyHeader date:int action:MessageAction reactions:flags.20?MessageReactions ttl_period:flags.25?int = Message; messageMediaEmpty#3ded6320 = MessageMedia; -messageMediaPhoto#695150d7 flags:# spoiler:flags.3?true photo:flags.0?Photo ttl_seconds:flags.2?int = MessageMedia; +messageMediaPhoto#e216eb63 flags:# spoiler:flags.3?true live_photo:flags.4?true photo:flags.0?Photo ttl_seconds:flags.2?int document:flags.4?Document = MessageMedia; messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia; messageMediaContact#70322949 phone_number:string first_name:string last_name:string vcard:string user_id:long = MessageMedia; messageMediaUnsupported#9f84f49e = MessageMedia; -messageMediaDocument#52d8ccd9 flags:# nopremium:flags.3?true spoiler:flags.4?true video:flags.6?true round:flags.7?true voice:flags.8?true document:flags.0?Document alt_documents:flags.5?Vector video_cover:flags.9?Photo video_timestamp:flags.10?int ttl_seconds:flags.2?int = MessageMedia; +messageMediaDocument#52d8ccd9 flags:# nopremium:flags.3?true spoiler:flags.4?true video:flags.6?true round:flags.7?true voice:flags.8?true live_photo:flags.11?true document:flags.0?Document alt_documents:flags.5?Vector video_cover:flags.9?Photo video_timestamp:flags.10?int ttl_seconds:flags.2?int = MessageMedia; messageMediaWebPage#ddf10c3b flags:# force_large_media:flags.0?true force_small_media:flags.1?true manual:flags.3?true safe:flags.4?true webpage:WebPage = MessageMedia; messageMediaVenue#2ec0533f geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string = MessageMedia; messageMediaGame#fdb19008 game:Game = MessageMedia; messageMediaInvoice#f6a548d3 flags:# shipping_address_requested:flags.1?true test:flags.3?true title:string description:string photo:flags.0?WebDocument receipt_msg_id:flags.2?int currency:string total_amount:long start_param:string extended_media:flags.4?MessageExtendedMedia = MessageMedia; messageMediaGeoLive#b940c666 flags:# geo:GeoPoint heading:flags.0?int period:int proximity_notification_radius:flags.1?int = MessageMedia; -messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia; -messageMediaDice#3f7ee58b value:int emoticon:string = MessageMedia; +messageMediaPoll#773f4e66 flags:# poll:Poll results:PollResults attached_media:flags.0?MessageMedia = MessageMedia; +messageMediaDice#8cbec07 flags:# value:int emoticon:string game_outcome:flags.0?messages.EmojiGameOutcome = MessageMedia; messageMediaStory#68cb6283 flags:# via_mention:flags.1?true peer:Peer id:int story:flags.0?StoryItem = MessageMedia; messageMediaGiveaway#aa073beb flags:# only_new_subscribers:flags.0?true winners_are_visible:flags.2?true channels:Vector countries_iso2:flags.1?Vector prize_description:flags.3?string quantity:int months:flags.4?int stars:flags.5?long until_date:int = MessageMedia; messageMediaGiveawayResults#ceaa3ea1 flags:# only_new_subscribers:flags.0?true refunded:flags.2?true channel_id:long additional_peers_count:flags.3?int launch_msg_id:int winners_count:int unclaimed_count:int winners:Vector months:flags.4?int stars:flags.5?long prize_description:flags.1?string until_date:int = MessageMedia; messageMediaPaidMedia#a8852491 stars_amount:long extended_media:Vector = MessageMedia; messageMediaToDo#8a53b014 flags:# todo:TodoList completions:flags.0?Vector = MessageMedia; +messageMediaVideoStream#ca5cab89 flags:# rtmp_stream:flags.0?true call:InputGroupCall = MessageMedia; messageActionEmpty#b6aef7b0 = MessageAction; messageActionChatCreate#bd47cbad title:string users:Vector = MessageAction; @@ -186,13 +188,13 @@ messageActionSetChatTheme#b91bbd3a theme:ChatTheme = MessageAction; messageActionChatJoinedByRequest#ebbca3cb = MessageAction; messageActionWebViewDataSentMe#47dd8079 text:string data:string = MessageAction; messageActionWebViewDataSent#b4c38cb5 text:string = MessageAction; -messageActionGiftPremium#6c6274fa flags:# currency:string amount:long months:int crypto_currency:flags.0?string crypto_amount:flags.0?long message:flags.1?TextWithEntities = MessageAction; +messageActionGiftPremium#48e91302 flags:# currency:string amount:long days:int crypto_currency:flags.0?string crypto_amount:flags.0?long message:flags.1?TextWithEntities = MessageAction; messageActionTopicCreate#d999256 flags:# title_missing:flags.1?true title:string icon_color:int icon_emoji_id:flags.0?long = MessageAction; messageActionTopicEdit#c0944820 flags:# title:flags.0?string icon_emoji_id:flags.1?long closed:flags.2?Bool hidden:flags.3?Bool = MessageAction; messageActionSuggestProfilePhoto#57de635e photo:Photo = MessageAction; messageActionRequestedPeer#31518e9b button_id:int peers:Vector = MessageAction; messageActionSetChatWallPaper#5060a3f4 flags:# same:flags.0?true for_both:flags.1?true wallpaper:WallPaper = MessageAction; -messageActionGiftCode#56d03994 flags:# via_giveaway:flags.0?true unclaimed:flags.5?true boost_peer:flags.1?Peer months:int slug:string currency:flags.2?string amount:flags.2?long crypto_currency:flags.3?string crypto_amount:flags.3?long message:flags.4?TextWithEntities = MessageAction; +messageActionGiftCode#31c48347 flags:# via_giveaway:flags.0?true unclaimed:flags.5?true boost_peer:flags.1?Peer days:int slug:string currency:flags.2?string amount:flags.2?long crypto_currency:flags.3?string crypto_amount:flags.3?long message:flags.4?TextWithEntities = MessageAction; messageActionGiveawayLaunch#a80f51e4 flags:# stars:flags.0?long = MessageAction; messageActionGiveawayResults#87e2f155 flags:# stars:flags.0?true winners_count:int unclaimed_count:int = MessageAction; messageActionBoostApply#cc02aa6d boosts:int = MessageAction; @@ -200,8 +202,8 @@ messageActionRequestedPeerSentMe#93b31848 button_id:int peers:Vector = MessageAction; @@ -211,15 +213,24 @@ messageActionSuggestedPostApproval#ee7a1596 flags:# rejected:flags.0?true balanc messageActionSuggestedPostSuccess#95ddcf69 price:StarsAmount = MessageAction; messageActionSuggestedPostRefund#69f916f8 flags:# payer_initiated:flags.0?true = MessageAction; messageActionGiftTon#a8a3c699 flags:# currency:string amount:long crypto_currency:string crypto_amount:long transaction_id:flags.0?string = MessageAction; -messageActionPhoneNumberRequest#1baa035 = MessageAction; messageActionSuggestBirthday#2c8f2a25 birthday:Birthday = MessageAction; +messageActionStarGiftPurchaseOffer#774278d4 flags:# accepted:flags.0?int declined:flags.1?true gift:StarGift price:StarsAmount expires_at:int = MessageAction; +messageActionStarGiftPurchaseOfferDeclined#73ada76b flags:# expired:flags.0?true gift:StarGift price:StarsAmount = MessageAction; +messageActionNewCreatorPending#b07ed085 new_creator_id:long = MessageAction; +messageActionChangeCreator#e188503b new_creator_id:long = MessageAction; +messageActionNoForwardsToggle#bf7d6572 prev_value:Bool new_value:Bool = MessageAction; +messageActionNoForwardsRequest#3e2793ba flags:# expired:flags.0?true prev_value:Bool new_value:Bool = MessageAction; +messageActionManagedBotCreated#16605e3e bot_id:long = MessageAction; +messageActionPhoneNumberRequest#1baa035 = MessageAction; +messageActionPollDeleteAnswer#399674dc answer:PollAnswer = MessageAction; messageActionUserJoined#55555550 = MessageAction; messageActionUserUpdatedPhoto#55555551 new_user_photo:UserProfilePhoto = MessageAction; messageActionTTLChange#55555552 ttl:int = MessageAction; messageActionCreatedBroadcastList#55555557 = MessageAction; messageActionLoginUnknownLocation#555555f5 title:string address:string = MessageAction; +messageActionPollAppendAnswer#9da1cd6c answer:PollAnswer = MessageAction; -dialog#d58a08c6 flags:# pinned:flags.2?true unread_mark:flags.3?true view_forum_as_messages:flags.6?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int ttl_period:flags.5?int = Dialog; +dialog#fc89f7f3 flags:# pinned:flags.2?true unread_mark:flags.3?true view_forum_as_messages:flags.6?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int unread_poll_votes_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int ttl_period:flags.5?int = Dialog; dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog; photoEmpty#2331b22d id:long = Photo; @@ -270,7 +281,7 @@ inputReportReasonFake#f5ddd6e7 = ReportReason; inputReportReasonIllegalDrugs#a8eb2be = ReportReason; inputReportReasonPersonalDetails#9ec7863d = ReportReason; -userFull#a02bc13e flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true voice_messages_forbidden:flags.20?true translations_disabled:flags.23?true stories_pinned_available:flags.26?true blocked_my_stories_from:flags.27?true wallpaper_overridden:flags.28?true contact_require_premium:flags.29?true read_dates_private:flags.30?true flags2:# sponsored_enabled:flags2.7?true can_view_revenue:flags2.9?true bot_can_manage_emoji_status:flags2.10?true display_gifts_button:flags2.16?true id:long about:flags.1?string settings:PeerSettings personal_photo:flags.21?Photo profile_photo:flags.2?Photo fallback_photo:flags.22?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme:flags.15?ChatTheme private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights wallpaper:flags.24?WallPaper stories:flags.25?PeerStories business_work_hours:flags2.0?BusinessWorkHours business_location:flags2.1?BusinessLocation business_greeting_message:flags2.2?BusinessGreetingMessage business_away_message:flags2.3?BusinessAwayMessage business_intro:flags2.4?BusinessIntro birthday:flags2.5?Birthday personal_channel_id:flags2.6?long personal_channel_message:flags2.6?int stargifts_count:flags2.8?int starref_program:flags2.11?StarRefProgram bot_verification:flags2.12?BotVerification send_paid_messages_stars:flags2.14?long disallowed_stargifts:flags2.15?DisallowedGiftsSettings stars_rating:flags2.17?StarsRating stars_my_pending_rating:flags2.18?StarsRating stars_my_pending_rating_date:flags2.18?int main_tab:flags2.20?ProfileTab saved_music:flags2.21?Document note:flags2.22?TextWithEntities = UserFull; +userFull#6cbe645 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true voice_messages_forbidden:flags.20?true translations_disabled:flags.23?true stories_pinned_available:flags.26?true blocked_my_stories_from:flags.27?true wallpaper_overridden:flags.28?true contact_require_premium:flags.29?true read_dates_private:flags.30?true flags2:# sponsored_enabled:flags2.7?true can_view_revenue:flags2.9?true bot_can_manage_emoji_status:flags2.10?true display_gifts_button:flags2.16?true noforwards_my_enabled:flags2.23?true noforwards_peer_enabled:flags2.24?true id:long about:flags.1?string settings:PeerSettings personal_photo:flags.21?Photo profile_photo:flags.2?Photo fallback_photo:flags.22?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme:flags.15?ChatTheme private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights wallpaper:flags.24?WallPaper stories:flags.25?PeerStories business_work_hours:flags2.0?BusinessWorkHours business_location:flags2.1?BusinessLocation business_greeting_message:flags2.2?BusinessGreetingMessage business_away_message:flags2.3?BusinessAwayMessage business_intro:flags2.4?BusinessIntro birthday:flags2.5?Birthday personal_channel_id:flags2.6?long personal_channel_message:flags2.6?int stargifts_count:flags2.8?int starref_program:flags2.11?StarRefProgram bot_verification:flags2.12?BotVerification send_paid_messages_stars:flags2.14?long disallowed_stargifts:flags2.15?DisallowedGiftsSettings stars_rating:flags2.17?StarsRating stars_my_pending_rating:flags2.18?StarsRating stars_my_pending_rating_date:flags2.18?int main_tab:flags2.20?ProfileTab saved_music:flags2.21?Document note:flags2.22?TextWithEntities bot_manager_id:flags2.25?long = UserFull; contact#145ade0b user_id:long mutual:Bool = Contact; @@ -320,6 +331,7 @@ inputMessagesFilterGeo#e7026d0d = MessagesFilter; inputMessagesFilterContacts#e062db83 = MessagesFilter; inputMessagesFilterPinned#1bb00451 = MessagesFilter; inputMessagesFilterPhotoVideoDocuments#d95e73bb = MessagesFilter; +inputMessagesFilterPoll#fa2bc90a = MessagesFilter; updateNewMessage#1f2b0afd message:Message pts:int pts_count:int = Update; updateMessageID#4e90bfd6 id:int random_id:long = Update; @@ -329,7 +341,7 @@ updateChatUserTyping#83487af0 chat_id:long from_id:Peer action:SendMessageAction updateChatParticipants#7761198 participants:ChatParticipants = Update; updateUserStatus#e5bdf8de user_id:long status:UserStatus = Update; updateUserName#a7848924 user_id:long first_name:string last_name:string usernames:Vector = Update; -updateNewAuthorization#8951abef flags:# unconfirmed:flags.0?true hash:long date:flags.0?int device:flags.0?string location:flags.0?string = Update; +updateNewAuthorization#8951abef flags:# unconfirmed:flags.0?true hash:flags.0?long date:flags.0?int device:flags.0?string location:flags.0?string = Update; updateNewEncryptedMessage#12bcbd9a message:EncryptedMessage qts:int = Update; updateEncryptedChatTyping#1710f156 chat_id:int = Update; updateEncryption#b4a2e88d chat:EncryptedChat date:int = Update; @@ -383,7 +395,7 @@ updateChannelReadMessagesContents#25f324f7 flags:# channel_id:long top_msg_id:fl updateContactsReset#7084a7be = Update; updateChannelAvailableMessages#b23fc698 channel_id:long available_min_id:int = Update; updateDialogUnreadMark#b658f23e flags:# unread:flags.0?true peer:DialogPeer saved_peer_id:flags.1?Peer = Update; -updateMessagePoll#aca1657b flags:# poll_id:long poll:flags.0?Poll results:PollResults = Update; +updateMessagePoll#d64c522b flags:# peer:flags.1?Peer msg_id:flags.1?int top_msg_id:flags.2?int poll_id:long poll:flags.0?Poll results:PollResults = Update; updateChatDefaultBannedRights#54c01850 peer:Peer default_banned_rights:ChatBannedRights version:int = Update; updateFolderPeers#19360dc0 folder_peers:Vector pts:int pts_count:int = Update; updatePeerSettings#6a7e7366 peer:Peer settings:PeerSettings = Update; @@ -393,7 +405,7 @@ updateDeleteScheduledMessages#f2a71983 flags:# peer:Peer messages:Vector se updateTheme#8216fba3 theme:Theme = Update; updateGeoLiveViewed#871fb939 peer:Peer msg_id:int = Update; updateLoginToken#564fe691 = Update; -updateMessagePollVote#24f40e77 poll_id:long peer:Peer options:Vector qts:int = Update; +updateMessagePollVote#7699f014 poll_id:long peer:Peer options:Vector positions:Vector qts:int = Update; updateDialogFilter#26ffde7d flags:# id:int filter:flags.0?DialogFilter = Update; updateDialogFilterOrder#a5d72105 order:Vector = Update; updateDialogFilters#3504914f = Update; @@ -407,7 +419,7 @@ updatePinnedMessages#ed85eab5 flags:# pinned:flags.0?true peer:Peer messages:Vec updatePinnedChannelMessages#5bb98608 flags:# pinned:flags.0?true channel_id:long messages:Vector pts:int pts_count:int = Update; updateChat#f89a6a4e chat_id:long = Update; updateGroupCallParticipants#f2ebdb4e call:InputGroupCall participants:Vector version:int = Update; -updateGroupCall#97d64341 flags:# chat_id:flags.0?long call:GroupCall = Update; +updateGroupCall#9d2216e0 flags:# live_story:flags.2?true peer:flags.1?Peer call:GroupCall = Update; updatePeerHistoryTTL#bb9bb9a5 flags:# peer:Peer ttl_period:flags.0?int = Update; updateChatParticipant#d087663a flags:# chat_id:long date:int actor_id:long user_id:long prev_participant:flags.0?ChatParticipant new_participant:flags.1?ChatParticipant invite:flags.2?ExportedChatInvite qts:int = Update; updateChannelParticipant#985d3abb flags:# via_chatlist:flags.3?true channel_id:long date:int actor_id:long user_id:long prev_participant:flags.0?ChannelParticipant new_participant:flags.1?ChannelParticipant invite:flags.2?ExportedChatInvite qts:int = Update; @@ -428,8 +440,6 @@ updateRecentEmojiStatuses#30f443db = Update; updateRecentReactions#6f7863f4 = Update; updateMoveStickerSetToTop#86fccf85 flags:# masks:flags.0?true emojis:flags.1?true stickerset:long = Update; updateMessageExtendedMedia#d5a41724 peer:Peer msg_id:int extended_media:Vector = Update; -updateChannelPinnedTopic#192efbe3 flags:# pinned:flags.0?true channel_id:long topic_id:int = Update; -updateChannelPinnedTopics#fe198602 flags:# channel_id:long order:flags.0?Vector = Update; updateUser#20529438 user_id:long = Update; updateAutoSaveSettings#ec05b097 = Update; updateStory#75b3b798 peer:Peer story:StoryItem = Update; @@ -466,12 +476,19 @@ updateGroupCallChainBlocks#a477288f call:InputGroupCall sub_chain_id:int blocks: updateReadMonoForumInbox#77b0e372 channel_id:long saved_peer_id:Peer read_max_id:int = Update; updateReadMonoForumOutbox#a4a79376 channel_id:long saved_peer_id:Peer read_max_id:int = Update; updateMonoForumNoPaidException#9f812b08 flags:# exception:flags.0?true channel_id:long saved_peer_id:Peer = Update; -updatePinnedForumTopic#683b2c52 flags:# pinned:flags.0?int peer:Peer topic_id:int = Update; -updateGroupCallMessage#78c314e0 call:InputGroupCall from_id:Peer random_id:long message:TextWithEntities = Update; -updateTranscribeAudio#88617090 flags:# final:flags.0?true transcription_id:long text:string = Update; -updateBotSubscriptionExpire#a8ae3eb1 user_id:long payload:string until_date:int qts:int = Update; +updateGroupCallMessage#d8326f0d call:InputGroupCall message:GroupCallMessage = Update; updateGroupCallEncryptedMessage#c957a766 call:InputGroupCall from_id:Peer encrypted_message:bytes = Update; +updatePinnedForumTopic#683b2c52 flags:# pinned:flags.0?true peer:Peer topic_id:int = Update; updatePinnedForumTopics#def143d0 flags:# peer:Peer order:flags.0?Vector = Update; +updateDeleteGroupCallMessages#3e85e92c call:InputGroupCall messages:Vector = Update; +updateStarGiftAuctionState#48e246c2 gift_id:long state:StarGiftAuctionState = Update; +updateStarGiftAuctionUserState#dc58f31e gift_id:long user_state:StarGiftAuctionUserState = Update; +updateEmojiGameInfo#fb9c547a info:messages.EmojiGameInfo = Update; +updateStarGiftCraftFail#ac072444 = Update; +updateChatParticipantRank#bd8367b9 chat_id:long user_id:long rank:string version:int = Update; +updateManagedBot#4880ed9a user_id:long bot_id:long qts:int = Update; +updateTranscribeAudio#88617090 flags:# final:flags.0?true transcription_id:long text:string = Update; +updateBotSubscriptionExpire#a8ae3eb1 user_id:long payload:string until_date:int qts:int = Update; updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State; @@ -481,12 +498,12 @@ updates.differenceSlice#a8fb1981 new_messages:Vector new_encrypted_mess updates.differenceTooLong#4afe8f6d pts:int = updates.Difference; updatesTooLong#e317af7e = Updates; -updateShortMessage#313bc7f8 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true id:int user_id:long message:string pts:int pts_count:int date:int fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?long reply_to:flags.3?MessageReplyHeader entities:flags.7?Vector ttl_period:flags.25?int = Updates; -updateShortChatMessage#4d6deea5 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true id:int from_id:long chat_id:long message:string pts:int pts_count:int date:int fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?long reply_to:flags.3?MessageReplyHeader entities:flags.7?Vector ttl_period:flags.25?int = Updates; +updateShortMessage#313bc7f8 flags:# out:flags.1?true id:flags.13?int mentioned:flags.4?true user_id:long media_unread:flags.5?true message:string silent:flags.13?true pts:int pts_count:int date:int fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?long reply_to:flags.3?MessageReplyHeader entities:flags.7?Vector ttl_period:flags.25?int = Updates; +updateShortChatMessage#4d6deea5 flags:# out:flags.1?true id:flags.13?int mentioned:flags.4?true from_id:long media_unread:flags.5?true chat_id:long silent:flags.13?true message:string pts:int pts_count:int date:int fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?long reply_to:flags.3?MessageReplyHeader entities:flags.7?Vector ttl_period:flags.25?int = Updates; updateShort#78d4dec1 update:Update date:int = Updates; updatesCombined#725b04c3 updates:Vector users:Vector chats:Vector date:int seq_start:int seq:int = Updates; updates#74ae4240 updates:Vector users:Vector chats:Vector date:int seq:int = Updates; -updateShortSentMessage#9015e101 flags:# out:flags.1?true id:int pts:int pts_count:int date:int media:flags.9?MessageMedia entities:flags.7?Vector ttl_period:flags.25?int = Updates; +updateShortSentMessage#9015e101 flags:# out:flags.1?true id:flags.1?int pts:int pts_count:int date:int media:flags.9?MessageMedia entities:flags.7?Vector ttl_period:flags.25?int = Updates; photos.photos#8dca6aa5 photos:Vector users:Vector = photos.Photos; photos.photosSlice#15051f54 count:int photos:Vector users:Vector = photos.Photos; @@ -581,6 +598,7 @@ inputPrivacyKeyAbout#3823cc40 = InputPrivacyKey; inputPrivacyKeyBirthday#d65a11cc = InputPrivacyKey; inputPrivacyKeyStarGiftsAutoSave#e1732341 = InputPrivacyKey; inputPrivacyKeyNoPaidMessages#bdc597b4 = InputPrivacyKey; +inputPrivacyKeySavedMusic#4dbe9226 = InputPrivacyKey; privacyKeyStatusTimestamp#bc2eab30 = PrivacyKey; privacyKeyChatInvite#500e6dfa = PrivacyKey; @@ -595,6 +613,7 @@ privacyKeyAbout#a486b761 = PrivacyKey; privacyKeyBirthday#2000a518 = PrivacyKey; privacyKeyStarGiftsAutoSave#2ca4fdf8 = PrivacyKey; privacyKeyNoPaidMessages#17d348d2 = PrivacyKey; +privacyKeySavedMusic#ff7a571b = PrivacyKey; inputPrivacyValueAllowContacts#d09e07b = InputPrivacyRule; inputPrivacyValueAllowAll#184b35ce = InputPrivacyRule; @@ -694,24 +713,24 @@ botCommand#c27ac8c7 command:string description:string = BotCommand; botInfo#4d8a0299 flags:# has_preview_medias:flags.6?true user_id:flags.0?long description:flags.1?string description_photo:flags.4?Photo description_document:flags.5?Document commands:flags.2?Vector menu_button:flags.3?BotMenuButton privacy_policy_url:flags.7?string app_settings:flags.8?BotAppSettings verifier_settings:flags.9?BotVerifierSettings = BotInfo; -keyboardButton#a2fa4880 text:string = KeyboardButton; -keyboardButtonUrl#258aff05 text:string url:string = KeyboardButton; -keyboardButtonCallback#35bbdb6b flags:# requires_password:flags.0?true text:string data:bytes = KeyboardButton; -keyboardButtonRequestPhone#b16a6c29 text:string = KeyboardButton; -keyboardButtonRequestGeoLocation#fc796b3f text:string = KeyboardButton; -keyboardButtonSwitchInline#93b9fbb5 flags:# same_peer:flags.0?true text:string query:string peer_types:flags.1?Vector = KeyboardButton; -keyboardButtonGame#50f41ccf text:string = KeyboardButton; -keyboardButtonBuy#afd93fbb text:string = KeyboardButton; -keyboardButtonUrlAuth#10b78d29 flags:# text:string fwd_text:flags.0?string url:string button_id:int = KeyboardButton; -inputKeyboardButtonUrlAuth#d02e7fd4 flags:# request_write_access:flags.0?true text:string fwd_text:flags.1?string url:string bot:InputUser = KeyboardButton; -keyboardButtonRequestPoll#bbc7515d flags:# quiz:flags.0?Bool text:string = KeyboardButton; -inputKeyboardButtonUserProfile#e988037b text:string user_id:InputUser = KeyboardButton; -keyboardButtonUserProfile#308660c1 text:string user_id:long = KeyboardButton; -keyboardButtonWebView#13767230 text:string url:string = KeyboardButton; -keyboardButtonSimpleWebView#a0c0505c text:string url:string = KeyboardButton; -keyboardButtonRequestPeer#53d7bfd8 text:string button_id:int peer_type:RequestPeerType max_quantity:int = KeyboardButton; -inputKeyboardButtonRequestPeer#c9662d05 flags:# name_requested:flags.0?true username_requested:flags.1?true photo_requested:flags.2?true text:string button_id:int peer_type:RequestPeerType max_quantity:int = KeyboardButton; -keyboardButtonCopy#75d2698e text:string copy_text:string = KeyboardButton; +keyboardButton#7d170cff flags:# style:flags.10?KeyboardButtonStyle text:string = KeyboardButton; +keyboardButtonUrl#d80c25ec flags:# style:flags.10?KeyboardButtonStyle text:string url:string = KeyboardButton; +keyboardButtonCallback#e62bc960 flags:# requires_password:flags.0?true style:flags.10?KeyboardButtonStyle text:string data:bytes = KeyboardButton; +keyboardButtonRequestPhone#417efd8f flags:# style:flags.10?KeyboardButtonStyle text:string = KeyboardButton; +keyboardButtonRequestGeoLocation#aa40f94d flags:# style:flags.10?KeyboardButtonStyle text:string = KeyboardButton; +keyboardButtonSwitchInline#991399fc flags:# same_peer:flags.0?true style:flags.10?KeyboardButtonStyle text:string query:string peer_types:flags.1?Vector = KeyboardButton; +keyboardButtonGame#89c590f9 flags:# style:flags.10?KeyboardButtonStyle text:string = KeyboardButton; +keyboardButtonBuy#3fa53905 flags:# style:flags.10?KeyboardButtonStyle text:string = KeyboardButton; +keyboardButtonUrlAuth#f51006f9 flags:# style:flags.10?KeyboardButtonStyle text:string fwd_text:flags.0?string url:string button_id:int = KeyboardButton; +inputKeyboardButtonUrlAuth#68013e72 flags:# request_write_access:flags.0?true style:flags.10?KeyboardButtonStyle text:string fwd_text:flags.1?string url:string bot:InputUser = KeyboardButton; +keyboardButtonRequestPoll#7a11d782 flags:# style:flags.10?KeyboardButtonStyle quiz:flags.0?Bool text:string = KeyboardButton; +inputKeyboardButtonUserProfile#7d5e07c7 flags:# style:flags.10?KeyboardButtonStyle text:string user_id:InputUser = KeyboardButton; +keyboardButtonUserProfile#c0fd5d09 flags:# style:flags.10?KeyboardButtonStyle text:string user_id:long = KeyboardButton; +keyboardButtonWebView#e846b1a0 flags:# style:flags.10?KeyboardButtonStyle text:string url:string = KeyboardButton; +keyboardButtonSimpleWebView#e15c4370 flags:# style:flags.10?KeyboardButtonStyle text:string url:string = KeyboardButton; +keyboardButtonRequestPeer#5b0f15f5 flags:# style:flags.10?KeyboardButtonStyle text:string button_id:int peer_type:RequestPeerType max_quantity:int = KeyboardButton; +inputKeyboardButtonRequestPeer#2b78156 flags:# name_requested:flags.0?true username_requested:flags.1?true photo_requested:flags.2?true style:flags.10?KeyboardButtonStyle text:string button_id:int peer_type:RequestPeerType max_quantity:int = KeyboardButton; +keyboardButtonCopy#bcc4af10 flags:# style:flags.10?KeyboardButtonStyle text:string copy_text:string = KeyboardButton; keyboardButtonRow#77608b83 buttons:Vector = KeyboardButtonRow; @@ -741,6 +760,7 @@ messageEntityBankCard#761e6af4 offset:int length:int = MessageEntity; messageEntitySpoiler#32ca960f offset:int length:int = MessageEntity; messageEntityCustomEmoji#c8cf05f8 offset:int length:int document_id:long = MessageEntity; messageEntityBlockquote#f1ccaaac flags:# collapsed:flags.0?true offset:int length:int = MessageEntity; +messageEntityFormattedDate#904ac7c7 flags:# relative:flags.0?true short_time:flags.1?true long_time:flags.2?true short_date:flags.3?true long_date:flags.4?true day_of_week:flags.5?true offset:int length:int date:int = MessageEntity; inputChannelEmpty#ee8c1e86 = InputChannel; inputChannel#f35aec28 channel_id:long access_hash:long = InputChannel; @@ -757,11 +777,11 @@ updates.channelDifference#2064674e flags:# final:flags.0?true pts:int timeout:fl channelMessagesFilterEmpty#94d42ee7 = ChannelMessagesFilter; channelMessagesFilter#cd77d957 flags:# exclude_new_messages:flags.1?true ranges:Vector = ChannelMessagesFilter; -channelParticipant#cb397619 flags:# user_id:long date:int subscription_until_date:flags.0?int = ChannelParticipant; -channelParticipantSelf#4f607bef flags:# via_request:flags.0?true user_id:long inviter_id:long date:int subscription_until_date:flags.1?int = ChannelParticipant; +channelParticipant#1bd54456 flags:# user_id:long date:int subscription_until_date:flags.0?int rank:flags.2?string = ChannelParticipant; +channelParticipantSelf#a9478a1a flags:# via_request:flags.0?true user_id:long inviter_id:long date:int subscription_until_date:flags.1?int rank:flags.2?string = ChannelParticipant; channelParticipantCreator#2fe601d3 flags:# user_id:long admin_rights:ChatAdminRights rank:flags.0?string = ChannelParticipant; channelParticipantAdmin#34c3bb53 flags:# can_edit:flags.0?true self:flags.1?true user_id:long inviter_id:flags.1?long promoted_by:long date:int admin_rights:ChatAdminRights rank:flags.2?string = ChannelParticipant; -channelParticipantBanned#6df8014e flags:# left:flags.0?true peer:Peer kicked_by:long date:int banned_rights:ChatBannedRights = ChannelParticipant; +channelParticipantBanned#d5f0ad91 flags:# left:flags.0?true peer:Peer kicked_by:long date:int banned_rights:ChatBannedRights rank:flags.2?string = ChannelParticipant; channelParticipantLeft#1b03f006 peer:Peer = ChannelParticipant; channelParticipantsRecent#de3f3c79 = ChannelParticipantsFilter; @@ -973,7 +993,7 @@ inputWebFileAudioAlbumThumbLocation#f46fe924 flags:# small:flags.2?true document upload.webFile#21e753bc size:int mime_type:string file_type:storage.FileType mtime:int bytes:bytes = upload.WebFile; payments.paymentForm#a0058751 flags:# can_save_credentials:flags.2?true password_missing:flags.3?true form_id:long bot_id:long title:string description:string photo:flags.5?WebDocument invoice:Invoice provider_id:long url:string native_provider:flags.4?string native_params:flags.4?DataJSON additional_methods:flags.6?Vector saved_info:flags.0?PaymentRequestedInfo saved_credentials:flags.1?Vector users:Vector = payments.PaymentForm; -payments.paymentFormStars#7bf6b15c flags:# can_save_credentials:flags.2?true form_id:long password_missing:flags.3?true bot_id:long title:string description:string photo:flags.5?WebDocument invoice:Invoice users:Vector = payments.PaymentForm; +payments.paymentFormStars#7bf6b15c flags:# can_save_credentials:flags.2?true password_missing:flags.3?true form_id:long bot_id:long title:string description:string photo:flags.5?WebDocument invoice:Invoice users:Vector = payments.PaymentForm; payments.paymentFormStarGift#b425cfe1 form_id:long invoice:Invoice = payments.PaymentForm; payments.validatedRequestedInfo#d1451883 flags:# id:flags.0?string shipping_options:flags.1?Vector = payments.ValidatedRequestedInfo; @@ -1079,13 +1099,14 @@ channelAdminLogEventActionChangeEmojiStickerSet#46d840ab prev_stickerset:InputSt channelAdminLogEventActionToggleSignatureProfiles#60a79c79 new_value:Bool = ChannelAdminLogEventAction; channelAdminLogEventActionParticipantSubExtend#64642db3 prev_participant:ChannelParticipant new_participant:ChannelParticipant = ChannelAdminLogEventAction; channelAdminLogEventActionToggleAutotranslation#c517f77e new_value:Bool = ChannelAdminLogEventAction; +channelAdminLogEventActionParticipantEditRank#5806b4ec user_id:long prev_rank:string new_rank:string = ChannelAdminLogEventAction; channelAdminLogEventActionChangeTheme#fe69018d prev_value:string new_value:string = ChannelAdminLogEventAction; channelAdminLogEvent#1fad68cd id:long date:int user_id:long action:ChannelAdminLogEventAction = ChannelAdminLogEvent; channels.adminLogResults#ed8af74d events:Vector chats:Vector users:Vector = channels.AdminLogResults; -channelAdminLogEventsFilter#ea107ae4 flags:# join:flags.0?true leave:flags.1?true invite:flags.2?true ban:flags.3?true unban:flags.4?true kick:flags.5?true unkick:flags.6?true promote:flags.7?true demote:flags.8?true info:flags.9?true settings:flags.10?true pinned:flags.11?true edit:flags.12?true delete:flags.13?true group_call:flags.14?true invites:flags.15?true send:flags.16?true forums:flags.17?true sub_extend:flags.18?true = ChannelAdminLogEventsFilter; +channelAdminLogEventsFilter#ea107ae4 flags:# join:flags.0?true leave:flags.1?true invite:flags.2?true ban:flags.3?true unban:flags.4?true kick:flags.5?true unkick:flags.6?true promote:flags.7?true demote:flags.8?true info:flags.9?true settings:flags.10?true pinned:flags.11?true edit:flags.12?true delete:flags.13?true group_call:flags.14?true invites:flags.15?true send:flags.16?true forums:flags.17?true sub_extend:flags.18?true edit_rank:flags.19?true = ChannelAdminLogEventsFilter; popularContact#5ce14175 client_id:long importers:int = PopularContact; @@ -1231,21 +1252,22 @@ help.supportName#8c05f1c9 name:string = help.SupportName; help.userInfoEmpty#f3ae2eed = help.UserInfo; help.userInfo#1eb3758 message:string entities:Vector author:string date:int = help.UserInfo; -pollAnswer#ff16e2ca text:TextWithEntities option:bytes = PollAnswer; +pollAnswer#4b7d786a flags:# text:TextWithEntities option:bytes media:flags.0?MessageMedia added_by:flags.1?Peer date:flags.1?int = PollAnswer; +inputPollAnswer#199fed96 flags:# text:TextWithEntities input_media:flags.0?InputMedia = PollAnswer; -poll#58747131 id:long flags:# closed:flags.0?true public_voters:flags.1?true multiple_choice:flags.2?true quiz:flags.3?true question:TextWithEntities answers:Vector close_period:flags.4?int close_date:flags.5?int = Poll; +poll#b8425be9 id:long flags:# closed:flags.0?true public_voters:flags.1?true multiple_choice:flags.2?true quiz:flags.3?true open_answers:flags.6?true revoting_disabled:flags.7?true shuffle_answers:flags.8?true hide_results_until_close:flags.9?true creator:flags.10?true question:TextWithEntities answers:Vector close_period:flags.4?int close_date:flags.5?int hash:long = Poll; -pollAnswerVoters#3b6ddad2 flags:# chosen:flags.0?true correct:flags.1?true option:bytes voters:int = PollAnswerVoters; +pollAnswerVoters#3645230a flags:# chosen:flags.0?true correct:flags.1?true option:bytes voters:flags.2?int recent_voters:flags.2?Vector = PollAnswerVoters; -pollResults#7adf2420 flags:# min:flags.0?true results:flags.1?Vector total_voters:flags.2?int recent_voters:flags.3?Vector solution:flags.4?string solution_entities:flags.4?Vector = PollResults; +pollResults#ba7bb15e flags:# min:flags.0?true has_unread_votes:flags.6?true results:flags.1?Vector total_voters:flags.2?int recent_voters:flags.3?Vector solution:flags.4?string solution_entities:flags.4?Vector solution_media:flags.5?MessageMedia = PollResults; chatOnlines#f041e250 onlines:int = ChatOnlines; statsURL#47a971e0 url:string = StatsURL; -chatAdminRights#5fb224d5 flags:# change_info:flags.0?true post_messages:flags.1?true edit_messages:flags.2?true delete_messages:flags.3?true ban_users:flags.4?true invite_users:flags.5?true pin_messages:flags.7?true add_admins:flags.9?true anonymous:flags.10?true manage_call:flags.11?true other:flags.12?true manage_topics:flags.13?true post_stories:flags.14?true edit_stories:flags.15?true delete_stories:flags.16?true manage_direct_messages:flags.17?true = ChatAdminRights; +chatAdminRights#5fb224d5 flags:# change_info:flags.0?true post_messages:flags.1?true edit_messages:flags.2?true delete_messages:flags.3?true ban_users:flags.4?true invite_users:flags.5?true pin_messages:flags.7?true add_admins:flags.9?true anonymous:flags.10?true manage_call:flags.11?true other:flags.12?true manage_topics:flags.13?true post_stories:flags.14?true edit_stories:flags.15?true delete_stories:flags.16?true manage_direct_messages:flags.17?true manage_ranks:flags.18?true = ChatAdminRights; -chatBannedRights#9f120418 flags:# view_messages:flags.0?true send_messages:flags.1?true send_media:flags.2?true send_stickers:flags.3?true send_gifs:flags.4?true send_games:flags.5?true send_inline:flags.6?true embed_links:flags.7?true send_polls:flags.8?true change_info:flags.10?true invite_users:flags.15?true pin_messages:flags.17?true manage_topics:flags.18?true send_photos:flags.19?true send_videos:flags.20?true send_roundvideos:flags.21?true send_audios:flags.22?true send_voices:flags.23?true send_docs:flags.24?true send_plain:flags.25?true until_date:int = ChatBannedRights; +chatBannedRights#9f120418 flags:# view_messages:flags.0?true send_messages:flags.1?true send_media:flags.2?true send_stickers:flags.3?true send_gifs:flags.4?true send_games:flags.5?true send_inline:flags.6?true embed_links:flags.7?true send_polls:flags.8?true change_info:flags.10?true invite_users:flags.15?true pin_messages:flags.17?true manage_topics:flags.18?true send_photos:flags.19?true send_videos:flags.20?true send_roundvideos:flags.21?true send_audios:flags.22?true send_voices:flags.23?true send_docs:flags.24?true send_plain:flags.25?true edit_rank:flags.26?true until_date:int = ChatBannedRights; inputWallPaper#e630b979 id:long access_hash:long = InputWallPaper; inputWallPaperSlug#72091c80 slug:string = InputWallPaper; @@ -1279,8 +1301,8 @@ folderPeer#e9baa668 peer:Peer folder_id:int = FolderPeer; messages.searchCounter#e844ebff flags:# inexact:flags.1?true filter:MessagesFilter count:int = messages.SearchCounter; -urlAuthResultRequest#92d33a0e flags:# request_write_access:flags.0?true bot:User domain:string = UrlAuthResult; -urlAuthResultAccepted#8f8c0e4e url:string = UrlAuthResult; +urlAuthResultRequest#3cd623ec flags:# request_write_access:flags.0?true request_phone_number:flags.1?true match_codes_first:flags.5?true app:flags.6?true bot:User domain:string browser:flags.2?string platform:flags.2?string ip:flags.2?string region:flags.2?string match_codes:flags.3?Vector user_id_hint:flags.4?long verified_app_name:flags.7?string = UrlAuthResult; +urlAuthResultAccepted#623a8fa0 flags:# url:flags.0?string = UrlAuthResult; urlAuthResultDefault#a9d6db1f = UrlAuthResult; channelLocationEmpty#bfb5ad8b = ChannelLocation; @@ -1322,6 +1344,7 @@ webPageAttributeStory#2e94c3e7 flags:# peer:Peer id:int story:flags.0?StoryItem webPageAttributeStickerSet#50cc03d3 flags:# emojis:flags.0?true text_color:flags.1?true stickers:Vector = WebPageAttribute; webPageAttributeUniqueStarGift#cf6f6db8 gift:StarGift = WebPageAttribute; webPageAttributeStarGiftCollection#31cad303 icons:Vector = WebPageAttribute; +webPageAttributeStarGiftAuction#1c641c2 gift:StarGift end_date:int = WebPageAttribute; messages.votesList#4899484e flags:# count:int votes:Vector chats:Vector users:Vector next_offset:flags.0?string = messages.VotesList; @@ -1377,7 +1400,7 @@ messages.messageViews#b6c4f543 views:Vector chats:Vector use messages.discussionMessage#a6341782 flags:# messages:Vector max_id:flags.0?int read_inbox_max_id:flags.1?int read_outbox_max_id:flags.2?int unread_count:int chats:Vector users:Vector = messages.DiscussionMessage; -messageReplyHeader#6917560b flags:# reply_to_scheduled:flags.2?true forum_topic:flags.3?true quote:flags.9?true reply_to_msg_id:flags.4?int reply_to_peer_id:flags.0?Peer reply_from:flags.5?MessageFwdHeader reply_media:flags.8?MessageMedia reply_to_top_id:flags.1?int quote_text:flags.6?string quote_entities:flags.7?Vector quote_offset:flags.10?int todo_item_id:flags.11?int = MessageReplyHeader; +messageReplyHeader#1b97dd66 flags:# reply_to_scheduled:flags.2?true forum_topic:flags.3?true quote:flags.9?true reply_to_msg_id:flags.4?int reply_to_peer_id:flags.0?Peer reply_from:flags.5?MessageFwdHeader reply_media:flags.8?MessageMedia reply_to_top_id:flags.1?int quote_text:flags.6?string quote_entities:flags.7?Vector quote_offset:flags.10?int todo_item_id:flags.11?int poll_option:flags.12?bytes = MessageReplyHeader; messageReplyStoryHeader#e5af939 peer:Peer story_id:int = MessageReplyHeader; messageReplies#83d60fc2 flags:# comments:flags.0?true replies:int replies_pts:int recent_repliers:flags.1?Vector channel_id:flags.0?long max_id:flags.2?int read_max_id:flags.3?int = MessageReplies; @@ -1387,13 +1410,13 @@ peerBlocked#e8fd8014 peer_id:Peer date:int = PeerBlocked; stats.messageStats#7fe91c14 views_graph:StatsGraph reactions_by_emotion_graph:StatsGraph = stats.MessageStats; groupCallDiscarded#7780bcb4 id:long access_hash:long duration:int = GroupCall; -groupCall#553b0ba1 flags:# join_muted:flags.1?true can_change_join_muted:flags.2?true join_date_asc:flags.6?true schedule_start_subscribed:flags.8?true can_start_video:flags.9?true record_video_active:flags.11?true rtmp_stream:flags.12?true listeners_hidden:flags.13?true conference:flags.14?true creator:flags.15?true messages_enabled:flags.17?true can_change_messages_enabled:flags.18?true min:flags.19?true id:long access_hash:long participants_count:int title:flags.3?string stream_dc_id:flags.4?int record_start_date:flags.5?int schedule_date:flags.7?int unmuted_video_count:flags.10?int unmuted_video_limit:int version:int invite_link:flags.16?string = GroupCall; +groupCall#efb2b617 flags:# join_muted:flags.1?true can_change_join_muted:flags.2?true join_date_asc:flags.6?true schedule_start_subscribed:flags.8?true can_start_video:flags.9?true record_video_active:flags.11?true rtmp_stream:flags.12?true listeners_hidden:flags.13?true conference:flags.14?true creator:flags.15?true messages_enabled:flags.17?true can_change_messages_enabled:flags.18?true min:flags.19?true id:long access_hash:long participants_count:int title:flags.3?string stream_dc_id:flags.4?int record_start_date:flags.5?int schedule_date:flags.7?int unmuted_video_count:flags.10?int unmuted_video_limit:int version:int invite_link:flags.16?string send_paid_messages_stars:flags.20?long default_send_as:flags.21?Peer = GroupCall; inputGroupCall#d8aa840f id:long access_hash:long = InputGroupCall; inputGroupCallSlug#fe06823f slug:string = InputGroupCall; inputGroupCallInviteMessage#8c10603f msg_id:int = InputGroupCall; -groupCallParticipant#eba636fe flags:# muted:flags.0?true left:flags.1?true can_self_unmute:flags.2?true just_joined:flags.4?true versioned:flags.5?true min:flags.8?true muted_by_you:flags.9?true volume_by_admin:flags.10?true self:flags.12?true video_joined:flags.15?true peer:Peer date:int active_date:flags.3?int source:int volume:flags.7?int about:flags.11?string raise_hand_rating:flags.13?long video:flags.6?GroupCallParticipantVideo presentation:flags.14?GroupCallParticipantVideo = GroupCallParticipant; +groupCallParticipant#2a3dc7ac flags:# muted:flags.0?true left:flags.1?true can_self_unmute:flags.2?true just_joined:flags.4?true versioned:flags.5?true min:flags.8?true muted_by_you:flags.9?true volume_by_admin:flags.10?true self:flags.12?true video_joined:flags.15?true peer:Peer date:int active_date:flags.3?int source:int volume:flags.7?int about:flags.11?string raise_hand_rating:flags.13?long video:flags.6?GroupCallParticipantVideo presentation:flags.14?GroupCallParticipantVideo paid_stars_total:flags.16?long = GroupCallParticipant; phone.groupCall#9e727aad call:GroupCall participants:Vector participants_next_offset:string chats:Vector users:Vector = phone.GroupCall; @@ -1452,8 +1475,8 @@ account.resetPasswordOk#e926d63e = account.ResetPasswordResult; chatTheme#c3dffc04 emoticon:string = ChatTheme; chatThemeUniqueGift#3458f9c8 gift:StarGift theme_settings:Vector = ChatTheme; -account.chatThemes#16484857 flags:# hash:long themes:Vector chats:Vector users:Vector next_offset:flags.0?int = account.ChatThemes; account.chatThemesNotModified#e011e1c4 = account.ChatThemes; +account.chatThemes#be098173 flags:# hash:long themes:Vector chats:Vector users:Vector next_offset:flags.0?string = account.ChatThemes; sponsoredMessage#7dbf8673 flags:# recommended:flags.5?true can_report:flags.12?true random_id:bytes url:string title:string message:string entities:flags.1?Vector photo:flags.6?Photo media:flags.14?MessageMedia color:flags.13?PeerColor button_text:string sponsor_info:flags.7?string additional_info:flags.8?string min_display_duration:flags.15?int max_display_duration:flags.15?int = SponsoredMessage; @@ -1545,6 +1568,7 @@ inputInvoiceStarGiftResale#c39f5324 flags:# ton:flags.0?true slug:string to_id:I inputInvoiceStarGiftPrepaidUpgrade#9a0b48b8 peer:InputPeer hash:string = InputInvoice; inputInvoicePremiumAuthCode#3e77f614 purpose:InputStorePaymentPurpose = InputInvoice; inputInvoiceStarGiftDropOriginalDetails#923d8d1 stargift:InputSavedStarGift = InputInvoice; +inputInvoiceStarGiftAuctionBid#1ecafa10 flags:# hide_name:flags.0?true update_bid:flags.2?true peer:flags.3?InputPeer gift_id:long bid_amount:long message:flags.1?TextWithEntities = InputInvoice; payments.exportedInvoice#aed0cbd9 url:string = payments.ExportedInvoice; @@ -1606,7 +1630,7 @@ stickerKeyword#fcfeb29c document_id:long keyword:Vector = StickerKeyword username#b4073647 flags:# editable:flags.0?true active:flags.1?true username:string = Username; forumTopicDeleted#23f109b id:int = ForumTopic; -forumTopic#cdff0eca flags:# my:flags.1?true closed:flags.2?true pinned:flags.3?true short:flags.5?true hidden:flags.6?true title_missing:flags.7?true id:int date:int peer:Peer title:string icon_color:int icon_emoji_id:flags.0?long top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int from_id:Peer notify_settings:PeerNotifySettings draft:flags.4?DraftMessage = ForumTopic; +forumTopic#fcdad815 flags:# my:flags.1?true closed:flags.2?true pinned:flags.3?true short:flags.5?true hidden:flags.6?true title_missing:flags.7?true id:int date:int title:string icon_color:int icon_emoji_id:flags.0?long top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int unread_poll_votes_count:int from_id:Peer notify_settings:PeerNotifySettings draft:flags.4?DraftMessage = ForumTopic; messages.forumTopics#367617d3 flags:# order_by_create_date:flags.0?true count:int topics:Vector messages:Vector chats:Vector users:Vector pts:int = messages.ForumTopics; @@ -1615,8 +1639,9 @@ defaultHistoryTTL#43b46b20 period:int = DefaultHistoryTTL; exportedContactToken#41bf109b url:string expires:int = ExportedContactToken; requestPeerTypeUser#5f3b8a00 flags:# bot:flags.0?Bool premium:flags.1?Bool = RequestPeerType; -requestPeerTypeChat#c9f06e1b flags:# creator:flags.0?true user_admin_rights:flags.1?ChatAdminRights bot_participant:flags.5?true bot_admin_rights:flags.2?ChatAdminRights has_username:flags.3?Bool forum:flags.4?Bool = RequestPeerType; -requestPeerTypeBroadcast#339bef6c flags:# creator:flags.0?true user_admin_rights:flags.1?ChatAdminRights has_username:flags.3?Bool bot_admin_rights:flags.2?ChatAdminRights = RequestPeerType; +requestPeerTypeChat#c9f06e1b flags:# creator:flags.0?true has_username:flags.3?true bot_participant:flags.5?true forum:flags.4?true user_admin_rights:flags.5?ChatAdminRights bot_admin_rights:flags.5?ChatAdminRights = RequestPeerType; +requestPeerTypeBroadcast#339bef6c flags:# creator:flags.0?true has_username:flags.3?true user_admin_rights:ChatAdminRights bot_admin_rights:ChatAdminRights = RequestPeerType; +requestPeerTypeCreateBot#3e81e078 flags:# bot_managed:flags.0?true suggested_name:flags.1?string suggested_username:flags.2?string = RequestPeerType; emojiListNotModified#481eadfa = EmojiList; emojiList#7a1e11d1 hash:long document_id:Vector = EmojiList; @@ -1675,7 +1700,7 @@ messagePeerVoteMultiple#4628f6e6 peer:Peer options:Vector date:int = Mess storyViews#8d595cd6 flags:# has_viewers:flags.1?true views_count:int forwards_count:flags.2?int reactions:flags.3?Vector reactions_count:flags.4?int recent_viewers:flags.0?Vector = StoryViews; storyItemDeleted#51e6ee4f id:int = StoryItem; -storyItemSkipped#ffadc913 flags:# close_friends:flags.8?true id:int date:int expire_date:int = StoryItem; +storyItemSkipped#ffadc913 flags:# close_friends:flags.8?true live:flags.9?true id:int date:int expire_date:int = StoryItem; storyItem#edf164f1 flags:# pinned:flags.5?true public:flags.7?true close_friends:flags.8?true min:flags.9?true noforwards:flags.10?true edited:flags.11?true contacts:flags.12?true selected_contacts:flags.13?true out:flags.16?true id:int date:int from_id:flags.18?Peer fwd_from:flags.17?StoryFwdHeader expire_date:int caption:flags.0?string entities:flags.1?Vector media:MessageMedia media_areas:flags.14?Vector privacy:flags.2?Vector views:flags.3?StoryViews sent_reaction:flags.15?Reaction albums:flags.19?Vector = StoryItem; stories.allStoriesNotModified#1158fe3e flags:# state:string stealth_mode:StoriesStealthMode = stories.AllStories; @@ -1691,7 +1716,7 @@ stories.storyViewsList#59d78fc5 flags:# count:int views_count:int forwards_count stories.storyViews#de9eed1d views:Vector users:Vector = stories.StoryViews; -inputReplyToMessage#869fbe10 flags:# reply_to_msg_id:int top_msg_id:flags.0?int reply_to_peer_id:flags.1?InputPeer quote_text:flags.2?string quote_entities:flags.3?Vector quote_offset:flags.4?int monoforum_peer_id:flags.5?InputPeer todo_item_id:flags.6?int = InputReplyTo; +inputReplyToMessage#3bd4b7c2 flags:# reply_to_msg_id:int top_msg_id:flags.0?int reply_to_peer_id:flags.1?InputPeer quote_text:flags.2?string quote_entities:flags.3?Vector quote_offset:flags.4?int monoforum_peer_id:flags.5?InputPeer todo_item_id:flags.6?int poll_option:flags.7?bytes = InputReplyTo; inputReplyToStory#5881323a peer:InputPeer story_id:int = InputReplyTo; inputReplyToMonoForum#69d66c45 monoforum_peer_id:InputPeer = InputReplyTo; @@ -1719,7 +1744,7 @@ messages.webPage#fd5e12bd webpage:WebPage chats:Vector users:Vector premiumGiftCodeOption#257e962b flags:# users:int months:int store_product:flags.0?string store_quantity:flags.1?int currency:string amount:long = PremiumGiftCodeOption; -payments.checkedGiftCode#284a1096 flags:# via_giveaway:flags.2?true from_id:flags.4?Peer giveaway_msg_id:flags.3?int to_id:flags.0?long date:int months:int used_date:flags.1?int chats:Vector users:Vector = payments.CheckedGiftCode; +payments.checkedGiftCode#eb983f8f flags:# via_giveaway:flags.2?true from_id:flags.4?Peer giveaway_msg_id:flags.3?int to_id:flags.0?long date:int days:int used_date:flags.1?int chats:Vector users:Vector = payments.CheckedGiftCode; payments.giveawayInfo#4367daa0 flags:# participating:flags.0?true preparing_results:flags.3?true start_date:int joined_too_early_date:flags.1?int admin_disallowed_chat_id:flags.2?long disallowed_country:flags.4?string = payments.GiveawayInfo; payments.giveawayInfoResults#e175e66f flags:# winner:flags.0?true refunded:flags.1?true start_date:int gift_code_slug:flags.3?string stars_prize:flags.4?long finish_date:int winners_count:int activated_count:flags.2?int = payments.GiveawayInfo; @@ -1750,8 +1775,8 @@ publicForwardStory#edf3add0 peer:Peer story:StoryItem = PublicForward; stats.publicForwards#93037e20 flags:# count:int forwards:Vector next_offset:flags.0?string chats:Vector users:Vector = stats.PublicForwards; peerColor#b54b5acf flags:# color:flags.0?int background_emoji_id:flags.1?long = PeerColor; -inputPeerColorCollectible#b8ea86a9 collectible_id:long = PeerColor; peerColorCollectible#b9c0639a flags:# collectible_id:long gift_emoji_id:long background_emoji_id:long accent_color:int colors:Vector dark_accent_color:flags.0?int dark_colors:flags.1?Vector = PeerColor; +inputPeerColorCollectible#b8ea86a9 collectible_id:long = PeerColor; help.peerColorSet#26219a58 colors:Vector = help.PeerColorSet; help.peerColorProfileSet#767d61eb palette_colors:Vector bg_colors:Vector story_colors:Vector = help.PeerColorSet; @@ -1876,7 +1901,7 @@ channels.sponsoredMessageReportResultReported#ad798849 = channels.SponsoredMessa reactionNotificationsFromContacts#bac3a61a = ReactionNotificationsFrom; reactionNotificationsFromAll#4b9e22a0 = ReactionNotificationsFrom; -reactionsNotifySettings#56e34970 flags:# messages_notify_from:flags.0?ReactionNotificationsFrom stories_notify_from:flags.1?ReactionNotificationsFrom sound:NotificationSound show_previews:Bool = ReactionsNotifySettings; +reactionsNotifySettings#71e4ea58 flags:# messages_notify_from:flags.0?ReactionNotificationsFrom stories_notify_from:flags.1?ReactionNotificationsFrom poll_votes_notify_from:flags.2?ReactionNotificationsFrom sound:NotificationSound show_previews:Bool = ReactionsNotifySettings; availableEffect#93c3e27e flags:# premium_required:flags.2?true id:long emoticon:string static_icon_id:flags.0?long effect_sticker_id:long effect_animation_id:flags.1?long = AvailableEffect; @@ -1896,7 +1921,7 @@ starsTransactionPeerAPI#f9677aad = StarsTransactionPeer; starsTopupOption#bd915c0 flags:# extended:flags.1?true stars:long store_product:flags.0?string currency:string amount:long = StarsTopupOption; -starsTransaction#13659eb0 flags:# refund:flags.3?true pending:flags.4?true failed:flags.6?true gift:flags.10?true reaction:flags.11?true subscription:flags.12?true stargift_upgrade:flags.18?true floodskip:flags.15?true business_transfer:flags.21?true stargift_resale:flags.22?true paid_message:flags.19?true posts_search:flags.24?true premium_gift:flags.20?true stargift_prepaid_upgrade:flags.25?true stargift_drop_original_details:flags.26?true id:string amount:StarsAmount date:int peer:StarsTransactionPeer title:flags.0?string description:flags.1?string photo:flags.2?WebDocument transaction_date:flags.5?int transaction_url:flags.5?string bot_payload:flags.7?bytes msg_id:flags.8?int extended_media:flags.9?Vector subscription_period:flags.12?int giveaway_post_id:flags.13?int stargift:flags.14?StarGift floodskip_number:flags.15?int starref_commission_permille:flags.16?int starref_peer:flags.17?Peer starref_amount:flags.17?StarsAmount paid_messages:flags.19?int premium_gift_months:flags.20?int ads_proceeds_from_date:flags.23?int ads_proceeds_to_date:flags.23?int = StarsTransaction; +starsTransaction#13659eb0 flags:# refund:flags.3?true pending:flags.4?true failed:flags.6?true gift:flags.10?true reaction:flags.11?true subscription:flags.12?true floodskip:flags.15?true stargift_upgrade:flags.18?true paid_message:flags.19?true premium_gift:flags.20?true business_transfer:flags.21?true stargift_resale:flags.22?true posts_search:flags.24?true stargift_prepaid_upgrade:flags.25?true stargift_drop_original_details:flags.26?true phonegroup_message:flags.27?true stargift_auction_bid:flags.28?true offer:flags.29?true id:string amount:StarsAmount date:int peer:StarsTransactionPeer title:flags.0?string description:flags.1?string photo:flags.2?WebDocument transaction_date:flags.5?int transaction_url:flags.5?string bot_payload:flags.7?bytes msg_id:flags.8?int extended_media:flags.9?Vector subscription_period:flags.12?int giveaway_post_id:flags.13?int stargift:flags.14?StarGift floodskip_number:flags.15?int starref_commission_permille:flags.16?int starref_peer:flags.17?Peer starref_amount:flags.17?StarsAmount paid_messages:flags.19?int premium_gift_months:flags.20?int ads_proceeds_from_date:flags.23?int ads_proceeds_to_date:flags.23?int = StarsTransaction; payments.starsStatus#6c9ce8ed flags:# balance:StarsAmount subscriptions:flags.1?Vector subscriptions_next_offset:flags.2?string subscriptions_missing_balance:flags.4?long history:flags.3?Vector next_offset:flags.0?string chats:Vector users:Vector = payments.StarsStatus; @@ -1934,8 +1959,8 @@ starsGiveawayOption#94ce852a flags:# extended:flags.0?true default:flags.1?true starsGiveawayWinnersOption#54236209 flags:# default:flags.0?true users:int per_user_stars:long = StarsGiveawayWinnersOption; -starGift#80ac53c3 flags:# limited:flags.0?true sold_out:flags.1?true birthday:flags.2?true can_upgrade:flags.3?true require_premium:flags.7?true limited_per_user:flags.8?true peer_color_available:flags.10?true id:long sticker:Document stars:long availability_remains:flags.0?int availability_total:flags.0?int availability_resale:flags.4?long convert_stars:long first_sale_date:flags.1?int last_sale_date:flags.1?int upgrade_stars:flags.3?long resell_min_stars:flags.4?long title:flags.5?string released_by:flags.6?Peer per_user_total:flags.8?int per_user_remains:flags.8?int locked_until_date:flags.9?int = StarGift; -starGiftUnique#b0bf741b flags:# require_premium:flags.6?true resale_ton_only:flags.7?true theme_available:flags.9?true id:long gift_id:long title:string slug:string num:int owner_id:flags.0?Peer owner_name:flags.1?string owner_address:flags.2?string attributes:Vector availability_issued:int availability_total:int gift_address:flags.3?string resell_amount:flags.4?Vector released_by:flags.5?Peer value_amount:flags.8?long value_currency:flags.8?string theme_peer:flags.10?Peer peer_color:flags.11?PeerColor host_id:flags.12?Peer = StarGift; +starGift#313a9547 flags:# limited:flags.0?true sold_out:flags.1?true birthday:flags.2?true can_upgrade:flags.3?true require_premium:flags.7?true limited_per_user:flags.8?true peer_color_available:flags.10?true auction:flags.11?true id:long sticker:Document stars:long availability_remains:flags.0?int availability_total:flags.0?int availability_resale:flags.4?long convert_stars:long first_sale_date:flags.1?int last_sale_date:flags.1?int upgrade_stars:flags.3?long resell_min_stars:flags.4?long title:flags.5?string released_by:flags.6?Peer per_user_total:flags.8?int per_user_remains:flags.8?int locked_until_date:flags.9?int auction_slug:flags.11?string gifts_per_round:flags.11?int auction_start_date:flags.11?int upgrade_variants:flags.12?int background:flags.13?StarGiftBackground = StarGift; +starGiftUnique#85f0a9cd flags:# require_premium:flags.6?true resale_ton_only:flags.7?true theme_available:flags.9?true burned:flags.14?true crafted:flags.15?true id:long gift_id:long title:string slug:string num:int owner_id:flags.0?Peer owner_name:flags.1?string owner_address:flags.2?string attributes:Vector availability_issued:int availability_total:int gift_address:flags.3?string resell_amount:flags.4?Vector released_by:flags.5?Peer value_amount:flags.8?long value_currency:flags.8?string value_usd_amount:flags.8?long theme_peer:flags.10?Peer peer_color:flags.11?PeerColor host_id:flags.12?Peer offer_min_stars:flags.13?int craft_chance_permille:flags.16?int = StarGift; payments.starGiftsNotModified#a388a368 = payments.StarGifts; payments.starGifts#2ed82995 hash:int gifts:Vector chats:Vector users:Vector = payments.StarGifts; @@ -1970,12 +1995,12 @@ botVerifierSettings#b0cd6617 flags:# can_modify_custom_description:flags.1?true botVerification#f93cd45c bot_id:long icon:long description:string = BotVerification; -starGiftAttributeModel#39d99013 name:string document:Document rarity_permille:int = StarGiftAttribute; -starGiftAttributePattern#13acff19 name:string document:Document rarity_permille:int = StarGiftAttribute; -starGiftAttributeBackdrop#d93d859c name:string backdrop_id:int center_color:int edge_color:int pattern_color:int text_color:int rarity_permille:int = StarGiftAttribute; +starGiftAttributeModel#565251e2 flags:# crafted:flags.0?true name:string document:Document rarity:StarGiftAttributeRarity = StarGiftAttribute; +starGiftAttributePattern#4e7085ea name:string document:Document rarity:StarGiftAttributeRarity = StarGiftAttribute; +starGiftAttributeBackdrop#9f2504e4 name:string backdrop_id:int center_color:int edge_color:int pattern_color:int text_color:int rarity:StarGiftAttributeRarity = StarGiftAttribute; starGiftAttributeOriginalDetails#e0bff26c flags:# sender_id:flags.0?Peer recipient_id:Peer date:int message:flags.1?TextWithEntities = StarGiftAttribute; -payments.starGiftUpgradePreview#167bd90b sample_attributes:Vector = payments.StarGiftUpgradePreview; +payments.starGiftUpgradePreview#3de1dfed sample_attributes:Vector prices:Vector next_prices:Vector = payments.StarGiftUpgradePreview; users.users#62d706b8 users:Vector = users.Users; users.usersSlice#315a4974 count:int users:Vector = users.Users; @@ -1984,7 +2009,7 @@ payments.uniqueStarGift#416c56e8 gift:StarGift chats:Vector users:Vector users:Vector = messages.WebPagePreview; -savedStarGift#8983a452 flags:# name_hidden:flags.0?true unsaved:flags.5?true refunded:flags.9?true can_upgrade:flags.10?true pinned_to_top:flags.12?true upgrade_separate:flags.17?true from_id:flags.1?Peer date:int gift:StarGift message:flags.2?TextWithEntities msg_id:flags.3?int saved_id:flags.11?long convert_stars:flags.4?long upgrade_stars:flags.6?long can_export_at:flags.7?int transfer_stars:flags.8?long can_transfer_at:flags.13?int can_resell_at:flags.14?int collection_id:flags.15?Vector prepaid_upgrade_hash:flags.16?string drop_original_details_stars:flags.18?long = SavedStarGift; +savedStarGift#41df43fc flags:# name_hidden:flags.0?true unsaved:flags.5?true refunded:flags.9?true can_upgrade:flags.10?true pinned_to_top:flags.12?true upgrade_separate:flags.17?true from_id:flags.1?Peer date:int gift:StarGift message:flags.2?TextWithEntities msg_id:flags.3?int saved_id:flags.11?long convert_stars:flags.4?long upgrade_stars:flags.6?long can_export_at:flags.7?int transfer_stars:flags.8?long can_transfer_at:flags.13?int can_resell_at:flags.14?int collection_id:flags.15?Vector prepaid_upgrade_hash:flags.16?string drop_original_details_stars:flags.18?long gift_num:flags.19?int can_craft_at:flags.20?int = SavedStarGift; payments.savedStarGifts#95f389b1 flags:# count:int chat_notifications_enabled:flags.1?Bool gifts:Vector next_offset:flags.0?string chats:Vector users:Vector = payments.SavedStarGifts; @@ -2006,7 +2031,7 @@ requirementToContactPaidMessages#b4f67e93 stars_amount:long = RequirementToConta businessBotRights#a0624cf7 flags:# reply:flags.0?true read_messages:flags.1?true delete_sent_messages:flags.2?true delete_received_messages:flags.3?true edit_name:flags.4?true edit_bio:flags.5?true edit_profile_photo:flags.6?true edit_username:flags.7?true view_gifts:flags.8?true sell_gifts:flags.9?true change_gift_settings:flags.10?true transfer_and_upgrade_gifts:flags.11?true transfer_stars:flags.12?true manage_stories:flags.13?true = BusinessBotRights; -disallowedGiftsSettings#71f276c4 flags:# disallow_unlimited_stargifts:flags.0?true disallow_limited_stargifts:flags.1?true disallow_unique_stargifts:flags.2?true disallow_premium_gifts:flags.3?true = DisallowedGiftsSettings; +disallowedGiftsSettings#71f276c4 flags:# disallow_unlimited_stargifts:flags.0?true disallow_limited_stargifts:flags.1?true disallow_unique_stargifts:flags.2?true disallow_premium_gifts:flags.3?true disallow_stargifts_from_channels:flags.4?true = DisallowedGiftsSettings; sponsoredPeer#c69708d3 flags:# random_id:bytes peer:Peer sponsor_info:flags.0?string additional_info:flags.1?string = SponsoredPeer; @@ -2029,7 +2054,7 @@ todoItem#cba9a52f id:int title:TextWithEntities = TodoItem; todoList#49b92a26 flags:# others_can_append:flags.0?true others_can_complete:flags.1?true title:TextWithEntities list:Vector = TodoList; -todoCompletion#4cc120b7 id:int completed_by:long date:int = TodoCompletion; +todoCompletion#221bb5e4 id:int completed_by:Peer date:int = TodoCompletion; suggestedPost#e8e37e5 flags:# accepted:flags.1?true rejected:flags.2?true price:flags.3?StarsAmount schedule_date:flags.0?int = SuggestedPost; @@ -2071,17 +2096,85 @@ inputChatThemeEmpty#83268483 = InputChatTheme; inputChatTheme#c93de95c emoticon:string = InputChatTheme; inputChatThemeUniqueGift#87e5dfe4 slug:string = InputChatTheme; -starGiftUpgradePreview#3de1dfed sample_attributes:Vector prices:Vector next_prices:Vector = StarGiftUpgradePreview; +starGiftUpgradePrice#99ea331d date:int upgrade_stars:long = StarGiftUpgradePrice; + +groupCallMessage#1a8afc7e flags:# from_admin:flags.1?true id:int from_id:Peer date:int message:TextWithEntities paid_message_stars:flags.0?long = GroupCallMessage; + +groupCallDonor#ee430c85 flags:# top:flags.0?true my:flags.1?true anonymous:flags.2?true peer_id:flags.3?Peer stars:long = GroupCallDonor; + +phone.groupCallStars#9d1dbd26 total_stars:long top_donors:Vector chats:Vector users:Vector = phone.GroupCallStars; + +recentStory#711d692d flags:# live:flags.0?true max_id:flags.1?int = RecentStory; + +auctionBidLevel#310240cc pos:int amount:long date:int = AuctionBidLevel; + +starGiftAuctionStateNotModified#fe333952 = StarGiftAuctionState; +starGiftAuctionState#771a4e66 version:int start_date:int end_date:int min_bid_amount:long bid_levels:Vector top_bidders:Vector next_round_at:int last_gift_num:int gifts_left:int current_round:int total_rounds:int rounds:Vector = StarGiftAuctionState; +starGiftAuctionStateFinished#972dabbf flags:# start_date:int end_date:int average_price:long listed_count:flags.0?int fragment_listed_count:flags.1?int fragment_listed_url:flags.1?string = StarGiftAuctionState; + +starGiftAuctionUserState#2eeed1c4 flags:# returned:flags.1?true bid_amount:flags.0?long bid_date:flags.0?int min_bid_amount:flags.0?long bid_peer:flags.0?Peer acquired_count:int = StarGiftAuctionUserState; + +payments.starGiftAuctionState#6b39f4ec gift:StarGift state:StarGiftAuctionState user_state:StarGiftAuctionUserState timeout:int users:Vector chats:Vector = payments.StarGiftAuctionState; + +starGiftAuctionAcquiredGift#42b00348 flags:# name_hidden:flags.0?true peer:Peer date:int bid_amount:long round:int pos:int message:flags.1?TextWithEntities gift_num:flags.2?int = StarGiftAuctionAcquiredGift; + +payments.starGiftAuctionAcquiredGifts#7d5bd1f0 gifts:Vector users:Vector chats:Vector = payments.StarGiftAuctionAcquiredGifts; + +starGiftActiveAuctionState#d31bc45d gift:StarGift state:StarGiftAuctionState user_state:StarGiftAuctionUserState = StarGiftActiveAuctionState; + +payments.starGiftActiveAuctionsNotModified#db33dad0 = payments.StarGiftActiveAuctions; +payments.starGiftActiveAuctions#aef6abbc auctions:Vector users:Vector chats:Vector = payments.StarGiftActiveAuctions; + +inputStarGiftAuction#2e16c98 gift_id:long = InputStarGiftAuction; +inputStarGiftAuctionSlug#7ab58308 slug:string = InputStarGiftAuction; + +passkey#98613ebf flags:# id:string name:string date:int software_emoji_id:flags.0?long last_usage_date:flags.1?int = Passkey; + +account.passkeys#f8e0aa1c passkeys:Vector = account.Passkeys; + +account.passkeyRegistrationOptions#e16b5ce1 options:DataJSON = account.PasskeyRegistrationOptions; + +auth.passkeyLoginOptions#e2037789 options:DataJSON = auth.PasskeyLoginOptions; + +inputPasskeyResponseRegister#3e63935c client_data:DataJSON attestation_data:bytes = InputPasskeyResponse; +inputPasskeyResponseLogin#c31fc14a client_data:DataJSON authenticator_data:bytes signature:bytes user_handle:string = InputPasskeyResponse; + +inputPasskeyCredentialPublicKey#3c27b78f id:string raw_id:string response:InputPasskeyResponse = InputPasskeyCredential; +inputPasskeyCredentialFirebasePNV#5b1ccb28 pnv_token:string = InputPasskeyCredential; + +starGiftBackground#aff56398 center_color:int edge_color:int text_color:int = StarGiftBackground; + +starGiftAuctionRound#3aae0528 num:int duration:int = StarGiftAuctionRound; +starGiftAuctionRoundExtendable#aa021e5 num:int duration:int extend_top:int extend_window:int = StarGiftAuctionRound; + +payments.starGiftUpgradeAttributes#46c6e36f attributes:Vector = payments.StarGiftUpgradeAttributes; + +messages.emojiGameOutcome#da2ad647 seed:bytes stake_ton_amount:long ton_amount:long = messages.EmojiGameOutcome; + +messages.emojiGameUnavailable#59e65335 = messages.EmojiGameInfo; +messages.emojiGameDiceInfo#44e56023 flags:# game_hash:string prev_stake:long current_streak:int params:Vector plays_left:flags.0?int = messages.EmojiGameInfo; + +starGiftAttributeRarity#36437737 permille:int = StarGiftAttributeRarity; +starGiftAttributeRarityUncommon#dbce6389 = StarGiftAttributeRarity; +starGiftAttributeRarityRare#f08d516b = StarGiftAttributeRarity; +starGiftAttributeRarityEpic#78fbf3a8 = StarGiftAttributeRarity; +starGiftAttributeRarityLegendary#cef7e7a8 = StarGiftAttributeRarity; + +keyboardButtonStyle#4fdd3430 flags:# bg_primary:flags.0?true bg_danger:flags.1?true bg_success:flags.2?true icon:flags.3?long = KeyboardButtonStyle; messages.messageEmpty#3f4e0648 = messages.MessageEmpty; -premiumGiftOption#79c059f7 flags:# months:int currency:string amount:long bot_url:flags.1?string store_product:flags.0?string = PremiumGiftOption; +inputMessageReadMetric#402b4495 msg_id:int view_id:long time_in_view_ms:int active_time_in_view_ms:int height_to_viewport_ratio_permille:int seen_range_ratio_permille:int = InputMessageReadMetric; -starGiftUpgradePrice#99ea331d date:int upgrade_stars:long = StarGiftUpgradePrice; +messageEntityDiffDelete#652c1c5 offset:int length:int = JsonParser.Deserializable; +messageEntityDiffInsert#71777116 offset:int length:int = JsonParser.Deserializable; +messageEntityDiffReplace#c6c1e5a7 offset:int length:int old_text:string = JsonParser.Deserializable; + +premiumGiftOption#79c059f7 flags:# months:int currency:string amount:long bot_url:flags.1?string store_product:flags.0?string = PremiumGiftOption; messages.webViewResult#aadf159b result:BotInlineResult users:Vector = messages.WebViewResult; -chatThemes#be098173 flags:# hash:long themes:Vector chats:Vector users:Vector next_offset:flags.0?string = ChatThemes; +requestedButton#f13bbcd7 webapp_req_id:string = RequestedButton; ---functions--- @@ -2120,6 +2213,9 @@ auth.importWebTokenAuthorization#2db873a9 api_id:int api_hash:string web_auth_to auth.requestFirebaseSms#8e39261e flags:# phone_number:string phone_code_hash:string safety_net_token:flags.0?string play_integrity_token:flags.2?string ios_push_secret:flags.1?string = Bool; auth.resetLoginEmail#7e960193 phone_number:string phone_code_hash:string = auth.SentCode; auth.reportMissingCode#cb9deff6 phone_number:string phone_code_hash:string mnc:string = Bool; +auth.checkPaidAuth#56e59f9c phone_number:string phone_code_hash:string form_id:long = auth.SentCode; +auth.initPasskeyLogin#518ad0b7 api_id:int api_hash:string = auth.PasskeyLoginOptions; +auth.finishPasskeyLogin#9857ad07 flags:# credential:InputPasskeyCredential from_dc_id:flags.0?int from_auth_key_id:flags.0?long = auth.Authorization; account.registerDevice#ec86017a flags:# no_muted:flags.0?true token_type:int token:string app_sandbox:Bool secret:bytes other_uids:Vector = Bool; account.unregisterDevice#6a0d3206 token_type:int token:string other_uids:Vector = Bool; @@ -2209,7 +2305,7 @@ account.getAutoSaveSettings#adcbbcda = account.AutoSaveSettings; account.saveAutoSaveSettings#d69b8361 flags:# users:flags.0?true chats:flags.1?true broadcasts:flags.2?true peer:flags.3?InputPeer settings:AutoSaveSettings = Bool; account.deleteAutoSaveExceptions#53bc0020 = Bool; account.invalidateSignInCodes#ca8ae8ba codes:Vector = Bool; -account.updateColor#7cefa15d flags:# for_profile:flags.1?true color:flags.2?int background_emoji_id:flags.0?long = Bool; +account.updateColor#684d214e flags:# for_profile:flags.1?true color:flags.2?PeerColor = Bool; account.getDefaultBackgroundEmojis#a60ab9ce hash:long = EmojiList; account.getChannelDefaultEmojiStatuses#7727a7d5 hash:long = account.EmojiStatuses; account.getChannelRestrictedStatusEmojis#35a9e0d5 hash:long = EmojiList; @@ -2239,7 +2335,11 @@ account.toggleNoPaidMessagesException#fe2eda76 flags:# refund_charged:flags.0?tr account.setMainProfileTab#5dee78b0 tab:ProfileTab = Bool; account.saveMusic#b26732a9 flags:# unsave:flags.0?true id:InputDocument after_id:flags.1?InputDocument = Bool; account.getSavedMusicIds#e09d5faf hash:long = account.SavedMusicIds; -account.getUniqueGiftChatThemes#fe74ef9f offset:int limit:int hash:long = account.ChatThemes; +account.getUniqueGiftChatThemes#e42ce9c9 offset:string limit:int hash:long = account.ChatThemes; +account.initPasskeyRegistration#429547e8 = account.PasskeyRegistrationOptions; +account.registerPasskey#55b41fd6 credential:InputPasskeyCredential = Passkey; +account.getPasskeys#ea1f0c52 = account.Passkeys; +account.deletePasskey#f5b5563f id:string = Bool; users.getUsers#d91a548 id:Vector = Vector; users.getFullUser#b60f5918 id:InputUser = users.UserFull; @@ -2276,6 +2376,7 @@ contacts.editCloseFriends#ba6705f0 id:Vector = Bool; contacts.setBlocked#94c65c76 flags:# my_stories_from:flags.0?true id:Vector limit:int = Bool; contacts.getBirthdays#daeda864 = contacts.ContactBirthdays; contacts.getSponsoredPeers#b6c8c393 q:string = contacts.SponsoredPeers; +contacts.updateContactNote#139f63fb id:InputUser note:TextWithEntities = Bool; contacts.importCard#4fe196fe export_card:Vector = User; messages.getMessages#63c66506 id:Vector = messages.Messages; @@ -2287,9 +2388,9 @@ messages.deleteHistory#b08f922a flags:# just_clear:flags.0?true revoke:flags.1?t messages.deleteMessages#e58e95d2 flags:# revoke:flags.0?true id:Vector = messages.AffectedMessages; messages.receivedMessages#5a954c0 max_id:int = Vector; messages.setTyping#58943ee2 flags:# peer:InputPeer top_msg_id:flags.0?int action:SendMessageAction = Bool; -messages.sendMessage#fe05dc9a flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true invert_media:flags.16?true allow_paid_floodskip:flags.19?true peer:InputPeer reply_to:flags.0?InputReplyTo message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long allow_paid_stars:flags.21?long suggested_post:flags.22?SuggestedPost = Updates; -messages.sendMedia#ac55d9c1 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true invert_media:flags.16?true allow_paid_floodskip:flags.19?true peer:InputPeer reply_to:flags.0?InputReplyTo media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long allow_paid_stars:flags.21?long suggested_post:flags.22?SuggestedPost = Updates; -messages.forwardMessages#978928ca flags:# silent:flags.5?true background:flags.6?true with_my_score:flags.8?true drop_author:flags.11?true drop_media_captions:flags.12?true noforwards:flags.14?true allow_paid_floodskip:flags.19?true from_peer:InputPeer id:Vector random_id:Vector to_peer:InputPeer top_msg_id:flags.9?int reply_to:flags.22?InputReplyTo schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut video_timestamp:flags.20?int allow_paid_stars:flags.21?long suggested_post:flags.23?SuggestedPost = Updates; +messages.sendMessage#545cd15a flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true invert_media:flags.16?true allow_paid_floodskip:flags.19?true peer:InputPeer reply_to:flags.0?InputReplyTo message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector schedule_date:flags.10?int schedule_repeat_period:flags.24?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long allow_paid_stars:flags.21?long suggested_post:flags.22?SuggestedPost = Updates; +messages.sendMedia#330e77f flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true noforwards:flags.14?true update_stickersets_order:flags.15?true invert_media:flags.16?true allow_paid_floodskip:flags.19?true peer:InputPeer reply_to:flags.0?InputReplyTo media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector schedule_date:flags.10?int schedule_repeat_period:flags.24?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long allow_paid_stars:flags.21?long suggested_post:flags.22?SuggestedPost = Updates; +messages.forwardMessages#13704a7c flags:# silent:flags.5?true background:flags.6?true with_my_score:flags.8?true drop_author:flags.11?true drop_media_captions:flags.12?true noforwards:flags.14?true allow_paid_floodskip:flags.19?true from_peer:InputPeer id:Vector random_id:Vector to_peer:InputPeer top_msg_id:flags.9?int reply_to:flags.22?InputReplyTo schedule_date:flags.10?int schedule_repeat_period:flags.24?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut effect:flags.18?long video_timestamp:flags.20?int allow_paid_stars:flags.21?long suggested_post:flags.23?SuggestedPost = Updates; messages.reportSpam#cf1592db peer:InputPeer = Bool; messages.getPeerSettings#efd9a6a2 peer:InputPeer = messages.PeerSettings; messages.report#fc78af9b peer:InputPeer id:Vector option:bytes message:string = ReportResult; @@ -2334,7 +2435,7 @@ messages.getInlineBotResults#514e999d flags:# bot:InputUser peer:InputPeer geo_p messages.setInlineBotResults#bb12a419 flags:# gallery:flags.0?true private:flags.1?true query_id:long results:Vector cache_time:int next_offset:flags.2?string switch_pm:flags.3?InlineBotSwitchPM switch_webview:flags.4?InlineBotWebView = Bool; messages.sendInlineBotResult#c0cf7646 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true hide_via:flags.11?true peer:InputPeer reply_to:flags.0?InputReplyTo random_id:long query_id:long id:string schedule_date:flags.10?int send_as:flags.13?InputPeer quick_reply_shortcut:flags.17?InputQuickReplyShortcut allow_paid_stars:flags.21?long = Updates; messages.getMessageEditData#fda68d36 peer:InputPeer id:int = messages.MessageEditData; -messages.editMessage#dfd14005 flags:# no_webpage:flags.1?true invert_media:flags.16?true peer:InputPeer id:int message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector schedule_date:flags.15?int quick_reply_shortcut_id:flags.17?int = Updates; +messages.editMessage#51e842e1 flags:# no_webpage:flags.1?true invert_media:flags.16?true peer:InputPeer id:int message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector schedule_date:flags.15?int schedule_repeat_period:flags.18?int quick_reply_shortcut_id:flags.17?int = Updates; messages.editInlineBotMessage#83557dba flags:# no_webpage:flags.1?true invert_media:flags.16?true id:InputBotInlineMessageID message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector = Bool; messages.getBotCallbackAnswer#9342ca07 flags:# game:flags.1?true peer:InputPeer msg_id:int data:flags.0?bytes password:flags.2?InputCheckPasswordSRP = messages.BotCallbackAnswer; messages.setBotCallbackAnswer#d58f130a flags:# alert:flags.1?true query_id:long message:flags.0?string url:flags.2?string cache_time:int = Bool; @@ -2376,7 +2477,7 @@ messages.getDialogUnreadMarks#21202222 flags:# parent_peer:flags.0?InputPeer = V messages.clearAllDrafts#7e58ee9c = Bool; messages.updatePinnedMessage#d2aaf7ec flags:# silent:flags.0?true unpin:flags.1?true pm_oneside:flags.2?true peer:InputPeer id:int = Updates; messages.sendVote#10ea6184 peer:InputPeer msg_id:int options:Vector = Updates; -messages.getPollResults#73bb643b peer:InputPeer msg_id:int = Updates; +messages.getPollResults#eda3e33b peer:InputPeer msg_id:int poll_hash:long = Updates; messages.getOnlines#6e2be050 peer:InputPeer = ChatOnlines; messages.editChatAbout#def60797 peer:InputPeer about:string = Bool; messages.editChatDefaultBannedRights#a5866b41 peer:InputPeer banned_rights:ChatBannedRights = Updates; @@ -2385,8 +2486,8 @@ messages.getEmojiKeywordsDifference#1508b6af lang_code:string from_version:int = messages.getEmojiKeywordsLanguages#4e9963b2 lang_codes:Vector = Vector; messages.getEmojiURL#d5b10c26 lang_code:string = EmojiURL; messages.getSearchCounters#1bbcf300 flags:# peer:InputPeer saved_peer_id:flags.2?InputPeer top_msg_id:flags.0?int filters:Vector = Vector; -messages.requestUrlAuth#198fb446 flags:# peer:flags.1?InputPeer msg_id:flags.1?int button_id:flags.1?int url:flags.2?string = UrlAuthResult; -messages.acceptUrlAuth#b12c7125 flags:# write_allowed:flags.0?true peer:flags.1?InputPeer msg_id:flags.1?int button_id:flags.1?int url:flags.2?string = UrlAuthResult; +messages.requestUrlAuth#894cc99c flags:# peer:flags.1?InputPeer msg_id:flags.1?int button_id:flags.1?int url:flags.2?string in_app_origin:flags.3?string = UrlAuthResult; +messages.acceptUrlAuth#67a3f0de flags:# write_allowed:flags.0?true share_phone_number:flags.3?true peer:flags.1?InputPeer msg_id:flags.1?int button_id:flags.1?int url:flags.2?string match_code:flags.4?string = UrlAuthResult; messages.hidePeerSettingsBar#4facb138 peer:InputPeer = Bool; messages.getScheduledHistory#f516760b peer:InputPeer hash:long = messages.Messages; messages.getScheduledMessages#bdbb0464 peer:InputPeer id:Vector = messages.Messages; @@ -2424,7 +2525,7 @@ messages.getSearchResultsCalendar#6aa3f6bd flags:# peer:InputPeer saved_peer_id: messages.getSearchResultsPositions#9c7f2f10 flags:# peer:InputPeer saved_peer_id:flags.2?InputPeer filter:MessagesFilter offset_id:int limit:int = messages.SearchResultsPositions; messages.hideChatJoinRequest#7fe7e815 flags:# approved:flags.0?true peer:InputPeer user_id:InputUser = Updates; messages.hideAllChatJoinRequests#e085f4ea flags:# approved:flags.0?true peer:InputPeer link:flags.1?string = Updates; -messages.toggleNoForwards#b11eafa2 peer:InputPeer enabled:Bool = Updates; +messages.toggleNoForwards#b2081a35 flags:# peer:InputPeer enabled:Bool request_msg_id:flags.0?int = Updates; messages.saveDefaultSendAs#ccfddf96 peer:InputPeer send_as:InputPeer = Bool; messages.sendReaction#d30d78d4 flags:# big:flags.1?true add_to_recent:flags.2?true peer:InputPeer msg_id:int reaction:flags.0?Vector = Updates; messages.getMessagesReactions#8bba90e6 peer:InputPeer id:Vector = Updates; @@ -2432,7 +2533,7 @@ messages.getMessageReactionsList#461b3f48 flags:# peer:InputPeer id:int reaction messages.setChatAvailableReactions#864b2581 flags:# peer:InputPeer available_reactions:ChatReactions reactions_limit:flags.0?int paid_enabled:flags.1?Bool = Updates; messages.getAvailableReactions#18dea0ac hash:int = messages.AvailableReactions; messages.setDefaultReaction#4f47a016 reaction:Reaction = Bool; -messages.translateText#63183030 flags:# peer:flags.0?InputPeer id:flags.0?Vector text:flags.1?Vector to_lang:string = messages.TranslatedText; +messages.translateText#a5eec345 flags:# peer:flags.0?InputPeer id:flags.0?Vector text:flags.1?Vector to_lang:string tone:flags.2?string = messages.TranslatedText; messages.getUnreadReactions#bd7f90ac flags:# peer:InputPeer top_msg_id:flags.0?int saved_peer_id:flags.1?InputPeer offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages; messages.readReactions#9ec44f93 flags:# peer:InputPeer top_msg_id:flags.0?int saved_peer_id:flags.1?InputPeer = messages.AffectedHistory; messages.searchSentMedia#107e31a0 q:string filter:MessagesFilter limit:int = messages.Messages; @@ -2456,7 +2557,7 @@ messages.clearRecentReactions#9dfeefb4 = Bool; messages.getExtendedMedia#84f80814 peer:InputPeer id:Vector = Updates; messages.setDefaultHistoryTTL#9eb51445 period:int = Bool; messages.getDefaultHistoryTTL#658b7188 = DefaultHistoryTTL; -messages.sendBotRequestedPeer#91b2d060 peer:InputPeer msg_id:int button_id:int requested_peers:Vector = Updates; +messages.sendBotRequestedPeer#6c5cf2a7 flags:# peer:InputPeer msg_id:flags.0?int webapp_req_id:flags.1?string button_id:int requested_peers:Vector = Updates; messages.getEmojiGroups#7488ce5b hash:int = messages.EmojiGroups; messages.getEmojiStatusGroups#2ecd56cd hash:int = messages.EmojiGroups; messages.getEmojiProfilePhotoGroups#21a548f3 hash:int = messages.EmojiGroups; @@ -2508,25 +2609,36 @@ messages.readSavedHistory#ba4a3b5b parent_peer:InputPeer peer:InputPeer max_id:i messages.toggleTodoCompleted#d3e03124 peer:InputPeer msg_id:int completed:Vector incompleted:Vector = Updates; messages.appendTodoList#21a61057 peer:InputPeer msg_id:int list:Vector = Updates; messages.toggleSuggestedPostApproval#8107455c flags:# reject:flags.1?true peer:InputPeer msg_id:int schedule_date:flags.0?int reject_comment:flags.2?string = Updates; -messages.updateContactNote#139f63fb id:InputUser note:TextWithEntities = Bool; +messages.getForumTopics#3ba47bff flags:# peer:InputPeer q:flags.0?string offset_date:int offset_id:int offset_topic:int limit:int = messages.ForumTopics; +messages.getForumTopicsByID#af0a4a08 peer:InputPeer topics:Vector = messages.ForumTopics; +messages.editForumTopic#cecc1134 flags:# peer:InputPeer topic_id:int title:flags.0?string icon_emoji_id:flags.1?long closed:flags.2?Bool hidden:flags.3?Bool = Updates; messages.updatePinnedForumTopic#175df251 peer:InputPeer topic_id:int pinned:Bool = Updates; -messages.getWebViewResult#22b6c214 peer:InputPeer bot:InputUser query_id:long = messages.WebViewResult; +messages.reorderPinnedForumTopics#e7841f0 flags:# force:flags.0?true peer:InputPeer order:Vector = Updates; messages.createForumTopic#2f98c3d5 flags:# title_missing:flags.4?true peer:InputPeer title:string icon_color:flags.0?int icon_emoji_id:flags.3?long random_id:long send_as:flags.2?InputPeer = Updates; +messages.deleteTopicHistory#d2816f10 peer:InputPeer top_msg_id:int = messages.AffectedHistory; +messages.getEmojiGameInfo#fb7e8ca7 = messages.EmojiGameInfo; +messages.summarizeText#abbbd346 flags:# peer:InputPeer id:int to_lang:flags.0?string tone:flags.2?string = TextWithEntities; +messages.editChatCreator#f743b857 peer:InputPeer user_id:InputUser password:InputCheckPasswordSRP = Updates; +messages.getFutureChatCreatorAfterLeave#3b7d0ea6 peer:InputPeer = User; +messages.editChatParticipantRank#a00f32b0 peer:InputPeer participant:InputPeer rank:string = Updates; +messages.declineUrlAuth#35436bbc url:string = Bool; +messages.checkUrlAuthMatchCode#c9a47b0b url:string match_code:string = Bool; +messages.readPollVotes#1720b4d8 flags:# peer:InputPeer top_msg_id:flags.0?int = messages.AffectedHistory; +messages.addPollAnswer#19bc4b6d peer:InputPeer msg_id:int answer:PollAnswer = Updates; +messages.getWebViewResult#22b6c214 peer:InputPeer bot:InputUser query_id:long = messages.WebViewResult; messages.forwardMessage#33963bf9 peer:InputPeer id:int random_id:long = Updates; -messages.getForumTopics#3ba47bff flags:# peer:InputPeer q:flags.0?string offset_date:int offset_id:int offset_topic:int limit:int = messages.ForumTopics; -messages.checkPaidAuth#56e59f9c phone_number:string phone_code_hash:string form_id:long = auth.SentCode; -messages.updateColor#684d214e flags:# for_profile:flags.1?true color:flags.2?PeerColor = Bool; +messages.reportReadMetrics#4067c5e6 peer:InputPeer metrics:Vector = Bool; +messages.getUnreadPollVotes#43286cf2 flags:# peer:InputPeer top_msg_id:flags.0?int offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages; +messages.exportBotToken#63b089 bot_id:long revoke:Bool = ExportedBotToken; messages.getStatsURL#812c2ae6 flags:# dark:flags.0?true peer:InputPeer params:string = StatsURL; messages.getAllChats#875f74be except_ids:Vector = messages.Chats; -messages.sendGroupCallMessage#87893014 call:InputGroupCall random_id:long message:TextWithEntities = Bool; -messages.getForumTopicsByID#af0a4a08 peer:InputPeer topics:Vector = messages.ForumTopics; -messages.editForumTopic#cecc1134 flags:# peer:InputPeer topic_id:int title:flags.0?string icon_emoji_id:flags.1?long closed:flags.2?Bool hidden:flags.3?Bool = Updates; -messages.deleteTopicHistory#d2816f10 peer:InputPeer top_msg_id:int = messages.AffectedHistory; +messages.checkUsername#87f2219b username:string = Bool; +messages.deletePollAnswer#ac8505a5 peer:InputPeer msg_id:int option:bytes = Updates; +messages.getRequestedWebViewButton#bf25b7f3 bot:InputUser webapp_req_id:string = KeyboardButton; +messages.reportMusicListen#ddbcd819 id:InputDocument listened_duration:int = Bool; messages.setWebViewResult#e41cd11d query_id:long = Bool; -messages.getUniqueGiftChatThemes#e42ce9c9 offset:string limit:int hash:long = ChatThemes; -messages.sendGroupCallEncryptedMessage#e5afa56d call:InputGroupCall encrypted_message:bytes = Bool; -messages.reorderPinnedForumTopics#e7841f0 flags:# force:flags.0?int peer:InputPeer order:Vector = Updates; -messages.toggleGroupCallSettings#e9723804 flags:# reset_invite_hash:flags.1?true call:InputGroupCall join_muted:flags.0?Bool messages_enabled:flags.2?Bool = Updates; +messages.createBot#e5b17f2b flags:# via_deeplink:flags.0?true name:string username:string manager_id:InputUser = User; +messages.composeMessageWithAI#fd426afe flags:# proofread:flags.0?true text:TextWithEntities translate_to_lang:flags.1?string change_tone:flags.2?string = ComposedMessageWithAI; updates.getState#edd4882a = updates.State; updates.getDifference#19c2f763 flags:# pts:int pts_limit:flags.1?int pts_total_limit:flags.0?int date:int qts:int qts_limit:flags.2?int = updates.Difference; @@ -2582,7 +2694,7 @@ channels.getParticipant#a0ab6cc6 channel:InputChannel participant:InputPeer = ch channels.getChannels#a7f6bbb id:Vector = messages.Chats; channels.getFullChannel#8736a09 channel:InputChannel = messages.ChatFull; channels.createChannel#91006707 flags:# broadcast:flags.0?true megagroup:flags.1?true for_import:flags.3?true forum:flags.5?true title:string about:string geo_point:flags.2?InputGeoPoint address:flags.2?string ttl_period:flags.4?int = Updates; -channels.editAdmin#d33c8902 channel:InputChannel user_id:InputUser admin_rights:ChatAdminRights rank:string = Updates; +channels.editAdmin#9a98ad68 flags:# channel:InputChannel user_id:InputUser admin_rights:ChatAdminRights rank:flags.0?string = Updates; channels.editTitle#566decd0 channel:InputChannel title:string = Updates; channels.editPhoto#f12e57c9 channel:InputChannel photo:InputChatPhoto = Updates; channels.checkUsername#10e6bd2c channel:InputChannel username:string = Bool; @@ -2603,12 +2715,11 @@ channels.togglePreHistoryHidden#eabbb94c channel:InputChannel enabled:Bool = Upd channels.getLeftChannels#8341ecc0 offset:int = messages.Chats; channels.getGroupsForDiscussion#f5dad378 = messages.Chats; channels.setDiscussionGroup#40582bb2 broadcast:InputChannel group:InputChannel = Bool; -channels.editCreator#8f38cd1f channel:InputChannel user_id:InputUser password:InputCheckPasswordSRP = Updates; channels.editLocation#58e63f6d channel:InputChannel geo_point:InputGeoPoint address:string = Bool; channels.toggleSlowMode#edd49ef0 channel:InputChannel seconds:int = Updates; channels.getInactiveChannels#11e831ee = messages.InactiveChats; channels.convertToGigagroup#b290c69 channel:InputChannel = Updates; -channels.getSendAs#e785a43f flags:# for_paid_reactions:flags.0?true peer:InputPeer = channels.SendAsPeers; +channels.getSendAs#e785a43f flags:# for_paid_reactions:flags.0?true for_live_stories:flags.1?true peer:InputPeer = channels.SendAsPeers; channels.deleteParticipantHistory#367544db channel:InputChannel participant:InputPeer = messages.AffectedHistory; channels.toggleJoinToSend#e4cb9580 channel:InputChannel enabled:Bool = Updates; channels.toggleJoinRequest#4c2985b6 channel:InputChannel enabled:Bool = Updates; @@ -2616,13 +2727,6 @@ channels.reorderUsernames#b45ced1d channel:InputChannel order:Vector = B channels.toggleUsername#50f24105 channel:InputChannel username:string active:Bool = Bool; channels.deactivateAllUsernames#a245dd3 channel:InputChannel = Bool; channels.toggleForum#3ff75734 channel:InputChannel enabled:Bool tabs:Bool = Updates; -channels.createForumTopic#f40c0224 flags:# channel:InputChannel title:string icon_color:flags.0?int icon_emoji_id:flags.3?long random_id:long send_as:flags.2?InputPeer = Updates; -channels.getForumTopics#de560d1 flags:# channel:InputChannel q:flags.0?string offset_date:int offset_id:int offset_topic:int limit:int = messages.ForumTopics; -channels.getForumTopicsByID#b0831eb9 channel:InputChannel topics:Vector = messages.ForumTopics; -channels.editForumTopic#f4dfa185 flags:# channel:InputChannel topic_id:int title:flags.0?string icon_emoji_id:flags.1?long closed:flags.2?Bool hidden:flags.3?Bool = Updates; -channels.updatePinnedForumTopic#6c2d9026 channel:InputChannel topic_id:int pinned:Bool = Updates; -channels.deleteTopicHistory#34435f2d channel:InputChannel top_msg_id:int = messages.AffectedHistory; -channels.reorderPinnedForumTopics#2950a18f flags:# force:flags.0?true channel:InputChannel order:Vector = Updates; channels.toggleAntiSpam#68f3e4eb channel:InputChannel enabled:Bool = Updates; channels.reportAntiSpamFalsePositive#a850a693 channel:InputChannel msg_id:int = Bool; channels.toggleParticipantsHidden#6a6e7854 channel:InputChannel enabled:Bool = Updates; @@ -2719,7 +2823,7 @@ payments.getStarGiftWithdrawalUrl#d06e93a8 stargift:InputSavedStarGift password: payments.toggleChatStarGiftNotifications#60eaefa1 flags:# enabled:flags.0?true peer:InputPeer = Bool; payments.toggleStarGiftsPinnedToTop#1513e7b0 peer:InputPeer stargift:Vector = Bool; payments.canPurchaseStore#4fdc5ea7 purpose:InputStorePaymentPurpose = Bool; -payments.getResaleStarGifts#7a5fa236 flags:# sort_by_price:flags.1?true sort_by_num:flags.2?true attributes_hash:flags.0?long gift_id:long attributes:flags.3?Vector offset:string limit:int = payments.ResaleStarGifts; +payments.getResaleStarGifts#7a5fa236 flags:# sort_by_price:flags.1?true sort_by_num:flags.2?true for_craft:flags.4?true stars_only:flags.5?true attributes_hash:flags.0?long gift_id:long attributes:flags.3?Vector offset:string limit:int = payments.ResaleStarGifts; payments.updateStarGiftPrice#edbe6ccb stargift:InputSavedStarGift resell_amount:StarsAmount = Updates; payments.createStarGiftCollection#1f4a0e87 peer:InputPeer title:string stargift:Vector = StarGiftCollection; payments.updateStarGiftCollection#4fddbee7 flags:# peer:InputPeer collection_id:int title:flags.0?string delete_stargift:flags.1?Vector add_stargift:flags.2?Vector order:flags.3?Vector = StarGiftCollection; @@ -2728,6 +2832,14 @@ payments.deleteStarGiftCollection#ad5648e8 peer:InputPeer collection_id:int = Bo payments.getStarGiftCollections#981b91dd peer:InputPeer hash:long = payments.StarGiftCollections; payments.getUniqueStarGiftValueInfo#4365af6b slug:string = payments.UniqueStarGiftValueInfo; payments.checkCanSendGift#c0c4edc9 gift_id:long = payments.CheckCanSendGiftResult; +payments.getStarGiftAuctionState#5c9ff4d6 auction:InputStarGiftAuction version:int = payments.StarGiftAuctionState; +payments.getStarGiftAuctionAcquiredGifts#6ba2cbec gift_id:long = payments.StarGiftAuctionAcquiredGifts; +payments.getStarGiftActiveAuctions#a5d0514d hash:long = payments.StarGiftActiveAuctions; +payments.resolveStarGiftOffer#e9ce781c flags:# decline:flags.0?true offer_msg_id:int = Updates; +payments.sendStarGiftOffer#8fb86b41 flags:# peer:InputPeer slug:string price:StarsAmount duration:int random_id:long allow_paid_stars:flags.0?long = Updates; +payments.getStarGiftUpgradeAttributes#6d038b58 gift_id:long = payments.StarGiftUpgradeAttributes; +payments.getCraftStarGifts#fd05dd00 gift_id:long offset:string limit:int = payments.SavedStarGifts; +payments.craftStarGift#b0f9684f stargift:Vector = Updates; payments.requestRecurringPayment#146e958d user_id:InputUser recurring_init_charge:string invoice_media:InputMedia = Updates; stickers.createStickerSet#9021ab67 flags:# masks:flags.0?true emojis:flags.5?true text_color:flags.6?true user_id:InputUser title:string short_name:string thumb:flags.2?InputDocument stickers:Vector software:flags.3?string = messages.StickerSet; @@ -2756,7 +2868,7 @@ phone.joinGroupCall#8fb53057 flags:# muted:flags.0?true video_stopped:flags.2?tr phone.leaveGroupCall#500377f9 call:InputGroupCall source:int = Updates; phone.inviteToGroupCall#7b393160 call:InputGroupCall users:Vector = Updates; phone.discardGroupCall#7a777135 call:InputGroupCall = Updates; -phone.toggleGroupCallSettings#74bbb43d flags:# reset_invite_hash:flags.1?true call:InputGroupCall join_muted:flags.0?Bool = Updates; +phone.toggleGroupCallSettings#974392f2 flags:# reset_invite_hash:flags.1?true call:InputGroupCall join_muted:flags.0?Bool messages_enabled:flags.2?Bool send_paid_messages_stars:flags.3?long = Updates; phone.getGroupCall#41845db call:InputGroupCall limit:int = phone.GroupCall; phone.getGroupParticipants#c558d8ab call:InputGroupCall ids:Vector sources:Vector offset:string limit:int = phone.GroupParticipants; phone.checkGroupCall#b59cf977 call:InputGroupCall sources:Vector = Vector; @@ -2771,7 +2883,7 @@ phone.saveDefaultGroupCallJoinAs#575e1f8c peer:InputPeer join_as:InputPeer = Boo phone.joinGroupCallPresentation#cbea6bc4 call:InputGroupCall params:DataJSON = Updates; phone.leaveGroupCallPresentation#1c50d144 call:InputGroupCall = Updates; phone.getGroupCallStreamChannels#1ab21940 call:InputGroupCall = phone.GroupCallStreamChannels; -phone.getGroupCallStreamRtmpUrl#deb3abbf peer:InputPeer revoke:Bool = phone.GroupCallStreamRtmpUrl; +phone.getGroupCallStreamRtmpUrl#5af4c73a flags:# live_story:flags.0?true peer:InputPeer revoke:Bool = phone.GroupCallStreamRtmpUrl; phone.saveCallLog#41248786 peer:InputPhoneCall file:InputFile = Bool; phone.createConferenceCall#7d0444bb flags:# muted:flags.0?true video_stopped:flags.2?true join:flags.3?true random_id:int public_key:flags.3?int256 block:flags.3?bytes params:flags.3?DataJSON = Updates; phone.deleteConferenceCallParticipants#8ca60525 flags:# only_left:flags.0?true kick:flags.1?true call:InputGroupCall ids:Vector block:bytes = Updates; @@ -2779,6 +2891,12 @@ phone.sendConferenceCallBroadcast#c6701900 call:InputGroupCall block:bytes = Upd phone.inviteConferenceCallParticipant#bcf22685 flags:# video:flags.0?true call:InputGroupCall user_id:InputUser = Updates; phone.declineConferenceCallInvite#3c479971 msg_id:int = Updates; phone.getGroupCallChainBlocks#ee9f88a6 call:InputGroupCall sub_chain_id:int offset:int limit:int = Updates; +phone.sendGroupCallMessage#b1d11410 flags:# call:InputGroupCall random_id:long message:TextWithEntities allow_paid_stars:flags.0?long send_as:flags.1?InputPeer = Updates; +phone.sendGroupCallEncryptedMessage#e5afa56d call:InputGroupCall encrypted_message:bytes = Bool; +phone.deleteGroupCallMessages#f64f54f7 flags:# report_spam:flags.0?true call:InputGroupCall messages:Vector = Updates; +phone.deleteGroupCallParticipantMessages#1dbfeca0 flags:# report_spam:flags.0?true call:InputGroupCall participant:InputPeer = Updates; +phone.getGroupCallStars#6f636302 call:InputGroupCall = phone.GroupCallStars; +phone.saveDefaultSendAs#4167add1 call:InputGroupCall send_as:InputPeer = Bool; langpack.getLangPack#f2f2330a lang_pack:string lang_code:string = LangPackDifference; langpack.getStrings#efea3803 lang_pack:string lang_code:string keys:Vector = Vector; @@ -2829,7 +2947,7 @@ stories.activateStealthMode#57bbd166 flags:# past:flags.0?true future:flags.1?tr stories.sendReaction#7fd736b2 flags:# add_to_recent:flags.0?true peer:InputPeer story_id:int reaction:Reaction = Updates; stories.getPeerStories#2c4ada50 peer:InputPeer = stories.PeerStories; stories.getAllReadPeerStories#9b5ae7f9 = Updates; -stories.getPeerMaxIDs#535983c3 id:Vector = Vector; +stories.getPeerMaxIDs#78499170 id:Vector = Vector; stories.getChatsToSend#a56a8b60 = messages.Chats; stories.togglePeerStoriesHidden#bd0415c4 peer:InputPeer hidden:Bool = Bool; stories.getStoryReactionsList#b9b2881f flags:# forwards_first:flags.2?true peer:InputPeer id:int reaction:flags.0?Reaction offset:flags.1?string limit:int = stories.StoryReactionsList; @@ -2841,6 +2959,7 @@ stories.reorderAlbums#8535fbd9 peer:InputPeer order:Vector = Bool; stories.deleteAlbum#8d3456d0 peer:InputPeer album_id:int = Bool; stories.getAlbums#25b3eac7 peer:InputPeer hash:long = stories.Albums; stories.getAlbumStories#ac806d61 peer:InputPeer album_id:int offset:int limit:int = stories.Stories; +stories.startLive#d069ccde flags:# pinned:flags.2?true noforwards:flags.4?true rtmp_stream:flags.5?true peer:InputPeer caption:flags.0?string entities:flags.1?Vector privacy_rules:Vector random_id:long messages_enabled:flags.6?Bool send_paid_messages_stars:flags.7?long = Updates; premium.getBoostsList#60f67660 flags:# gifts:flags.0?true peer:InputPeer offset:string limit:int = premium.BoostsList; premium.getMyBoosts#be77b4a = premium.MyBoosts; @@ -2858,4 +2977,4 @@ smsjobs.finishJob#4f1ebf24 flags:# job_id:string error:flags.0?string = Bool; fragment.getCollectibleInfo#be1e85ba collectible:InputCollectible = fragment.CollectibleInfo; -// LAYER 216 \ No newline at end of file +// LAYER 224 \ No newline at end of file diff --git a/compiler/api/template/combinator.txt b/compiler/api/template/combinator.txt index fa7a7697..ec4de4cf 100644 --- a/compiler/api/template/combinator.txt +++ b/compiler/api/template/combinator.txt @@ -1,16 +1,18 @@ {notice} from io import BytesIO +from typing import TYPE_CHECKING, List, Optional, Any from pyrogram.raw.core.primitives import Int, Long, Int128, Int256, Bool, Bytes, String, Double, Vector from pyrogram.raw.core import TLObject -from pyrogram import raw -from typing import List, Optional, Any + +if TYPE_CHECKING: + from pyrogram import raw {warning} -class {name}(TLObject): # type: ignore +class {name}(TLObject{generic_type}): """{docstring} """ diff --git a/compiler/api/template/type.txt b/compiler/api/template/type.txt index 2480f5ba..cb6830d2 100644 --- a/compiler/api/template/type.txt +++ b/compiler/api/template/type.txt @@ -6,6 +6,11 @@ from typing import Union from pyrogram import raw {name} = Union[{types}] -{name}.__doc__ = """ - {docstring} -""" \ No newline at end of file +_doc = """{docstring}""" +try: + _t = type({name}) + # typing.Union (and UnionType) can have a read-only __doc__ on newer Python versions + if _t.__module__ != "typing" and not (_t.__module__ == "types" and _t.__name__ == "UnionType"): + {name}.__doc__ = _doc +except (AttributeError, TypeError): + pass diff --git a/compiler/docs/compiler.py b/compiler/docs/compiler.py index f87f1f07..ec4362ab 100644 --- a/compiler/docs/compiler.py +++ b/compiler/docs/compiler.py @@ -222,6 +222,21 @@ def get_title_list(s: str) -> list: export_session_string set_parse_mode """, + decorators=""" + Decorators + on_message + on_edited_message + on_callback_query + on_inline_query + on_chosen_inline_result + on_poll + on_user_status + on_deleted_messages + on_chat_member_updated + on_raw_update + on_disconnect + on_chat_join_request + """, messages=""" Messages send_message @@ -242,6 +257,7 @@ def get_title_list(s: str) -> list: send_contact send_cached_media send_reaction + send_paid_reaction edit_message_text edit_message_caption edit_message_media @@ -387,6 +403,7 @@ def get_title_list(s: str) -> list: set_chat_menu_button get_chat_menu_button answer_web_app_query + send_streaming_text """, authorization=""" Authorization @@ -744,4 +761,4 @@ def start(): DESTINATION = "../../docs/source/telegram" PYROGRAM_API_DEST = "../../docs/source/api" - start() \ No newline at end of file + start() diff --git a/compiler/docs/template/methods.rst b/compiler/docs/template/methods.rst index f76e249d..d8576c06 100644 --- a/compiler/docs/template/methods.rst +++ b/compiler/docs/template/methods.rst @@ -31,6 +31,19 @@ Utilities {utilities} +Decorators +---------- + +.. autosummary:: + :nosignatures: + + {decorators} + +.. toctree:: + :hidden: + + {decorators} + .. currentmodule:: pyrogram .. autosummary:: @@ -165,4 +178,4 @@ Learn more about how to use the raw API at :doc:`Advanced Usage <../../topics/ad .. toctree:: :hidden: - {advanced} \ No newline at end of file + {advanced} diff --git a/compiler/errors/source/400_BAD_REQUEST.tsv b/compiler/errors/source/400_BAD_REQUEST.tsv index fae60221..7f8917fe 100644 --- a/compiler/errors/source/400_BAD_REQUEST.tsv +++ b/compiler/errors/source/400_BAD_REQUEST.tsv @@ -238,6 +238,7 @@ GROUPCALL_FORBIDDEN The group call has already ended. GROUPCALL_INVALID The specified group call is invalid. GROUPCALL_JOIN_MISSING You haven't joined this group call. GROUPCALL_NOT_MODIFIED Group call settings weren't modified. +GROUPCALL_MESSAGE_FORBIDDEN You are not allowed to send group call messages. GROUPCALL_SSRC_DUPLICATE_MUCH The app needs to retry joining the group call with a new SSRC value. GROUPED_MEDIA_INVALID Invalid grouped media. GROUP_CALL_INVALID The group call is invalid @@ -408,6 +409,7 @@ PRICING_CHAT_INVALID The pricing for the [subscription](https://core.telegram.or PRIVACY_KEY_INVALID The privacy key is invalid. PRIVACY_TOO_LONG Too many privacy rules were specified, the current limit is 1000. PRIVACY_VALUE_INVALID The specified privacy rule combination is invalid. +PUBLIC_KEY_INVALID The specified public key is invalid. PUBLIC_KEY_REQUIRED A public key is required. PURPOSE_INVALID The specified payment purpose is invalid. QUERY_ID_EMPTY The query ID is empty. @@ -421,6 +423,7 @@ QUIZ_CORRECT_ANSWERS_TOO_MUCH You specified too many correct answers in a quiz, QUIZ_CORRECT_ANSWER_INVALID An invalid value was provided to the correct_answers field. QUIZ_MULTIPLE_INVALID Quizzes can't have the multiple_choice flag set! QUOTE_TEXT_INVALID The specified `reply_to`.`quote_text` field is invalid. +TEXTDRAFT_PEER_INVALID The draft peer specified for the request is invalid. RAISE_HAND_FORBIDDEN You cannot raise your hand. RANDOM_ID_EMPTY Random ID empty. RANDOM_ID_EXPIRED The specified `random_id` was expired (most likely it didn't follow the required `uint64_t random_id = (time() << 32) | ((uint64_t)random_uint32_t())` format, or the specified time is too far in the past). @@ -647,4 +650,4 @@ WEBPAGE_URL_INVALID The specified webpage `url` is invalid. WEBPUSH_AUTH_INVALID The specified web push authentication secret is invalid. WEBPUSH_KEY_INVALID The specified web push elliptic curve Diffie-Hellman public key is invalid. WEBPUSH_TOKEN_INVALID The specified web push token is invalid. -YOU_BLOCKED_USER You blocked this user. \ No newline at end of file +YOU_BLOCKED_USER You blocked this user. diff --git a/compiler/errors/source/403_FORBIDDEN.tsv b/compiler/errors/source/403_FORBIDDEN.tsv index 15fa54b2..dc1609d1 100644 --- a/compiler/errors/source/403_FORBIDDEN.tsv +++ b/compiler/errors/source/403_FORBIDDEN.tsv @@ -3,6 +3,7 @@ id message ABOUT_TOO_LONG About string too long. ACCESS_TOKEN_EXPIRED Access token expired. ACCESS_TOKEN_INVALID Access token invalid. +ACCESS_DENIED Access denied. ADDRESS_INVALID The specified geopoint address is invalid. ADMINS_TOO_MUCH There are too many admins. ADMIN_ID_INVALID The specified admin ID is invalid. @@ -38,6 +39,7 @@ BOT_CHANNELS_NA Bots can't edit admin privileges. BOT_COMMAND_DESCRIPTION_INVALID The specified command description is invalid. BOT_COMMAND_INVALID The specified command is invalid. BOT_DOMAIN_INVALID Bot domain invalid. +BOT_FORUM_CREATE_FORBIDDEN Bots are not allowed to create forum topics in this chat. BOT_GROUPS_BLOCKED This bot can't be added to groups. BOT_INLINE_DISABLED This bot can't be used in inline mode. BOT_INVALID This is not a valid bot. @@ -513,4 +515,4 @@ WEBPUSH_AUTH_INVALID The specified web push authentication secret is invalid. WEBPUSH_KEY_INVALID The specified web push elliptic curve Diffie-Hellman public key is invalid. WEBPUSH_TOKEN_INVALID The specified web push token is invalid. YOUR_PRIVACY_RESTRICTED You cannot fetch the read date of this message because you have disallowed other users to do so for *your* messages; to fix, allow other users to see *your* exact last online date OR purchase a [Telegram Premium](https://core.telegram.org/api/premium) subscription. -YOU_BLOCKED_USER You blocked this user. \ No newline at end of file +YOU_BLOCKED_USER You blocked this user. diff --git a/compiler/errors/source/500_INTERNAL_SERVER_ERROR.tsv b/compiler/errors/source/500_INTERNAL_SERVER_ERROR.tsv index 675bb84b..c36385ea 100644 --- a/compiler/errors/source/500_INTERNAL_SERVER_ERROR.tsv +++ b/compiler/errors/source/500_INTERNAL_SERVER_ERROR.tsv @@ -460,6 +460,7 @@ STORY_NOT_MODIFIED The new story information you passed is equal to the previous STORY_PERIOD_INVALID The specified story period is invalid for this account. STORY_SEND_FLOOD_MONTHLY_X You've hit the monthly story limit as specified by the [`stories_sent_monthly_limit_*` client configuration parameters](https://core.telegram.org/api/config#stories-sent-monthly-limit-default): wait for the specified number of seconds before posting a new story. STORY_SEND_FLOOD_WEEKLY_X You've hit the weekly story limit as specified by the [`stories_sent_weekly_limit_*` client configuration parameters](https://core.telegram.org/api/config#stories-sent-weekly-limit-default): wait for the specified number of seconds before posting a new story. +STORYCHAT_INVALID The specified story chat is invalid. SWITCH_PM_TEXT_EMPTY The switch_pm.text field was empty. TAKEOUT_INIT_DELAY_X Sorry, for security reasons, you will be able to begin downloading your data in {value} seconds. We have notified all your devices about the export request to make sure it's authorized and to give you time to react if it's not. TAKEOUT_INVALID The specified takeout ID is invalid. @@ -553,4 +554,4 @@ WEBPUSH_KEY_INVALID The specified web push elliptic curve Diffie-Hellman public WEBPUSH_TOKEN_INVALID The specified web push token is invalid. WORKER_BUSY_TOO_LONG_RETRY Server workers are too busy right now due to Telegram having internal problems. Please try again later WP_ID_GENERATE_FAILED Telegram is having internal problems. Please try again later -YOU_BLOCKED_USER You blocked this user. \ No newline at end of file +YOU_BLOCKED_USER You blocked this user. diff --git a/docs/source/start/examples/index.rst b/docs/source/start/examples/index.rst index 70b188bb..305979e2 100644 --- a/docs/source/start/examples/index.rst +++ b/docs/source/start/examples/index.rst @@ -26,6 +26,9 @@ to give you a basic idea. :doc:`inline_queries`, "Handle inline queries (as bot) and answer with results" :doc:`use_inline_bots`, "Query an inline bot (as user) and send a result to a chat" :doc:`bot_keyboards`, "Send normal and inline keyboards using regular bots" + :doc:`styled_keyboards`, "Send keyboards with custom styles (colors, icons)" + :doc:`star_gifts`, "Handle Star Gift service messages" + :doc:`streaming_text`, "Stream typing updates for conversational bots" :doc:`raw_updates`, "Handle raw updates (old, should be avoided)" For more advanced examples, see https://github.com/ColinShark/Pyrogram-Snippets. @@ -43,4 +46,7 @@ For more advanced examples, see https://github.com/ColinShark/Pyrogram-Snippets. inline_queries use_inline_bots bot_keyboards + styled_keyboards + star_gifts + streaming_text raw_updates diff --git a/docs/source/start/examples/star_gifts.rst b/docs/source/start/examples/star_gifts.rst new file mode 100644 index 00000000..f10a84aa --- /dev/null +++ b/docs/source/start/examples/star_gifts.rst @@ -0,0 +1,119 @@ +star_gifts +========== + +This example shows how to handle Star Gift service messages. + +Star Gifts are a Telegram feature that allows users to send gifts to each other. When a gift is received, +a service message is sent with the gift details. This example demonstrates how to detect and handle these messages. + +.. code-block:: python + + from pyrogram import Client, filters + from pyrogram.enums import MessageServiceType + + app = Client("my_account") + + + @app.on_message(filters.service) + async def handle_service_messages(client, message): + """Handle service messages including star gifts.""" + + # Check if this is a star gift message + if message.service == MessageServiceType.STAR_GIFT: + print(f"Received a Star Gift!") + print(f"Message ID: {message.id}") + print(f"From: {message.from_user.first_name if message.from_user else 'Anonymous'}") + print(f"Date: {message.date}") + + # You can access the raw action for more details + # The raw action contains: gift, name_hidden, saved, converted, etc. + + elif message.service == MessageServiceType.STAR_GIFT_UNIQUE: + print(f"Received a Unique/Collectible Star Gift!") + print(f"Message ID: {message.id}") + print(f"This is a special collectible gift that can be traded as NFT") + + elif message.service == MessageServiceType.NEW_CREATOR_PENDING: + print(f"Creator transfer is pending!") + print(f"A new creator has been nominated for this channel/group") + + elif message.service == MessageServiceType.CHANGE_CREATOR: + print(f"Creator has been changed!") + print(f"The ownership of this channel/group has been transferred") + + + @app.on_message(filters.service) + async def log_all_service_types(client, message): + """Log all service message types for debugging.""" + if message.service: + print(f"Service message type: {message.service}") + + + app.run() + + +Using StarGift and StarGiftUnique Types +--------------------------------------- + +The high-level ``StarGift`` and ``StarGiftUnique`` types provide easy access to gift properties: + +.. code-block:: python + + from pyrogram.types import StarGift, StarGiftUnique + + # StarGift properties: + # - id: Unique identifier of the gift + # - sticker: Sticker representing the gift + # - stars: Price in Telegram Stars + # - convert_stars: Stars the receiver can convert to + # - limited: Whether it's a limited-supply gift + # - sold_out: Whether the gift sold out + # - birthday: Whether it's a birthday-themed gift + # - can_upgrade: Whether it can be upgraded to collectible + # - availability_remains: Remaining gifts (for limited) + # - availability_total: Total supply (for limited) + + # StarGiftUnique properties (collectible gifts): + # - id: Unique identifier + # - gift_id: Base gift type ID + # - title: Collectible title + # - slug: For creating deep links + # - num: Unique number among collectibles of same type + # - burned: Whether the gift was burned + # - crafted: Whether it was crafted + # - owner_id: User ID of owner + # - owner_address: TON blockchain address + # - gift_address: NFT address on blockchain + + +Filtering Star Gift Messages +---------------------------- + +You can create a custom filter for star gift messages: + +.. code-block:: python + + from pyrogram import Client, filters + from pyrogram.enums import MessageServiceType + + # Custom filter for star gifts + star_gift_filter = filters.create( + lambda _, __, m: m.service in ( + MessageServiceType.STAR_GIFT, + MessageServiceType.STAR_GIFT_UNIQUE + ) + ) + + app = Client("my_account") + + + @app.on_message(star_gift_filter) + async def on_star_gift(client, message): + """Handle only star gift messages.""" + if message.service == MessageServiceType.STAR_GIFT: + await message.reply("Thank you for the star gift! ⭐") + else: + await message.reply("Wow, a unique collectible gift! 🎁") + + + app.run() diff --git a/docs/source/start/examples/streaming_text.rst b/docs/source/start/examples/streaming_text.rst new file mode 100644 index 00000000..37fd10d0 --- /dev/null +++ b/docs/source/start/examples/streaming_text.rst @@ -0,0 +1,33 @@ +Streaming replies +================= +Telegram bots can now keep independent threaded conversations so AI assistants handle multiple topics in parallel. While an answer is being generated you can stream intermediate text, letting Telegram display the native “Thinking…” chip exactly like the official AI bot experience. + +See the official announcement_ for a quick overview. You can pass either a single string or a list of strings to ``send_streaming_text``—each string becomes one chunk in the typing stream. + +.. _announcement: https://telegram.org/blog/comments-in-video-chats-threads-for-bots/it?setln=en#threads-and-streaming-responses-for-ai-bots + +.. code-block:: python + :caption: streaming_text.py + + from pyrogram import Client, filters + + app = Client("streaming-example") + + @app.on_message(filters.command("ai")) + async def stream_reply(client, message): + streaming_chunks = [ + "Hello! Let me think…", + "OK, I see what you need…", + "Working out the details…", + "Here comes the final advice…" + ] + + await client.send_streaming_text( + chat_id=message.chat.id, + streaming_text=streaming_chunks, + message_thread_id=message.message_thread_id + ) + # Or, for a single status update: + # await client.send_streaming_text(chat_id=message.chat.id, streaming_text="Hello! Let me think…") + + app.run() diff --git a/docs/source/start/examples/styled_keyboards.rst b/docs/source/start/examples/styled_keyboards.rst new file mode 100644 index 00000000..2ed6500e --- /dev/null +++ b/docs/source/start/examples/styled_keyboards.rst @@ -0,0 +1,285 @@ +styled_keyboards +================ + +This example shows how to use the new KeyboardButtonStyle to create styled keyboard buttons with custom colors and icons. + +Available since Layer 224, keyboard buttons can now have custom styles including background colors (primary, danger, success) and custom emoji icons. This works for both ReplyKeyboardMarkup (regular keyboards) and InlineKeyboardMarkup (inline buttons). + +Reply Keyboard Examples +----------------------- + +.. code-block:: python + + from pyrogram import Client + from pyrogram.types import ( + ReplyKeyboardMarkup, + KeyboardButton, + KeyboardButtonStyle + ) + + # Create a client using your bot token + app = Client("my_bot", bot_token="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11") + + + async def main(): + async with app: + # Example 1: Button with primary (blue) background + await app.send_message( + "me", # Edit this + "Styled keyboard with primary button", + reply_markup=ReplyKeyboardMarkup( + [[ + KeyboardButton( + text="Primary Action", + style=KeyboardButtonStyle(bg_primary=True) + ) + ]], + resize_keyboard=True + ) + ) + + # Example 2: Button with danger (red) background + await app.send_message( + "me", # Edit this + "Styled keyboard with danger button", + reply_markup=ReplyKeyboardMarkup( + [[ + KeyboardButton( + text="Delete All", + style=KeyboardButtonStyle(bg_danger=True) + ) + ]], + resize_keyboard=True + ) + ) + + # Example 3: Button with success (green) background + await app.send_message( + "me", # Edit this + "Styled keyboard with success button", + reply_markup=ReplyKeyboardMarkup( + [[ + KeyboardButton( + text="Confirm", + style=KeyboardButtonStyle(bg_success=True) + ) + ]], + resize_keyboard=True + ) + ) + + # Example 4: Button with custom emoji icon + await app.send_message( + "me", # Edit this + "Styled keyboard with icon", + reply_markup=ReplyKeyboardMarkup( + [[ + KeyboardButton( + text="Settings", + style=KeyboardButtonStyle( + icon=5368324170671202286 # Custom emoji ID + ) + ) + ]], + resize_keyboard=True + ) + ) + + # Example 5: Mixed styles in one keyboard + await app.send_message( + "me", # Edit this + "Choose an action:", + reply_markup=ReplyKeyboardMarkup( + [ + [ + KeyboardButton( + text="Save", + style=KeyboardButtonStyle(bg_success=True) + ), + KeyboardButton( + text="Cancel", + style=KeyboardButtonStyle(bg_danger=True) + ) + ], + [ + KeyboardButton( + text="More Options", + style=KeyboardButtonStyle(bg_primary=True) + ) + ] + ], + resize_keyboard=True + ) + ) + + + app.run(main()) + +Inline Keyboard Examples +------------------------ + +.. code-block:: python + + from pyrogram import Client + from pyrogram.types import ( + InlineKeyboardMarkup, + InlineKeyboardButton, + KeyboardButtonStyle, + WebAppInfo, + LoginUrl + ) + + # Create a client using your bot token + app = Client("my_bot", bot_token="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11") + + + async def main(): + async with app: + # Example 1: Callback button with primary (blue) background + await app.send_message( + "me", # Edit this + "Callback button example:", + reply_markup=InlineKeyboardMarkup( + [[ + InlineKeyboardButton( + text="Click Me", + callback_data="clicked", + style=KeyboardButtonStyle(bg_primary=True) + ) + ]] + ) + ) + + # Example 2: URL button with danger (red) style + await app.send_message( + "me", # Edit this + "URL button example:", + reply_markup=InlineKeyboardMarkup( + [[ + InlineKeyboardButton( + text="Open Website", + url="https://example.com", + style=KeyboardButtonStyle(bg_danger=True) + ) + ]] + ) + ) + + # Example 3: Switch inline query button with success (green) style + await app.send_message( + "me", # Edit this + "Inline query buttons:", + reply_markup=InlineKeyboardMarkup( + [ + [ + InlineKeyboardButton( + text="Search in other chat", + switch_inline_query="search query", + style=KeyboardButtonStyle(bg_primary=True) + ) + ], + [ + InlineKeyboardButton( + text="Search here", + switch_inline_query_current_chat="search query", + style=KeyboardButtonStyle(bg_success=True) + ) + ] + ] + ) + ) + + # Example 4: User profile button with custom emoji icon + await app.send_message( + "me", # Edit this + "User profile button:", + reply_markup=InlineKeyboardMarkup( + [[ + InlineKeyboardButton( + text="View Profile", + user_id=123456789, # Replace with actual user ID + style=KeyboardButtonStyle( + icon=5368324170671202286 # Custom emoji ID + ) + ) + ]] + ) + ) + + # Example 5: WebApp button with primary style + await app.send_message( + "me", # Edit this + "WebApp button:", + reply_markup=InlineKeyboardMarkup( + [[ + InlineKeyboardButton( + text="Open WebApp", + web_app=WebAppInfo(url="https://example.com/webapp"), + style=KeyboardButtonStyle(bg_primary=True) + ) + ]] + ) + ) + + # Example 6: Login URL button with style + await app.send_message( + "me", # Edit this + "Login button:", + reply_markup=InlineKeyboardMarkup( + [[ + InlineKeyboardButton( + text="Login with Telegram", + login_url=LoginUrl( + url="https://example.com/login", + forward_text="Login to Example", + request_write_access=True + ), + style=KeyboardButtonStyle(bg_success=True) + ) + ]] + ) + ) + + # Example 7: All button types in one keyboard + await app.send_message( + "me", # Edit this + "Complete keyboard with all styled button types:", + reply_markup=InlineKeyboardMarkup( + [ + # Row 1: Callback buttons + [ + InlineKeyboardButton( + text="✅ Confirm", + callback_data="confirm", + style=KeyboardButtonStyle(bg_success=True) + ), + InlineKeyboardButton( + text="❌ Cancel", + callback_data="cancel", + style=KeyboardButtonStyle(bg_danger=True) + ) + ], + # Row 2: URL button + [ + InlineKeyboardButton( + text="🌐 Visit Website", + url="https://example.com", + style=KeyboardButtonStyle(bg_primary=True) + ) + ], + # Row 3: Inline query buttons + [ + InlineKeyboardButton( + text="🔍 Search", + switch_inline_query_current_chat="", + style=KeyboardButtonStyle( + icon=5368324170671202286 # Search emoji + ) + ) + ] + ] + ) + ) + + + app.run(main()) diff --git a/pyrogram/client.py b/pyrogram/client.py index 5c7f781e..68daa3fc 100644 --- a/pyrogram/client.py +++ b/pyrogram/client.py @@ -48,12 +48,12 @@ from pyrogram.errors import ( SessionPasswordNeeded, VolumeLocNotFound, ChannelPrivate, - BadRequest, + BadRequest, AuthBytesInvalid, - FloodWait, + FloodWait, FloodPremiumWait, - ChannelInvalid, - PersistentTimestampInvalid, + ChannelInvalid, + PersistentTimestampInvalid, PersistentTimestampOutdated ) from pyrogram.handlers.handler import Handler @@ -330,7 +330,7 @@ def __init__( self.updates_watchdog_event = asyncio.Event() self.last_update_time = datetime.now() - self.loop = asyncio.get_event_loop() + self.loop = None self.config_file = config_file def __enter__(self): @@ -1359,4 +1359,4 @@ def __setitem__(self, key, value): if len(self.store) > self.capacity: for _ in range(self.capacity // 2 + 1): - del self.store[next(iter(self.store))] \ No newline at end of file + del self.store[next(iter(self.store))] diff --git a/pyrogram/dispatcher.py b/pyrogram/dispatcher.py index e9174b69..1354abc9 100644 --- a/pyrogram/dispatcher.py +++ b/pyrogram/dispatcher.py @@ -55,7 +55,7 @@ class Dispatcher: def __init__(self, client: "pyrogram.Client"): self.client = client - self.loop = asyncio.get_event_loop() + self.loop = None self.handler_worker_tasks = [] self.locks_list = [] @@ -144,12 +144,19 @@ async def chat_join_request_parser(update, users, chats): async def start(self): if not self.client.no_updates: + loop = asyncio.get_running_loop() + self.loop = loop + for i in range(self.client.workers): self.locks_list.append(asyncio.Lock()) - self.handler_worker_tasks.append( - self.loop.create_task(self.handler_worker(self.locks_list[-1])) - ) + task = loop.create_task(self.handler_worker(self.locks_list[-1])) + + # Avoid noisy \"Task was destroyed but it is pending\" warnings when the loop exits abruptly. + if hasattr(task, "_log_destroy_pending"): + task._log_destroy_pending = False + + self.handler_worker_tasks.append(task) log.info("Started %s HandlerTasks", self.client.workers) @@ -169,7 +176,17 @@ async def stop(self): log.info("Stopped %s HandlerTasks", self.client.workers) + self.loop = None + def add_handler(self, handler, group: int): + if self.loop is None or not self.handler_worker_tasks: + if group not in self.groups: + self.groups[group] = [] + self.groups = OrderedDict(sorted(self.groups.items())) + + self.groups[group].append(handler) + return + async def fn(): for lock in self.locks_list: await lock.acquire() @@ -187,6 +204,13 @@ async def fn(): self.loop.create_task(fn()) def remove_handler(self, handler, group: int): + if self.loop is None or not self.handler_worker_tasks: + if group not in self.groups: + raise ValueError(f"Group {group} does not exist. Handler was not removed.") + + self.groups[group].remove(handler) + return + async def fn(): for lock in self.locks_list: await lock.acquire() diff --git a/pyrogram/enums/chat_action.py b/pyrogram/enums/chat_action.py index 167937e0..4a49aa78 100644 --- a/pyrogram/enums/chat_action.py +++ b/pyrogram/enums/chat_action.py @@ -68,5 +68,14 @@ class ChatAction(AutoName): CHOOSE_STICKER = raw.types.SendMessageChooseStickerAction "Choosing sticker" + EMOJI_INTERACTION = raw.types.SendMessageEmojiInteraction + "Playing emoji interaction" + + EMOJI_INTERACTION_SEEN = raw.types.SendMessageEmojiInteractionSeen + "Emoji interaction seen" + + TEXT_DRAFT = raw.types.SendMessageTextDraftAction + "Streaming text draft" + CANCEL = raw.types.SendMessageCancelAction "Cancel ongoing chat action" diff --git a/pyrogram/enums/message_service_type.py b/pyrogram/enums/message_service_type.py index 8a60e29e..f5d7792b 100644 --- a/pyrogram/enums/message_service_type.py +++ b/pyrogram/enums/message_service_type.py @@ -71,3 +71,15 @@ class MessageServiceType(AutoName): WEB_APP_DATA = auto() "Web app data" + + STAR_GIFT = auto() + "Star gift received" + + STAR_GIFT_UNIQUE = auto() + "Unique/collectible star gift" + + NEW_CREATOR_PENDING = auto() + "New creator transfer pending" + + CHANGE_CREATOR = auto() + "Creator changed" diff --git a/pyrogram/methods/advanced/invoke.py b/pyrogram/methods/advanced/invoke.py index 0af771ad..652e0d4f 100644 --- a/pyrogram/methods/advanced/invoke.py +++ b/pyrogram/methods/advanced/invoke.py @@ -17,6 +17,7 @@ # along with Pyrogram. If not, see . import logging +from typing import TypeVar, overload import pyrogram from pyrogram import raw @@ -25,11 +26,13 @@ log = logging.getLogger(__name__) +ReturnType = TypeVar('ReturnType') + class Invoke: async def invoke( self: "pyrogram.Client", - query: TLObject, + query: TLObject[ReturnType], retries: int = Session.MAX_RETRIES, timeout: float = Session.WAIT_TIMEOUT, sleep_threshold: float = None diff --git a/pyrogram/methods/auth/initialize.py b/pyrogram/methods/auth/initialize.py index 7188b668..a0b9cad0 100644 --- a/pyrogram/methods/auth/initialize.py +++ b/pyrogram/methods/auth/initialize.py @@ -49,4 +49,7 @@ async def initialize( self.updates_watchdog_task = asyncio.create_task(self.updates_watchdog()) + if hasattr(self.updates_watchdog_task, "_log_destroy_pending"): + self.updates_watchdog_task._log_destroy_pending = False + self.is_initialized = True diff --git a/pyrogram/methods/bots/__init__.py b/pyrogram/methods/bots/__init__.py index da52fcfb..3630ef86 100644 --- a/pyrogram/methods/bots/__init__.py +++ b/pyrogram/methods/bots/__init__.py @@ -28,6 +28,7 @@ from .request_callback_answer import RequestCallbackAnswer from .send_game import SendGame from .send_inline_bot_result import SendInlineBotResult +from .send_streaming_text import SendStreamingText from .set_bot_commands import SetBotCommands from .set_bot_default_privileges import SetBotDefaultPrivileges from .set_chat_menu_button import SetChatMenuButton @@ -50,6 +51,7 @@ class Bots( GetBotDefaultPrivileges, SetChatMenuButton, GetChatMenuButton, - AnswerWebAppQuery + AnswerWebAppQuery, + SendStreamingText ): pass diff --git a/pyrogram/methods/bots/send_streaming_text.py b/pyrogram/methods/bots/send_streaming_text.py new file mode 100644 index 00000000..054bf7fe --- /dev/null +++ b/pyrogram/methods/bots/send_streaming_text.py @@ -0,0 +1,162 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present Dan +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . + +import asyncio +from typing import List +from typing import Optional +from typing import Sequence +from typing import Union + +import pyrogram +from pyrogram import enums +from pyrogram import raw +from pyrogram import types +from pyrogram import utils + + +class SendStreamingText: + async def send_streaming_text( + self: "pyrogram.Client", + chat_id: Union[int, str], + streaming_text: Union[str, Sequence[str]], + delay: float = 2.0, + parse_mode: Optional["enums.ParseMode"] = None, + entities: Optional[List["types.MessageEntity"]] = None, + reply_to_message_id: Optional[int] = None, + message_thread_id: Optional[int] = None, + ) -> bool: + """Send a sequence of live *thinking/streaming text*. + + .. include:: /_includes/usable-by/bots.rst + + Telegram clients display the native **“Thinking…”** status while these updates are streamed, + just like the official AI bot experience. + + This method uses the low-level + :obj:`~pyrogram.raw.functions.messages.SetTyping` method with + :obj:`~pyrogram.raw.types.SendMessageTextDraftAction` to send + **thinking / streaming text generation** updates to the recipient. + + Parameters: + chat_id (``int`` | ``str``): + Unique identifier (int) or username (str) of the target chat. + + streaming_text (``str`` | Sequence of ``str``): + Text or text chunks to send as streaming “thinking” updates. + When a single string is passed, it is sent as one update. + + delay (``float``, *optional*): + Delay (in seconds) between successive streaming updates. Defaults to 2.0. + + parse_mode (:obj:`~pyrogram.enums.ParseMode`, *optional*): + Mode for parsing entities if they are used inside the streaming text (rare). + + entities (List of :obj:`~pyrogram.types.MessageEntity`, *optional*): + Special entities that appear in the streaming text entries. + + reply_to_message_id (``int``, *optional*): + ID of the original message to reply to. + + message_thread_id (``int``, *optional*): + Forum topic ID. Required for threaded replies in forum chats. + + Returns: + ``bool``: The result of the last streamed typing update. + + Example: + .. code-block:: python + + # Send a thinking stream + await app.send_streaming_text( + message.chat.id, + streaming_text=[ + "Hello! Let me think…", + "OK, I see what you need…", + "Working out the details…", + "Here comes the final advice…" + ], + message_thread_id=message.message_thread_id, + delay=2.0 + ) + + # Single chunk variant + await app.send_streaming_text( + message.chat.id, + streaming_text="Hello! Let me think…", + message_thread_id=message.message_thread_id + ) + """ + + if isinstance(streaming_text, str): + chunks = [streaming_text] + else: + chunks = list(streaming_text) + + if not chunks: + return False + + should_parse_entities = bool(parse_mode or entities) + parsed_chunks = [] + + for chunk in chunks: + if not isinstance(chunk, str): + raise TypeError("Each streaming_text entry must be a string.") + + if should_parse_entities: + parsed = await utils.parse_text_entities( + self, + chunk, + parse_mode, + entities + ) + + message_text = parsed["message"] + message_entities = parsed["entities"] or [] + else: + message_text = chunk + message_entities = [] + + parsed_chunks.append((message_text, message_entities)) + + peer = await self.resolve_peer(chat_id) + reply_to = utils.get_reply_head_fm(message_thread_id, reply_to_message_id) + top_msg_id = reply_to.top_msg_id if reply_to else message_thread_id + typing_random_id = self.rnd_id() + + result = False + total_chunks = len(parsed_chunks) + + for idx, (text, text_entities) in enumerate(parsed_chunks, start=1): + result = await self.invoke( + raw.functions.messages.SetTyping( + peer=peer, + action=raw.types.SendMessageTextDraftAction( + random_id=typing_random_id, + text=raw.types.TextWithEntities( + text=text, + entities=text_entities + ) + ), + top_msg_id=top_msg_id + ) + ) + + if idx != total_chunks and delay and delay > 0: + await asyncio.sleep(delay) + + return result diff --git a/pyrogram/methods/messages/send_message.py b/pyrogram/methods/messages/send_message.py index 370d5df9..97ac0d16 100644 --- a/pyrogram/methods/messages/send_message.py +++ b/pyrogram/methods/messages/send_message.py @@ -169,6 +169,9 @@ async def send_message( date=utils.timestamp_to_datetime(r.date), outgoing=r.out, reply_markup=reply_markup, + reply_to_message_id=reply_to_message_id, + reply_to_top_message_id=message_thread_id, + message_thread_id=message_thread_id, entities=[ types.MessageEntity._parse(None, entity, {}) for entity in entities diff --git a/pyrogram/methods/messages/send_reaction.py b/pyrogram/methods/messages/send_reaction.py index 5f5690f5..e63bdf8e 100644 --- a/pyrogram/methods/messages/send_reaction.py +++ b/pyrogram/methods/messages/send_reaction.py @@ -66,22 +66,24 @@ async def send_reaction( # Retract a reaction await app.send_reaction(chat_id, message_id=message_id) """ - if isinstance(emoji, list): - emoji = [ + if not emoji: + reaction = None + elif isinstance(emoji, list): + reaction = [ raw.types.ReactionCustomEmoji(document_id=i) if isinstance(i, int) else raw.types.ReactionEmoji(emoticon=i) for i in emoji ] else: - emoji = [raw.types.ReactionEmoji(emoticon=emoji)] if emoji else [] + reaction = [raw.types.ReactionEmoji(emoticon=emoji)] if message_id is not None: await self.invoke( raw.functions.messages.SendReaction( peer=await self.resolve_peer(chat_id), msg_id=message_id, - reaction=emoji, + reaction=reaction, big=big ) ) diff --git a/pyrogram/methods/utilities/start.py b/pyrogram/methods/utilities/start.py index d8314da1..0904da35 100644 --- a/pyrogram/methods/utilities/start.py +++ b/pyrogram/methods/utilities/start.py @@ -16,6 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . +import asyncio import logging import pyrogram @@ -55,6 +56,8 @@ async def main(): app.run(main()) """ + self.loop = asyncio.get_running_loop() + is_authorized = await self.connect() try: diff --git a/pyrogram/methods/utilities/stop.py b/pyrogram/methods/utilities/stop.py index 1b28add0..3b04007f 100644 --- a/pyrogram/methods/utilities/stop.py +++ b/pyrogram/methods/utilities/stop.py @@ -16,6 +16,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . +import asyncio + import pyrogram @@ -60,10 +62,12 @@ async def main(): async def do_it(): await self.terminate() await self.disconnect() + self.loop = None if block: await do_it() else: - self.loop.create_task(do_it()) + loop = self.loop or asyncio.get_running_loop() + loop.create_task(do_it()) return self diff --git a/pyrogram/raw/core/tl_object.py b/pyrogram/raw/core/tl_object.py index ff67566e..dbfb70d8 100644 --- a/pyrogram/raw/core/tl_object.py +++ b/pyrogram/raw/core/tl_object.py @@ -18,12 +18,14 @@ from io import BytesIO from json import dumps -from typing import cast, List, Any, Union, Dict +from typing import cast, List, Any, Union, Dict, TypeVar, Generic from ..all import objects +ReturnType = TypeVar("ReturnType") -class TLObject: + +class TLObject(Generic[ReturnType]): __slots__: List[str] = [] QUALNAME = "Base" @@ -78,5 +80,5 @@ def __eq__(self, other: Any) -> bool: def __len__(self) -> int: return len(self.write()) - def __call__(self, *args: Any, **kwargs: Any) -> Any: + def __call__(self, *args: Any, **kwargs: Any) -> ReturnType: pass diff --git a/pyrogram/session/session.py b/pyrogram/session/session.py index bd02897a..06a3de1b 100644 --- a/pyrogram/session/session.py +++ b/pyrogram/session/session.py @@ -102,9 +102,11 @@ def __init__( self.is_started = asyncio.Event() - self.loop = asyncio.get_event_loop() + self.loop = None async def start(self): + self.loop = asyncio.get_running_loop() + while True: self.connection = self.client.connection_factory( dc_id=self.dc_id, @@ -120,6 +122,9 @@ async def start(self): self.recv_task = self.loop.create_task(self.recv_worker()) + if hasattr(self.recv_task, "_log_destroy_pending"): + self.recv_task._log_destroy_pending = False + await self.send(raw.functions.Ping(ping_id=0), timeout=self.START_TIMEOUT) if not self.is_cdn: @@ -142,6 +147,9 @@ async def start(self): self.ping_task = self.loop.create_task(self.ping_worker()) + if hasattr(self.ping_task, "_log_destroy_pending"): + self.ping_task._log_destroy_pending = False + log.info("Session initialized: Layer %s", layer) log.info("Device: %s - %s", self.client.device_model, self.client.app_version) log.info("System: %s (%s)", self.client.system_version, self.client.lang_code) @@ -185,6 +193,8 @@ async def stop(self): log.info("Session stopped") + self.loop = None + async def restart(self): now = datetime.now() if ( @@ -199,7 +209,9 @@ async def restart(self): async def handle_packet(self, packet): try: - data = await self.loop.run_in_executor( + loop = self.loop or asyncio.get_running_loop() + + data = await loop.run_in_executor( pyrogram.crypto_executor, mtproto.unpack, BytesIO(packet), @@ -209,7 +221,11 @@ async def handle_packet(self, packet): ) except ValueError as e: log.debug(e) - self.loop.create_task(self.restart()) + loop = self.loop or asyncio.get_running_loop() + restart_task = loop.create_task(self.restart()) + + if hasattr(restart_task, "_log_destroy_pending"): + restart_task._log_destroy_pending = False return messages = ( @@ -271,7 +287,10 @@ async def handle_packet(self, packet): msg_id = msg.body.msg_id else: if self.client is not None: - self.loop.create_task(self.client.handle_updates(msg.body)) + update_task = self.loop.create_task(self.client.handle_updates(msg.body)) + + if hasattr(update_task, "_log_destroy_pending"): + update_task._log_destroy_pending = False if msg_id in self.results: self.results[msg_id].value = getattr(msg.body, "result", msg.body) @@ -305,7 +324,10 @@ async def ping_worker(self): ), False ) except OSError: - self.loop.create_task(self.restart()) + restart_task = self.loop.create_task(self.restart()) + + if hasattr(restart_task, "_log_destroy_pending"): + restart_task._log_destroy_pending = False break except RPCError: pass @@ -334,11 +356,17 @@ async def recv_worker(self): ) if self.is_started.is_set(): - self.loop.create_task(self.restart()) + restart_task = self.loop.create_task(self.restart()) + + if hasattr(restart_task, "_log_destroy_pending"): + restart_task._log_destroy_pending = False break - self.loop.create_task(self.handle_packet(packet)) + packet_task = self.loop.create_task(self.handle_packet(packet)) + + if hasattr(packet_task, "_log_destroy_pending"): + packet_task._log_destroy_pending = False log.info("NetworkTask stopped") @@ -351,7 +379,9 @@ async def send(self, data: TLObject, wait_response: bool = True, timeout: float log.debug("Sent: %s", message) - payload = await self.loop.run_in_executor( + loop = self.loop or asyncio.get_running_loop() + + payload = await loop.run_in_executor( pyrogram.crypto_executor, mtproto.pack, message, diff --git a/pyrogram/sync.py b/pyrogram/sync.py index 94c82a3d..47df5db9 100644 --- a/pyrogram/sync.py +++ b/pyrogram/sync.py @@ -26,9 +26,27 @@ from pyrogram.methods.utilities import idle as idle_module, compose as compose_module +def _ensure_event_loop(): + """ + Python 3.14 no longer creates an implicit event loop for the main thread. + Reproduce the old behaviour by instantiating and setting one on-demand. + """ + try: + return asyncio.get_running_loop() + except RuntimeError: + pass + + try: + return asyncio.get_event_loop() + except RuntimeError: + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + return loop + + def async_to_sync(obj, name): function = getattr(obj, name) - main_loop = asyncio.get_event_loop() + main_loop = _ensure_event_loop() def async_to_sync_gen(agen, loop, is_main_thread): async def anext(agen): diff --git a/pyrogram/types/bots_and_keyboards/__init__.py b/pyrogram/types/bots_and_keyboards/__init__.py index 6f05a3b4..a9a22758 100644 --- a/pyrogram/types/bots_and_keyboards/__init__.py +++ b/pyrogram/types/bots_and_keyboards/__init__.py @@ -32,6 +32,7 @@ from .inline_keyboard_button import InlineKeyboardButton from .inline_keyboard_markup import InlineKeyboardMarkup from .keyboard_button import KeyboardButton +from .keyboard_button_style import KeyboardButtonStyle from .login_url import LoginUrl from .menu_button import MenuButton from .menu_button_commands import MenuButtonCommands @@ -50,6 +51,7 @@ "InlineKeyboardButton", "InlineKeyboardMarkup", "KeyboardButton", + "KeyboardButtonStyle", "ReplyKeyboardMarkup", "ReplyKeyboardRemove", "LoginUrl", diff --git a/pyrogram/types/bots_and_keyboards/inline_keyboard_button.py b/pyrogram/types/bots_and_keyboards/inline_keyboard_button.py index a1d8a7ad..fa40a896 100644 --- a/pyrogram/types/bots_and_keyboards/inline_keyboard_button.py +++ b/pyrogram/types/bots_and_keyboards/inline_keyboard_button.py @@ -69,6 +69,9 @@ class InlineKeyboardButton(Object): callback_game (:obj:`~pyrogram.types.CallbackGame`, *optional*): Description of the game that will be launched when the user presses the button. **NOTE**: This type of button **must** always be the first button in the first row. + + style (:obj:`~pyrogram.types.KeyboardButtonStyle`, *optional*): + Style configuration for the button (background color, icon). """ def __init__( @@ -81,7 +84,8 @@ def __init__( user_id: int = None, switch_inline_query: str = None, switch_inline_query_current_chat: str = None, - callback_game: "types.CallbackGame" = None + callback_game: "types.CallbackGame" = None, + style: "types.KeyboardButtonStyle" = None ): super().__init__() @@ -94,10 +98,13 @@ def __init__( self.switch_inline_query = switch_inline_query self.switch_inline_query_current_chat = switch_inline_query_current_chat self.callback_game = callback_game + self.style = style # self.pay = pay @staticmethod def read(b: "raw.base.KeyboardButton"): + style = types.KeyboardButtonStyle.read(getattr(b, "style", None)) + if isinstance(b, raw.types.KeyboardButtonCallback): # Try decode data to keep it as string, but if fails, fallback to bytes so we don't lose any information, # instead of decoding by ignoring/replacing errors. @@ -108,43 +115,50 @@ def read(b: "raw.base.KeyboardButton"): return InlineKeyboardButton( text=b.text, - callback_data=data + callback_data=data, + style=style ) if isinstance(b, raw.types.KeyboardButtonUrl): return InlineKeyboardButton( text=b.text, - url=b.url + url=b.url, + style=style ) if isinstance(b, raw.types.KeyboardButtonUrlAuth): return InlineKeyboardButton( text=b.text, - login_url=types.LoginUrl.read(b) + login_url=types.LoginUrl.read(b), + style=style ) if isinstance(b, raw.types.KeyboardButtonUserProfile): return InlineKeyboardButton( text=b.text, - user_id=b.user_id + user_id=b.user_id, + style=style ) if isinstance(b, raw.types.KeyboardButtonSwitchInline): if b.same_peer: return InlineKeyboardButton( text=b.text, - switch_inline_query_current_chat=b.query + switch_inline_query_current_chat=b.query, + style=style ) else: return InlineKeyboardButton( text=b.text, - switch_inline_query=b.query + switch_inline_query=b.query, + style=style ) if isinstance(b, raw.types.KeyboardButtonGame): return InlineKeyboardButton( text=b.text, - callback_game=types.CallbackGame() + callback_game=types.CallbackGame(), + style=style ) if isinstance(b, raw.types.KeyboardButtonWebView): @@ -152,57 +166,68 @@ def read(b: "raw.base.KeyboardButton"): text=b.text, web_app=types.WebAppInfo( url=b.url - ) + ), + style=style ) async def write(self, client: "pyrogram.Client"): + style = self.style.write() if self.style else None + if self.callback_data is not None: # Telegram only wants bytes, but we are allowed to pass strings too, for convenience. data = bytes(self.callback_data, "utf-8") if isinstance(self.callback_data, str) else self.callback_data return raw.types.KeyboardButtonCallback( text=self.text, - data=data + data=data, + style=style ) if self.url is not None: return raw.types.KeyboardButtonUrl( text=self.text, - url=self.url + url=self.url, + style=style ) if self.login_url is not None: return self.login_url.write( text=self.text, - bot=await client.resolve_peer(self.login_url.bot_username or "self") + bot=await client.resolve_peer(self.login_url.bot_username or "self"), + style=style ) if self.user_id is not None: return raw.types.InputKeyboardButtonUserProfile( text=self.text, - user_id=await client.resolve_peer(self.user_id) + input_user=await client.resolve_peer(self.user_id), + style=style ) if self.switch_inline_query is not None: return raw.types.KeyboardButtonSwitchInline( text=self.text, - query=self.switch_inline_query + query=self.switch_inline_query, + style=style ) if self.switch_inline_query_current_chat is not None: return raw.types.KeyboardButtonSwitchInline( text=self.text, query=self.switch_inline_query_current_chat, - same_peer=True + same_peer=True, + style=style ) if self.callback_game is not None: return raw.types.KeyboardButtonGame( - text=self.text + text=self.text, + style=style ) if self.web_app is not None: return raw.types.KeyboardButtonWebView( text=self.text, - url=self.web_app.url + url=self.web_app.url, + style=style ) diff --git a/pyrogram/types/bots_and_keyboards/keyboard_button.py b/pyrogram/types/bots_and_keyboards/keyboard_button.py index 5c8d4b73..e89c6b2f 100644 --- a/pyrogram/types/bots_and_keyboards/keyboard_button.py +++ b/pyrogram/types/bots_and_keyboards/keyboard_button.py @@ -40,9 +40,12 @@ class KeyboardButton(Object): web_app (:obj:`~pyrogram.types.WebAppInfo`, *optional*): If specified, the described `Web App `_ will be launched when the - button is pressed. The Web App will be able to send a “web_app_data” service message. Available in private + button is pressed. The Web App will be able to send a "web_app_data" service message. Available in private chats only. + style (:obj:`~pyrogram.types.KeyboardButtonStyle`, *optional*): + Style configuration for the button (background color, icon). + """ def __init__( @@ -50,7 +53,8 @@ def __init__( text: str, request_contact: bool = None, request_location: bool = None, - web_app: "types.WebAppInfo" = None + web_app: "types.WebAppInfo" = None, + style: "types.KeyboardButtonStyle" = None ): super().__init__() @@ -58,22 +62,29 @@ def __init__( self.request_contact = request_contact self.request_location = request_location self.web_app = web_app + self.style = style @staticmethod def read(b): + style = types.KeyboardButtonStyle.read(getattr(b, "style", None)) + if isinstance(b, raw.types.KeyboardButton): + if style: + return KeyboardButton(text=b.text, style=style) return b.text if isinstance(b, raw.types.KeyboardButtonRequestPhone): return KeyboardButton( text=b.text, - request_contact=True + request_contact=True, + style=style ) if isinstance(b, raw.types.KeyboardButtonRequestGeoLocation): return KeyboardButton( text=b.text, - request_location=True + request_location=True, + style=style ) if isinstance(b, raw.types.KeyboardButtonSimpleWebView): @@ -81,15 +92,18 @@ def read(b): text=b.text, web_app=types.WebAppInfo( url=b.url - ) + ), + style=style ) def write(self): + style = self.style.write() if self.style else None + if self.request_contact: - return raw.types.KeyboardButtonRequestPhone(text=self.text) + return raw.types.KeyboardButtonRequestPhone(text=self.text, style=style) elif self.request_location: - return raw.types.KeyboardButtonRequestGeoLocation(text=self.text) + return raw.types.KeyboardButtonRequestGeoLocation(text=self.text, style=style) elif self.web_app: - return raw.types.KeyboardButtonSimpleWebView(text=self.text, url=self.web_app.url) + return raw.types.KeyboardButtonSimpleWebView(text=self.text, url=self.web_app.url, style=style) else: - return raw.types.KeyboardButton(text=self.text) + return raw.types.KeyboardButton(text=self.text, style=style) diff --git a/pyrogram/types/bots_and_keyboards/keyboard_button_style.py b/pyrogram/types/bots_and_keyboards/keyboard_button_style.py new file mode 100644 index 00000000..06066d0e --- /dev/null +++ b/pyrogram/types/bots_and_keyboards/keyboard_button_style.py @@ -0,0 +1,73 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present Dan +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . + +from pyrogram import raw +from ..object import Object + + +class KeyboardButtonStyle(Object): + """Style configuration for keyboard buttons. + + Parameters: + bg_primary (``bool``, *optional*): + Use primary background color for the button. + + bg_danger (``bool``, *optional*): + Use danger/red background color for the button. + + bg_success (``bool``, *optional*): + Use success/green background color for the button. + + icon (``int``, *optional*): + Custom emoji ID to use as button icon. + """ + + def __init__( + self, + *, + bg_primary: bool = None, + bg_danger: bool = None, + bg_success: bool = None, + icon: int = None + ): + super().__init__() + + self.bg_primary = bg_primary + self.bg_danger = bg_danger + self.bg_success = bg_success + self.icon = icon + + @staticmethod + def read(style: "raw.types.KeyboardButtonStyle") -> "KeyboardButtonStyle": + if style is None: + return None + + return KeyboardButtonStyle( + bg_primary=style.bg_primary or None, + bg_danger=style.bg_danger or None, + bg_success=style.bg_success or None, + icon=style.icon + ) + + def write(self) -> "raw.types.KeyboardButtonStyle": + return raw.types.KeyboardButtonStyle( + bg_primary=self.bg_primary, + bg_danger=self.bg_danger, + bg_success=self.bg_success, + icon=self.icon + ) diff --git a/pyrogram/types/bots_and_keyboards/login_url.py b/pyrogram/types/bots_and_keyboards/login_url.py index a0af5a1a..2cec2055 100644 --- a/pyrogram/types/bots_and_keyboards/login_url.py +++ b/pyrogram/types/bots_and_keyboards/login_url.py @@ -49,7 +49,7 @@ class LoginUrl(Object): See `Linking your domain to the bot `_ for more details. - request_write_access (``str``, *optional*): + request_write_access (``bool``, *optional*): Pass True to request the permission for your bot to send messages to the user. button_id (``int``): @@ -61,7 +61,7 @@ def __init__( url: str, forward_text: str = None, bot_username: str = None, - request_write_access: str = None, + request_write_access: bool = None, button_id: int = None ): super().__init__() @@ -80,11 +80,12 @@ def read(b: "raw.types.KeyboardButtonUrlAuth") -> "LoginUrl": button_id=b.button_id ) - def write(self, text: str, bot: "raw.types.InputUser"): + def write(self, text: str, bot: "raw.types.InputUser", style: "raw.types.KeyboardButtonStyle" = None): return raw.types.InputKeyboardButtonUrlAuth( text=text, url=self.url, bot=bot, fwd_text=self.forward_text, - request_write_access=self.request_write_access + request_write_access=self.request_write_access, + style=style ) diff --git a/pyrogram/types/messages_and_media/__init__.py b/pyrogram/types/messages_and_media/__init__.py index f4da93aa..f03feb7e 100644 --- a/pyrogram/types/messages_and_media/__init__.py +++ b/pyrogram/types/messages_and_media/__init__.py @@ -42,9 +42,10 @@ from .web_app_data import WebAppData from .web_page import WebPage from .message_reactions import MessageReactions +from .star_gift import StarGift, StarGiftUnique __all__ = [ "Animation", "Audio", "Contact", "Document", "Game", "Location", "Message", "MessageEntity", "Photo", "Thumbnail", "StrippedThumbnail", "Poll", "PollOption", "Sticker", "Venue", "Video", "VideoNote", "Voice", "WebPage", "Dice", - "Reaction", "WebAppData", "MessageReactions", "Story", "Giveaway", "AlternativeVideo" + "Reaction", "WebAppData", "MessageReactions", "Story", "Giveaway", "AlternativeVideo", "StarGift", "StarGiftUnique" ] diff --git a/pyrogram/types/messages_and_media/message.py b/pyrogram/types/messages_and_media/message.py index e1e4f30a..b0e7a489 100644 --- a/pyrogram/types/messages_and_media/message.py +++ b/pyrogram/types/messages_and_media/message.py @@ -106,6 +106,9 @@ class Message(Object, Update): For replies, the original message. Note that the Message object in this field will not contain further reply_to_message fields even if it itself is a reply. + message_thread_id (``int``, *optional*): + Identifier of the forum topic this message belongs to, if any. + mentioned (``bool``, *optional*): The message contains a mention. @@ -334,6 +337,7 @@ def __init__( reply_to_message_id: int = None, reply_to_top_message_id: int = None, reply_to_message: "Message" = None, + message_thread_id: int = None, mentioned: bool = None, empty: bool = None, service: "enums.MessageServiceType" = None, @@ -390,6 +394,16 @@ def __init__( video_chat_ended: "types.VideoChatEnded" = None, video_chat_members_invited: "types.VideoChatMembersInvited" = None, web_app_data: "types.WebAppData" = None, + show_caption_above_media: bool = None, + silent: bool = None, + legacy: bool = None, + pinned: bool = None, + unread_media: bool = None, + from_offline: bool = None, + video_processing_pending: bool = None, + paid_suggested_post_stars: bool = None, + paid_suggested_post_ton: bool = None, + channel_post: bool = None, reply_markup: Union[ "types.InlineKeyboardMarkup", "types.ReplyKeyboardMarkup", @@ -415,6 +429,14 @@ def __init__( self.reply_to_message_id = reply_to_message_id self.reply_to_top_message_id = reply_to_top_message_id self.reply_to_message = reply_to_message + if message_thread_id is not None: + self.message_thread_id = message_thread_id + else: + self.message_thread_id = None + if reply_to_top_message_id is not None: + self.message_thread_id = reply_to_top_message_id + elif chat and getattr(chat, "is_forum", False): + self.message_thread_id = id self.mentioned = mentioned self.empty = empty self.service = service @@ -468,6 +490,16 @@ def __init__( self.matches = matches self.command = command self.reply_markup = reply_markup + self.show_caption_above_media = show_caption_above_media + self.silent = silent + self.legacy = legacy + self.pinned = pinned + self.unread_media = unread_media + self.from_offline = from_offline + self.video_processing_pending = video_processing_pending + self.paid_suggested_post_stars = paid_suggested_post_stars + self.paid_suggested_post_ton = paid_suggested_post_ton + self.channel_post = channel_post self.video_chat_scheduled = video_chat_scheduled self.video_chat_started = video_chat_started self.video_chat_ended = video_chat_ended @@ -573,6 +605,14 @@ async def _parse( elif isinstance(action, raw.types.MessageActionWebViewDataSentMe): web_app_data = types.WebAppData._parse(action) service_type = enums.MessageServiceType.WEB_APP_DATA + elif isinstance(action, raw.types.MessageActionStarGift): + service_type = enums.MessageServiceType.STAR_GIFT + elif isinstance(action, raw.types.MessageActionStarGiftUnique): + service_type = enums.MessageServiceType.STAR_GIFT_UNIQUE + elif isinstance(action, raw.types.MessageActionNewCreatorPending): + service_type = enums.MessageServiceType.NEW_CREATOR_PENDING + elif isinstance(action, raw.types.MessageActionChangeCreator): + service_type = enums.MessageServiceType.CHANGE_CREATOR from_user = types.User._parse(client, users.get(user_id, None)) sender_chat = types.Chat._parse(client, message, users, chats, is_chat=False) if not from_user else None @@ -797,13 +837,57 @@ async def _parse( from_user = types.User._parse(client, users.get(user_id, None)) sender_chat = types.Chat._parse(client, message, users, chats, is_chat=False) if not from_user else None + chat_obj = types.Chat._parse(client, message, users, chats, is_chat=True) + + reply_to_message_id = None + reply_to_top_message_id = None + reply_to_checklist_task_id = None + reply_to_story_id = None + reply_to_story_user_id = None + message_thread_id = None + topic_message = None + quote = None + + if message.reply_to: + if isinstance(message.reply_to, raw.types.MessageReplyHeader): + header = message.reply_to + reply_to_message_id = header.reply_to_msg_id + reply_to_top_message_id = header.reply_to_top_id + reply_to_checklist_task_id = header.todo_item_id + + if header.forum_topic: + topic_message = True + if header.reply_to_top_id: + message_thread_id = header.reply_to_top_id + elif header.reply_to_msg_id: + message_thread_id = header.reply_to_msg_id + else: + message_thread_id = 1 + if ( + header.reply_to_msg_id is not None and + header.reply_to_top_id is not None and + header.reply_to_msg_id == header.reply_to_top_id + ): + reply_to_message_id = None + elif header.reply_to_top_id: + message_thread_id = header.reply_to_top_id + + if header.quote: + quote = getattr(message.reply_to, "quote", None) + elif isinstance(message.reply_to, raw.types.MessageReplyStoryHeader): + reply_to_message_id = message.reply_to.story_id + reply_to_story_id = message.reply_to.story_id + reply_to_story_user_id = utils.get_peer_id(message.reply_to.peer) + + if reply_to_message_id is not None and getattr(chat_obj, "is_forum", False) and reply_to_top_message_id is None: + reply_to_top_message_id = 1 reactions = types.MessageReactions._parse(client, message.reactions) parsed_message = Message( id=message.id, date=utils.timestamp_to_datetime(message.date), - chat=types.Chat._parse(client, message, users, chats, is_chat=True), + chat=chat_obj, from_user=from_user, sender_chat=sender_chat, text=( @@ -864,35 +948,67 @@ async def _parse( forwards=message.forwards, via_bot=types.User._parse(client, users.get(message.via_bot_id, None)), outgoing=message.out, + show_caption_above_media=message.invert_media, + silent=message.silent, + legacy=message.legacy, + pinned=message.pinned, + unread_media=message.media_unread, + from_offline=message.offline, + video_processing_pending=message.video_processing_pending, + paid_suggested_post_stars=message.paid_suggested_post_stars, + paid_suggested_post_ton=message.paid_suggested_post_ton, + channel_post=message.post, reply_markup=reply_markup, reactions=reactions, client=client ) - if message.reply_to: - parsed_message.reply_to_message_id = None - parsed_message.reply_to_top_message_id = None - if isinstance(message.reply_to, raw.types.MessageReplyHeader): - parsed_message.reply_to_message_id = message.reply_to.reply_to_msg_id - parsed_message.reply_to_top_message_id = message.reply_to.reply_to_top_id - if isinstance(message.reply_to, raw.types.MessageReplyStoryHeader): - parsed_message.reply_to_message_id = message.reply_to.story_id + if reply_to_message_id is not None: + parsed_message.reply_to_message_id = reply_to_message_id - if replies: - try: - key = (parsed_message.chat.id, parsed_message.reply_to_message_id) - reply_to_message = client.message_cache[key] + if reply_to_top_message_id is not None: + parsed_message.reply_to_top_message_id = reply_to_top_message_id - if not reply_to_message: - reply_to_message = await client.get_messages( - parsed_message.chat.id, - reply_to_message_ids=message.id, - replies=replies - 1 - ) + if reply_to_checklist_task_id is not None: + parsed_message.reply_to_checklist_task_id = reply_to_checklist_task_id - parsed_message.reply_to_message = reply_to_message - except MessageIdsEmpty: - pass + if topic_message: + parsed_message.topic_message = True + + if quote is not None: + parsed_message.quote = quote + + if message_thread_id is not None: + parsed_message.message_thread_id = message_thread_id + + if reply_to_story_id is not None: + parsed_message.reply_to_story_id = reply_to_story_id + parsed_message.reply_to_story_user_id = reply_to_story_user_id + + if message.reply_to and replies and parsed_message.reply_to_message_id is not None: + try: + key = (parsed_message.chat.id, parsed_message.reply_to_message_id) + reply_to_message = client.message_cache[key] + + if not reply_to_message: + reply_to_message = await client.get_messages( + parsed_message.chat.id, + reply_to_message_ids=message.id, + replies=replies - 1 + ) + + parsed_message.reply_to_message = reply_to_message + except MessageIdsEmpty: + pass + + if getattr(parsed_message.chat, "is_forum", False): + if parsed_message.message_thread_id is None or parsed_message.message_thread_id == parsed_message.id: + if parsed_message.reply_to_top_message_id is not None: + parsed_message.message_thread_id = parsed_message.reply_to_top_message_id + elif getattr(parsed_message.reply_to_message, "message_thread_id", None) is not None: + parsed_message.message_thread_id = parsed_message.reply_to_message.message_thread_id + else: + parsed_message.message_thread_id = 1 if not parsed_message.poll: # Do not cache poll messages client.message_cache[(parsed_message.chat.id, parsed_message.id)] = parsed_message @@ -1031,6 +1147,7 @@ async def reply_text( disable_web_page_preview=disable_web_page_preview, disable_notification=disable_notification, reply_to_message_id=reply_to_message_id, + message_thread_id=self.message_thread_id, partial_reply=partial_reply, schedule_date=schedule_date, protect_content=protect_content, @@ -1183,6 +1300,7 @@ async def reply_animation( thumb=thumb, disable_notification=disable_notification, reply_to_message_id=reply_to_message_id, + message_thread_id=self.message_thread_id, partial_reply=partial_reply, reply_markup=reply_markup, progress=progress, @@ -1328,6 +1446,7 @@ async def reply_audio( thumb=thumb, disable_notification=disable_notification, reply_to_message_id=reply_to_message_id, + message_thread_id=self.message_thread_id, partial_reply=partial_reply, reply_markup=reply_markup, progress=progress, @@ -1422,6 +1541,7 @@ async def reply_cached_media( caption_entities=caption_entities, disable_notification=disable_notification, reply_to_message_id=reply_to_message_id, + message_thread_id=self.message_thread_id, partial_reply=partial_reply, reply_markup=reply_markup ) @@ -1550,6 +1670,7 @@ async def reply_contact( vcard=vcard, disable_notification=disable_notification, reply_to_message_id=reply_to_message_id, + message_thread_id=self.message_thread_id, partial_reply=partial_reply, reply_markup=reply_markup ) @@ -1695,6 +1816,7 @@ async def reply_document( force_document=force_document, disable_notification=disable_notification, reply_to_message_id=reply_to_message_id, + message_thread_id=self.message_thread_id, partial_reply=partial_reply, schedule_date=schedule_date, reply_markup=reply_markup, @@ -1768,6 +1890,7 @@ async def reply_game( game_short_name=game_short_name, disable_notification=disable_notification, reply_to_message_id=reply_to_message_id, + message_thread_id=self.message_thread_id, reply_markup=reply_markup ) @@ -1838,6 +1961,7 @@ async def reply_inline_bot_result( result_id=result_id, disable_notification=disable_notification, reply_to_message_id=reply_to_message_id, + message_thread_id=self.message_thread_id, partial_reply=partial_reply ) @@ -1918,6 +2042,7 @@ async def reply_location( longitude=longitude, disable_notification=disable_notification, reply_to_message_id=reply_to_message_id, + message_thread_id=self.message_thread_id, partial_reply=partial_reply, reply_markup=reply_markup ) @@ -1986,6 +2111,7 @@ async def reply_media_group( media=media, disable_notification=disable_notification, reply_to_message_id=reply_to_message_id, + message_thread_id=self.message_thread_id, partial_reply=partial_reply ) @@ -2117,6 +2243,7 @@ async def reply_photo( ttl_seconds=ttl_seconds, disable_notification=disable_notification, reply_to_message_id=reply_to_message_id, + message_thread_id=self.message_thread_id, partial_reply=partial_reply, reply_markup=reply_markup, progress=progress, @@ -2269,6 +2396,7 @@ async def reply_poll( disable_notification=disable_notification, protect_content=protect_content, reply_to_message_id=reply_to_message_id, + message_thread_id=self.message_thread_id, partial_reply=partial_reply, schedule_date=schedule_date, reply_markup=reply_markup @@ -2374,6 +2502,7 @@ async def reply_sticker( sticker=sticker, disable_notification=disable_notification, reply_to_message_id=reply_to_message_id, + message_thread_id=self.message_thread_id, partial_reply=partial_reply, reply_markup=reply_markup, progress=progress, @@ -2480,6 +2609,7 @@ async def reply_venue( foursquare_type=foursquare_type, disable_notification=disable_notification, reply_to_message_id=reply_to_message_id, + message_thread_id=self.message_thread_id, partial_reply=partial_reply, reply_markup=reply_markup ) @@ -2640,6 +2770,7 @@ async def reply_video( supports_streaming=supports_streaming, disable_notification=disable_notification, reply_to_message_id=reply_to_message_id, + message_thread_id=self.message_thread_id, partial_reply=partial_reply, reply_markup=reply_markup, progress=progress, @@ -2764,6 +2895,7 @@ async def reply_video_note( thumb=thumb, disable_notification=disable_notification, reply_to_message_id=reply_to_message_id, + message_thread_id=self.message_thread_id, partial_reply=partial_reply, reply_markup=reply_markup, progress=progress, @@ -2891,6 +3023,7 @@ async def reply_voice( duration=duration, disable_notification=disable_notification, reply_to_message_id=reply_to_message_id, + message_thread_id=self.message_thread_id, partial_reply=partial_reply, reply_markup=reply_markup, progress=progress, @@ -3237,6 +3370,7 @@ async def copy( disable_web_page_preview=not self.web_page, disable_notification=disable_notification, reply_to_message_id=reply_to_message_id, + message_thread_id=self.message_thread_id, schedule_date=schedule_date, protect_content=protect_content, reply_markup=self.reply_markup if reply_markup is object else reply_markup @@ -3247,6 +3381,7 @@ async def copy( chat_id=chat_id, disable_notification=disable_notification, reply_to_message_id=reply_to_message_id, + message_thread_id=self.message_thread_id, schedule_date=schedule_date, protect_content=protect_content, has_spoiler=has_spoiler, diff --git a/pyrogram/types/messages_and_media/star_gift.py b/pyrogram/types/messages_and_media/star_gift.py new file mode 100644 index 00000000..ec7d140e --- /dev/null +++ b/pyrogram/types/messages_and_media/star_gift.py @@ -0,0 +1,248 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present Dan +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . + +from datetime import datetime +from typing import Optional + +import pyrogram +from pyrogram import raw, types, utils +from ..object import Object + + +class StarGift(Object): + """A star gift. + + Parameters: + id (``int``): + Unique identifier of the gift. + + sticker (:obj:`~pyrogram.types.Sticker`): + Sticker that represents the gift. + + stars (``int``): + Price of the gift in Telegram Stars. + + convert_stars (``int``): + Amount of Stars the receiver can convert this gift to. + + limited (``bool``, *optional*): + Whether this is a limited-supply gift. + + sold_out (``bool``, *optional*): + Whether this gift sold out and cannot be bought anymore. + + birthday (``bool``, *optional*): + Whether this is a birthday-themed gift. + + can_upgrade (``bool``, *optional*): + Whether this gift can be upgraded to a collectible. + + require_premium (``bool``, *optional*): + Whether this gift can only be bought by Premium users. + + availability_remains (``int``, *optional*): + For limited-supply gifts: remaining number of gifts available. + + availability_total (``int``, *optional*): + For limited-supply gifts: total number of gifts in initial supply. + + first_sale_date (:py:obj:`~datetime.datetime`, *optional*): + For sold out gifts: when the gift was first bought. + + last_sale_date (:py:obj:`~datetime.datetime`, *optional*): + For sold out gifts: when the gift was last bought. + + upgrade_stars (``int``, *optional*): + Stars needed to upgrade this gift to a collectible. + + title (``str``, *optional*): + Title of the gift. + """ + + def __init__( + self, + *, + client: "pyrogram.Client" = None, + id: int, + sticker: "types.Sticker" = None, + stars: int, + convert_stars: int, + limited: bool = None, + sold_out: bool = None, + birthday: bool = None, + can_upgrade: bool = None, + require_premium: bool = None, + availability_remains: int = None, + availability_total: int = None, + first_sale_date: datetime = None, + last_sale_date: datetime = None, + upgrade_stars: int = None, + title: str = None + ): + super().__init__(client) + + self.id = id + self.sticker = sticker + self.stars = stars + self.convert_stars = convert_stars + self.limited = limited + self.sold_out = sold_out + self.birthday = birthday + self.can_upgrade = can_upgrade + self.require_premium = require_premium + self.availability_remains = availability_remains + self.availability_total = availability_total + self.first_sale_date = first_sale_date + self.last_sale_date = last_sale_date + self.upgrade_stars = upgrade_stars + self.title = title + + @staticmethod + async def _parse( + client: "pyrogram.Client", + star_gift: "raw.types.StarGift" + ) -> "StarGift": + return StarGift( + client=client, + id=star_gift.id, + sticker=await types.Sticker._parse(client, star_gift.sticker, {}) if star_gift.sticker else None, + stars=star_gift.stars, + convert_stars=star_gift.convert_stars, + limited=star_gift.limited or None, + sold_out=star_gift.sold_out or None, + birthday=star_gift.birthday or None, + can_upgrade=star_gift.can_upgrade or None, + require_premium=star_gift.require_premium or None, + availability_remains=star_gift.availability_remains, + availability_total=star_gift.availability_total, + first_sale_date=utils.timestamp_to_datetime(star_gift.first_sale_date), + last_sale_date=utils.timestamp_to_datetime(star_gift.last_sale_date), + upgrade_stars=star_gift.upgrade_stars, + title=star_gift.title + ) + + +class StarGiftUnique(Object): + """A unique/collectible star gift. + + Parameters: + id (``int``): + Unique identifier of the collectible gift. + + gift_id (``int``): + Unique ID of the base gift type. + + title (``str``): + Collectible title. + + slug (``str``): + Slug for creating deep links. + + num (``int``): + Unique number among all collectibles of the same type. + + availability_issued (``int``): + Number of gifts of this type upgraded to collectible. + + availability_total (``int``): + Total number that can be upgraded. + + require_premium (``bool``, *optional*): + Whether only Premium users can buy this. + + burned (``bool``, *optional*): + Whether this gift has been burned. + + crafted (``bool``, *optional*): + Whether this gift was crafted. + + owner_id (``int``, *optional*): + User ID of the owner. + + owner_name (``str``, *optional*): + Name of the owner if ID is not available. + + owner_address (``str``, *optional*): + TON blockchain address of the owner. + + gift_address (``str``, *optional*): + TON blockchain address of the NFT. + """ + + def __init__( + self, + *, + client: "pyrogram.Client" = None, + id: int, + gift_id: int, + title: str, + slug: str, + num: int, + availability_issued: int, + availability_total: int, + require_premium: bool = None, + burned: bool = None, + crafted: bool = None, + owner_id: int = None, + owner_name: str = None, + owner_address: str = None, + gift_address: str = None + ): + super().__init__(client) + + self.id = id + self.gift_id = gift_id + self.title = title + self.slug = slug + self.num = num + self.availability_issued = availability_issued + self.availability_total = availability_total + self.require_premium = require_premium + self.burned = burned + self.crafted = crafted + self.owner_id = owner_id + self.owner_name = owner_name + self.owner_address = owner_address + self.gift_address = gift_address + + @staticmethod + def _parse( + client: "pyrogram.Client", + star_gift: "raw.types.StarGiftUnique" + ) -> "StarGiftUnique": + owner_id = None + if star_gift.owner_id: + owner_id = utils.get_raw_peer_id(star_gift.owner_id) + + return StarGiftUnique( + client=client, + id=star_gift.id, + gift_id=star_gift.gift_id, + title=star_gift.title, + slug=star_gift.slug, + num=star_gift.num, + availability_issued=star_gift.availability_issued, + availability_total=star_gift.availability_total, + require_premium=star_gift.require_premium or None, + burned=star_gift.burned or None, + crafted=star_gift.crafted or None, + owner_id=owner_id, + owner_name=star_gift.owner_name, + owner_address=star_gift.owner_address, + gift_address=star_gift.gift_address + ) diff --git a/pyrogram/types/user_and_chats/__init__.py b/pyrogram/types/user_and_chats/__init__.py index 2710f56a..02bc039b 100644 --- a/pyrogram/types/user_and_chats/__init__.py +++ b/pyrogram/types/user_and_chats/__init__.py @@ -34,6 +34,7 @@ from .emoji_status import EmojiStatus from .invite_link_importer import InviteLinkImporter from .restriction import Restriction +from .peer_color import PeerColor from .user import User from .username import Username from .video_chat_ended import VideoChatEnded @@ -65,5 +66,6 @@ "ChatPrivileges", "ChatJoiner", "EmojiStatus", - "ChatReactions" + "ChatReactions", + "PeerColor" ] diff --git a/pyrogram/types/user_and_chats/chat.py b/pyrogram/types/user_and_chats/chat.py index 5323a7b0..83e216b8 100644 --- a/pyrogram/types/user_and_chats/chat.py +++ b/pyrogram/types/user_and_chats/chat.py @@ -142,6 +142,66 @@ class Chat(Object): usernames (List of :obj:`~pyrogram.types.Username`, *optional*): The list of chat's collectible (and basic) usernames if availables. + admin_privileges (:obj:`~pyrogram.types.ChatPrivileges`, *optional*): + Administrator rights available to the current user in this chat. + + stories_hidden (``bool``, *optional*): + True, if stories from this chat are hidden for the current user. + + stories_hidden_min (``bool``, *optional*): + True, if the chat only shows the minimum number of stories. + + stories_unavailable (``bool``, *optional*): + True, if stories from this chat are currently unavailable. + + signature_profiles (``bool``, *optional*): + True, if signature profiles are enabled for this chat. + + autotranslation (``bool``, *optional*): + True, if automatic translation is enabled for this chat. + + broadcast_messages_allowed (``bool``, *optional*): + True, if broadcast messages are allowed in this chat. + + monoforum (``bool``, *optional*): + True, if this chat is a monoforum instance. + + forum_tabs (``bool``, *optional*): + True, if forum tabs are enabled for this chat. + + stories_max_id (``int``, *optional*): + Identifier of the most recent story viewed in this chat. + + color (:obj:`~pyrogram.types.PeerColor`, *optional*): + Accent color information associated with the chat. + + profile_color (:obj:`~pyrogram.types.PeerColor`, *optional*): + Profile color information associated with the chat. + + emoji_status (:obj:`~pyrogram.types.EmojiStatus`, *optional*): + Emoji status attached to the chat. + + access_hash (``int``, *optional*): + Access hash required for MTProto requests involving this chat. + + level (``int``, *optional*): + Current chat level, if available. + + subscription_until_date (:py:obj:`~datetime.datetime`, *optional*): + Expiration date of an active subscription for this chat. + + bot_verification_icon (``int``, *optional*): + Identifier of the bot verification icon associated with this chat. + + send_paid_messages_stars (``int``, *optional*): + Number of Stars required to send paid messages in the chat. + + linked_monoforum_id (``int``, *optional*): + Identifier of the linked monoforum, if any. + + restriction_reason (List of :obj:`~pyrogram.types.Restriction`, *optional*): + Reasons why access to this chat may be restricted. + full_name (``str``, *property*): Full name of the other party in a private chat, for private chats and bots. """ @@ -182,6 +242,26 @@ def __init__( has_visible_history: bool = None, has_hidden_members: bool = None, is_forum: bool = None, + admin_privileges: "types.ChatPrivileges" = None, + stories_hidden: bool = None, + stories_hidden_min: bool = None, + stories_unavailable: bool = None, + signature_profiles: bool = None, + autotranslation: bool = None, + broadcast_messages_allowed: bool = None, + monoforum: bool = None, + forum_tabs: bool = None, + stories_max_id: int = None, + color: "types.PeerColor" = None, + profile_color: "types.PeerColor" = None, + emoji_status: "types.EmojiStatus" = None, + access_hash: int = None, + level: int = None, + subscription_until_date: datetime = None, + bot_verification_icon: int = None, + send_paid_messages_stars: int = None, + linked_monoforum_id: int = None, + restriction_reason: List["types.Restriction"] = None, ): super().__init__(client) @@ -217,6 +297,26 @@ def __init__( self.has_visible_history = has_visible_history self.has_hidden_members = has_hidden_members self.is_forum = is_forum + self.admin_privileges = admin_privileges + self.stories_hidden = stories_hidden + self.stories_hidden_min = stories_hidden_min + self.stories_unavailable = stories_unavailable + self.signature_profiles = signature_profiles + self.autotranslation = autotranslation + self.broadcast_messages_allowed = broadcast_messages_allowed + self.monoforum = monoforum + self.forum_tabs = forum_tabs + self.stories_max_id = stories_max_id + self.color = color + self.profile_color = profile_color + self.emoji_status = emoji_status + self.access_hash = access_hash + self.level = level + self.subscription_until_date = subscription_until_date + self.bot_verification_icon = bot_verification_icon + self.send_paid_messages_stars = send_paid_messages_stars + self.linked_monoforum_id = linked_monoforum_id + self.restriction_reason = restriction_reason or restrictions @property def full_name(self) -> str: @@ -226,6 +326,8 @@ def full_name(self) -> str: def _parse_user_chat(client, user: raw.types.User) -> "Chat": peer_id = user.id + parsed_restrictions = types.List([types.Restriction._parse(r) for r in user.restriction_reason]) or None + return Chat( id=peer_id, type=enums.ChatType.BOT if user.bot else enums.ChatType.PRIVATE, @@ -238,9 +340,17 @@ def _parse_user_chat(client, user: raw.types.User) -> "Chat": first_name=user.first_name, last_name=user.last_name, photo=types.ChatPhoto._parse(client, user.photo, peer_id, user.access_hash), - restrictions=types.List([types.Restriction._parse(r) for r in user.restriction_reason]) or None, + restrictions=parsed_restrictions, + restriction_reason=parsed_restrictions, dc_id=getattr(getattr(user, "photo", None), "dc_id", None), usernames=types.List([types.Username._parse(r) for r in user.usernames]) or None, + stories_hidden=getattr(user, "stories_hidden", None), + stories_unavailable=getattr(user, "stories_unavailable", None), + stories_max_id=getattr(user, "stories_max_id", None), + color=types.PeerColor._parse(getattr(user, "color", None)), + profile_color=types.PeerColor._parse(getattr(user, "profile_color", None)), + emoji_status=types.EmojiStatus._parse(client, getattr(user, "emoji_status", None)), + access_hash=getattr(user, "access_hash", None), client=client ) @@ -249,6 +359,8 @@ def _parse_chat_chat(client, chat: raw.types.Chat) -> "Chat": peer_id = -chat.id usernames = getattr(chat, "usernames", []) + parsed_restrictions = types.List([types.Restriction._parse(r) for r in getattr(chat, "restriction_reason", [])]) or None + return Chat( id=peer_id, type=enums.ChatType.GROUP, @@ -260,6 +372,21 @@ def _parse_chat_chat(client, chat: raw.types.Chat) -> "Chat": dc_id=getattr(getattr(chat, "photo", None), "dc_id", None), has_protected_content=getattr(chat, "noforwards", None), usernames=types.List([types.Username._parse(r) for r in usernames]) or None, + admin_privileges=types.ChatPrivileges._parse(getattr(chat, "admin_rights", None)), + stories_hidden=getattr(chat, "stories_hidden", None), + stories_hidden_min=getattr(chat, "stories_hidden_min", None), + stories_unavailable=getattr(chat, "stories_unavailable", None), + signature_profiles=getattr(chat, "signature_profiles", None), + autotranslation=getattr(chat, "autotranslation", None), + broadcast_messages_allowed=getattr(chat, "broadcast_messages_allowed", None), + monoforum=getattr(chat, "monoforum", None), + forum_tabs=getattr(chat, "forum_tabs", None), + stories_max_id=getattr(chat, "stories_max_id", None), + color=types.PeerColor._parse(getattr(chat, "color", None)), + profile_color=types.PeerColor._parse(getattr(chat, "profile_color", None)), + emoji_status=types.EmojiStatus._parse(client, getattr(chat, "emoji_status", None)), + access_hash=getattr(chat, "access_hash", None), + restriction_reason=parsed_restrictions, client=client ) @@ -269,6 +396,8 @@ def _parse_channel_chat(client, channel: raw.types.Channel) -> "Chat": restriction_reason = getattr(channel, "restriction_reason", []) usernames = getattr(channel, "usernames", []) + parsed_restrictions = types.List([types.Restriction._parse(r) for r in restriction_reason]) or None + return Chat( id=peer_id, type=enums.ChatType.SUPERGROUP if getattr(channel, "megagroup", None) else enums.ChatType.CHANNEL, @@ -281,14 +410,34 @@ def _parse_channel_chat(client, channel: raw.types.Channel) -> "Chat": username=getattr(channel, "username", None), photo=types.ChatPhoto._parse(client, getattr(channel, "photo", None), peer_id, getattr(channel, "access_hash", 0)), - restrictions=types.List([types.Restriction._parse(r) for r in restriction_reason]) or None, + restrictions=parsed_restrictions, + restriction_reason=parsed_restrictions, permissions=types.ChatPermissions._parse(getattr(channel, "default_banned_rights", None)), members_count=getattr(channel, "participants_count", None), dc_id=getattr(getattr(channel, "photo", None), "dc_id", None), has_protected_content=getattr(channel, "noforwards", None), usernames=types.List([types.Username._parse(r) for r in usernames]) or None, + admin_privileges=types.ChatPrivileges._parse(getattr(channel, "admin_rights", None)), client=client, is_forum=getattr(channel, "forum", None), + stories_hidden=getattr(channel, "stories_hidden", None), + stories_hidden_min=getattr(channel, "stories_hidden_min", None), + stories_unavailable=getattr(channel, "stories_unavailable", None), + signature_profiles=getattr(channel, "signature_profiles", None), + autotranslation=getattr(channel, "autotranslation", None), + broadcast_messages_allowed=getattr(channel, "broadcast_messages_allowed", None), + monoforum=getattr(channel, "monoforum", None), + forum_tabs=getattr(channel, "forum_tabs", None), + stories_max_id=getattr(channel, "stories_max_id", None), + color=types.PeerColor._parse(getattr(channel, "color", None)), + profile_color=types.PeerColor._parse(getattr(channel, "profile_color", None)), + emoji_status=types.EmojiStatus._parse(client, getattr(channel, "emoji_status", None)), + access_hash=getattr(channel, "access_hash", None), + level=getattr(channel, "level", None), + subscription_until_date=utils.timestamp_to_datetime(getattr(channel, "subscription_until_date", None)), + bot_verification_icon=getattr(channel, "bot_verification_icon", None), + send_paid_messages_stars=getattr(channel, "send_paid_messages_stars", None), + linked_monoforum_id=getattr(channel, "linked_monoforum_id", None) ) @staticmethod @@ -357,6 +506,40 @@ async def _parse_full(client, chat_full: Union[raw.types.messages.ChatFull, raw. # TODO: Add StickerSet type parsed_chat.can_set_sticker_set = full_chat.can_set_stickers parsed_chat.sticker_set_name = getattr(full_chat.stickerset, "short_name", None) + if getattr(full_chat, "admin_rights", None): + parsed_chat.admin_privileges = types.ChatPrivileges._parse(full_chat.admin_rights) + parsed_chat.stories_hidden = getattr(full_chat, "stories_hidden", parsed_chat.stories_hidden) + parsed_chat.stories_hidden_min = getattr(full_chat, "stories_hidden_min", parsed_chat.stories_hidden_min) + parsed_chat.stories_unavailable = getattr(full_chat, "stories_unavailable", parsed_chat.stories_unavailable) + parsed_chat.signature_profiles = getattr(full_chat, "signature_profiles", parsed_chat.signature_profiles) + parsed_chat.autotranslation = getattr(full_chat, "autotranslation", parsed_chat.autotranslation) + parsed_chat.broadcast_messages_allowed = getattr(full_chat, "broadcast_messages_allowed", parsed_chat.broadcast_messages_allowed) + parsed_chat.monoforum = getattr(full_chat, "monoforum", parsed_chat.monoforum) + parsed_chat.forum_tabs = getattr(full_chat, "forum_tabs", parsed_chat.forum_tabs) + parsed_chat.stories_max_id = getattr(full_chat, "stories_max_id", parsed_chat.stories_max_id) + parsed_chat.color = types.PeerColor._parse(getattr(full_chat, "color", None)) or parsed_chat.color + parsed_chat.profile_color = types.PeerColor._parse(getattr(full_chat, "profile_color", None)) or parsed_chat.profile_color + parsed_chat.emoji_status = types.EmojiStatus._parse(client, getattr(full_chat, "emoji_status", None)) or parsed_chat.emoji_status + parsed_chat.level = getattr(full_chat, "level", parsed_chat.level) + parsed_chat.subscription_until_date = utils.timestamp_to_datetime(getattr(full_chat, "subscription_until_date", None)) or parsed_chat.subscription_until_date + parsed_chat.bot_verification_icon = getattr(full_chat, "bot_verification_icon", parsed_chat.bot_verification_icon) + parsed_chat.send_paid_messages_stars = getattr(full_chat, "send_paid_messages_stars", parsed_chat.send_paid_messages_stars) + parsed_chat.linked_monoforum_id = getattr(full_chat, "linked_monoforum_id", parsed_chat.linked_monoforum_id) + if getattr(full_chat, "default_banned_rights", None): + parsed_chat.permissions = types.ChatPermissions._parse(full_chat.default_banned_rights) + if getattr(full_chat, "banned_rights", None): + parsed_chat.permissions = types.ChatPermissions._parse(full_chat.banned_rights) + if getattr(full_chat, "admin_rights", None): + parsed_chat.admin_privileges = types.ChatPrivileges._parse(full_chat.admin_rights) + + full_restrictions = types.List([ + types.Restriction._parse(r) + for r in getattr(full_chat, "restriction_reason", []) + ]) or None + + if full_restrictions: + parsed_chat.restrictions = full_restrictions + parsed_chat.restriction_reason = full_restrictions linked_chat_raw = chats.get(full_chat.linked_chat_id, None) diff --git a/pyrogram/types/user_and_chats/chat_privileges.py b/pyrogram/types/user_and_chats/chat_privileges.py index 05797822..77128f79 100644 --- a/pyrogram/types/user_and_chats/chat_privileges.py +++ b/pyrogram/types/user_and_chats/chat_privileges.py @@ -16,6 +16,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . +from typing import Optional + from pyrogram import raw from ..object import Object @@ -78,6 +80,9 @@ class ChatPrivileges(Object): can_manage_topics (``bool``, *optional*): True, if the user is allowed to create, rename, close, and reopen forum topics. supergroups only + + can_manage_direct_messages (``bool``, *optional*): + True, if the administrator can manage direct messages in the chat's. """ def __init__( @@ -98,6 +103,7 @@ def __init__( can_edit_stories: bool = False, # Channels only can_delete_stories: bool = False, # Channels only can_manage_topics: bool = False, # supergroups only + can_manage_direct_messages: bool = False, ): super().__init__(None) @@ -116,9 +122,13 @@ def __init__( self.can_edit_stories: bool = can_edit_stories self.can_delete_stories: bool = can_delete_stories self.can_manage_topics: bool = can_manage_topics + self.can_manage_direct_messages: bool = can_manage_direct_messages @staticmethod - def _parse(admin_rights: "raw.base.ChatAdminRights") -> "ChatPrivileges": + def _parse(admin_rights: "raw.base.ChatAdminRights") -> Optional["ChatPrivileges"]: + if admin_rights is None: + return None + return ChatPrivileges( can_change_info=admin_rights.change_info, can_post_messages=admin_rights.post_messages, @@ -134,5 +144,6 @@ def _parse(admin_rights: "raw.base.ChatAdminRights") -> "ChatPrivileges": can_manage_topics=admin_rights.manage_topics, can_post_stories=admin_rights.post_stories, can_edit_stories=admin_rights.edit_stories, - can_delete_stories=admin_rights.delete_stories + can_delete_stories=admin_rights.delete_stories, + can_manage_direct_messages=getattr(admin_rights, "manage_direct_messages", False) ) diff --git a/pyrogram/types/user_and_chats/peer_color.py b/pyrogram/types/user_and_chats/peer_color.py new file mode 100644 index 00000000..e4a45a48 --- /dev/null +++ b/pyrogram/types/user_and_chats/peer_color.py @@ -0,0 +1,100 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present Dan +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . + +from typing import List, Optional + +from pyrogram import raw +from ..object import Object + + +class PeerColor(Object): + """Represents the accent color information of a peer. + + Parameters: + color (``int``, *optional*): + Identifier of the color palette. + + background_emoji_id (``int``, *optional*): + Custom emoji identifier used for the background pattern. + + collectible_id (``int``, *optional*): + Collectible identifier when the color comes from a collectible. + + gift_emoji_id (``int``, *optional*): + Emoji identifier of the collectible gift. + + accent_color (``int``, *optional*): + Accent color value for collectible colors. + + colors (List of ``int``, *optional*): + List of palette colors for collectible colors. + + dark_accent_color (``int``, *optional*): + Accent color for dark mode. + + dark_colors (List of ``int``, *optional*): + Dark palette colors. + """ + + def __init__( + self, + *, + client=None, + color: Optional[int] = None, + background_emoji_id: Optional[int] = None, + collectible_id: Optional[int] = None, + gift_emoji_id: Optional[int] = None, + accent_color: Optional[int] = None, + colors: Optional[List[int]] = None, + dark_accent_color: Optional[int] = None, + dark_colors: Optional[List[int]] = None + ): + super().__init__(client) + + self.color = color + self.background_emoji_id = background_emoji_id + self.collectible_id = collectible_id + self.gift_emoji_id = gift_emoji_id + self.accent_color = accent_color + self.colors = colors + self.dark_accent_color = dark_accent_color + self.dark_colors = dark_colors + + @staticmethod + def _parse(peer_color: "raw.base.PeerColor") -> Optional["PeerColor"]: + if peer_color is None: + return None + + if isinstance(peer_color, raw.types.PeerColor): + return PeerColor( + color=getattr(peer_color, "color", None), + background_emoji_id=getattr(peer_color, "background_emoji_id", None) + ) + + if isinstance(peer_color, raw.types.PeerColorCollectible): + return PeerColor( + collectible_id=peer_color.collectible_id, + gift_emoji_id=peer_color.gift_emoji_id, + background_emoji_id=peer_color.background_emoji_id, + accent_color=peer_color.accent_color, + colors=list(peer_color.colors) if getattr(peer_color, "colors", None) else None, + dark_accent_color=getattr(peer_color, "dark_accent_color", None), + dark_colors=list(peer_color.dark_colors) if getattr(peer_color, "dark_colors", None) else None + ) + + return None diff --git a/pyrogram/types/user_and_chats/user.py b/pyrogram/types/user_and_chats/user.py index a86e5a59..774aefca 100644 --- a/pyrogram/types/user_and_chats/user.py +++ b/pyrogram/types/user_and_chats/user.py @@ -181,7 +181,31 @@ def __init__( phone_number: str = None, photo: "types.ChatPhoto" = None, restrictions: List["types.Restriction"] = None, - usernames: List["types.Username"] = None + usernames: List["types.Username"] = None, + bot_chat_history: bool = None, + bot_nochats: bool = None, + bot_inline_geo: bool = None, + apply_min_photo: bool = None, + bot_attach_menu: bool = None, + attach_menu_enabled: bool = None, + bot_can_edit: bool = None, + close_friend: bool = None, + stories_hidden: bool = None, + stories_unavailable: bool = None, + contact_require_premium: bool = None, + bot_business: bool = None, + bot_has_main_app: bool = None, + bot_forum_view: bool = None, + access_hash: int = None, + bot_info_version: int = None, + bot_inline_placeholder: str = None, + stories_max_id: int = None, + color: "types.PeerColor" = None, + profile_color: "types.PeerColor" = None, + bot_active_users: int = None, + bot_verification_icon: int = None, + send_paid_messages_stars: int = None, + restriction_reason: List["types.Restriction"] = None ): super().__init__(client) @@ -210,6 +234,30 @@ def __init__( self.photo = photo self.restrictions = restrictions self.usernames = usernames + self.bot_chat_history = bot_chat_history + self.bot_nochats = bot_nochats + self.bot_inline_geo = bot_inline_geo + self.apply_min_photo = apply_min_photo + self.bot_attach_menu = bot_attach_menu + self.attach_menu_enabled = attach_menu_enabled + self.bot_can_edit = bot_can_edit + self.close_friend = close_friend + self.stories_hidden = stories_hidden + self.stories_unavailable = stories_unavailable + self.contact_require_premium = contact_require_premium + self.bot_business = bot_business + self.bot_has_main_app = bot_has_main_app + self.bot_forum_view = bot_forum_view + self.access_hash = access_hash + self.bot_info_version = bot_info_version + self.bot_inline_placeholder = bot_inline_placeholder + self.stories_max_id = stories_max_id + self.color = color + self.profile_color = profile_color + self.bot_active_users = bot_active_users + self.bot_verification_icon = bot_verification_icon + self.send_paid_messages_stars = send_paid_messages_stars + self.restriction_reason = restriction_reason or restrictions @property def full_name(self) -> str: @@ -228,6 +276,8 @@ def _parse(client, user: "raw.base.User") -> Optional["User"]: if user is None or isinstance(user, raw.types.UserEmpty): return None + parsed_restrictions = types.List([types.Restriction._parse(r) for r in user.restriction_reason]) or None + return User( id=user.id, is_self=user.is_self, @@ -250,8 +300,32 @@ def _parse(client, user: "raw.base.User") -> Optional["User"]: dc_id=getattr(user.photo, "dc_id", None), phone_number=user.phone, photo=types.ChatPhoto._parse(client, user.photo, user.id, user.access_hash), - restrictions=types.List([types.Restriction._parse(r) for r in user.restriction_reason]) or None, + restrictions=parsed_restrictions, + restriction_reason=parsed_restrictions, usernames=types.List([types.Username._parse(r) for r in user.usernames]) or None, + bot_chat_history=getattr(user, "bot_chat_history", None), + bot_nochats=getattr(user, "bot_nochats", None), + bot_inline_geo=getattr(user, "bot_inline_geo", None), + apply_min_photo=getattr(user, "apply_min_photo", None), + bot_attach_menu=getattr(user, "bot_attach_menu", None), + attach_menu_enabled=getattr(user, "attach_menu_enabled", None), + bot_can_edit=getattr(user, "bot_can_edit", None), + close_friend=getattr(user, "close_friend", None), + stories_hidden=getattr(user, "stories_hidden", None), + stories_unavailable=getattr(user, "stories_unavailable", None), + contact_require_premium=getattr(user, "contact_require_premium", None), + bot_business=getattr(user, "bot_business", None), + bot_has_main_app=getattr(user, "bot_has_main_app", None), + bot_forum_view=getattr(user, "bot_forum_view", None), + access_hash=getattr(user, "access_hash", None), + bot_info_version=getattr(user, "bot_info_version", None), + bot_inline_placeholder=getattr(user, "bot_inline_placeholder", None), + stories_max_id=getattr(user, "stories_max_id", None), + color=types.PeerColor._parse(getattr(user, "color", None)), + profile_color=types.PeerColor._parse(getattr(user, "profile_color", None)), + bot_active_users=getattr(user, "bot_active_users", None), + bot_verification_icon=getattr(user, "bot_verification_icon", None), + send_paid_messages_stars=getattr(user, "send_paid_messages_stars", None), client=client ) diff --git a/pyrogram/utils.py b/pyrogram/utils.py index 044e935c..68b1fcbf 100644 --- a/pyrogram/utils.py +++ b/pyrogram/utils.py @@ -202,7 +202,7 @@ def unpack_inline_message_id(inline_message_id: str) -> "raw.base.InputBotInline MIN_CHANNEL_ID_OLD = -1002147483647 -MIN_CHANNEL_ID = -1009999999999 +MIN_CHANNEL_ID = -100999999999999 MAX_CHANNEL_ID = -1000000000000 MIN_CHAT_ID_OLD = -2147483647 MIN_CHAT_ID = -999999999999