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..1fcaf1d1 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) @@ -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..21338ef8 100644 --- a/compiler/api/source/main_api.tl +++ b/compiler/api/source/main_api.tl @@ -36,7 +36,7 @@ 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; @@ -61,6 +61,7 @@ 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 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,7 +116,7 @@ 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; +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 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; @@ -132,7 +133,7 @@ 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#9cb490e9 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 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; @@ -147,12 +148,13 @@ 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; +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,8 +213,10 @@ 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; +messageActionPhoneNumberRequest#1baa035 = MessageAction; messageActionUserJoined#55555550 = MessageAction; messageActionUserUpdatedPhoto#55555551 new_user_photo:UserProfilePhoto = MessageAction; messageActionTTLChange#55555552 ttl:int = MessageAction; @@ -270,7 +274,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#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_gifts: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; contact#145ade0b user_id:long mutual:Bool = Contact; @@ -407,7 +411,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 +432,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 +468,16 @@ 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; +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; @@ -581,6 +587,7 @@ inputPrivacyKeyAbout#3823cc40 = InputPrivacyKey; inputPrivacyKeyBirthday#d65a11cc = InputPrivacyKey; inputPrivacyKeyStarGiftsAutoSave#e1732341 = InputPrivacyKey; inputPrivacyKeyNoPaidMessages#bdc597b4 = InputPrivacyKey; +inputPrivacyKeySavedMusic#4dbe9226 = InputPrivacyKey; privacyKeyStatusTimestamp#bc2eab30 = PrivacyKey; privacyKeyChatInvite#500e6dfa = PrivacyKey; @@ -595,6 +602,7 @@ privacyKeyAbout#a486b761 = PrivacyKey; privacyKeyBirthday#2000a518 = PrivacyKey; privacyKeyStarGiftsAutoSave#2ca4fdf8 = PrivacyKey; privacyKeyNoPaidMessages#17d348d2 = PrivacyKey; +privacyKeySavedMusic#ff7a571b = PrivacyKey; inputPrivacyValueAllowContacts#d09e07b = InputPrivacyRule; inputPrivacyValueAllowAll#184b35ce = InputPrivacyRule; @@ -973,7 +981,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; @@ -1322,6 +1330,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; @@ -1387,13 +1396,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 +1461,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 +1554,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 +1616,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#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:flags.7?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; 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; @@ -1675,7 +1685,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; @@ -1719,7 +1729,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 +1760,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; @@ -1896,7 +1906,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 +1944,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#569d64c9 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 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 = StarGift; payments.starGiftsNotModified#a388a368 = payments.StarGifts; payments.starGifts#2ed82995 hash:int gifts:Vector chats:Vector users:Vector = payments.StarGifts; @@ -1975,7 +1985,7 @@ starGiftAttributePattern#13acff19 name:string document:Document rarity_permille: starGiftAttributeBackdrop#d93d859c name:string backdrop_id:int center_color:int edge_color:int pattern_color:int text_color:int rarity_permille:int = 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 +1994,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#ead6805e 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 = 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 +2016,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 +2039,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,18 +2081,70 @@ 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; 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; -starGiftUpgradePrice#99ea331d date:int upgrade_stars:long = StarGiftUpgradePrice; - 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; - ---functions--- invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; @@ -2120,6 +2182,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 +2274,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 +2304,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 +2345,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 +2357,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 +2404,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; @@ -2508,25 +2578,20 @@ 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#9d4104e2 flags:# peer:InputPeer id:int to_lang:flags.0?string = TextWithEntities; +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.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.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; 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; @@ -2608,7 +2673,7 @@ channels.editLocation#58e63f6d channel:InputChannel geo_point:InputGeoPoint addr 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 +2681,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; @@ -2728,6 +2786,12 @@ 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.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 +2820,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 +2835,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 +2843,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 +2899,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 +2911,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 +2929,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 221 \ 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..cfd21aed 100644 --- a/compiler/api/template/type.txt +++ b/compiler/api/template/type.txt @@ -6,6 +6,9 @@ from typing import Union from pyrogram import raw {name} = Union[{types}] -{name}.__doc__ = """ +try: + {name}.__doc__ = """ {docstring} -""" \ No newline at end of file + """ +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..434961aa 100644 --- a/docs/source/start/examples/index.rst +++ b/docs/source/start/examples/index.rst @@ -26,6 +26,7 @@ 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:`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 +44,5 @@ For more advanced examples, see https://github.com/ColinShark/Pyrogram-Snippets. inline_queries use_inline_bots bot_keyboards + streaming_text raw_updates 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/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/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..4286c37a 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 ( @@ -209,7 +219,10 @@ async def handle_packet(self, packet): ) except ValueError as e: log.debug(e) - 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 return messages = ( @@ -271,7 +284,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 +321,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 +353,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") 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/messages_and_media/message.py b/pyrogram/types/messages_and_media/message.py index e1e4f30a..644b938f 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 @@ -797,13 +829,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 +940,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 +1139,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 +1292,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 +1438,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 +1533,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 +1662,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 +1808,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 +1882,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 +1953,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 +2034,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 +2103,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 +2235,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 +2388,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 +2494,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 +2601,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 +2762,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 +2887,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 +3015,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 +3362,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 +3373,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/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