diff --git a/compiler/api/source/main_api.tl b/compiler/api/source/main_api.tl index f22edfb66..eff530685 100644 --- a/compiler/api/source/main_api.tl +++ b/compiler/api/source/main_api.tl @@ -52,6 +52,7 @@ inputMediaPoll#f94e5f1 flags:# poll:Poll correct_answers:flags.0?Vector s inputMediaDice#e66fbf7b emoticon:string = InputMedia; inputMediaStory#89fdd778 peer:InputPeer id:int = InputMedia; inputMediaWebPage#c21b8849 flags:# force_large_media:flags.0?true force_small_media:flags.1?true optional:flags.2?true url:string = InputMedia; +inputMediaPaidMedia#aa661fc3 stars_amount:long extended_media:Vector = 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; @@ -90,7 +91,7 @@ storage.fileMp4#b3cea0e4 = storage.FileType; storage.fileWebp#1081464c = storage.FileType; userEmpty#d3bc4b7a id:long = User; -user#215c4438 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 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 = User; +user#83314fca 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 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 = 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; @@ -109,7 +110,7 @@ channel#aadfc8f flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5 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; -channelFull#bbab348d flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true antispam:flags2.1?true participants_hidden:flags2.2?true translations_disabled:flags2.3?true stories_pinned_available:flags2.5?true view_forum_as_messages:flags2.6?true restricted_sponsored:flags2.11?true can_view_revenue:flags2.12?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions reactions_limit:flags2.13?int stories:flags2.4?PeerStories wallpaper:flags2.7?WallPaper boosts_applied:flags2.8?int boosts_unrestrict:flags2.9?int emojiset:flags2.10?StickerSet = ChatFull; +channelFull#bbab348d flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true antispam:flags2.1?true participants_hidden:flags2.2?true translations_disabled:flags2.3?true stories_pinned_available:flags2.5?true view_forum_as_messages:flags2.6?true restricted_sponsored:flags2.11?true can_view_revenue:flags2.12?true paid_media_allowed:flags2.14?true can_view_stars_revenue:flags2.15?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions reactions_limit:flags2.13?int stories:flags2.4?PeerStories wallpaper:flags2.7?WallPaper boosts_applied:flags2.8?int boosts_unrestrict:flags2.9?int emojiset:flags2.10?StickerSet = ChatFull; chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant; chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant; @@ -141,6 +142,7 @@ messageMediaDice#3f7ee58b value:int emoticon:string = MessageMedia; messageMediaStory#68cb6283 flags:# via_mention:flags.1?true peer:Peer id:int story:flags.0?StoryItem = MessageMedia; messageMediaGiveaway#daad85b0 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:int until_date:int = MessageMedia; messageMediaGiveawayResults#c6991068 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:int prize_description:flags.1?string until_date:int = MessageMedia; +messageMediaPaidMedia#a8852491 stars_amount:long extended_media:Vector = MessageMedia; messageActionEmpty#b6aef7b0 = MessageAction; messageActionChatCreate#bd47cbad title:string users:Vector = MessageAction; @@ -185,6 +187,8 @@ messageActionGiveawayLaunch#332ba9ed = MessageAction; messageActionGiveawayResults#2a9fadc5 winners_count:int unclaimed_count:int = MessageAction; messageActionBoostApply#cc02aa6d boosts:int = MessageAction; messageActionRequestedPeerSentMe#93b31848 button_id:int peers:Vector = MessageAction; +messageActionPaymentRefunded#41b3e202 flags:# peer:Peer currency:string total_amount:long payload:flags.0?bytes charge:PaymentCharge = MessageAction; +messageActionGiftStars#45d5b021 flags:# currency:string amount:long stars:long crypto_currency:flags.0?string crypto_amount:flags.0?long transaction_id:flags.1?string = MessageAction; dialog#d58a08c6 flags:# pinned:flags.2?true unread_mark:flags.3?true view_forum_as_messages:flags.6?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int ttl_period:flags.5?int = Dialog; dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog; @@ -392,7 +396,7 @@ updateUserEmojiStatus#28373599 user_id:long emoji_status:EmojiStatus = Update; updateRecentEmojiStatuses#30f443db = Update; updateRecentReactions#6f7863f4 = Update; updateMoveStickerSetToTop#86fccf85 flags:# masks:flags.0?true emojis:flags.1?true stickerset:long = Update; -updateMessageExtendedMedia#5a73a98c peer:Peer msg_id:int extended_media:MessageExtendedMedia = 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; @@ -423,6 +427,8 @@ updateBotDeleteBusinessMessage#a02a982e connection_id:string peer:Peer messages: updateNewStoryReaction#1824e40b story_id:int peer:Peer reaction:Reaction = Update; updateBroadcastRevenueTransactions#dfd961f5 peer:Peer balances:BroadcastRevenueBalances = Update; updateStarsBalance#fb85198 balance:long = Update; +updateBusinessBotCallbackQuery#1ea2fda7 flags:# query_id:long user_id:long connection_id:string message:Message reply_to_message:flags.2?Message chat_instance:long data:flags.0?bytes = Update; +updateStarsRevenueStatus#a584b019 peer:Peer status:StarsRevenueStatus = Update; updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State; @@ -571,7 +577,7 @@ accountDaysTTL#b8d0afdf days:int = AccountDaysTTL; documentAttributeImageSize#6c37c15c w:int h:int = DocumentAttribute; documentAttributeAnimated#11b58939 = DocumentAttribute; documentAttributeSticker#6319d612 flags:# mask:flags.1?true alt:string stickerset:InputStickerSet mask_coords:flags.0?MaskCoords = DocumentAttribute; -documentAttributeVideo#d38ff1c2 flags:# round_message:flags.0?true supports_streaming:flags.1?true nosound:flags.3?true duration:double w:int h:int preload_prefix_size:flags.2?int = DocumentAttribute; +documentAttributeVideo#17399fad flags:# round_message:flags.0?true supports_streaming:flags.1?true nosound:flags.3?true duration:double w:int h:int preload_prefix_size:flags.2?int video_start_ts:flags.4?double = DocumentAttribute; documentAttributeAudio#9852f9c6 flags:# voice:flags.10?true duration:int title:flags.0?string performer:flags.1?string waveform:flags.2?bytes = DocumentAttribute; documentAttributeFilename#15590068 file_name:string = DocumentAttribute; documentAttributeHasStickers#9801d2f7 = DocumentAttribute; @@ -632,7 +638,7 @@ messages.stickerSetNotModified#d3f924eb = messages.StickerSet; botCommand#c27ac8c7 command:string description:string = BotCommand; -botInfo#8f300b57 flags:# user_id:flags.0?long description:flags.1?string description_photo:flags.4?Photo description_document:flags.5?Document commands:flags.2?Vector menu_button:flags.3?BotMenuButton = BotInfo; +botInfo#8f300b57 flags:# has_preview_medias:flags.6?true user_id:flags.0?long description:flags.1?string description_photo:flags.4?Photo description_document:flags.5?Document commands:flags.2?Vector menu_button:flags.3?BotMenuButton = BotInfo; keyboardButton#a2fa4880 text:string = KeyboardButton; keyboardButtonUrl#258aff05 text:string url:string = KeyboardButton; @@ -767,7 +773,7 @@ auth.sentCodeTypeMissedCall#82006484 prefix:string length:int = auth.SentCodeTyp auth.sentCodeTypeEmailCode#f450f59b flags:# apple_signin_allowed:flags.0?true google_signin_allowed:flags.1?true email_pattern:string length:int reset_available_period:flags.3?int reset_pending_date:flags.4?int = auth.SentCodeType; auth.sentCodeTypeSetUpEmailRequired#a5491dea flags:# apple_signin_allowed:flags.0?true google_signin_allowed:flags.1?true = auth.SentCodeType; auth.sentCodeTypeFragmentSms#d9565c39 url:string length:int = auth.SentCodeType; -auth.sentCodeTypeFirebaseSms#13c90f17 flags:# nonce:flags.0?bytes play_integrity_nonce:flags.2?bytes receipt:flags.1?string push_timeout:flags.1?int length:int = auth.SentCodeType; +auth.sentCodeTypeFirebaseSms#9fd736 flags:# nonce:flags.0?bytes play_integrity_project_id:flags.2?long play_integrity_nonce:flags.2?bytes receipt:flags.1?string push_timeout:flags.1?int length:int = auth.SentCodeType; auth.sentCodeTypeSmsWord#a416ac81 flags:# beginning:flags.0?string = auth.SentCodeType; auth.sentCodeTypeSmsPhrase#b37794af flags:# beginning:flags.0?string = auth.SentCodeType; @@ -792,6 +798,7 @@ topPeerCategoryChannels#161d9628 = TopPeerCategory; topPeerCategoryPhoneCalls#1e76a78c = TopPeerCategory; topPeerCategoryForwardUsers#a8406ca9 = TopPeerCategory; topPeerCategoryForwardChats#fbeec0f0 = TopPeerCategory; +topPeerCategoryBotsApp#fd9e7bec = TopPeerCategory; topPeerCategoryPeers#fb834291 category:TopPeerCategory count:int peers:Vector = TopPeerCategoryPeers; @@ -800,7 +807,7 @@ contacts.topPeers#70b772a8 categories:Vector chats:Vector< contacts.topPeersDisabled#b52c939d = contacts.TopPeers; draftMessageEmpty#1b0c841a flags:# date:flags.0?int = DraftMessage; -draftMessage#3fccf7ef flags:# no_webpage:flags.1?true invert_media:flags.6?true reply_to:flags.4?InputReplyTo message:string entities:flags.3?Vector media:flags.5?InputMedia date:int = DraftMessage; +draftMessage#2d65321f flags:# no_webpage:flags.1?true invert_media:flags.6?true reply_to:flags.4?InputReplyTo message:string entities:flags.3?Vector media:flags.5?InputMedia date:int effect:flags.7?long = DraftMessage; messages.featuredStickersNotModified#c6dc0c66 count:int = messages.FeaturedStickers; messages.featuredStickers#be382906 flags:# premium:flags.0?true hash:long count:int sets:Vector unread:Vector = messages.FeaturedStickers; @@ -1428,9 +1435,7 @@ attachMenuBots#3c4301c0 hash:long bots:Vector users:Vector attachMenuBotsBot#93bf667f bot:AttachMenuBot users:Vector = AttachMenuBotsBot; -webViewResultUrl#c14557c query_id:long url:string = WebViewResult; - -simpleWebViewResultUrl#882f76bb url:string = SimpleWebViewResult; +webViewResultUrl#4d22ff98 flags:# fullsize:flags.1?true query_id:flags.0?long url:string = WebViewResult; webViewMessageSent#c94511c flags:# msg_id:flags.0?InputBotInlineMessageID = WebViewMessageSent; @@ -1458,7 +1463,7 @@ attachMenuPeerTypeBroadcast#7bfbdefc = AttachMenuPeerType; inputInvoiceMessage#c5b56859 peer:InputPeer msg_id:int = InputInvoice; inputInvoiceSlug#c326caef slug:string = InputInvoice; inputInvoicePremiumGiftCode#98986c0d purpose:InputStorePaymentPurpose option:PremiumGiftCodeOption = InputInvoice; -inputInvoiceStars#1da33ad8 option:StarsTopupOption = InputInvoice; +inputInvoiceStars#65f00ce3 purpose:InputStorePaymentPurpose = InputInvoice; payments.exportedInvoice#aed0cbd9 url:string = payments.ExportedInvoice; @@ -1470,7 +1475,8 @@ inputStorePaymentPremiumSubscription#a6751e66 flags:# restore:flags.0?true upgra inputStorePaymentGiftPremium#616f7fe8 user_id:InputUser currency:string amount:long = InputStorePaymentPurpose; inputStorePaymentPremiumGiftCode#a3805f3f flags:# users:Vector boost_peer:flags.0?InputPeer currency:string amount:long = InputStorePaymentPurpose; inputStorePaymentPremiumGiveaway#160544ca flags:# only_new_subscribers:flags.0?true winners_are_visible:flags.3?true boost_peer:InputPeer additional_peers:flags.1?Vector countries_iso2:flags.2?Vector prize_description:flags.4?string random_id:long until_date:int currency:string amount:long = InputStorePaymentPurpose; -inputStorePaymentStars#4f0ee8df flags:# stars:long currency:string amount:long = InputStorePaymentPurpose; +inputStorePaymentStarsTopup#dddd0f56 stars:long currency:string amount:long = InputStorePaymentPurpose; +inputStorePaymentStarsGift#1d741ef7 user_id:InputUser stars:long currency:string amount:long = InputStorePaymentPurpose; premiumGiftOption#74c34319 flags:# months:int currency:string amount:long bot_url:string store_product:flags.0?string = PremiumGiftOption; @@ -1560,8 +1566,6 @@ botApp#95fcd1d6 flags:# id:long access_hash:long short_name:string title:string messages.botApp#eb50adf5 flags:# inactive:flags.0?true request_write_access:flags.1?true has_settings:flags.2?true app:BotApp = messages.BotApp; -appWebViewResultUrl#3c1b4f0d url:string = AppWebViewResult; - inlineBotWebView#b57295d5 text:string url:string = InlineBotWebView; readParticipantDate#4a4ff172 user_id:long date:int = ReadParticipantDate; @@ -1611,14 +1615,16 @@ exportedStoryLink#3fc9053b link:string = ExportedStoryLink; storiesStealthMode#712e27fd flags:# active_until_date:flags.0?int cooldown_until_date:flags.1?int = StoriesStealthMode; -mediaAreaCoordinates#3d1ea4e x:double y:double w:double h:double rotation:double = MediaAreaCoordinates; +mediaAreaCoordinates#cfc9e002 flags:# x:double y:double w:double h:double rotation:double radius:flags.0?double = MediaAreaCoordinates; mediaAreaVenue#be82db9c coordinates:MediaAreaCoordinates geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string = MediaArea; inputMediaAreaVenue#b282217f coordinates:MediaAreaCoordinates query_id:long result_id:string = MediaArea; -mediaAreaGeoPoint#df8b3b22 coordinates:MediaAreaCoordinates geo:GeoPoint = MediaArea; +mediaAreaGeoPoint#cad5452d flags:# coordinates:MediaAreaCoordinates geo:GeoPoint address:flags.0?GeoPointAddress = MediaArea; mediaAreaSuggestedReaction#14455871 flags:# dark:flags.0?true flipped:flags.1?true coordinates:MediaAreaCoordinates reaction:Reaction = MediaArea; mediaAreaChannelPost#770416af coordinates:MediaAreaCoordinates channel_id:long msg_id:int = MediaArea; inputMediaAreaChannelPost#2271f2bf coordinates:MediaAreaCoordinates channel:InputChannel msg_id:int = MediaArea; +mediaAreaUrl#37381085 coordinates:MediaAreaCoordinates url:string = MediaArea; +mediaAreaWeather#49a6549c coordinates:MediaAreaCoordinates emoji:string temperature_c:double color:int = MediaArea; peerStories#9a35e999 flags:# peer:Peer max_read_id:flags.0?int stories:Vector = PeerStories; @@ -1808,13 +1814,38 @@ starsTransactionPeerPlayMarket#7b560a0b = StarsTransactionPeer; starsTransactionPeerPremiumBot#250dbaf8 = StarsTransactionPeer; starsTransactionPeerFragment#e92fd902 = StarsTransactionPeer; starsTransactionPeer#d80da15d peer:Peer = StarsTransactionPeer; +starsTransactionPeerAds#60682812 = StarsTransactionPeer; starsTopupOption#bd915c0 flags:# extended:flags.1?true stars:long store_product:flags.0?string currency:string amount:long = StarsTopupOption; -starsTransaction#cc7079b2 flags:# refund:flags.3?true id:string stars:long date:int peer:StarsTransactionPeer title:flags.0?string description:flags.1?string photo:flags.2?WebDocument = StarsTransaction; +starsTransaction#2db5418f flags:# refund:flags.3?true pending:flags.4?true failed:flags.6?true gift:flags.10?true id:string stars:long 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 = StarsTransaction; payments.starsStatus#8cf4ee60 flags:# balance:long history:Vector next_offset:flags.0?string chats:Vector users:Vector = payments.StarsStatus; +foundStory#e87acbc0 peer:Peer story:StoryItem = FoundStory; + +stories.foundStories#e2de7737 flags:# count:int stories:Vector next_offset:flags.0?string chats:Vector users:Vector = stories.FoundStories; + +geoPointAddress#de4c5d93 flags:# country_iso2:string state:flags.0?string city:flags.1?string street:flags.2?string = GeoPointAddress; + +starsRevenueStatus#79342946 flags:# withdrawal_enabled:flags.0?true current_balance:long available_balance:long overall_revenue:long next_withdrawal_at:flags.1?int = StarsRevenueStatus; + +payments.starsRevenueStats#c92bb73b revenue_graph:StatsGraph status:StarsRevenueStatus usd_rate:double = payments.StarsRevenueStats; + +payments.starsRevenueWithdrawalUrl#1dab80b7 url:string = payments.StarsRevenueWithdrawalUrl; + +payments.starsRevenueAdsAccountUrl#394e7f21 url:string = payments.StarsRevenueAdsAccountUrl; + +inputStarsTransaction#206ae6d1 flags:# refund:flags.0?true id:string = InputStarsTransaction; + +starsGiftOption#5e0589f1 flags:# extended:flags.1?true stars:long store_product:flags.0?string currency:string amount:long = StarsGiftOption; + +bots.popularAppBots#1991b13b flags:# next_offset:flags.0?string users:Vector = bots.PopularAppBots; + +botPreviewMedia#23e91ba3 date:int media:MessageMedia = BotPreviewMedia; + +bots.previewInfo#ca71d64 media:Vector lang_codes:Vector = bots.PreviewInfo; + ---functions--- invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; @@ -1981,7 +2012,7 @@ contacts.unblock#b550d328 flags:# my_stories_from:flags.0?true id:InputPeer = Bo contacts.getBlocked#9a868f80 flags:# my_stories_from:flags.0?true offset:int limit:int = contacts.Blocked; contacts.search#11f812d8 q:string limit:int = contacts.Found; contacts.resolveUsername#f93ccba3 username:string = contacts.ResolvedPeer; -contacts.getTopPeers#973478b6 flags:# correspondents:flags.0?true bots_pm:flags.1?true bots_inline:flags.2?true phone_calls:flags.3?true forward_users:flags.4?true forward_chats:flags.5?true groups:flags.10?true channels:flags.15?true offset:int limit:int hash:long = contacts.TopPeers; +contacts.getTopPeers#973478b6 flags:# correspondents:flags.0?true bots_pm:flags.1?true bots_inline:flags.2?true phone_calls:flags.3?true forward_users:flags.4?true forward_chats:flags.5?true groups:flags.10?true channels:flags.15?true bots_app:flags.16?true offset:int limit:int hash:long = contacts.TopPeers; contacts.resetTopPeerRating#1ae373ac category:TopPeerCategory peer:InputPeer = Bool; contacts.resetSaved#879537f1 = Bool; contacts.getSaved#82f1e39f = Vector; @@ -2058,7 +2089,7 @@ messages.editInlineBotMessage#83557dba flags:# no_webpage:flags.1?true invert_me 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; messages.getPeerDialogs#e470bcfd peers:Vector = messages.PeerDialogs; -messages.saveDraft#7ff3b806 flags:# no_webpage:flags.1?true invert_media:flags.6?true reply_to:flags.4?InputReplyTo peer:InputPeer message:string entities:flags.3?Vector media:flags.5?InputMedia = Bool; +messages.saveDraft#d372c5ce flags:# no_webpage:flags.1?true invert_media:flags.6?true reply_to:flags.4?InputReplyTo peer:InputPeer message:string entities:flags.3?Vector media:flags.5?InputMedia effect:flags.7?long = Bool; messages.getAllDrafts#6a3f8d65 = Updates; messages.getFeaturedStickers#64780b14 hash:long = messages.FeaturedStickers; messages.readFeaturedStickers#5b118126 id:Vector = Bool; @@ -2158,9 +2189,9 @@ messages.searchSentMedia#107e31a0 q:string filter:MessagesFilter limit:int = mes messages.getAttachMenuBots#16fcc2cb hash:long = AttachMenuBots; messages.getAttachMenuBot#77216192 bot:InputUser = AttachMenuBotsBot; messages.toggleBotInAttachMenu#69f59d69 flags:# write_allowed:flags.0?true bot:InputUser enabled:Bool = Bool; -messages.requestWebView#269dc2c1 flags:# from_bot_menu:flags.4?true silent:flags.5?true peer:InputPeer bot:InputUser url:flags.1?string start_param:flags.3?string theme_params:flags.2?DataJSON platform:string reply_to:flags.0?InputReplyTo send_as:flags.13?InputPeer = WebViewResult; +messages.requestWebView#269dc2c1 flags:# from_bot_menu:flags.4?true silent:flags.5?true compact:flags.7?true peer:InputPeer bot:InputUser url:flags.1?string start_param:flags.3?string theme_params:flags.2?DataJSON platform:string reply_to:flags.0?InputReplyTo send_as:flags.13?InputPeer = WebViewResult; messages.prolongWebView#b0d81a83 flags:# silent:flags.5?true peer:InputPeer bot:InputUser query_id:long reply_to:flags.0?InputReplyTo send_as:flags.13?InputPeer = Bool; -messages.requestSimpleWebView#1a46500a flags:# from_switch_webview:flags.1?true from_side_menu:flags.2?true bot:InputUser url:flags.3?string start_param:flags.4?string theme_params:flags.0?DataJSON platform:string = SimpleWebViewResult; +messages.requestSimpleWebView#413a3e73 flags:# from_switch_webview:flags.1?true from_side_menu:flags.2?true compact:flags.7?true bot:InputUser url:flags.3?string start_param:flags.4?string theme_params:flags.0?DataJSON platform:string = WebViewResult; messages.sendWebViewResultMessage#a4314f5 bot_query_id:string result:InputBotInlineResult = WebViewMessageSent; messages.sendWebViewData#dc0242c8 bot:InputUser random_id:long button_text:string data:string = Updates; messages.transcribeAudio#269e9a49 peer:InputPeer msg_id:int = messages.TranscribedAudio; @@ -2182,7 +2213,7 @@ messages.getEmojiProfilePhotoGroups#21a548f3 hash:int = messages.EmojiGroups; messages.searchCustomEmoji#2c11c0d7 emoticon:string hash:long = EmojiList; messages.togglePeerTranslations#e47cb579 flags:# disabled:flags.0?true peer:InputPeer = Bool; messages.getBotApp#34fdc5c3 app:InputBotApp hash:long = messages.BotApp; -messages.requestAppWebView#8c5a3b3c flags:# write_allowed:flags.0?true peer:InputPeer app:InputBotApp start_param:flags.1?string theme_params:flags.2?DataJSON platform:string = AppWebViewResult; +messages.requestAppWebView#53618bce flags:# write_allowed:flags.0?true compact:flags.7?true peer:InputPeer app:InputBotApp start_param:flags.1?string theme_params:flags.2?DataJSON platform:string = WebViewResult; messages.setChatWallPaper#8ffacae1 flags:# for_both:flags.3?true revert:flags.4?true peer:InputPeer wallpaper:flags.0?InputWallPaper settings:flags.2?WallPaperSettings id:flags.1?int = Updates; messages.searchEmojiStickerSets#92b4494c flags:# exclude_featured:flags.0?true q:string hash:long = messages.FoundStickerSets; messages.getSavedDialogs#5381d21a flags:# exclude_pinned:flags.0?true offset_date:int offset_id:int offset_peer:InputPeer limit:int hash:long = messages.SavedDialogs; @@ -2210,6 +2241,7 @@ messages.getAvailableEffects#dea20a39 hash:int = messages.AvailableEffects; messages.editFactCheck#589ee75 peer:InputPeer msg_id:int text:TextWithEntities = Updates; messages.deleteFactCheck#d1da940c peer:InputPeer msg_id:int = Updates; messages.getFactCheck#b9cdc5ee peer:InputPeer msg_id:Vector = Vector; +messages.requestMainWebView#c9e01e7b flags:# compact:flags.7?true peer:InputPeer bot:InputUser start_param:flags.1?string theme_params:flags.0?DataJSON platform:string = WebViewResult; 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; @@ -2338,6 +2370,13 @@ bots.toggleUsername#53ca973 bot:InputUser username:string active:Bool = Bool; bots.canSendMessage#1359f4e6 bot:InputUser = Bool; bots.allowSendMessage#f132e3ef bot:InputUser = Updates; bots.invokeWebViewCustomMethod#87fc5e7 bot:InputUser custom_method:string params:DataJSON = DataJSON; +bots.getPopularAppBots#c2510192 offset:string limit:int = bots.PopularAppBots; +bots.addPreviewMedia#17aeb75a bot:InputUser lang_code:string media:InputMedia = BotPreviewMedia; +bots.editPreviewMedia#8525606f bot:InputUser lang_code:string media:InputMedia new_media:InputMedia = BotPreviewMedia; +bots.deletePreviewMedia#2d0135b3 bot:InputUser lang_code:string media:Vector = Bool; +bots.reorderPreviewMedias#b627f3aa bot:InputUser lang_code:string order:Vector = Bool; +bots.getPreviewInfo#423ab3ad bot:InputUser lang_code:string = bots.PreviewInfo; +bots.getPreviewMedias#a2a5594d bot:InputUser = Vector; payments.getPaymentForm#37148dbb flags:# invoice:InputInvoice theme_params:flags.0?DataJSON = payments.PaymentForm; payments.getPaymentReceipt#2478d1cc peer:InputPeer msg_id:int = payments.PaymentReceipt; @@ -2357,9 +2396,14 @@ payments.getGiveawayInfo#f4239425 peer:InputPeer msg_id:int = payments.GiveawayI payments.launchPrepaidGiveaway#5ff58f20 peer:InputPeer giveaway_id:long purpose:InputStorePaymentPurpose = Updates; payments.getStarsTopupOptions#c00ec7d3 = Vector; payments.getStarsStatus#104fcfa7 peer:InputPeer = payments.StarsStatus; -payments.getStarsTransactions#673ac2f9 flags:# inbound:flags.0?true outbound:flags.1?true peer:InputPeer offset:string = payments.StarsStatus; +payments.getStarsTransactions#97938d5a flags:# inbound:flags.0?true outbound:flags.1?true ascending:flags.2?true peer:InputPeer offset:string limit:int = payments.StarsStatus; payments.sendStarsForm#2bb731d flags:# form_id:long invoice:InputInvoice = payments.PaymentResult; payments.refundStarsCharge#25ae8f4a user_id:InputUser charge_id:string = Updates; +payments.getStarsRevenueStats#d91ffad6 flags:# dark:flags.0?true peer:InputPeer = payments.StarsRevenueStats; +payments.getStarsRevenueWithdrawalUrl#13bbe8b3 peer:InputPeer stars:long password:InputCheckPasswordSRP = payments.StarsRevenueWithdrawalUrl; +payments.getStarsRevenueAdsAccountUrl#d1d7efc5 peer:InputPeer = payments.StarsRevenueAdsAccountUrl; +payments.getStarsTransactionsByID#27842d2e peer:InputPeer id:Vector = payments.StarsStatus; +payments.getStarsGiftOptions#d3c96bc8 flags:# user_id:flags.0?InputUser = Vector; 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; stickers.removeStickerFromSet#f7760f51 sticker:InputDocument = messages.StickerSet; @@ -2461,6 +2505,7 @@ 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; stories.togglePinnedToTop#b297e9b peer:InputPeer id:Vector = Bool; +stories.searchPosts#6cea116a flags:# hashtag:flags.0?string area:flags.1?MediaArea offset:string limit:int = stories.FoundStories; premium.getBoostsList#60f67660 flags:# gifts:flags.0?true peer:InputPeer offset:string limit:int = premium.BoostsList; premium.getMyBoosts#be77b4a = premium.MyBoosts; @@ -2478,4 +2523,4 @@ smsjobs.finishJob#4f1ebf24 flags:# job_id:string error:flags.0?string = Bool; fragment.getCollectibleInfo#be1e85ba collectible:InputCollectible = fragment.CollectibleInfo; -// LAYER 181 +// LAYER 185 diff --git a/compiler/docs/compiler.py b/compiler/docs/compiler.py index e1917a6b9..fcfcafddc 100644 --- a/compiler/docs/compiler.py +++ b/compiler/docs/compiler.py @@ -204,6 +204,8 @@ def get_title_list(s: str) -> list: send_web_page start_bot update_color + delete_chat_history + send_paid_media """, chats=""" Chats @@ -274,6 +276,7 @@ def get_title_list(s: str) -> list: get_chat_photos get_chat_photos_count set_profile_photo + set_personal_channel delete_profile_photos set_username update_profile @@ -285,7 +288,6 @@ def get_title_list(s: str) -> list: update_status check_username update_birthday - update_personal_channel """, invite_links=""" Invite Links @@ -314,10 +316,13 @@ def get_title_list(s: str) -> list: import_contacts get_contacts get_contacts_count + search_contacts """, payments=""" Payments check_gift_code + get_payment_form + send_payment_form """, phone=""" Phone @@ -333,6 +338,7 @@ def get_title_list(s: str) -> list: Bots get_inline_bot_results send_inline_bot_result + send_invoice answer_callback_query answer_inline_query request_callback_answer @@ -370,6 +376,9 @@ def get_title_list(s: str) -> list: recover_password accept_terms_of_service log_out + get_active_sessions + reset_session + reset_sessions """, advanced=""" Advanced @@ -402,6 +411,13 @@ def get_title_list(s: str) -> list: apply_boost get_boosts get_boosts_status + """, + account=""" + Account + get_account_ttl + set_account_ttl + set_privacy + get_privacy """ ) @@ -454,7 +470,6 @@ def get_title_list(s: str) -> list: User Username Chat - ChatPreview ChatPhoto ChatMember ChatPermissions @@ -472,6 +487,8 @@ def get_title_list(s: str) -> list: Folder GroupCallMember ChatColor + FoundContacts + PrivacyRule """, messages_media=""" Messages & Media @@ -512,6 +529,9 @@ def get_title_list(s: str) -> list: GiftCode CheckedGiftCode SuccessfulPayment + PaidMediaInfo + PaidMediaPreview + PaymentForm """, bot_keyboards=""" Bot keyboards @@ -536,7 +556,7 @@ def get_title_list(s: str) -> list: RequestChatInfo RequestUserInfo RequestPollInfo - PaymentInfo + OrderInfo PreCheckoutQuery ShippingAddress """, @@ -592,8 +612,22 @@ def get_title_list(s: str) -> list: """, authorization=""" Authorization + ActiveSession + ActiveSessions SentCode TermsOfService + """, + input_privacy_rule=""" + InputPrivacyRule + InputPrivacyRuleAllowAll + InputPrivacyRuleAllowContacts + InputPrivacyRuleAllowPremium + InputPrivacyRuleAllowUsers + InputPrivacyRuleAllowChats + InputPrivacyRuleDisallowAll + InputPrivacyRuleDisallowContacts + InputPrivacyRuleDisallowUsers + InputPrivacyRuleDisallowChats """ ) @@ -664,6 +698,7 @@ def get_title_list(s: str) -> list: Message.react Message.read Message.view + Message.pay """, chat=""" Chat @@ -751,6 +786,10 @@ def get_title_list(s: str) -> list: Folder.pin_chat Folder.remove_chat Folder.export_link + """, + active_session=""" + ActiveSession + ActiveSession.reset """ ) diff --git a/compiler/docs/template/bound-methods.rst b/compiler/docs/template/bound-methods.rst index 163753ddf..6ff55697e 100644 --- a/compiler/docs/template/bound-methods.rst +++ b/compiler/docs/template/bound-methods.rst @@ -139,3 +139,16 @@ Folder :hidden: {folder_toctree} + +ActiveSession +------------- + +.. hlist:: + :columns: 2 + + {active_session_hlist} + +.. toctree:: + :hidden: + + {active_session_toctree} diff --git a/compiler/docs/template/methods.rst b/compiler/docs/template/methods.rst index 839a9210b..6963c2c76 100644 --- a/compiler/docs/template/methods.rst +++ b/compiler/docs/template/methods.rst @@ -177,6 +177,58 @@ Premium {premium} +Phone +----- + +.. autosummary:: + :nosignatures: + + {phone} + +.. toctree:: + :hidden: + + {phone} + +Business +-------- + +.. autosummary:: + :nosignatures: + + {business} + +.. toctree:: + :hidden: + + {business} + +Payments +-------- + +.. autosummary:: + :nosignatures: + + {payments} + +.. toctree:: + :hidden: + + {payments} + +Account +------- + +.. autosummary:: + :nosignatures: + + {account} + +.. toctree:: + :hidden: + + {account} + Advanced -------- diff --git a/compiler/docs/template/types.rst b/compiler/docs/template/types.rst index e404ad4cd..d371a4f73 100644 --- a/compiler/docs/template/types.rst +++ b/compiler/docs/template/types.rst @@ -123,4 +123,17 @@ Authorization .. toctree:: :hidden: - {authorization} \ No newline at end of file + {authorization} + +InputPrivacyRule +---------------- + +.. autosummary:: + :nosignatures: + + {input_privacy_rule} + +.. toctree:: + :hidden: + + {input_privacy_rule} diff --git a/compiler/errors/source/400_BAD_REQUEST.tsv b/compiler/errors/source/400_BAD_REQUEST.tsv index 6bc07178e..a36f3555b 100644 --- a/compiler/errors/source/400_BAD_REQUEST.tsv +++ b/compiler/errors/source/400_BAD_REQUEST.tsv @@ -2,10 +2,12 @@ id message ABOUT_TOO_LONG The provided about/bio text is too long ACCESS_TOKEN_EXPIRED The bot token has expired ACCESS_TOKEN_INVALID The bot access token is invalid +ADDRESS_INVALID The specified geopoint address is invalid. ADMINS_TOO_MUCH The chat has too many administrators ADMIN_ID_INVALID The specified admin ID is invalid ADMIN_RANK_EMOJI_NOT_ALLOWED Emoji are not allowed in custom administrator titles ADMIN_RANK_INVALID The custom administrator title is invalid or too long +ADMIN_RIGHTS_EMPTY The chatAdminRights constructor passed in keyboardButtonRequestPeer.peer_type.user_admin_rights has no rights set (i.e. flags is 0). ALBUM_PHOTOS_TOO_MANY Too many photos were included in the album API_ID_INVALID The api_id/api_hash combination is invalid API_ID_PUBLISHED_FLOOD You are using an API key that is limited on the server side because it was published somewhere @@ -20,12 +22,18 @@ AUTH_TOKEN_INVALID An invalid authorization token was provided AUTH_TOKEN_INVALID2 An invalid authorization token was provided AUTH_TOKEN_INVALIDX The specified auth token is invalid AUTOARCHIVE_NOT_AVAILABLE This feature is not yet enabled for your account due to it not receiving too many private messages from strangers +BALANCE_TOO_LOW Your stars balance too low BANK_CARD_NUMBER_INVALID The credit card number is invalid BANNED_RIGHTS_INVALID You provided a set of restrictions that is invalid BASE_PORT_LOC_INVALID The base port location is invalid +BIRTHDAY_INVALID The age should be less than 150 year old in Telegram BOOSTS_EMPTY Boosts empty BOOSTS_REQUIRED Boosts required +BOOST_NOT_MODIFIED You're already [boosting](https://core.telegram.org/api/boost) the specified channel. +BOOST_PEER_INVALID The specified `boost_peer` is invalid. BOTS_TOO_MUCH The chat has too many bots +BOT_APP_INVALID The specified bot app is invalid. +BOT_APP_SHORTNAME_INVALID The specified bot app short name is invalid. BOT_CHANNELS_NA Bots can't edit admin privileges BOT_COMMAND_DESCRIPTION_INVALID The command description was empty, too long or had invalid characters BOT_COMMAND_INVALID The specified command is invalid @@ -41,17 +49,21 @@ BOT_PAYMENTS_DISABLED This method can only be run by a bot BOT_POLLS_DISABLED Sending polls by bots has been disabled BOT_RESPONSE_TIMEOUT The bot did not answer to the callback query in time BOT_SCORE_NOT_MODIFIED The bot score was not modified +BOT_WEBVIEW_DISABLED A webview cannot be opened in the specified conditions: emitted for example if `from_bot_menu` or `url` are set and `peer` is not the chat with the bot. BROADCAST_CALLS_DISABLED Broadcast calls disabled BROADCAST_ID_INVALID The channel is invalid BROADCAST_PUBLIC_VOTERS_FORBIDDEN Polls with public voters cannot be sent in channels BROADCAST_REQUIRED The request can only be used with a channel BUTTON_DATA_INVALID The button callback data is invalid or too large +BUTTON_ID_INVALID The button_id parameter is invalid BUTTON_TEXT_INVALID The specified button text is invalid BUTTON_TYPE_INVALID The type of one of the buttons you provided is invalid BUTTON_URL_INVALID The button url is invalid +BUTTON_USER_INVALID The user_id passed to inputKeyboardButtonUserProfile is invalid BUTTON_USER_PRIVACY_RESTRICTED The privacy settings of the user specified in a keyboard button do not allow creating such button CALL_ALREADY_ACCEPTED The call is already accepted CALL_ALREADY_DECLINED The call is already declined +CALL_OCCUPY_FAILED The call failed because the user is already making another call. CALL_PEER_INVALID The provided call peer object is invalid CALL_PROTOCOL_FLAGS_INVALID Call protocol flags invalid CDN_METHOD_INVALID The method can't be used on CDN DCs @@ -61,11 +73,16 @@ CHANNELS_TOO_MUCH You have joined too many channels or supergroups, leave some a CHANNEL_ADD_INVALID Internal error. CHANNEL_BANNED The channel is banned CHANNEL_FORUM_MISSING The channel forum is missing +CHANNEL_ID_INVALID The specified supergroup ID is invalid. CHANNEL_INVALID The channel parameter is invalid CHANNEL_PARICIPANT_MISSING The current user is not in the channel CHANNEL_PRIVATE The channel/supergroup is not accessible CHANNEL_TOO_BIG The channel too big CHANNEL_TOO_LARGE The channel is too large +CHARGE_ALREADY_REFUNDED The charge id was already used for a refund. +CHARGE_NOT_FOUND The charge id was not found. +CHATLISTS_TOO_MUCH You have too much chatlists on your account +CHATLIST_EXCLUDE_INVALID The specified `exclude_peers` are invalid. CHAT_ABOUT_NOT_MODIFIED The chat about text was not modified because you tried to edit it using the same content CHAT_ABOUT_TOO_LONG The chat about text is too long CHAT_ADMIN_REQUIRED The method requires chat admin privileges @@ -77,6 +94,7 @@ CHAT_INVALID The chat is invalid CHAT_INVITE_PERMANENT The chat invite link is primary CHAT_LINK_EXISTS The action failed because the supergroup is linked to a channel CHAT_NOT_MODIFIED The chat settings (title, permissions, photo, etc..) were not modified because you tried to edit them using the same content +CHAT_PUBLIC_REQUIRED You can only enable join requests in public groups. CHAT_RESTRICTED The chat is restricted and cannot be used CHAT_REVOKE_DATE_UNSUPPORTED `min_date` and `max_date` are not available for using with non-user peers CHAT_SEND_INLINE_FORBIDDEN You cannot use inline bots to send messages in this chat @@ -96,10 +114,12 @@ CONNECTION_SYSTEM_EMPTY The connection to the system is empty CONNECTION_SYSTEM_LANG_CODE_EMPTY The system language code is empty CONTACT_ADD_MISSING Contact to add is missing CONTACT_ID_INVALID The provided contact id is invalid +CONTACT_MISSING The specified user is not a contact. CONTACT_NAME_EMPTY The provided contact name is empty CONTACT_REQ_MISSING Missing contact request CREATE_CALL_FAILED An error occurred while creating the call CURRENCY_TOTAL_AMOUNT_INVALID The total amount of all prices is invalid +CUSTOM_REACTIONS_TOO_MANY Too many custom reactions were specified. DATA_INVALID The encrypted data is invalid DATA_JSON_INVALID The provided JSON data is invalid DATA_TOO_LONG Data too long @@ -110,10 +130,12 @@ DOCUMENT_INVALID The document is invalid EMAIL_HASH_EXPIRED The email hash expired and cannot be used to verify it EMAIL_INVALID The email provided is invalid EMAIL_NOT_ALLOWED This email is not allowed +EMAIL_NOT_SETUP In order to change the login email with emailVerifyPurposeLoginChange, an existing login email must already be set using emailVerifyPurposeLoginSetup. EMAIL_UNCONFIRMED Email unconfirmed EMAIL_UNCONFIRMED_X The provided email isn't confirmed, {value} is the length of the verification code that was just sent to the email EMAIL_VERIFY_EXPIRED The verification email has expired EMOJI_INVALID The specified theme emoji is valid +EMOJI_MARKUP_INVALID The specified `video_emoji_markup` was invalid. EMOJI_NOT_MODIFIED The theme wasn't changed EMOTICON_EMPTY The emoticon parameter is empty EMOTICON_INVALID The emoticon parameter is invalid @@ -130,6 +152,9 @@ ERROR_TEXT_EMPTY The provided error message is empty EXPIRE_DATE_INVALID The expiration date is invalid EXPIRE_FORBIDDEN Expire forbidden EXPORT_CARD_INVALID The provided card is invalid +EXTENDED_MEDIA_AMOUNT_INVALID The maximum amount of `star_count` should be less than the `stars_paid_post_amount_max` [client configuration parameters](/api/config). +EXTENDED_MEDIA_PEER_INVALID The specified chat type is invalid. +EXTENDED_MEDIA_TYPE_INVALID The specified extended media type is unsupported. EXTERNAL_URL_INVALID The external media URL is invalid FIELD_NAME_EMPTY The field with the name FIELD_NAME is missing FIELD_NAME_INVALID The field with the name FIELD_NAME is invalid @@ -150,6 +175,7 @@ FILE_REFERENCE_EMPTY The file id contains an empty file reference, you must obta FILE_REFERENCE_EXPIRED The file id contains an expired file reference, you must obtain a valid one by fetching the message from the origin context FILE_REFERENCE_INVALID The file id contains an invalid file reference, you must obtain a valid one by fetching the message from the origin context FILE_TITLE_EMPTY An empty file title was specified +FILE_TOKEN_INVALID The specified file token is invalid. FILTER_ID_INVALID The specified filter ID is invalid FILTER_INCLUDE_EMPTY The filter include is empty FILTER_NOT_SUPPORTED The specified filter cannot be used in this context @@ -157,18 +183,23 @@ FILTER_TITLE_EMPTY The title field of the filter is empty FIRSTNAME_INVALID The first name is invalid FOLDER_ID_EMPTY The folder you tried to delete was already empty FOLDER_ID_INVALID The folder id is invalid +FORM_ID_EXPIRED The specified id has expired. +FORUM_ENABLED You can't execute the specified action because the group is a [forum](https://core.telegram.org/api/forum), disable forum functionality to continue. FRESH_CHANGE_ADMINS_FORBIDDEN You can't change administrator settings in this chat because your session was logged-in recently FROM_MESSAGE_BOT_DISABLED Bots can't use fromMessage min constructors FROM_PEER_INVALID The from peer value is invalid GAME_BOT_INVALID You cannot send that game with the current bot +GENERAL_MODIFY_ICON_FORBIDDEN You can't modify the icon of the "General" topic. GEO_POINT_INVALID Invalid geo point provided GIFT_SLUG_EXPIRED The gift slug is expired +GIFT_SLUG_INVALID The specified slug is invalid. GIF_CONTENT_TYPE_INVALID GIF content-type invalid GIF_ID_INVALID The provided gif/animation id is invalid GRAPH_EXPIRED_RELOAD This graph has expired, please obtain a new graph token GRAPH_INVALID_RELOAD Invalid graph token provided, please reload the stats and provide the updated token GRAPH_OUTDATED_RELOAD The graph data is outdated GROUPCALL_ALREADY_DISCARDED The group call was already discarded +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 @@ -181,7 +212,9 @@ IMAGE_PROCESS_FAILED The server failed to process your image IMPORT_FILE_INVALID The imported file is invalid IMPORT_FORMAT_UNRECOGNIZED The imported format is unrecognized IMPORT_ID_INVALID The import id is invalid +IMPORT_TOKEN_INVALID The specified token is invalid. INLINE_RESULT_EXPIRED The inline bot query expired +INPUT_CHATLIST_INVALID The specified folder is invalid. INPUT_CONSTRUCTOR_INVALID The provided constructor is invalid INPUT_FETCH_ERROR An error occurred while deserializing TL parameters INPUT_FETCH_FAIL Failed deserializing TL payload @@ -190,7 +223,9 @@ INPUT_LAYER_INVALID The provided layer is invalid INPUT_METHOD_INVALID The method invoked is invalid in the current schema INPUT_REQUEST_TOO_LONG The input request is too long INPUT_TEXT_EMPTY The specified text is empty +INPUT_TEXT_TOO_LONG The specified text is too long. INPUT_USER_DEACTIVATED The target user has been deleted/deactivated +INVITES_TOO_MUCH The maximum number of per-folder invites specified by the `chatlist_invites_limit_default`/`chatlist_invites_limit_premium` [client configuration parameters »](/api/config#chatlist-invites-limit-default) was reached. INVITE_FORBIDDEN_WITH_JOINAS If the user has anonymously joined a group call as a channel, they can't invite other users to the group call because that would cause deanonymization, because the invite would be sent using the original user ID, not the anonymized channel ID INVITE_HASH_EMPTY The invite hash is empty INVITE_HASH_EXPIRED The chat invite link is no longer valid @@ -220,7 +255,9 @@ MEDIA_INVALID The media is invalid MEDIA_NEW_INVALID The new media to edit the message with is invalid MEDIA_PREV_INVALID The previous media cannot be edited with anything else MEDIA_TTL_INVALID The media ttl is invalid +MEDIA_TYPE_INVALID The specified media type cannot be used in stories. MEDIA_VIDEO_STORY_MISSING The media does not have a photo or a video +MEGAGROUP_GEO_REQUIRED This method can only be invoked on a geogroup. MEGAGROUP_ID_INVALID The supergroup is invalid MEGAGROUP_PREHISTORY_HIDDEN The action failed because the supergroup has the pre-history hidden MEGAGROUP_REQUIRED The request can only be used with a supergroup @@ -242,10 +279,12 @@ NEW_SALT_INVALID The new salt is invalid NEW_SETTINGS_EMPTY No password is set on the current account, and no new password was specified in `new_settings` NEW_SETTINGS_INVALID The new settings are invalid NEXT_OFFSET_INVALID The next offset value is invalid +NOGENERAL_HIDE_FORBIDDEN The hidden parameter is only valid for the General topic message_thread_id=1 OFFSET_INVALID The offset parameter is invalid OFFSET_PEER_ID_INVALID The provided offset peer is invalid OPTIONS_TOO_MUCH The poll options are too many OPTION_INVALID The option specified is invalid and does not exist in the target poll +ORDER_INVALID The specified username order is invalid. PACK_SHORT_NAME_INVALID Invalid sticker pack name. It must begin with a letter, can't contain consecutive underscores and must end in '_by_'. PACK_SHORT_NAME_OCCUPIED A sticker pack with this name already exists PACK_TITLE_INVALID The sticker pack title is invalid @@ -256,10 +295,12 @@ PARTICIPANT_VERSION_OUTDATED The other participant is using an outdated Telegram PASSWORD_EMPTY The password provided is empty PASSWORD_HASH_INVALID The two-step verification password is invalid PASSWORD_MISSING The account is missing the two-step verification password +PASSWORD_RECOVERY_EXPIRED The recovery code has expired. PASSWORD_RECOVERY_NA The password recovery e-mail is not available PASSWORD_REQUIRED The two-step verification password is required for this method PASSWORD_TOO_FRESH_X The two-step verification password was added recently and you are required to wait {value} seconds PAYMENT_PROVIDER_INVALID The payment provider was not recognised or its token was invalid +PEERS_LIST_EMPTY The specified list of peers is empty. PEER_FLOOD The method can't be used because your account is currently limited PEER_HISTORY_EMPTY Peer history empty PEER_ID_INVALID The peer id being used is invalid or not known yet. Make sure you meet the peer before interacting with it @@ -293,6 +334,7 @@ PHOTO_THUMB_URL_EMPTY The photo thumb URL is empty PHOTO_THUMB_URL_INVALID The photo thumb URL is invalid PINNED_DIALOGS_TOO_MUCH Too many pinned dialogs PIN_RESTRICTED You can't pin messages in private chats with other people +PLATFORM_INVALID The provided platform is invalid. Allowed values are "android", "ios", "wp", "bb", "desktop", "web", "ubp", "other". POLL_ANSWERS_INVALID The poll answers are invalid POLL_ANSWER_INVALID One of the poll answers is not acceptable POLL_OPTION_DUPLICATE A duplicate option was sent in the same poll @@ -301,9 +343,11 @@ POLL_QUESTION_INVALID The poll question is invalid POLL_UNSUPPORTED This layer does not support polls in the invoked method POLL_VOTE_REQUIRED Cast a vote in the poll before calling this method PREMIUM_ACCOUNT_REQUIRED The method requires a premium user account +PREMIUM_GIFTCODE_WAS_REFUNDED This gift code can't be redeemed because the giveaway organizer requested a refund PRIVACY_KEY_INVALID The privacy key is invalid PRIVACY_TOO_LONG Your privacy exception list has exceeded the maximum capacity PRIVACY_VALUE_INVALID The privacy value is invalid +PUBLIC_BROADCAST_EXPECTED A public channel was expected, but something else was provided PUBLIC_KEY_REQUIRED A public key is required QUERY_ID_EMPTY The query ID is empty QUERY_ID_INVALID The callback query id is invalid @@ -327,6 +371,8 @@ REPLY_MARKUP_GAME_EMPTY The provided reply markup for the game is empty REPLY_MARKUP_INVALID The provided reply markup is invalid REPLY_MARKUP_TOO_LONG The reply markup is too long REPLY_MESSAGE_ID_INVALID The reply message id is invalid +REPLY_TO_INVALID The specified `reply_to` field is invalid. +REPLY_TO_USER_INVALID The replied-to user is invalid. RESET_REQUEST_MISSING No password reset is in progress RESULTS_TOO_MUCH The result contains too many items RESULT_ID_DUPLICATE The result contains items with duplicated identifiers @@ -336,6 +382,7 @@ RESULT_TYPE_INVALID The result type is invalid REVOTE_NOT_ALLOWED You cannot change your vote RIGHTS_NOT_MODIFIED The new admin rights are equal to the old rights, no change was made RSA_DECRYPT_FAILED Internal RSA decryption failed +SAVED_DIALOGS_UNSUPPORTED You cannot use this method SCHEDULE_BOT_NOT_ALLOWED Bots are not allowed to schedule messages SCHEDULE_DATE_INVALID Invalid schedule date provided SCHEDULE_DATE_TOO_LATE The date you tried to schedule is too far in the future (more than one year) @@ -354,7 +401,9 @@ SHA256_HASH_INVALID The provided SHA256 hash is invalid SHORTNAME_OCCUPY_FAILED An error occurred when trying to register the short-name used for the sticker pack. Try a different name SHORT_NAME_INVALID The specified short name is invalid SHORT_NAME_OCCUPIED The specified short name is already in use +SLOTS_EMPTY The specified slot list is empty. SLOWMODE_MULTI_MSGS_DISABLED Slowmode is enabled, you cannot forward multiple messages to this group +SLUG_INVALID The specified invoice slug is invalid. SMS_CODE_CREATE_FAILED An error occurred while creating the SMS code SRP_ID_INVALID Invalid SRP ID provided SRP_PASSWORD_CHANGED The password has changed @@ -378,15 +427,23 @@ STICKER_PNG_NOPNG Stickers must be png files but the provided image was not a pn STICKER_TGS_NODOC You must send the animated sticker as a document STICKER_TGS_NOTGS A tgs sticker file was expected, but something else was provided STICKER_THUMB_PNG_NOPNG A png sticker thumbnail file was expected, but something else was provided +STICKER_THUMB_TGS_NOTGS Incorrect stickerset TGS thumb file provided. STICKER_VIDEO_BIG The specified video sticker is too big STICKER_VIDEO_NODOC You must send the video sticker as a document STICKER_VIDEO_NOWEBM A webm video file was expected, but something else was provided +STORAGE_KEY_REQUIRED A cloud storage key is required. STORIES_NEVER_CREATED You have never created any stories STORIES_TOO_MUCH Too many stories in the current account +STORY_ID_EMPTY You specified no story IDs. +STORY_ID_INVALID The specified story ID is invalid. +STORY_NOT_MODIFIED The new story information you passed is equal to the previous story information, thus it wasn't modified. STORY_PERIOD_INVALID The story period is invalid +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. SWITCH_PM_TEXT_EMPTY The switch_pm.text field was empty TAKEOUT_INVALID The takeout id is invalid TAKEOUT_REQUIRED The method must be invoked inside a takeout session +TASK_ALREADY_EXISTS An email reset was already requested. TEMP_AUTH_KEY_ALREADY_BOUND The passed temporary key is already bound to another perm_auth_key_id TEMP_AUTH_KEY_EMPTY The temporary auth key provided is empty THEME_FILE_INVALID Invalid theme file provided @@ -397,11 +454,18 @@ THEME_TITLE_INVALID The specified theme title is invalid TITLE_INVALID The specified stickerpack title is invalid TMP_PASSWORD_DISABLED The temporary password is disabled TMP_PASSWORD_INVALID The temporary password is invalid +TOKEN_EMPTY The specified token is empty. TOKEN_INVALID The provided token is invalid +TOKEN_SECRET_INVALID The specified token secret is invalid +TOKEN_TYPE_INVALID The specified token type is invalid. +TOPICS_EMPTY You specified no topic IDs. TOPIC_CLOSED The topic was closed +TOPIC_CLOSE_SEPARATELY The `close` flag cannot be provided together with any of the other flags. TOPIC_DELETED The topic was deleted +TOPIC_HIDE_SEPARATELY The `hide` flag cannot be provided together with any of the other flags. TOPIC_ID_INVALID The provided topic ID is invalid TOPIC_NOT_MODIFIED The topic was not modified +TOPIC_TITLE_EMPTY The specified topic title is empty. TO_LANG_INVALID The specified destination language is invalid TRANSCRIPTION_FAILED Telegram is having internal problems. Please try again later to transcribe the audio. TTL_DAYS_INVALID The provided TTL days is invalid @@ -413,6 +477,7 @@ UNKNOWN_ERROR Unknown error UNTIL_DATE_INVALID That date parameter is invalid URL_INVALID The URL provided is invalid USAGE_LIMIT_INVALID The usage limit is invalid +USERNAMES_ACTIVE_TOO_MUCH The maximum number of active usernames was reached. USERNAME_INVALID The username is invalid USERNAME_NOT_MODIFIED The username was not modified because you tried to edit it using the same one USERNAME_NOT_OCCUPIED The username is not occupied by anyone @@ -440,6 +505,7 @@ USER_NOT_MUTUAL_CONTACT The user is not a mutual contact USER_NOT_PARTICIPANT The user is not a member of this chat USER_PUBLIC_MISSING The accounts username is missing USER_VOLUME_INVALID The specified user volume is invalid +VENUE_ID_INVALID The specified venue ID is invalid. VIDEO_CONTENT_TYPE_INVALID The video content type is invalid (i.e.: not streamable) VIDEO_FILE_INVALID The video file is invalid VIDEO_TITLE_EMPTY The specified video title is empty @@ -448,6 +514,7 @@ VOLUME_LOC_NOT_FOUND The volume location can't be found WALLPAPER_FILE_INVALID The provided file cannot be used as a wallpaper WALLPAPER_INVALID The input wallpaper was not valid WALLPAPER_MIME_INVALID The wallpaper mime type is invalid +WALLPAPER_NOT_FOUND The specified wallpaper could not be found. WC_CONVERT_URL_INVALID WC convert URL invalid WEBDOCUMENT_INVALID The web document is invalid WEBDOCUMENT_MIME_INVALID The web document mime type is invalid diff --git a/compiler/errors/source/403_FORBIDDEN.tsv b/compiler/errors/source/403_FORBIDDEN.tsv index 64aaeb937..ef59691f9 100644 --- a/compiler/errors/source/403_FORBIDDEN.tsv +++ b/compiler/errors/source/403_FORBIDDEN.tsv @@ -1,4 +1,5 @@ id message +ANONYMOUS_REACTIONS_DISABLED Sorry, anonymous administrators cannot leave reactions or participate in polls. BROADCAST_FORBIDDEN The request can't be used in channels CHANNEL_PUBLIC_GROUP_NA The channel/supergroup is not available CHAT_ADMIN_INVITE_REQUIRED You don't have rights to invite other users @@ -6,6 +7,7 @@ CHAT_ADMIN_REQUIRED The method requires chat admin privileges CHAT_FORBIDDEN You cannot write in this chat CHAT_GUEST_SEND_FORBIDDEN You need to join the discussion group before commenting CHAT_SEND_AUDIOS_FORBIDDEN You can't send audio messages in this chat +CHAT_SEND_DOCS_FORBIDDEN You can't send documents in this chat. CHAT_SEND_GAME_FORBIDDEN You can't send a game to this chat CHAT_SEND_GIFS_FORBIDDEN You can't send animations in this chat CHAT_SEND_INLINE_FORBIDDEN You cannot use inline bots to send messages in this chat @@ -13,6 +15,7 @@ CHAT_SEND_MEDIA_FORBIDDEN You can't send media messages in this chat CHAT_SEND_PHOTOS_FORBIDDEN You can't send photos in this chat CHAT_SEND_PLAIN_FORBIDDEN You can't send non-media (text) messages in this chat CHAT_SEND_POLL_FORBIDDEN You can't send polls in this chat +CHAT_SEND_ROUNDVIDEOS_FORBIDDEN You cannot send video notes in this chat CHAT_SEND_STICKERS_FORBIDDEN You can't send stickers in this chat CHAT_SEND_VIDEOS_FORBIDDEN You can't send videos in this chat CHAT_SEND_VOICES_FORBIDDEN You can't send voice recordings in this chat @@ -41,4 +44,5 @@ USER_INVALID The provided user is invalid USER_IS_BLOCKED The user is blocked USER_NOT_MUTUAL_CONTACT The provided user is not a mutual contact USER_PRIVACY_RESTRICTED The user's privacy settings is preventing you to perform this action -USER_RESTRICTED You are limited/restricted. You can't perform this action \ No newline at end of file +USER_RESTRICTED You are limited/restricted. You can't perform this action +VOICE_MESSAGES_FORBIDDEN This user's privacy settings forbid you from sending voice messages. \ No newline at end of file diff --git a/compiler/errors/source/406_NOT_ACCEPTABLE.tsv b/compiler/errors/source/406_NOT_ACCEPTABLE.tsv index 831bc6638..3d7b1af28 100644 --- a/compiler/errors/source/406_NOT_ACCEPTABLE.tsv +++ b/compiler/errors/source/406_NOT_ACCEPTABLE.tsv @@ -1,5 +1,8 @@ id message AUTH_KEY_DUPLICATED The same authorization key (session file) was used in more than one place simultaneously. You must delete your session file and log in again with your phone number or bot token +BANNED_RIGHTS_INVALID You provided some invalid flags in the banned rights. +BOT_PRECHECKOUT_FAILED Bot precheckout is failed +CALL_PROTOCOL_COMPAT_LAYER_INVALID The other side of the call does not support any of the VoIP protocols supported by the local client, as specified by the `protocol.layer` and `protocol.library_versions` fields. CHANNEL_PRIVATE The channel/supergroup is not accessible CHANNEL_TOO_LARGE Сhannel is too large to be deleted. Contact support for removal CHAT_FORWARDS_RESTRICTED You can't forward messages from a protected chat @@ -9,14 +12,18 @@ FRESH_CHANGE_PHONE_FORBIDDEN You can't change your phone number because your ses FRESH_RESET_AUTHORISATION_FORBIDDEN You can't terminate other authorized sessions because the current was logged-in recently GIFTCODE_NOT_ALLOWED Giftcode not allowed INVITE_HASH_EXPIRED The chat the user tried to join has expired and is not valid anymore +PAYMENT_UNSUPPORTED A detailed description of the error will be received separately as described [here »](https://core.telegram.org/api/errors#406-not-acceptable). PHONE_NUMBER_INVALID The phone number is invalid PHONE_PASSWORD_FLOOD You have tried to log-in too many times PREMIUM_CURRENTLY_UNAVAILABLE Premium currently unavailable PREVIOUS_CHAT_IMPORT_ACTIVE_WAIT_XMIN Similar to a flood wait, must wait {value} minutes +PRIVACY_PREMIUM_REQUIRED You need a [Telegram Premium subscription](https://core.telegram.org/api/premium) to send a message to this user. SEND_CODE_UNAVAILABLE Returned when all available options for this type of number were already used (e.g. flash-call, then SMS, then this error might be returned to trigger a second resend) STICKERSET_INVALID The sticker set is invalid STICKERSET_OWNER_ANONYMOUS This sticker set can't be used as the group's sticker set because it was created by one of its anonymous admins +TOPIC_CLOSED This topic was closed, you can't send messages to it anymore. +TOPIC_DELETED The specified topic was deleted. UPDATE_APP_TO_LOGIN Update app to login USERPIC_PRIVACY_REQUIRED You need to disable privacy settings for your profile picture in order to make your geolocation public USERPIC_UPLOAD_REQUIRED You must have a profile picture to publish your geolocation -USER_RESTRICTED You are limited/restricted. You can't perform this action \ No newline at end of file +USER_RESTRICTED You are limited/restricted. You can't perform this action diff --git a/compiler/errors/source/500_INTERNAL_SERVER_ERROR.tsv b/compiler/errors/source/500_INTERNAL_SERVER_ERROR.tsv index fa97ede4c..e7799a33b 100644 --- a/compiler/errors/source/500_INTERNAL_SERVER_ERROR.tsv +++ b/compiler/errors/source/500_INTERNAL_SERVER_ERROR.tsv @@ -2,7 +2,9 @@ id message API_CALL_ERROR API call error due to Telegram having internal problems. Please try again later AUTH_RESTART User authorization has restarted CALL_OCCUPY_FAILED The call failed because the user is already making another call +CDN_UPLOAD_TIMEOUT A server-side timeout occurred while reuploading the file to the CDN DC. CHAT_ID_GENERATE_FAILED Failure while generating the chat ID due to Telegram having internal problems. Please try again later +CHAT_INVALID Invalid chat. CHAT_OCCUPY_LOC_FAILED An internal error occurred while creating the chat CHAT_OCCUPY_USERNAME_FAILED Failure to occupy chat username due to Telegram having internal problems. Please try again later CHP_CALL_FAIL Telegram is having internal problems. Please try again later @@ -22,6 +24,7 @@ MEMBER_OCCUPY_PRIMARY_LOC_FAILED Telegram is having internal problems. Please tr MEMBER_OCCUPY_USERNAME_FAILED Failure to occupy member username due to Telegram having internal problems. Please try again later MSGID_DECREASE_RETRY Telegram is having internal problems. Please try again later MSG_RANGE_UNSYNC Message range unsynchronized due to Telegram having internal problems. Please try again later +MSG_WAIT_FAILED A waiting call returned an error. MT_SEND_QUEUE_TOO_LONG The MTProto send queue has grown too much due to Telegram having internal problems. Please try again later NEED_CHAT_INVALID The provided chat is invalid NEED_MEMBER_INVALID The provided member is invalid or does not exist @@ -36,8 +39,11 @@ REG_ID_GENERATE_FAILED The registration id failed to generate due to Telegram ha RPC_CALL_FAIL Telegram is having internal problems. Please try again later RPC_CONNECT_FAILED Telegram is having internal problems. Please try again later RPC_MCGET_FAIL Telegram is having internal problems. Please try again later +RPC_SEND_FAIL Telegram is having internal problems. Please try again later +SEND_MEDIA_INVALID The specified media is invalid. SIGN_IN_FAILED Failure while signing in due to Telegram having internal problems. Please try again later STORAGE_CHECK_FAILED Server storage check failed due to Telegram having internal problems. Please try again later +STORAGE_CHOOSE_VOLUME_FAILED Storage choose volume failed due to Telegram having internal problems. Please try again later STORE_INVALID_SCALAR_TYPE Telegram is having internal problems. Please try again later TIMEOUT A timeout occurred while fetching data from the worker UNKNOWN_METHOD The method you tried to call cannot be called on non-CDN DCs diff --git a/pyrogram/__init__.py b/pyrogram/__init__.py index 24a55b7ce..bc4dff9ea 100644 --- a/pyrogram/__init__.py +++ b/pyrogram/__init__.py @@ -16,7 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -__version__ = "2.0.147" +__version__ = "2.0.148" __license__ = "GNU Lesser General Public License v3.0 (LGPL-3.0)" __copyright__ = "Copyright (C) 2017-present Dan " diff --git a/pyrogram/enums/privacy_key.py b/pyrogram/enums/privacy_key.py new file mode 100644 index 000000000..8edc2fc19 --- /dev/null +++ b/pyrogram/enums/privacy_key.py @@ -0,0 +1,57 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present Dan +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . + +from pyrogram import raw +from .auto_name import AutoName + + +class PrivacyKey(AutoName): + """Privacy key enumeration used in :meth:`~pyrogram.Client.set_privacy`.""" + + ABOUT = raw.types.InputPrivacyKeyAbout + "Whether people can see your bio" + + ADDED_BY_PHONE = raw.types.InputPrivacyKeyAddedByPhone + "Whether people can add you to their contact list by your phone number" + + BIRTHDAY = raw.types.InputPrivacyKeyBirthday + "Whether the user can see our birthday." + + CHAT_INVITE = raw.types.InputPrivacyKeyChatInvite + "Whether people will be able to invite you to chats" + + FORWARDS = raw.types.InputPrivacyKeyForwards + "Whether messages forwarded from you will be anonymous" + + PHONE_CALL = raw.types.InputPrivacyKeyPhoneCall + "Whether you will accept phone calls" + + PHONE_NUMBER = raw.types.InputPrivacyKeyPhoneNumber + "Whether people will be able to see your phone number" + + PHONE_P2P = raw.types.InputPrivacyKeyPhoneP2P + "Whether to allow P2P communication during VoIP calls" + + PROFILE_PHOTO = raw.types.InputPrivacyKeyProfilePhoto + "Whether people will be able to see your profile picture" + + STATUS = raw.types.InputPrivacyKeyStatusTimestamp + "Whether people will be able to see our exact last online timestamp." + + VOICE_MESSAGES = raw.types.InputPrivacyKeyVoiceMessages + "Whether people can send you voice messages or round videos (Premium users only)." diff --git a/pyrogram/methods/__init__.py b/pyrogram/methods/__init__.py index bcf4ebe0c..b91bf8f29 100644 --- a/pyrogram/methods/__init__.py +++ b/pyrogram/methods/__init__.py @@ -16,6 +16,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . +from .account import Account from .advanced import Advanced from .auth import Auth from .business import Business @@ -35,6 +36,7 @@ class Methods( + Account, Advanced, Auth, Business, diff --git a/pyrogram/methods/account/__init__.py b/pyrogram/methods/account/__init__.py new file mode 100644 index 000000000..4e36a1ba1 --- /dev/null +++ b/pyrogram/methods/account/__init__.py @@ -0,0 +1,30 @@ +# 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 .get_account_ttl import GetAccountTTL +from .get_privacy import GetPrivacy +from .set_account_ttl import SetAccountTTL +from .set_privacy import SetPrivacy + +class Account( + GetAccountTTL, + GetPrivacy, + SetAccountTTL, + SetPrivacy +): + pass diff --git a/pyrogram/methods/account/get_account_ttl.py b/pyrogram/methods/account/get_account_ttl.py new file mode 100644 index 000000000..b468c5daa --- /dev/null +++ b/pyrogram/methods/account/get_account_ttl.py @@ -0,0 +1,44 @@ +# 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 pyrogram +from pyrogram import raw + + +class GetAccountTTL: + async def get_account_ttl( + self: "pyrogram.Client", + ): + """Get days to live of account. + + .. include:: /_includes/usable-by/users.rst + + Returns: + ``int``: Time to live in days of the current account. + + Example: + .. code-block:: python + + # Get ttl in days + await app.get_account_ttl() + """ + r = await self.invoke( + raw.functions.account.GetAccountTTL() + ) + + return r.days diff --git a/pyrogram/methods/account/get_privacy.py b/pyrogram/methods/account/get_privacy.py new file mode 100644 index 000000000..1d9217135 --- /dev/null +++ b/pyrogram/methods/account/get_privacy.py @@ -0,0 +1,55 @@ +# 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 pyrogram +from pyrogram import raw, types, enums + + +class GetPrivacy: + async def get_privacy( + self: "pyrogram.Client", + key: "enums.PrivacyKey" + ): + """Get account privacy rules. + + .. include:: /_includes/usable-by/users.rst + + Parameters: + key (:obj:`~pyrogram.enums.PrivacyKey`): + Privacy key. + + Returns: + List of :obj:`~pyrogram.types.PrivacyRule`: On success, the list of privacy rules is returned. + + Example: + .. code-block:: python + + from pyrogram import enums + + await app.get_privacy(enums.PrivacyKey.PHONE_NUMBER) + """ + r = await self.invoke( + raw.functions.account.GetPrivacy( + key=key.value() + ) + ) + + users = {i.id: i for i in r.users} + chats = {i.id: i for i in r.chats} + + return types.List(types.PrivacyRule._parse(self, rule, users, chats) for rule in r.rules) diff --git a/pyrogram/methods/account/set_account_ttl.py b/pyrogram/methods/account/set_account_ttl.py new file mode 100644 index 000000000..45cc37ee2 --- /dev/null +++ b/pyrogram/methods/account/set_account_ttl.py @@ -0,0 +1,51 @@ +# 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 pyrogram +from pyrogram import raw + + +class SetAccountTTL: + async def set_account_ttl( + self: "pyrogram.Client", + days: int + ): + """Set days to live of account. + + .. include:: /_includes/usable-by/users.rst + + Parameters: + days (``int``): + Time to live in days. + + Returns: + ``bool``: On success, True is returned. + + Example: + .. code-block:: python + + # Set ttl in days + await app.set_account_ttl(365) + """ + r = await self.invoke( + raw.functions.account.SetAccountTTL( + ttl=raw.types.AccountDaysTTL(days=days) + ) + ) + + return r diff --git a/pyrogram/methods/account/set_privacy.py b/pyrogram/methods/account/set_privacy.py new file mode 100644 index 000000000..719580e2d --- /dev/null +++ b/pyrogram/methods/account/set_privacy.py @@ -0,0 +1,73 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present Dan +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . + +from typing import List, Union + +import pyrogram +from pyrogram import raw, types, enums + + +class SetPrivacy: + async def set_privacy( + self: "pyrogram.Client", + key: "enums.PrivacyKey", + rules: List[Union[ + "types.InputPrivacyRuleAllowAll", + "types.InputPrivacyRuleAllowContacts", + "types.InputPrivacyRuleAllowPremium", + "types.InputPrivacyRuleAllowUsers", + "types.InputPrivacyRuleAllowChats", + "types.InputPrivacyRuleDisallowAll", + "types.InputPrivacyRuleDisallowContacts", + "types.InputPrivacyRuleDisallowUsers", + "types.InputPrivacyRuleDisallowChats", + ]], + ): + """Set account privacy rules. + + .. include:: /_includes/usable-by/users.rst + + Parameters: + key (:obj:`~pyrogram.enums.PrivacyKey`): + Privacy key. + + rules (Iterable of :obj:`~pyrogram.types.InputPrivacyRule`): + List of privacy rules. + + Returns: + List of :obj:`~pyrogram.types.PrivacyRule`: On success, the list of privacy rules is returned. + + Example: + .. code-block:: python + + from pyrogram import enums, types + + # Prevent everyone from seeing your phone number + await app.set_privacy(enums.PrivacyKey.PHONE_NUMBER, [types.InputPrivacyRuleDisallowAll()]) + """ + r = await self.invoke( + raw.functions.account.SetPrivacy( + key=key.value(), + rules=[await rule.write(self) for rule in rules] + ) + ) + + users = {i.id: i for i in r.users} + chats = {i.id: i for i in r.chats} + + return types.List(types.PrivacyRule._parse(self, rule, users, chats) for rule in r.rules) diff --git a/pyrogram/methods/auth/__init__.py b/pyrogram/methods/auth/__init__.py index ce585648d..53a96531d 100644 --- a/pyrogram/methods/auth/__init__.py +++ b/pyrogram/methods/auth/__init__.py @@ -20,11 +20,14 @@ from .check_password import CheckPassword from .connect import Connect from .disconnect import Disconnect +from .get_active_sessions import GetActiveSessions from .get_password_hint import GetPasswordHint from .initialize import Initialize from .log_out import LogOut from .recover_password import RecoverPassword from .resend_code import ResendCode +from .reset_session import ResetSession +from .reset_sessions import ResetSessions from .send_code import SendCode from .send_recovery_code import SendRecoveryCode from .sign_in import SignIn @@ -38,11 +41,14 @@ class Auth( CheckPassword, Connect, Disconnect, + GetActiveSessions, GetPasswordHint, Initialize, LogOut, RecoverPassword, ResendCode, + ResetSession, + ResetSessions, SendCode, SendRecoveryCode, SignIn, diff --git a/pyrogram/methods/auth/get_active_sessions.py b/pyrogram/methods/auth/get_active_sessions.py new file mode 100644 index 000000000..9a3ff4981 --- /dev/null +++ b/pyrogram/methods/auth/get_active_sessions.py @@ -0,0 +1,39 @@ +# 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 pyrogram +from pyrogram import raw, types + + +class GetActiveSessions: + async def get_active_sessions( + self: "pyrogram.Client" + ) -> "types.ActiveSessions": + """Returns all active sessions of the current user. + + .. include:: /_includes/usable-by/users.rst + + Returns: + :obj:`~pyrogram.types.ActiveSessions`: On success, all the active sessions of the current user is returned. + + """ + r = await self.invoke( + raw.functions.account.GetAuthorizations() + ) + + return types.ActiveSessions._parse(r) diff --git a/pyrogram/methods/auth/reset_session.py b/pyrogram/methods/auth/reset_session.py new file mode 100644 index 000000000..6332794e4 --- /dev/null +++ b/pyrogram/methods/auth/reset_session.py @@ -0,0 +1,40 @@ +# 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 pyrogram +from pyrogram import raw + + +class ResetSession: + async def reset_session( + self: "pyrogram.Client", + id: int + ) -> bool: + """Log out an active authorized session by its hash. + + .. include:: /_includes/usable-by/users.rst + + Returns: + ``bool``: On success, in case the session is destroyed, True is returned. Otherwise, False is returned. + + """ + r = await self.invoke( + raw.functions.account.ResetAuthorization(hash=id) + ) + + return r diff --git a/pyrogram/methods/auth/reset_sessions.py b/pyrogram/methods/auth/reset_sessions.py new file mode 100644 index 000000000..4a980e564 --- /dev/null +++ b/pyrogram/methods/auth/reset_sessions.py @@ -0,0 +1,39 @@ +# 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 pyrogram +from pyrogram import raw + + +class ResetSessions: + async def reset_sessions( + self: "pyrogram.Client" + ) -> bool: + """Terminates all user's authorized sessions except for the current one. + + .. include:: /_includes/usable-by/users.rst + + Returns: + ``bool``: On success, in case the sessions is destroyed, True is returned. Otherwise, False is returned. + + """ + r = await self.invoke( + raw.functions.auth.ResetAuthorizations() + ) + + return r diff --git a/pyrogram/methods/bots/__init__.py b/pyrogram/methods/bots/__init__.py index cc4dc3f1d..ea009c5bc 100644 --- a/pyrogram/methods/bots/__init__.py +++ b/pyrogram/methods/bots/__init__.py @@ -26,9 +26,11 @@ from .get_chat_menu_button import GetChatMenuButton from .get_game_high_scores import GetGameHighScores from .get_inline_bot_results import GetInlineBotResults +from .refund_star_payment import RefundStarPayment from .request_callback_answer import RequestCallbackAnswer from .send_game import SendGame from .send_inline_bot_result import SendInlineBotResult +from .send_invoice import SendInvoice from .set_bot_commands import SetBotCommands from .set_bot_default_privileges import SetBotDefaultPrivileges from .set_chat_menu_button import SetChatMenuButton @@ -39,8 +41,10 @@ class Bots( AnswerCallbackQuery, AnswerInlineQuery, GetInlineBotResults, + RefundStarPayment, RequestCallbackAnswer, SendInlineBotResult, + SendInvoice, SendGame, SetGameScore, GetGameHighScores, diff --git a/pyrogram/methods/bots/answer_pre_checkout_query.py b/pyrogram/methods/bots/answer_pre_checkout_query.py index e9cc452c4..6d1d0cbe8 100644 --- a/pyrogram/methods/bots/answer_pre_checkout_query.py +++ b/pyrogram/methods/bots/answer_pre_checkout_query.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 + import pyrogram from pyrogram import raw @@ -24,8 +26,8 @@ class AnswerPreCheckoutQuery: async def answer_pre_checkout_query( self: "pyrogram.Client", pre_checkout_query_id: str, - success: bool = None, - error: str = None + ok: Optional[bool] = None, + error_message: Optional[str] = None ): """Send answers to pre-checkout queries. @@ -35,11 +37,11 @@ async def answer_pre_checkout_query( pre_checkout_query_id (``str``): Unique identifier for the query to be answered. - success (``bool``, *optional*): + ok (``bool``, *optional*): Set this flag if everything is alright (goods are available, etc.) and the bot is ready to proceed with the order. Otherwise do not set it, and set the error field, instead. - error (``str``, *optional*): + error_message (``str``, *optional*): Error message in human readable form that explains the reason for failure to proceed with the checkout. Required if ``success`` isn't set. @@ -50,15 +52,15 @@ async def answer_pre_checkout_query( .. code-block:: python # Proceed with the order - await app.answer_pre_checkout_query(query_id, success=True) + await app.answer_pre_checkout_query(query_id, ok=True) # Answer with error message - await app.answer_pre_checkout_query(query_id, error=error) + await app.answer_pre_checkout_query(query_id, ok=False, error_message="Out of stock") """ return await self.invoke( raw.functions.messages.SetBotPrecheckoutResults( query_id=int(pre_checkout_query_id), - success=success or None, - error=error or None + success=ok, + error=error_message ) ) diff --git a/pyrogram/methods/bots/refund_star_payment.py b/pyrogram/methods/bots/refund_star_payment.py new file mode 100644 index 000000000..7fc280176 --- /dev/null +++ b/pyrogram/methods/bots/refund_star_payment.py @@ -0,0 +1,54 @@ +# 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 Union + +import pyrogram +from pyrogram import raw + + +class RefundStarPayment: + async def refund_star_payment( + self: "pyrogram.Client", + user_id: Union[int, str], + telegram_payment_charge_id: str + ) -> bool: + """Refunds a successful payment in `Telegram Stars `_. + + .. include:: /_includes/usable-by/bots.rst + + Parameters: + user_id (``int`` | ``str``): + Unique identifier (int) or username (str) of the target user, whose payment will be refunded. + + telegram_payment_charge_id (``str``): + Telegram payment identifier. + + Returns: + ``bool``: True on success + + """ + + r = await self.invoke( + raw.functions.payments.RefundStarsCharge( + user_id=await self.resolve_peer(user_id), + charge_id=telegram_payment_charge_id + ) + ) + + return bool(r) diff --git a/pyrogram/methods/bots/send_invoice.py b/pyrogram/methods/bots/send_invoice.py new file mode 100644 index 000000000..f09646502 --- /dev/null +++ b/pyrogram/methods/bots/send_invoice.py @@ -0,0 +1,237 @@ +# 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 logging +from typing import List, Optional, Union + +import pyrogram +from pyrogram import enums, raw, utils, types + +log = logging.getLogger(__name__) + + +class SendInvoice: + async def send_invoice( + self: "pyrogram.Client", + chat_id: Union[int, str], + title: str, + description: str, + payload: Union[str, bytes], + currency: str, + prices: List["types.LabeledPrice"], + message_thread_id: Optional[int] = None, + provider_token: Optional[str] = None, + max_tip_amount: Optional[int] = None, + suggested_tip_amounts: Optional[List[int]] = None, + start_parameter: Optional[str] = None, + provider_data: Optional[str] = None, + photo_url: Optional[str] = None, + photo_size: Optional[int] = None, + photo_width: Optional[int] = None, + photo_height: Optional[int] = None, + need_name: Optional[bool] = None, + need_phone_number: Optional[bool] = None, + need_email: Optional[bool] = None, + need_shipping_address: Optional[bool] = None, + send_phone_number_to_provider: Optional[bool] = None, + send_email_to_provider: Optional[bool] = None, + is_flexible: Optional[bool] = None, + disable_notification: Optional[bool] = None, + protect_content: Optional[bool] = None, + message_effect_id: Optional[int] = None, + reply_to_message_id: Optional[int] = None, + reply_markup: Optional[Union[ + "types.InlineKeyboardMarkup", + "types.ReplyKeyboardMarkup", + "types.ReplyKeyboardRemove", + "types.ForceReply" + ]] = None, + caption: str = "", + parse_mode: Optional["enums.ParseMode"] = None, + caption_entities: Optional[List["types.MessageEntity"]] = None + ) -> "types.Message": + """Use this method to send invoices. + + .. include:: /_includes/usable-by/bots.rst + + Parameters: + chat_id (``int`` | ``str``): + Unique identifier (int) or username (str) of the target chat. + + title (``str``): + Product name, 1-32 characters. + + description (``str``): + Product description, 1-255 characters + + payload (``str`` | ``bytes``): + Bot-defined invoice payload, 1-128 bytes. This will not be displayed to the user, use for your internal processes. + + currency (``str``): + Three-letter ISO 4217 currency code, see `more on currencies `_. Pass ``XTR`` for payments in `Telegram Stars `_. + + prices (List of :obj:`~pyrogram.types.LabeledPrice`): + Price breakdown, a JSON-serialized list of components (e.g. product price, tax, discount, delivery cost, delivery tax, bonus, etc.). Must contain exactly one item for payments in `Telegram Stars `_. + + message_thread_id (``int``, *optional*): + If the message is in a thread, ID of the original message. + + reply_to_message_id (``int``, *optional*): + If the message is a reply, ID of the original message. + + provider_token (``str``, *optional*): + Payment provider token, obtained via `@BotFather `_. Pass an empty string for payments in `Telegram Stars `_. + + max_tip_amount (``int``, *optional*): + The maximum accepted amount for tips in the smallest units of the currency (integer, **not** float/double). For example, for a maximum tip of ``US$ 1.45`` pass ``max_tip_amount = 145``. See the exp parameter in `currencies.json `_, it shows the number of digits past the decimal point for each currency (2 for the majority of currencies). Defaults to 0. Not supported for payments in `Telegram Stars `_. + + suggested_tip_amounts (List of ``int``, *optional*): + An array of suggested amounts of tips in the smallest units of the currency (integer, **not** float/double). At most 4 suggested tip amounts can be specified. The suggested tip amounts must be positive, passed in a strictly increased order and must not exceed ``max_tip_amount``. + + start_parameter (``str``, *optional*): + Unique deep-linking parameter. If left empty, **forwarded copies** of the sent message will have a Pay button, allowing multiple users to pay directly from the forwarded message, using the same invoice. If non-empty, forwarded copies of the sent message will have a URL button with a deep link to the bot (instead of a Pay button), with the value used as the start parameter. + + provider_data (``str``, *optional*): + JSON-serialized data about the invoice, which will be shared with the payment provider. A detailed description of required fields should be provided by the payment provider. + + photo_url (``str``, *optional*): + URL of the product photo for the invoice. Can be a photo of the goods or a marketing image for a service. People like it better when they see what they are paying for. + + photo_size (``int``, *optional*): + Photo size in bytes + + photo_width (``int``, *optional*): + Photo width + + photo_height (``int``, *optional*): + Photo height + + need_name (``bool``, *optional*): + Pass True if you require the user's full name to complete the order. Ignored for payments in `Telegram Stars `_. + + need_phone_number (``bool``, *optional*): + Pass True if you require the user's phone number to complete the order. Ignored for payments in `Telegram Stars `_. + + need_email (``bool``, *optional*): + Pass True if you require the user's email address to complete the order. Ignored for payments in `Telegram Stars `_. + + need_shipping_address (``bool``, *optional*): + Pass True if you require the user's shipping address to complete the order. Ignored for payments in `Telegram Stars `_. + + send_phone_number_to_provider (``bool``, *optional*): + Pass True if the user's phone number should be sent to the provider. Ignored for payments in `Telegram Stars `_. + + send_email_to_provider (``bool``, *optional*): + Pass True if the user's email address should be sent to the provider. Ignored for payments in `Telegram Stars `_. + + is_flexible (``bool``, *optional*): + Pass True if the final price depends on the shipping method. Ignored for payments in `Telegram Stars `_. + + disable_notification (``bool``, *optional*): + Sends the message silently. + Users will receive a notification with no sound. + + protect_content (``bool``, *optional*): + Protects the contents of the sent message from forwarding and saving. + + message_effect_id (``int`` ``64-bit``, *optional*): + Unique identifier of the message effect to be added to the message; for private chats only. + + reply_markup (:obj:`~pyrogram.types.InlineKeyboardMarkup` | :obj:`~pyrogram.types.ReplyKeyboardMarkup` | :obj:`~pyrogram.types.ReplyKeyboardRemove` | :obj:`~pyrogram.types.ForceReply`, *optional*): + Additional interface options. An object for an inline keyboard, custom reply keyboard, + instructions to remove reply keyboard or to force a reply from the user. + + caption (``str``, *optional*): + Document caption, 0-1024 characters. + + parse_mode (:obj:`~pyrogram.enums.ParseMode`, *optional*): + By default, texts are parsed using both Markdown and HTML styles. + You can combine both syntaxes together. + + caption_entities (List of :obj:`~pyrogram.types.MessageEntity`): + List of special entities that appear in the caption, which can be specified instead of *parse_mode*. + + Returns: + :obj:`~pyrogram.types.Message`: On success, the sent invoice message is returned. + + """ + media = raw.types.InputMediaInvoice( + title=title, + description=description, + photo=raw.types.InputWebDocument( + url=photo_url, + mime_type="image/jpg", + size=photo_size, + attributes=[ + raw.types.DocumentAttributeImageSize( + w=photo_width, + h=photo_height + ) + ] + ) if photo_url else None, + invoice=raw.types.Invoice( + currency=currency, + prices=[i.write() for i in prices], + test=self.test_mode, + name_requested=need_name, + phone_requested=need_phone_number, + email_requested=need_email, + shipping_address_requested=need_shipping_address, + flexible=is_flexible, + phone_to_provider=send_phone_number_to_provider, + email_to_provider=send_email_to_provider, + max_tip_amount=max_tip_amount, + suggested_tip_amounts=suggested_tip_amounts + ), + payload=payload.encode() if isinstance(payload, str) else payload, + provider=provider_token, + provider_data=raw.types.DataJSON( + data=provider_data if provider_data else "{}" + ), + start_param=start_parameter + ) + + rpc = raw.functions.messages.SendMedia( + peer=await self.resolve_peer(chat_id), + media=media, + silent=disable_notification or None, + reply_to=utils.get_reply_to( + reply_to_message_id=reply_to_message_id, + message_thread_id=message_thread_id + ), + random_id=self.rnd_id(), + noforwards=protect_content, + reply_markup=await reply_markup.write(self) if reply_markup else None, + effect=message_effect_id, + **await utils.parse_text_entities(self, caption, parse_mode, caption_entities) + ) + + r = await self.invoke(rpc) + + for i in r.updates: + if isinstance(i, (raw.types.UpdateNewMessage, + raw.types.UpdateNewChannelMessage, + raw.types.UpdateNewScheduledMessage, + raw.types.UpdateBotNewBusinessMessage)): + return await types.Message._parse( + self, i.message, + {i.id: i for i in r.users}, + {i.id: i for i in r.chats}, + is_scheduled=isinstance(i, raw.types.UpdateNewScheduledMessage), + business_connection_id=getattr(i, "connection_id", None) + ) diff --git a/pyrogram/methods/contacts/__init__.py b/pyrogram/methods/contacts/__init__.py index 5849ce438..cf069b2a2 100644 --- a/pyrogram/methods/contacts/__init__.py +++ b/pyrogram/methods/contacts/__init__.py @@ -21,6 +21,7 @@ from .get_contacts import GetContacts from .get_contacts_count import GetContactsCount from .import_contacts import ImportContacts +from .search_contacts import SearchContacts class Contacts( @@ -28,6 +29,7 @@ class Contacts( DeleteContacts, ImportContacts, GetContactsCount, - AddContact + AddContact, + SearchContacts ): pass diff --git a/pyrogram/methods/contacts/search_contacts.py b/pyrogram/methods/contacts/search_contacts.py new file mode 100644 index 000000000..5e9591a2d --- /dev/null +++ b/pyrogram/methods/contacts/search_contacts.py @@ -0,0 +1,59 @@ +# 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 pyrogram +from pyrogram import raw +from pyrogram import types + + +class SearchContacts: + async def search_contacts( + self: "pyrogram.Client", + query: str, + limit: int = 0 + ): + """Returns users or channels found by name substring and auxiliary data. + + .. include:: /_includes/usable-by/users.rst + + Parameters: + query (``str``): + Target substring. + + limit (``int``, *optional*): + Maximum number of users to be returned. + + Returns: + :obj:`~pyrogram.types.FoundContacts`: On success, a list of chats is returned. + + Example: + .. code-block:: python + + await app.search_contacts("pyrogram") + """ + total = limit or (1 << 31) - 1 + limit = min(100, total) + + r = await self.invoke( + raw.functions.contacts.Search( + q=query, + limit=limit + ) + ) + + return types.FoundContacts._parse(self, r) diff --git a/pyrogram/methods/messages/__init__.py b/pyrogram/methods/messages/__init__.py index a9657175f..fd56a6eab 100644 --- a/pyrogram/methods/messages/__init__.py +++ b/pyrogram/methods/messages/__init__.py @@ -18,6 +18,7 @@ from .copy_media_group import CopyMediaGroup from .copy_message import CopyMessage +from .delete_chat_history import DeleteChatHistory from .delete_messages import DeleteMessages from .download_media import DownloadMedia from .edit_inline_caption import EditInlineCaption @@ -60,6 +61,7 @@ from .send_location import SendLocation from .send_media_group import SendMediaGroup from .send_message import SendMessage +from .send_paid_media import SendPaidMedia from .send_photo import SendPhoto from .send_poll import SendPoll from .send_reaction import SendReaction @@ -96,6 +98,7 @@ class Messages( SendLocation, SendMediaGroup, SendMessage, + SendPaidMedia, SendPhoto, SendSticker, SendVenue, @@ -124,6 +127,7 @@ class Messages( SearchMessages, SearchGlobal, CopyMessage, + DeleteChatHistory, CopyMediaGroup, SearchMessagesCount, SearchPosts, diff --git a/pyrogram/methods/messages/delete_chat_history.py b/pyrogram/methods/messages/delete_chat_history.py new file mode 100644 index 000000000..2399a7bda --- /dev/null +++ b/pyrogram/methods/messages/delete_chat_history.py @@ -0,0 +1,101 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present Dan +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . + +from datetime import datetime +import logging +from typing import Union + +import pyrogram +from pyrogram import raw +from pyrogram import utils + +log = logging.getLogger(__name__) + + +class DeleteChatHistory: + async def delete_chat_history( + self: "pyrogram.Client", + chat_id: Union[int, str], + max_id: int = 0, + revoke: bool = None, + just_clear = None, + min_date: datetime = None, + max_date: datetime = None, + ) -> int: + """Delete the history of a chat. + + .. include:: /_includes/usable-by/users.rst + + Parameters: + chat_id (``int`` | ``str``): + Unique identifier (int) or username (str) of the target chat. + + max_id (``int``, *optional*): + Maximum ID of message to delete. + + revoke (``bool``, *optional*): + Deletes messages history for everyone. + Required ``True`` if using in channel. + + just_clear (``bool``, *optional*): + If True, clear history for the current user, without actually removing chat. + For private and simple group chats only. + + min_date (:py:obj:`~datetime.datetime`, *optional*): + Delete all messages newer than this time. + For private and simple group chats only. + + max_date (:py:obj:`~datetime.datetime`, *optional*): + Delete all messages older than this time. + For private and simple group chats only. + + Returns: + ``int``: Amount of affected messages + + Example: + .. code-block:: python + + # Delete all messages in channel + await app.delete_chat_history(chat_id, revoke=True) + """ + peer = await self.resolve_peer(chat_id) + + if isinstance(peer, raw.types.InputPeerChannel): + r = await self.invoke( + raw.functions.channels.DeleteHistory( + channel=raw.types.InputChannel( + channel_id=peer.channel_id, + access_hash=peer.access_hash + ), + max_id=max_id, + for_everyone=revoke + ) + ) + else: + r = await self.invoke( + raw.functions.messages.DeleteHistory( + peer=peer, + max_id=max_id, + just_clear=just_clear, + revoke=revoke, + min_date=utils.datetime_to_timestamp(min_date), + max_date=utils.datetime_to_timestamp(max_date) + ) + ) + + return len(r.updates[0].messages) if isinstance(peer, raw.types.InputPeerChannel) else r.pts_count diff --git a/pyrogram/methods/messages/inline_session.py b/pyrogram/methods/messages/inline_session.py index cf74e5ad2..3206a043b 100644 --- a/pyrogram/methods/messages/inline_session.py +++ b/pyrogram/methods/messages/inline_session.py @@ -24,6 +24,9 @@ async def get_session(client: "pyrogram.Client", dc_id: int) -> Session: + if dc_id == await client.storage.dc_id(): + return client.session + async with client.media_sessions_lock: if client.media_sessions.get(dc_id): return client.media_sessions[dc_id] diff --git a/pyrogram/methods/messages/search_messages.py b/pyrogram/methods/messages/search_messages.py index 4bd5f13b8..38cd30367 100644 --- a/pyrogram/methods/messages/search_messages.py +++ b/pyrogram/methods/messages/search_messages.py @@ -17,6 +17,7 @@ # along with Pyrogram. If not, see . from typing import Union, List, AsyncGenerator, Optional +from datetime import datetime import pyrogram from pyrogram import raw, types, utils, enums @@ -29,7 +30,12 @@ async def get_chunk( query: str = "", filter: "enums.MessagesFilter" = enums.MessagesFilter.EMPTY, offset: int = 0, + offset_id: int = 0, + min_date: datetime = utils.zero_datetime(), + max_date: datetime = utils.zero_datetime(), limit: int = 100, + min_id: int = 0, + max_id: int = 0, from_user: Union[int, str] = None ) -> List["types.Message"]: r = await client.invoke( @@ -37,13 +43,13 @@ async def get_chunk( peer=await client.resolve_peer(chat_id), q=query, filter=filter.value(), - min_date=0, - max_date=0, - offset_id=0, + min_date=utils.datetime_to_timestamp(min_date), + max_date= utils.datetime_to_timestamp(max_date), + offset_id=offset_id, add_offset=offset, limit=limit, - min_id=0, - max_id=0, + min_id=min_id, + max_id=max_id, from_id=( await client.resolve_peer(from_user) if from_user @@ -64,6 +70,11 @@ async def search_messages( chat_id: Union[int, str], query: str = "", offset: int = 0, + offset_id: int = 0, + min_date: datetime = utils.zero_datetime(), + max_date: datetime = utils.zero_datetime(), + min_id: int = 0, + max_id: int = 0, filter: "enums.MessagesFilter" = enums.MessagesFilter.EMPTY, limit: int = 0, from_user: Union[int, str] = None @@ -90,6 +101,21 @@ async def search_messages( Sequential number of the first message to be returned. Defaults to 0. + offset_id (``int``, *optional*): + Identifier of the first message to be returned. + + min_date (:py:obj:`~datetime.datetime`, *optional*): + Pass a date as offset to retrieve only older messages starting from that date. + + max_date (:py:obj:`~datetime.datetime`, *optional*): + Pass a date as offset to retrieve only newer messages starting from that date. + + min_id (``int``, *optional*): + If a positive value was provided, the method will return only messages with IDs more than min_id. + + max_id (``int``, *optional*): + If a positive value was provided, the method will return only messages with IDs less than max_id. + filter (:obj:`~pyrogram.enums.MessagesFilter`, *optional*): Pass a filter in order to search for specific kind of messages only. Defaults to any message (no filter). @@ -133,6 +159,11 @@ async def search_messages( query=query, filter=filter, offset=offset, + offset_id=offset_id, + min_date=min_date, + max_date=max_date, + min_id=min_id, + max_id=max_id, limit=limit, from_user=from_user ) diff --git a/pyrogram/methods/messages/send_media_group.py b/pyrogram/methods/messages/send_media_group.py index 41e74eac5..9b5e7a92c 100644 --- a/pyrogram/methods/messages/send_media_group.py +++ b/pyrogram/methods/messages/send_media_group.py @@ -213,7 +213,7 @@ async def send_media_group( thumb=await self.save_file(i.thumb), spoiler=i.has_spoiler, mime_type=self.guess_mime_type(i.media) or "video/mp4", - nosound_video=i.no_sound, + nosound_video=True, # no-sounds videos cannot be sent in a media group attributes=[ raw.types.DocumentAttributeVideo( supports_streaming=i.supports_streaming or None, @@ -267,7 +267,7 @@ async def send_media_group( thumb=await self.save_file(i.thumb), spoiler=i.has_spoiler, mime_type=self.guess_mime_type(getattr(i.media, "name", "video.mp4")) or "video/mp4", - nosound_video=i.no_sound, + nosound_video=True, # no-sounds videos cannot be sent in a media group attributes=[ raw.types.DocumentAttributeVideo( supports_streaming=i.supports_streaming or None, diff --git a/pyrogram/methods/messages/send_paid_media.py b/pyrogram/methods/messages/send_paid_media.py new file mode 100644 index 000000000..ea6b91652 --- /dev/null +++ b/pyrogram/methods/messages/send_paid_media.py @@ -0,0 +1,282 @@ +# 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 logging +import os +from datetime import datetime +from typing import Union, List, Optional + +import pyrogram +from pyrogram import raw +from pyrogram import types +from pyrogram import utils +from pyrogram import enums +from pyrogram.file_id import FileType + +log = logging.getLogger(__name__) + + +class SendPaidMedia: + # TODO: Add progress parameter + async def send_paid_media( + self: "pyrogram.Client", + chat_id: Union[int, str], + stars_amount: int, + media: List[Union[ + "types.InputMediaPhoto", + "types.InputMediaVideo", + ]], + caption: str = "", + parse_mode: Optional["enums.ParseMode"] = None, + caption_entities: List["types.MessageEntity"] = None, + disable_notification: bool = None, + reply_to_message_id: int = None, + quote_text: str = None, + quote_entities: List["types.MessageEntity"] = None, + quote_offset: int = None, + schedule_date: datetime = None, + protect_content: bool = None, + show_above_text: bool = None + ) -> List["types.Message"]: + """Send a group or one paid photo/video. + + .. include:: /_includes/usable-by/users-bots.rst + + Parameters: + chat_id (``int`` | ``str``): + Unique identifier (int) or username (str) of the target chat. + For your personal cloud (Saved Messages) you can simply use "me" or "self". + For a contact that exists in your Telegram address book you can use his phone number (str). + + stars_amount (``int``): + The number of Telegram Stars that must be paid to buy access to the media. + + media (List of :obj:`~pyrogram.types.InputMediaPhoto`, :obj:`~pyrogram.types.InputMediaVideo`): + A list describing photos and videos to be sent, must include 1–10 items. + + caption (``str``, *optional*): + Media caption, 0-1024 characters after entities parsing. + + parse_mode (:obj:`~pyrogram.enums.ParseMode`, *optional*): + By default, texts are parsed using both Markdown and HTML styles. + You can combine both syntaxes together. + + disable_notification (``bool``, *optional*): + Sends the message silently. + Users will receive a notification with no sound. + + reply_to_message_id (``int``, *optional*): + If the message is a reply, ID of the original message. + + quote_text (``str``, *optional*): + Text of the quote to be sent. + + parse_mode (:obj:`~pyrogram.enums.ParseMode`, *optional*): + By default, texts are parsed using both Markdown and HTML styles. + You can combine both syntaxes together. + + quote_entities (List of :obj:`~pyrogram.types.MessageEntity`, *optional*): + List of special entities that appear in quote text, which can be specified instead of *parse_mode*. + + quote_offset (``int``, *optional*): + Offset for quote in original message. + + schedule_date (:py:obj:`~datetime.datetime`, *optional*): + Date when the message will be automatically sent. + + protect_content (``bool``, *optional*): + Protects the contents of the sent message from forwarding and saving. + + show_above_text (``bool``, *optional*): + If True, link preview will be shown above the message text. + Otherwise, the link preview will be shown below the message text. + + Returns: + :obj:`~pyrogram.types.Message`: On success, the sent message is returned. + + Example: + .. code-block:: python + + from pyrogram.types import InputMediaPhoto, InputMediaVideo + + await app.send_paid_media( + chat_id, + stars_amount=50, + caption="Look at this!", + media=[ + InputMediaPhoto("photo1.jpg"), + InputMediaPhoto("photo2.jpg"), + InputMediaVideo("video.mp4") + ] + ) + """ + multi_media = [] + + for i in media: + if isinstance(i, types.InputMediaPhoto): + if isinstance(i.media, str): + if os.path.isfile(i.media): + media = await self.invoke( + raw.functions.messages.UploadMedia( + peer=await self.resolve_peer(chat_id), + media=raw.types.InputMediaUploadedPhoto( + file=await self.save_file(i.media), + spoiler=i.has_spoiler + ), + ) + ) + + media = raw.types.InputMediaPhoto( + id=raw.types.InputPhoto( + id=media.photo.id, + access_hash=media.photo.access_hash, + file_reference=media.photo.file_reference + ), + spoiler=i.has_spoiler + ) + else: + media = utils.get_input_media_from_file_id(i.media, FileType.PHOTO, has_spoiler=i.has_spoiler) + else: + media = await self.invoke( + raw.functions.messages.UploadMedia( + peer=await self.resolve_peer(chat_id), + media=raw.types.InputMediaUploadedPhoto( + file=await self.save_file(i.media), + spoiler=i.has_spoiler + ), + ) + ) + + media = raw.types.InputMediaPhoto( + id=raw.types.InputPhoto( + id=media.photo.id, + access_hash=media.photo.access_hash, + file_reference=media.photo.file_reference + ), + spoiler=i.has_spoiler + ) + elif isinstance(i, types.InputMediaVideo): + if isinstance(i.media, str): + if os.path.isfile(i.media): + media = await self.invoke( + raw.functions.messages.UploadMedia( + peer=await self.resolve_peer(chat_id), + media=raw.types.InputMediaUploadedDocument( + file=await self.save_file(i.media), + thumb=await self.save_file(i.thumb), + spoiler=i.has_spoiler, + mime_type=self.guess_mime_type(i.media) or "video/mp4", + nosound_video=True, + attributes=[ + raw.types.DocumentAttributeVideo( + supports_streaming=i.supports_streaming or None, + duration=i.duration, + w=i.width, + h=i.height + ), + raw.types.DocumentAttributeFilename(file_name=os.path.basename(i.media)) + ] + ), + ) + ) + + media = raw.types.InputMediaDocument( + id=raw.types.InputDocument( + id=media.document.id, + access_hash=media.document.access_hash, + file_reference=media.document.file_reference + ), + spoiler=i.has_spoiler + ) + else: + media = utils.get_input_media_from_file_id(i.media, FileType.VIDEO, has_spoiler=i.has_spoiler) + else: + media = await self.invoke( + raw.functions.messages.UploadMedia( + peer=await self.resolve_peer(chat_id), + media=raw.types.InputMediaUploadedDocument( + file=await self.save_file(i.media), + thumb=await self.save_file(i.thumb), + spoiler=i.has_spoiler, + mime_type=self.guess_mime_type(getattr(i.media, "name", "video.mp4")) or "video/mp4", + nosound_video=True, + attributes=[ + raw.types.DocumentAttributeVideo( + supports_streaming=i.supports_streaming or None, + duration=i.duration, + w=i.width, + h=i.height + ), + raw.types.DocumentAttributeFilename(file_name=getattr(i.media, "name", "video.mp4")) + ] + ), + ) + ) + + media = raw.types.InputMediaDocument( + id=raw.types.InputDocument( + id=media.document.id, + access_hash=media.document.access_hash, + file_reference=media.document.file_reference + ), + spoiler=i.has_spoiler + ) + else: + raise ValueError(f"{i.__class__.__name__} is not a supported type for send_paid_media") + + multi_media.append(media) + + quote_text, quote_entities = (await utils.parse_text_entities(self, quote_text, parse_mode, quote_entities)).values() + + r = await self.invoke( + raw.functions.messages.SendMedia( + peer=await self.resolve_peer(chat_id), + media=raw.types.InputMediaPaidMedia( + stars_amount=stars_amount, + extended_media=multi_media + ), + silent=disable_notification or None, + reply_to=utils.get_reply_to( + reply_to_message_id=reply_to_message_id, + quote_text=quote_text, + quote_entities=quote_entities, + quote_offset=quote_offset, + ), + random_id=self.rnd_id(), + schedule_date=utils.datetime_to_timestamp(schedule_date), + noforwards=protect_content, + invert_media=show_above_text, + **await utils.parse_text_entities(self, caption, parse_mode, caption_entities) + ), + sleep_threshold=60, + ) + + return await utils.parse_messages( + self, + raw.types.messages.Messages( + messages=[m.message for m in filter( + lambda u: isinstance(u, (raw.types.UpdateNewMessage, + raw.types.UpdateNewChannelMessage, + raw.types.UpdateNewScheduledMessage, + raw.types.UpdateBotNewBusinessMessage)), + r.updates + )], + users=r.users, + chats=r.chats + ), + ) diff --git a/pyrogram/methods/messages/send_video.py b/pyrogram/methods/messages/send_video.py index 9e6db2d09..2a936508e 100644 --- a/pyrogram/methods/messages/send_video.py +++ b/pyrogram/methods/messages/send_video.py @@ -57,7 +57,7 @@ async def send_video( quote_offset: int = None, schedule_date: datetime = None, protect_content: bool = None, - no_sound: bool = None, + no_sound: bool = True, business_connection_id: str = None, reply_markup: Union[ "types.InlineKeyboardMarkup", diff --git a/pyrogram/methods/payments/__init__.py b/pyrogram/methods/payments/__init__.py index d45ec785f..93ee99991 100644 --- a/pyrogram/methods/payments/__init__.py +++ b/pyrogram/methods/payments/__init__.py @@ -17,8 +17,12 @@ # along with Pyrogram. If not, see . from .check_giftcode import CheckGiftCode +from .get_payment_form import GetPaymentForm +from .send_payment_form import SendPaymentForm class Payments( - CheckGiftCode + CheckGiftCode, + GetPaymentForm, + SendPaymentForm ): pass diff --git a/pyrogram/methods/payments/get_payment_form.py b/pyrogram/methods/payments/get_payment_form.py new file mode 100644 index 000000000..f9b1fbb6d --- /dev/null +++ b/pyrogram/methods/payments/get_payment_form.py @@ -0,0 +1,83 @@ +# 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 re +from typing import Union + +import pyrogram +from pyrogram import raw, types + + +class GetPaymentForm: + async def get_payment_form( + self: "pyrogram.Client", + chat_id: Union[int, str], + message_id: Union[int, str], + ) -> "types.PaymentForm": + """Get information about a invoice or paid media. + + .. include:: /_includes/usable-by/users.rst + + Parameters: + chat_id (``int`` | ``str``): + Unique identifier (int) or username (str) of the target chat. + Unique identifier for the target chat in form of a *t.me/joinchat/* link, identifier (int) or username + of the target channel/supergroup (in the format @username). + + message_id (``int`` | ``str``): + Pass a message identifier or to get the invoice from message. + Pass a invoice link in form of a *t.me/$...* link or slug itself to get the payment form from link. + + Returns: + :obj:`~pyrogram.types.PaymentForm`: On success, a payment form is returned. + + Example: + .. code-block:: python + + # get payment form from message + app.get_payment_form(chat_id, 123) + + # get payment form from link + app.get_payment_form(chat_id, "https://t.me/$xvbzUtt5sUlJCAAATqZrWRy9Yzk") + """ + invoice = None + + if isinstance(message_id, int): + invoice = raw.types.InputInvoiceMessage( + peer=await self.resolve_peer(chat_id), + msg_id=message_id + ) + elif isinstance(message_id, str): + match = re.match(r"^(?:https?://)?(?:www\.)?(?:t(?:elegram)?\.(?:org|me|dog)/\$)([\w-]+)$", message_id) + + if match: + slug = match.group(1) + else: + slug = message_id + + invoice = raw.types.InputInvoiceSlug( + slug=slug + ) + + r = await self.invoke( + raw.functions.payments.GetPaymentForm( + invoice=invoice + ) + ) + + return types.PaymentForm._parse(self, r) diff --git a/pyrogram/methods/payments/send_payment_form.py b/pyrogram/methods/payments/send_payment_form.py new file mode 100644 index 000000000..69215fc6e --- /dev/null +++ b/pyrogram/methods/payments/send_payment_form.py @@ -0,0 +1,101 @@ +# 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 re +from typing import Union + +import pyrogram +from pyrogram import raw + + +class SendPaymentForm: + async def send_payment_form( + self: "pyrogram.Client", + chat_id: Union[int, str], + message_id: Union[int, str], + ) -> bool: + """Pay an invoice. + + .. note:: + + For now only stars invoices are supported. + + .. include:: /_includes/usable-by/users.rst + + Parameters: + chat_id (``int`` | ``str``): + Unique identifier (int) or username (str) of the target chat. + Unique identifier for the target chat in form of a *t.me/joinchat/* link, identifier (int) or username + of the target channel/supergroup (in the format @username). + + message_id (``int`` | ``str``): + Pass a message identifier or to get the invoice from message. + Pass a invoice link in form of a *t.me/$...* link or slug itself to get the payment form from link. + + Returns: + ``bool``: On success, True is returned. + + Example: + .. code-block:: python + + # Pay invoice from message + app.send_payment_form(chat_id, 123) + + # Pay invoice form from link + # Chat id can be None + app.send_payment_form(chat_id, "https://t.me/$xvbzUtt5sUlJCAAATqZrWRy9Yzk") + """ + invoice = None + + if isinstance(message_id, int): + invoice = raw.types.InputInvoiceMessage( + peer=await self.resolve_peer(chat_id), + msg_id=message_id + ) + elif isinstance(message_id, str): + match = re.match(r"^(?:https?://)?(?:www\.)?(?:t(?:elegram)?\.(?:org|me|dog)/\$)([\w-]+)$", message_id) + + if match: + slug = match.group(1) + else: + slug = message_id + + invoice = raw.types.InputInvoiceSlug( + slug=slug + ) + + form = await self.get_payment_form(chat_id=chat_id, message_id=message_id) + + # if form.invoice.currency == "XTR": + await self.invoke( + raw.functions.payments.SendStarsForm( + form_id=form.id, + invoice=invoice + ) + ) + # TODO: Add support for regular invoices (credentials) + # else: + # r = await self.invoke( + # raw.functions.payments.SendPaymentForm( + # form_id=form.id, + # invoice=invoice, + # credentials=raw.types.InputPaymentCredentials(data=raw.types.DataJSON(data={})) + # ) + # ) + + return True diff --git a/pyrogram/types/__init__.py b/pyrogram/types/__init__.py index bb2090f1d..476a45835 100644 --- a/pyrogram/types/__init__.py +++ b/pyrogram/types/__init__.py @@ -21,6 +21,7 @@ from .inline_mode import * from .input_media import * from .input_message_content import * +from .input_privacy_rule import * from .list import List from .messages_and_media import * from .object import Object diff --git a/pyrogram/types/authorization/__init__.py b/pyrogram/types/authorization/__init__.py index b31ad26a5..04a34f2a4 100644 --- a/pyrogram/types/authorization/__init__.py +++ b/pyrogram/types/authorization/__init__.py @@ -16,7 +16,14 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . +from .active_session import ActiveSession +from .active_sessions import ActiveSessions from .sent_code import SentCode from .terms_of_service import TermsOfService -__all__ = ["TermsOfService", "SentCode"] +__all__ = [ + "ActiveSession", + "ActiveSessions", + "SentCode", + "TermsOfService", +] diff --git a/pyrogram/types/authorization/active_session.py b/pyrogram/types/authorization/active_session.py new file mode 100644 index 000000000..174c2d129 --- /dev/null +++ b/pyrogram/types/authorization/active_session.py @@ -0,0 +1,179 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present Dan +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . + +from datetime import datetime + +from pyrogram import raw, utils + +from ..object import Object + + +class ActiveSession(Object): + """Contains information about one session in a Telegram application used by the current user. Sessions must be shown to the user in the returned order. + + Parameters: + id (``int``): + Session identifier. + + device_model (``str``): + Model of the device the application has been run or is running on, as provided by the application. + + platform (``str``): + Operating system the application has been run or is running on, as provided by the application. + + system_version (``str``): + Version of the operating system the application has been run or is running on, as provided by the application. + + api_id (``int``): + Telegram API identifier, as provided by the application. + + application_name (``str``): + Name of the application, as provided by the application. + + application_version (``str``): + The version of the application, as provided by the application. + + log_in_date (:py:obj:`~datetime.datetime`, *optional*): + Point in time (Unix timestamp) when the user has logged in. + + last_active_date (:py:obj:`~datetime.datetime`, *optional*): + Point in time (Unix timestamp) when the session was last used. + + ip_address (``str``): + IP address from which the session was created, in human-readable format. + + location (``str``): + A human-readable description of the location from which the session was created, based on the IP address. + + country (``str``): + Country determined from IP. + + region (``str``): + Region determined from IP. + + is_current (``bool``): + True, if this session is the current session. + + is_password_pending (``bool``): + True, if a 2-step verification password is needed to complete authorization of the session. + + is_unconfirmed (``bool``): + True, if the session wasn't confirmed from another session. + + can_accept_secret_chats (``bool``): + True, if incoming secret chats can be accepted by the session. + + can_accept_calls (``bool``): + True, if incoming calls can be accepted by the session. + + is_official_application (``bool``): + True, if the application is an official application or uses the api_id of an official application. + + """ + + def __init__( + self, + *, + id: int = None, + device_model: str = None, + platform: str = None, + system_version: str = None, + api_id: int = None, + application_name: str = None, + application_version: str = None, + log_in_date: datetime = None, + last_active_date: datetime = None, + ip_address: str = None, + location: str = None, + country: str = None, + region: str = None, + is_current: bool = None, + is_password_pending: bool = None, + is_unconfirmed: bool = None, + can_accept_secret_chats: bool = None, + can_accept_calls: bool = None, + is_official_application: bool = None + ): + super().__init__() + + self.id = id + self.device_model = device_model + self.platform = platform + self.system_version = system_version + self.api_id = api_id + self.application_name = application_name + self.application_version = application_version + self.log_in_date = log_in_date + self.last_active_date = last_active_date + self.ip_address = ip_address + self.location = location + self.country = country + self.region = region + self.is_current = is_current + self.is_password_pending = is_password_pending + self.is_unconfirmed = is_unconfirmed + self.can_accept_secret_chats = can_accept_secret_chats + self.can_accept_calls = can_accept_calls + self.is_official_application = is_official_application + + @staticmethod + def _parse(session: "raw.types.Authorization") -> "ActiveSession": + return ActiveSession( + id=session.hash, + device_model=session.device_model, + platform=session.platform, + system_version=session.system_version, + api_id=session.api_id, + application_name=session.app_name, + application_version=session.app_version, + log_in_date=utils.timestamp_to_datetime(session.date_created), + last_active_date=utils.timestamp_to_datetime(session.date_active), + ip_address=session.ip, + location=session.region, + country=session.country, + region=session.region, + is_current=getattr(session, "current", None), + is_password_pending=getattr(session, "password_pending", None), + is_unconfirmed=getattr(session, "unconfirmed", None), + can_accept_secret_chats=not getattr(session, "encrypted_requests_disabled", False), + can_accept_calls=not getattr(session, "call_requests_disabled", False), + is_official_application=getattr(session, "official_app", None) + ) + + async def reset(self): + """Bound method *reset* of :obj:`~pyrogram.types.ActiveSession`. + + Use as a shortcut for: + + .. code-block:: python + + await client.reset_session(123456789) + + Example: + .. code-block:: python + + await session.reset() + + Returns: + True on success. + + Raises: + RPCError: In case of a Telegram RPC error. + """ + + return await self._client.reset_session(self.id) diff --git a/pyrogram/types/authorization/active_sessions.py b/pyrogram/types/authorization/active_sessions.py new file mode 100644 index 000000000..ff1965778 --- /dev/null +++ b/pyrogram/types/authorization/active_sessions.py @@ -0,0 +1,56 @@ +# 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 + +from pyrogram import raw, types + +from ..object import Object + + +class ActiveSessions(Object): + """Contains a list of currently active sessions + + Parameters: + inactive_session_ttl_days (``int``): + Number of days of inactivity before sessions will automatically be terminated; 1-366 days. + + active_sessions (List of :obj:`~pyrogram.types.ActiveSession`): + List of sessions. + """ + + def __init__( + self, + *, + inactive_session_ttl_days: int = None, + active_sessions: List["types.ActiveSession"] = None + ): + super().__init__() + + self.inactive_session_ttl_days = inactive_session_ttl_days + self.active_sessions = active_sessions + + @staticmethod + def _parse(authorizations: "raw.types.account.Authorizations") -> "ActiveSessions": + return ActiveSessions( + inactive_session_ttl_days=authorizations.authorization_ttl_days, + active_sessions=types.List([ + types.ActiveSession._parse(active) + for active in authorizations.authorizations + ]) + ) diff --git a/pyrogram/types/bots_and_keyboards/__init__.py b/pyrogram/types/bots_and_keyboards/__init__.py index ebec18ea8..21af449cf 100644 --- a/pyrogram/types/bots_and_keyboards/__init__.py +++ b/pyrogram/types/bots_and_keyboards/__init__.py @@ -32,23 +32,23 @@ from .inline_keyboard_button import InlineKeyboardButton from .inline_keyboard_markup import InlineKeyboardMarkup from .keyboard_button import KeyboardButton +from .labeled_price import LabeledPrice from .login_url import LoginUrl from .menu_button import MenuButton from .menu_button_commands import MenuButtonCommands from .menu_button_default import MenuButtonDefault from .menu_button_web_app import MenuButtonWebApp -from .payment_info import PaymentInfo +from .order_info import OrderInfo from .pre_checkout_query import PreCheckoutQuery from .reply_keyboard_markup import ReplyKeyboardMarkup from .reply_keyboard_remove import ReplyKeyboardRemove from .request_channel_info import RequestChannelInfo from .request_chat_info import RequestChatInfo -from .request_user_info import RequestUserInfo from .request_poll_info import RequestPollInfo +from .request_user_info import RequestUserInfo from .requested_chats import RequestedChats from .sent_web_app_message import SentWebAppMessage from .shipping_address import ShippingAddress -from .successful_payment import SuccessfulPayment from .web_app_info import WebAppInfo __all__ = [ @@ -66,6 +66,7 @@ "RequestUserInfo", "RequestPollInfo", "RequestedChats", + "LabeledPrice", "LoginUrl", "BotCommand", "BotCommandScope", @@ -80,10 +81,9 @@ "MenuButton", "MenuButtonCommands", "MenuButtonWebApp", + "OrderInfo", + "PreCheckoutQuery", "MenuButtonDefault", "SentWebAppMessage", - "ShippingAddress", - "PaymentInfo", - "PreCheckoutQuery", - "SuccessfulPayment" + "ShippingAddress" ] diff --git a/pyrogram/types/bots_and_keyboards/keyboard_button.py b/pyrogram/types/bots_and_keyboards/keyboard_button.py index 7bb4d377b..3137c41d6 100644 --- a/pyrogram/types/bots_and_keyboards/keyboard_button.py +++ b/pyrogram/types/bots_and_keyboards/keyboard_button.py @@ -43,7 +43,7 @@ class KeyboardButton(Object): request_poll (:obj:`~pyrogram.types.RequestPollInfo`, *optional*): If specified, the poll be sent when the button is pressed. - request_peer (:obj:`~pyrogram.types.RequestPeerTypeChannelInfo` | :obj:`~pyrogram.types.RequestPeerTypeChatInfo` | :obj:`~pyrogram.types.RequestPeerTypeUserInfo`, *optional*): + request_peer (:obj:`~pyrogram.types.RequestChannelInfo` | :obj:`~pyrogram.types.RequestChatInfo` | :obj:`~pyrogram.types.RequestUserInfo`, *optional*): If specified, the requested peer will be sent when the button is pressed. web_app (:obj:`~pyrogram.types.WebAppInfo`, *optional*): diff --git a/pyrogram/types/bots_and_keyboards/labeled_price.py b/pyrogram/types/bots_and_keyboards/labeled_price.py new file mode 100644 index 000000000..ca497b424 --- /dev/null +++ b/pyrogram/types/bots_and_keyboards/labeled_price.py @@ -0,0 +1,58 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present Dan +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . + +from pyrogram import raw + +from ..object import Object + + +class LabeledPrice(Object): + """This object represents a portion of the price for goods or services. + + Parameters: + label (``str``): + Portion label. + + amount (``int``): + Price of the product in the smallest units of the currency (integer, **not** float/double). For example, for a price of ``US$ 1.45`` pass ``amount = 145``. See the __exp__ parameter in `currencies.json `_, it shows the number of digits past the decimal point for each currency (2 for the majority of currencies). + + """ + + def __init__( + self, + label: str, + amount: int + ): + super().__init__() + + self.label = label + self.amount = amount + + @staticmethod + def _parse(labeled_price: "raw.types.LabeledPrice") -> "LabeledPrice": + if isinstance(labeled_price, raw.types.LabeledPrice): + return LabeledPrice( + label=labeled_price.label, + amount=labeled_price.amount + ) + + def write(self): + return raw.types.LabeledPrice( + label=self.label, + amount=self.amount + ) diff --git a/pyrogram/types/bots_and_keyboards/payment_info.py b/pyrogram/types/bots_and_keyboards/order_info.py similarity index 76% rename from pyrogram/types/bots_and_keyboards/payment_info.py rename to pyrogram/types/bots_and_keyboards/order_info.py index 16767c7ad..596686020 100644 --- a/pyrogram/types/bots_and_keyboards/payment_info.py +++ b/pyrogram/types/bots_and_keyboards/order_info.py @@ -16,33 +16,38 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from ..object import Object +from typing import Optional + from pyrogram import types +from ..object import Object -class PaymentInfo(Object): - """Contains information about a payment. + +class OrderInfo(Object): + """This object represents information about an order. Parameters: name (``str``, *optional*): - User's name. + User name. phone_number (``str``, *optional*): User's phone number. email (``str``, *optional*): - User's email. + User email. shipping_address (:obj:`~pyrogram.types.ShippingAddress`, *optional*): - User's shipping address. + User shipping address. + """ def __init__( - self, *, - name: str = None, - phone_number: str = None, - email: str = None, - shipping_address: "types.ShippingAddress" = None + self, + *, + name: Optional[str] = None, + phone_number: Optional[str] = None, + email: Optional[str] = None, + shipping_address: Optional["types.ShippingAddress"] = None ): super().__init__() diff --git a/pyrogram/types/bots_and_keyboards/pre_checkout_query.py b/pyrogram/types/bots_and_keyboards/pre_checkout_query.py index f8fde5546..e90ba50a2 100644 --- a/pyrogram/types/bots_and_keyboards/pre_checkout_query.py +++ b/pyrogram/types/bots_and_keyboards/pre_checkout_query.py @@ -16,18 +16,16 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from typing import Union, List, Match, Optional +from typing import Union, Optional import pyrogram -from pyrogram import raw, enums -from pyrogram import types +from pyrogram import types, raw from ..object import Object from ..update import Update -from ... import utils class PreCheckoutQuery(Object, Update): - """An incoming pre-checkout query from a buy button in an inline keyboard. + """This object contains information about an incoming pre-checkout query. Parameters: id (``str``): @@ -37,18 +35,18 @@ class PreCheckoutQuery(Object, Update): User who sent the query. currency (``str``): - Three-letter ISO 4217 currency code. + Three-letter ISO 4217 `currency `_ code, or ``XTR`` for payments in `Telegram Stars `_. total_amount (``int``): - Total price in the smallest units of the currency. + Total price in the smallest units of the currency (integer, **not** float/double). For example, for a price of ``US$ 1.45`` pass ``amount = 145``. See the __exp__ parameter in `currencies.json `_, it shows the number of digits past the decimal point for each currency (2 for the majority of currencies). - payload (``str``): + invoice_payload (``str``): Bot specified invoice payload. shipping_option_id (``str``, *optional*): Identifier of the shipping option chosen by the user. - payment_info (:obj:`~pyrogram.types.PaymentInfo`, *optional*): + order_info (:obj:`~pyrogram.types.OrderInfo`, *optional*): Payment information provided by the user. """ @@ -60,9 +58,9 @@ def __init__( from_user: "types.User", currency: str, total_amount: int, - payload: str, - shipping_option_id: str = None, - payment_info: "types.PaymentInfo" = None + invoice_payload: str, + shipping_option_id: Optional[str] = None, + order_info: Optional["types.OrderInfo"] = None ): super().__init__(client) @@ -70,27 +68,31 @@ def __init__( self.from_user = from_user self.currency = currency self.total_amount = total_amount - self.payload = payload + self.invoice_payload = invoice_payload self.shipping_option_id = shipping_option_id - self.payment_info = payment_info + self.order_info = order_info @staticmethod - async def _parse(client: "pyrogram.Client", pre_checkout_query, users) -> "PreCheckoutQuery": + async def _parse( + client: "pyrogram.Client", + pre_checkout_query: "raw.types.UpdateBotPrecheckoutQuery", + users: dict + ) -> "PreCheckoutQuery": # Try to decode pre-checkout query payload into string. If that fails, fallback to bytes instead of decoding by # ignoring/replacing errors, this way, button clicks will still work. try: - payload = pre_checkout_query.payload.decode() + invoice_payload = pre_checkout_query.payload.decode() except (UnicodeDecodeError, AttributeError): - payload = pre_checkout_query.payload + invoice_payload = pre_checkout_query.payload return PreCheckoutQuery( id=str(pre_checkout_query.query_id), from_user=types.User._parse(client, users[pre_checkout_query.user_id]), currency=pre_checkout_query.currency, total_amount=pre_checkout_query.total_amount, - payload=payload, + invoice_payload=invoice_payload, shipping_option_id=pre_checkout_query.shipping_option_id, - payment_info=types.PaymentInfo( + order_info=types.OrderInfo( name=pre_checkout_query.info.name, phone_number=pre_checkout_query.info.phone, email=pre_checkout_query.info.email, @@ -106,7 +108,7 @@ async def _parse(client: "pyrogram.Client", pre_checkout_query, users) -> "PreCh client=client ) - async def answer(self, success: bool = None, error: str = None): + async def answer(self, ok: bool = None, error_message: str = None): """Bound method *answer* of :obj:`~pyrogram.types.PreCheckoutQuery`. Use this method as a shortcut for: @@ -115,25 +117,26 @@ async def answer(self, success: bool = None, error: str = None): await client.answer_pre_checkout_query( pre_checkout_query.id, - success=True + ok=True ) Example: .. code-block:: python - await pre_checkout_query.answer(success=True) + await pre_checkout_query.answer(ok=True) Parameters: - success (``bool`` *optional*): - If true, an alert will be shown by the client instead of a notification at the top of the chat screen. - Defaults to False. + ok (``bool`` *optional*): + Specify True if everything is alright (goods are available, etc.) and the bot is ready to proceed with the order. Use False if there are any problems. - error (``bool`` *optional*): - If true, an alert will be shown by the client instead of a notification at the top of the chat screen. - Defaults to False. + error_message (``str`` *optional*): + Required if ok is False. Error message in human readable form that explains the reason for failure to proceed with the checkout (e.g. "Sorry, somebody just bought the last of our amazing black T-shirts while you were busy filling out your payment details. Please choose a different color or garment!"). Telegram will display this message to the user. + + Returns: + ``bool``: True, on success. """ return await self._client.answer_pre_checkout_query( pre_checkout_query_id=self.id, - success=success, - error=error + ok=ok, + error_message=error_message ) diff --git a/pyrogram/types/bots_and_keyboards/shipping_address.py b/pyrogram/types/bots_and_keyboards/shipping_address.py index 8e373f31b..c7a468e2a 100644 --- a/pyrogram/types/bots_and_keyboards/shipping_address.py +++ b/pyrogram/types/bots_and_keyboards/shipping_address.py @@ -23,39 +23,41 @@ class ShippingAddress(Object): """Contains information about a shipping address. Parameters: - street_line1 (``str``): - First line for the address. + country_code (``str``): + Two-letter `ISO 3166-1 alpha-2 `_ country code. - street_line1 (``str``): - Second line for the address. + state (``str``): + State, if applicable. city (``str``): - City for the address. + City. - state (``str``): - State for the address, if applicable. + street_line1 (``str``): + First line for the address. + + street_line2 (``str``): + Second line for the address. post_code (``str``): - Post code for the address. + Address post code. - country_code (``str``): - Two-letter ISO 3166-1 alpha-2 country code. """ def __init__( - self, *, + self, + *, + country_code: str, + state: str, + city: str, street_line1: str, street_line2: str, - city: str, - state: str, - post_code: str, - country_code: str + post_code: str ): super().__init__() + self.country_code = country_code + self.state = state + self.city = city self.street_line1 = street_line1 self.street_line2 = street_line2 - self.city = city - self.state = state self.post_code = post_code - self.country_code = country_code diff --git a/pyrogram/types/input_privacy_rule/__init__.py b/pyrogram/types/input_privacy_rule/__init__.py new file mode 100644 index 000000000..3cbfda408 --- /dev/null +++ b/pyrogram/types/input_privacy_rule/__init__.py @@ -0,0 +1,41 @@ +# 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 .input_privacy_rule import InputPrivacyRule +from .input_privacy_rule_allow_all import InputPrivacyRuleAllowAll +from .input_privacy_rule_allow_chats import InputPrivacyRuleAllowChats +from .input_privacy_rule_allow_contacts import InputPrivacyRuleAllowContacts +from .input_privacy_rule_allow_premium import InputPrivacyRuleAllowPremium +from .input_privacy_rule_allow_users import InputPrivacyRuleAllowUsers +from .input_privacy_rule_disallow_all import InputPrivacyRuleDisallowAll +from .input_privacy_rule_disallow_chats import InputPrivacyRuleDisallowChats +from .input_privacy_rule_disallow_contacts import InputPrivacyRuleDisallowContacts +from .input_privacy_rule_disallow_users import InputPrivacyRuleDisallowUsers + +__all__ = [ + "InputPrivacyRule", + "InputPrivacyRuleAllowAll", + "InputPrivacyRuleAllowChats", + "InputPrivacyRuleAllowContacts", + "InputPrivacyRuleAllowPremium", + "InputPrivacyRuleAllowUsers", + "InputPrivacyRuleDisallowAll", + "InputPrivacyRuleDisallowChats", + "InputPrivacyRuleDisallowContacts", + "InputPrivacyRuleDisallowUsers" +] diff --git a/pyrogram/types/input_privacy_rule/input_privacy_rule.py b/pyrogram/types/input_privacy_rule/input_privacy_rule.py new file mode 100644 index 000000000..b4e7493ab --- /dev/null +++ b/pyrogram/types/input_privacy_rule/input_privacy_rule.py @@ -0,0 +1,44 @@ +# 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 pyrogram + +from ..object import Object + + +class InputPrivacyRule(Object): + """Content of a privacy rule. + + It should be one of: + + - :obj:`~pyrogram.types.InputPrivacyRuleAllowAll` + - :obj:`~pyrogram.types.InputPrivacyRuleAllowContacts` + - :obj:`~pyrogram.types.InputPrivacyRuleAllowPremium` + - :obj:`~pyrogram.types.InputPrivacyRuleAllowUsers` + - :obj:`~pyrogram.types.InputPrivacyRuleAllowChats` + - :obj:`~pyrogram.types.InputPrivacyRuleDisallowAll` + - :obj:`~pyrogram.types.InputPrivacyRuleDisallowContacts` + - :obj:`~pyrogram.types.InputPrivacyRuleDisallowUsers` + - :obj:`~pyrogram.types.InputPrivacyRuleDisallowChats` + """ + + def __init__(self): + super().__init__() + + async def write(self, client: "pyrogram.Client"): + raise NotImplementedError diff --git a/pyrogram/types/input_privacy_rule/input_privacy_rule_allow_all.py b/pyrogram/types/input_privacy_rule/input_privacy_rule_allow_all.py new file mode 100644 index 000000000..f8134ca0f --- /dev/null +++ b/pyrogram/types/input_privacy_rule/input_privacy_rule_allow_all.py @@ -0,0 +1,33 @@ +# 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 pyrogram +from pyrogram import raw +from .input_privacy_rule import InputPrivacyRule + + +class InputPrivacyRuleAllowAll(InputPrivacyRule): + """Allow all users.""" + + def __init__( + self, + ): + super().__init__() + + async def write(self, client: "pyrogram.Client"): + return raw.types.InputPrivacyValueAllowAll() diff --git a/pyrogram/types/input_privacy_rule/input_privacy_rule_allow_chats.py b/pyrogram/types/input_privacy_rule/input_privacy_rule_allow_chats.py new file mode 100644 index 000000000..ca7311d9c --- /dev/null +++ b/pyrogram/types/input_privacy_rule/input_privacy_rule_allow_chats.py @@ -0,0 +1,49 @@ +# 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 Union, Iterable + +import pyrogram +from pyrogram import raw, utils +from .input_privacy_rule import InputPrivacyRule + + +class InputPrivacyRuleAllowChats(InputPrivacyRule): + """Allow only participants of certain chats. + + Parameters: + chat_ids (``int`` | ``str`` | Iterable of ``int`` or ``str``): + Unique identifier (int) or username (str) of the target chat. + """ + + def __init__( + self, + chat_ids: Union[int, str, Iterable[Union[int, str]]], + ): + super().__init__() + + self.chat_ids = chat_ids + + async def write(self, client: "pyrogram.Client"): + chats = list(self.chat_ids) if not isinstance(self.chat_ids, (int, str)) else [self.chat_ids] + chats = await asyncio.gather(*[client.resolve_peer(i) for i in chats]) + + return raw.types.InputPrivacyValueAllowChatParticipants( + chats=[utils.get_peer_id(i) for i in chats] + ) diff --git a/pyrogram/types/input_privacy_rule/input_privacy_rule_allow_contacts.py b/pyrogram/types/input_privacy_rule/input_privacy_rule_allow_contacts.py new file mode 100644 index 000000000..c7c52130a --- /dev/null +++ b/pyrogram/types/input_privacy_rule/input_privacy_rule_allow_contacts.py @@ -0,0 +1,33 @@ +# 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 pyrogram +from pyrogram import raw +from .input_privacy_rule import InputPrivacyRule + + +class InputPrivacyRuleAllowContacts(InputPrivacyRule): + """Allow contacts only.""" + + def __init__( + self, + ): + super().__init__() + + async def write(self, client: "pyrogram.Client"): + return raw.types.InputPrivacyValueAllowContacts() diff --git a/pyrogram/types/input_privacy_rule/input_privacy_rule_allow_premium.py b/pyrogram/types/input_privacy_rule/input_privacy_rule_allow_premium.py new file mode 100644 index 000000000..7bbc77cb9 --- /dev/null +++ b/pyrogram/types/input_privacy_rule/input_privacy_rule_allow_premium.py @@ -0,0 +1,33 @@ +# 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 pyrogram +from pyrogram import raw +from .input_privacy_rule import InputPrivacyRule + + +class InputPrivacyRuleAllowPremium(InputPrivacyRule): + """Allow only users with a Premium subscription, currently only usable for :obj:`~pyrogram.enums.PrivacyKey.CHAT_INVITE`.""" + + def __init__( + self, + ): + super().__init__() + + async def write(self, client: "pyrogram.Client"): + return raw.types.InputPrivacyValueAllowPremium() diff --git a/pyrogram/types/input_privacy_rule/input_privacy_rule_allow_users.py b/pyrogram/types/input_privacy_rule/input_privacy_rule_allow_users.py new file mode 100644 index 000000000..ab2b06466 --- /dev/null +++ b/pyrogram/types/input_privacy_rule/input_privacy_rule_allow_users.py @@ -0,0 +1,47 @@ +# 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 Union, Iterable + +import pyrogram +from pyrogram import raw +from .input_privacy_rule import InputPrivacyRule + + +class InputPrivacyRuleAllowUsers(InputPrivacyRule): + """Allow only participants of certain users. + + Parameters: + chat_ids (``int`` | ``str`` | Iterable of ``int`` or ``str``, *optional*): + Unique identifier (int) or username (str) of the target chat. + """ + + def __init__( + self, + chat_ids: Union[int, str, Iterable[Union[int, str]]], + ): + super().__init__() + + self.chat_ids = chat_ids + + async def write(self, client: "pyrogram.Client"): + users = list(self.chat_ids) if not isinstance(self.chat_ids, (int, str)) else [self.chat_ids] + users = await asyncio.gather(*[client.resolve_peer(i) for i in users]) + + return raw.types.InputPrivacyValueAllowUsers(users=users) diff --git a/pyrogram/types/input_privacy_rule/input_privacy_rule_disallow_all.py b/pyrogram/types/input_privacy_rule/input_privacy_rule_disallow_all.py new file mode 100644 index 000000000..1fa9306f1 --- /dev/null +++ b/pyrogram/types/input_privacy_rule/input_privacy_rule_disallow_all.py @@ -0,0 +1,33 @@ +# 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 pyrogram +from pyrogram import raw +from .input_privacy_rule import InputPrivacyRule + + +class InputPrivacyRuleDisallowAll(InputPrivacyRule): + """Disallow all users.""" + + def __init__( + self, + ): + super().__init__() + + async def write(self, client: "pyrogram.Client"): + return raw.types.InputPrivacyValueDisallowAll() diff --git a/pyrogram/types/input_privacy_rule/input_privacy_rule_disallow_chats.py b/pyrogram/types/input_privacy_rule/input_privacy_rule_disallow_chats.py new file mode 100644 index 000000000..625ab6451 --- /dev/null +++ b/pyrogram/types/input_privacy_rule/input_privacy_rule_disallow_chats.py @@ -0,0 +1,49 @@ +# 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 Union, Iterable + +import pyrogram +from pyrogram import raw, utils +from .input_privacy_rule import InputPrivacyRule + + +class InputPrivacyRuleDisallowChats(InputPrivacyRule): + """Disallow only participants of certain chats. + + Parameters: + chat_ids (``int`` | ``str`` | Iterable of ``int`` or ``str``): + Unique identifier (int) or username (str) of the target chat. + """ + + def __init__( + self, + chat_ids: Union[int, str, Iterable[Union[int, str]]], + ): + super().__init__() + + self.chat_ids = chat_ids + + async def write(self, client: "pyrogram.Client"): + chats = list(self.chat_ids) if not isinstance(self.chat_ids, (int, str)) else [self.chat_ids] + chats = await asyncio.gather(*[client.resolve_peer(i) for i in chats]) + + return raw.types.InputPrivacyValueDisallowChatParticipants( + chats=[utils.get_peer_id(i) for i in chats] + ) diff --git a/pyrogram/types/input_privacy_rule/input_privacy_rule_disallow_contacts.py b/pyrogram/types/input_privacy_rule/input_privacy_rule_disallow_contacts.py new file mode 100644 index 000000000..21ddf98ab --- /dev/null +++ b/pyrogram/types/input_privacy_rule/input_privacy_rule_disallow_contacts.py @@ -0,0 +1,33 @@ +# 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 pyrogram +from pyrogram import raw +from .input_privacy_rule import InputPrivacyRule + + +class InputPrivacyRuleDisallowContacts(InputPrivacyRule): + """Disallow contacts only.""" + + def __init__( + self, + ): + super().__init__() + + async def write(self, client: "pyrogram.Client"): + return raw.types.InputPrivacyValueDisallowContacts() diff --git a/pyrogram/types/input_privacy_rule/input_privacy_rule_disallow_users.py b/pyrogram/types/input_privacy_rule/input_privacy_rule_disallow_users.py new file mode 100644 index 000000000..17e543a14 --- /dev/null +++ b/pyrogram/types/input_privacy_rule/input_privacy_rule_disallow_users.py @@ -0,0 +1,47 @@ +# 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 Union, Iterable + +import pyrogram +from pyrogram import raw +from .input_privacy_rule import InputPrivacyRule + + +class InputPrivacyRuleDisallowUsers(InputPrivacyRule): + """Disallow only participants of certain users. + + Parameters: + chat_ids (``int`` | ``str`` | Iterable of ``int`` or ``str``, *optional*): + Unique identifier (int) or username (str) of the target chat. + """ + + def __init__( + self, + chat_ids: Union[int, str, Iterable[Union[int, str]]], + ): + super().__init__() + + self.chat_ids = chat_ids + + async def write(self, client: "pyrogram.Client"): + users = list(self.chat_ids) if not isinstance(self.chat_ids, (int, str)) else [self.chat_ids] + users = await asyncio.gather(*[client.resolve_peer(i) for i in users]) + + return raw.types.InputPrivacyValueDisallowUsers(users=users) diff --git a/pyrogram/types/messages_and_media/__init__.py b/pyrogram/types/messages_and_media/__init__.py index b4ca8a493..fc47844ef 100644 --- a/pyrogram/types/messages_and_media/__init__.py +++ b/pyrogram/types/messages_and_media/__init__.py @@ -42,6 +42,9 @@ from .message_entity import MessageEntity from .message_reactions import MessageReactions from .my_boost import MyBoost +from .paid_media_info import PaidMediaInfo +from .paid_media_preview import PaidMediaPreview +from .payment_form import PaymentForm from .photo import Photo from .poll import Poll from .poll_option import PollOption @@ -49,6 +52,7 @@ from .sticker import Sticker from .story import Story from .stripped_thumbnail import StrippedThumbnail +from .successful_payment import SuccessfulPayment from .thumbnail import Thumbnail from .venue import Venue from .video import Video @@ -84,6 +88,9 @@ "MessageEntity", "MessageReactions", "MyBoost", + "PaidMediaInfo", + "PaidMediaPreview", + "PaymentForm", "Photo", "Poll", "PollOption", @@ -91,6 +98,7 @@ "Sticker", "Story", "StrippedThumbnail", + "SuccessfulPayment", "Thumbnail", "Venue", "Video", diff --git a/pyrogram/types/messages_and_media/invoice.py b/pyrogram/types/messages_and_media/invoice.py index 3ff7e691a..21a21b939 100644 --- a/pyrogram/types/messages_and_media/invoice.py +++ b/pyrogram/types/messages_and_media/invoice.py @@ -16,9 +16,10 @@ # You should have received a copy of the GNU Lesser General Public License # along with Pyrogram. If not, see . -from typing import Optional +from typing import Optional, List, Union -from pyrogram import raw +import pyrogram +from pyrogram import raw, types from ..object import Object @@ -26,60 +27,136 @@ class Invoice(Object): """This object contains basic information about an invoice. Parameters: - title (``str``): + currency (``str``): + Three-letter ISO 4217 `currency `_ code. + + is_test (``bool``): + True, if the invoice is a test invoice. + + title (``str``, *optional*): Product name. - description (``str``): + description (``str``, *optional*): Product description. - start_parameter (``str``): + total_amount (``int``, *optional*): + Total price in the smallest units of the currency (integer, **not** float/double). For example, for a price of ``US$ 1.45`` pass ``amount = 145``. See the exp parameter in `currencies.json `_, it shows the number of digits past the decimal point for each currency (2 for the majority of currencies). + + start_parameter (``str``, *optional*): Unique bot deep-linking parameter that can be used to generate this invoice. - currency (``str``): - Three-letter ISO 4217 `currency `_ code. + prices (List of :obj:`~pyrogram.types.LabeledPrice`, *optional*): + Price breakdown, a list of components (e.g. product price, tax, discount, delivery cost, delivery tax, bonus, etc.). - total_amount (``int``): - Total price in the smallest units of the currency (integer, **not** float/double). For example, for a price of ``US$ 1.45`` pass ``amount = 145``. See the exp parameter in `currencies.json `_, it shows the number of digits past the decimal point for each currency (2 for the majority of currencies). + is_name_requested (``bool``, *optional*): + True, if the name should be specified. + + is_phone_requested (``bool``, *optional*): + True, if the phone should be specified. + + is_email_requested (``bool``, *optional*): + True, if the email address should be specified. is_shipping_address_requested (``bool``, *optional*): True, if the shipping address should be specified. - is_test (``bool``, *optional*): - True, if the invoice is a test invoice. + is_flexible (``bool``, *optional*): + True, if the final price depends on the shipping method. + + is_phone_to_provider (``bool``, *optional*): + True, if user's phone should be sent to provider. + + is_email_to_provider (``bool``, *optional*): + True, if user's email address should be sent to provider. + + is_recurring (``bool``, *optional*): + Whether this is a recurring payment. + + max_tip_amount (``int``, *optional*): + The maximum accepted amount for tips in the smallest units of the currency (integer, not float/double). + For example, for a price of US$ 1.45 pass amount = 145. + See the exp parameter in currencies.json, it shows the number of digits past the decimal point for each currency (2 for the majority of currencies). + + suggested_tip_amounts (List of ``int``, *optional*): + A vector of suggested amounts of tips in the smallest units of the currency (integer, not float/double). + At most 4 suggested tip amounts can be specified. + The suggested tip amounts must be positive, passed in a strictly increased order and must not exceed max_tip_amount. + + terms_url (``str``, *optional*): + Terms of service URL. + + raw (:obj:`~raw.base.payments.MessageMediaInvoice` | :obj:`~raw.base.Invoice`, *optional*): + The raw object, as received from the Telegram API. """ def __init__( self, *, client: "pyrogram.Client" = None, - title: str, - description: str, currency: str, - total_amount: int, + is_test: bool, + title: Optional[str] = None, + description: Optional[str] = None, + total_amount: Optional[int] = None, start_parameter: Optional[str] = None, + prices: Optional[List["types.LabeledPrice"]] = None, + is_name_requested: Optional[bool] = None, + is_phone_requested: Optional[bool] = None, + is_email_requested: Optional[bool] = None, is_shipping_address_requested: Optional[bool] = None, - is_test: Optional[bool] = None + is_flexible: Optional[bool] = None, + is_phone_to_provider: Optional[bool] = None, + is_email_to_provider: Optional[bool] = None, + is_recurring: Optional[bool] = None, + max_tip_amount: Optional[int] = None, + suggested_tip_amounts: Optional[List[int]] = None, + terms_url: Optional[str] = None, + raw: Union["raw.types.MessageMediaInvoice", "raw.types.Invoice"] = None ): super().__init__(client) + self.currency = currency + self.is_test = is_test self.title = title self.description = description - self.is_shipping_address_requested = is_shipping_address_requested - self.currency = currency - self.start_parameter = start_parameter self.total_amount = total_amount - self.is_test = is_test + self.start_parameter = start_parameter + self.prices = prices + self.is_name_requested = is_name_requested + self.is_phone_requested = is_phone_requested + self.is_email_requested = is_email_requested + self.is_shipping_address_requested = is_shipping_address_requested + self.is_flexible = is_flexible + self.is_phone_to_provider = is_phone_to_provider + self.is_email_to_provider = is_email_to_provider + self.is_recurring = is_recurring + self.max_tip_amount = max_tip_amount + self.suggested_tip_amounts = suggested_tip_amounts + self.terms_url = terms_url + self.raw = raw @staticmethod - def _parse(client, invoice: "raw.types.MessageMediaInvoice") -> "Invoice": + def _parse(client, invoice: Union["raw.types.MessageMediaInvoice", "raw.types.Invoice"]) -> "Invoice": return Invoice( - title=invoice.title, - description=invoice.description, currency=invoice.currency, - total_amount=invoice.total_amount, - start_parameter=invoice.start_param or None, + is_test=invoice.test, + title=getattr(invoice, "title", None), + description=getattr(invoice, "description", None), + total_amount=getattr(invoice, "total_amount", None), + start_parameter=getattr(invoice, "start_param", None) or None, + prices=types.List(types.LabeledPrice._parse(lp) for lp in invoice.prices) if getattr(invoice, "prices", None) else None, + is_name_requested=getattr(invoice, "name_requested", None), + is_phone_requested=getattr(invoice, "phone_requested", None), + is_email_requested=getattr(invoice, "email_requested", None), is_shipping_address_requested=getattr(invoice, "shipping_address_requested", None), - is_test=getattr(invoice, "test", None), + is_flexible=getattr(invoice, "flexible", None), + is_phone_to_provider=getattr(invoice, "phone_to_provider", None), + is_email_to_provider=getattr(invoice, "email_to_provider", None), + is_recurring=getattr(invoice, "recurring", None), + max_tip_amount=getattr(invoice, "max_tip_amount", None), + suggested_tip_amounts=getattr(invoice, "suggested_tip_amounts", None) or None, + terms_url=getattr(invoice, "terms_url", None), + raw=invoice, client=client # TODO: Add photo and extended media ) diff --git a/pyrogram/types/messages_and_media/message.py b/pyrogram/types/messages_and_media/message.py index 5bec9bbb9..2fbf5c4cf 100644 --- a/pyrogram/types/messages_and_media/message.py +++ b/pyrogram/types/messages_and_media/message.py @@ -143,6 +143,9 @@ class Message(Object, Update): This field will contain the enumeration type of the media message. You can use ``media = getattr(message, message.media.value)`` to access the media message. + paid_media (:obj:`~pyrogram.types.PaidMediaInfo`, *optional*): + The message is a paid media message. + show_above_text (``bool``, *optional*): If True, link preview will be shown above the message text. Otherwise, the link preview will be shown below the message text. @@ -405,7 +408,7 @@ class Message(Object, Update): Generate a link to this message, only for groups and channels. """ - # TODO: Add game missing field. Also successful_payment, connected_website + # TODO: Add game missing field, connected_website def __init__( self, @@ -437,6 +440,7 @@ def __init__( scheduled: bool = None, from_scheduled: bool = None, media: "enums.MessageMediaType" = None, + paid_media: "types.PaidMediaInfo" = None, show_above_text: bool = None, edit_date: datetime = None, edit_hidden: bool = None, @@ -545,6 +549,7 @@ def __init__( self.scheduled = scheduled self.from_scheduled = from_scheduled self.media = media + self.paid_media = paid_media self.show_above_text = show_above_text self.edit_date = edit_date self.edit_hidden = edit_hidden @@ -919,6 +924,7 @@ async def _parse( web_page = None poll = None dice = None + paid_media = None media = message.media media_type = None @@ -1021,6 +1027,9 @@ async def _parse( elif isinstance(media, raw.types.MessageMediaDice): dice = types.Dice._parse(client, media) media_type = enums.MessageMediaType.DICE + elif isinstance(media, raw.types.MessageMediaPaidMedia): + paid_media = types.PaidMediaInfo._parse(client, media) + media_type = enums.MessageMediaType.PAID_MEDIA else: media = None @@ -1084,6 +1093,7 @@ async def _parse( scheduled=is_scheduled, from_scheduled=message.from_scheduled, media=media_type, + paid_media=paid_media, show_above_text=getattr(message, "invert_media", None), edit_date=utils.timestamp_to_datetime(message.edit_date), edit_hidden=message.edit_hide, @@ -1216,10 +1226,7 @@ async def _parse( @property def link(self) -> str: - if ( - (self.chat.type in (enums.ChatType.GROUP, enums.ChatType.SUPERGROUP, enums.ChatType.CHANNEL) and - self.chat.username) or self.chat.username - ): + if self.chat.username: return f"https://t.me/{self.chat.username}/{self.id}" else: return f"https://t.me/c/{utils.get_channel_id(self.chat.id)}/{self.id}" @@ -4272,6 +4279,7 @@ async def copy( business_connection_id (``str``, *optional*): Unique identifier of the business connection on behalf of which the message will be sent. + reply_markup (:obj:`~pyrogram.types.InlineKeyboardMarkup` | :obj:`~pyrogram.types.ReplyKeyboardMarkup` | :obj:`~pyrogram.types.ReplyKeyboardRemove` | :obj:`~pyrogram.types.ForceReply`, *optional*): Additional interface options. An object for an inline keyboard, custom reply keyboard, instructions to remove reply keyboard or to force a reply from the user. @@ -4948,3 +4956,28 @@ async def view(self) -> bool: chat_id=self.chat.id, message_id=self.id ) + + async def pay(self) -> bool: + """Bound method *pay* of :obj:`~pyrogram.types.Message`. + + Use as a shortcut for: + + .. code-block:: python + + await client.send_payment_form( + chat_id=message.chat.id, + message_id=message_id + ) + + Example: + .. code-block:: python + + await message.pay() + + Returns: + True on success. + """ + return await self._client.send_payment_form( + chat_id=self.chat.id, + message_id=self.id + ) diff --git a/pyrogram/types/messages_and_media/paid_media_info.py b/pyrogram/types/messages_and_media/paid_media_info.py new file mode 100644 index 000000000..4bf8bba15 --- /dev/null +++ b/pyrogram/types/messages_and_media/paid_media_info.py @@ -0,0 +1,93 @@ +# 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, Union + +import pyrogram +from pyrogram import raw, types +from ..object import Object + + +class PaidMediaInfo(Object): + """Describes the paid media added to a message. + + Parameters: + stars_amount (``int``): + The number of Telegram Stars that must be paid to buy access to the media. + + media (List of :obj:`~pyrogram.types.Photo` | :obj:`~pyrogram.types.Video` | :obj:`~pyrogram.types.PaidMediaPreview`): + Information about the paid media. + """ + + def __init__( + self, + *, + stars_amount: str, + media: List[Union["types.Photo", "types.Video", "types.PaidMediaPreview"]] + ): + super().__init__() + + self.stars_amount = stars_amount + self.media = media + + @staticmethod + def _parse( + client: "pyrogram.Client", + message_paid_media: "raw.types.MessageMediaPaidMedia" + ) -> "PaidMediaInfo": + medias = [] + + for extended_media in message_paid_media.extended_media: + if isinstance(extended_media, raw.types.MessageExtendedMediaPreview): + thumbnail = None + + if isinstance(getattr(extended_media, "thumb", None), raw.types.PhotoStrippedSize): + thumbnail = types.StrippedThumbnail._parse(client, extended_media.thumb) + + medias.append( + types.PaidMediaPreview( + width=getattr(extended_media, "w", None), + height=getattr(extended_media, "h", None), + duration=getattr(extended_media, "video_duration", None), + thumbnail=thumbnail, + ) + ) + elif isinstance(extended_media, raw.types.MessageExtendedMedia): + media = extended_media.media + + if isinstance(media, raw.types.MessageMediaPhoto): + medias.append(types.Photo._parse(client, media.photo, media.ttl_seconds)) + elif isinstance(media, raw.types.MessageMediaDocument): + doc = media.document + + attributes = {type(i): i for i in doc.attributes} + + file_name = getattr( + attributes.get( + raw.types.DocumentAttributeFilename, None + ), "file_name", None + ) + + video_attributes = attributes[raw.types.DocumentAttributeVideo] + + medias.append(types.Video._parse(client, doc, video_attributes, file_name, media.ttl_seconds)) + + return PaidMediaInfo( + stars_amount=message_paid_media.stars_amount, + media=types.List(medias) + ) diff --git a/pyrogram/types/messages_and_media/paid_media_preview.py b/pyrogram/types/messages_and_media/paid_media_preview.py new file mode 100644 index 000000000..11d1d0209 --- /dev/null +++ b/pyrogram/types/messages_and_media/paid_media_preview.py @@ -0,0 +1,55 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017-present Dan +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . + +from pyrogram import types + +from ..object import Object + + +class PaidMediaPreview(Object): + """The paid media isn't available before the payment. + + Parameters: + width (``int``, *optional*): + Media width as defined by the sender. + + height (``int``, *optional*): + Media height as defined by the sender. + + duration (``int``, *optional*): + Duration of the media in seconds as defined by the sender. + + thumbnail (:obj:`~pyrogram.types.StrippedThumbnail`, *optional*): + Media thumbnail. + + """ + + def __init__( + self, + *, + width: int = None, + height: int = None, + duration: int = None, + thumbnail: "types.StrippedThumbnail" = None + ): + super().__init__() + + self.width = width + self.height = height + self.duration = duration + self.thumbnail = thumbnail diff --git a/pyrogram/types/messages_and_media/payment_form.py b/pyrogram/types/messages_and_media/payment_form.py new file mode 100644 index 000000000..0d6f0ef2d --- /dev/null +++ b/pyrogram/types/messages_and_media/payment_form.py @@ -0,0 +1,117 @@ +# 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 Optional + +import pyrogram +from pyrogram import types, raw +from ..object import Object + + +class PaymentForm(Object): + """This object contains basic information about an payment form. + + Parameters: + id (``int``): + Form id. + + bot (``str``): + Bot. + + title (``str``): + Form title. + + description (``str``): + Form description. + + invoice (``str``): + Invoice. + + provider (``str``, *optional*): + Payment provider. + + url (``str``, *optional*): + Payment form URL. + + can_save_credentials (``str``, *optional*): + Whether the user can choose to save credentials. + + is_password_missing (``str``, *optional*): + Indicates that the user can save payment credentials, + but only after setting up a 2FA password + (currently the account doesn't have a 2FA password). + + native_provider (``str``, *optional*): + Payment provider name. + + raw (:obj:`~raw.base.payments.PaymentForm`, *optional*): + The raw object, as received from the Telegram API. + """ + + def __init__( + self, + *, + client: "pyrogram.Client" = None, + id: int, + bot: "types.User", + title: str, + description: str, + invoice: "types.Invoice", + provider: Optional["types.User"] = None, + url: Optional[str] = None, + can_save_credentials: Optional[bool] = None, + is_password_missing: Optional[bool] = None, + native_provider: Optional[str] = None, + raw: "raw.base.payments.PaymentForm" = None, + # TODO: Add support for other params: + # native_params + # additional_params + # saved_info + # saved_credentials + ): + super().__init__(client) + + self.id = id + self.bot = bot + self.title = title + self.description = description + self.invoice = invoice + self.provider = provider + self.url = url + self.can_save_credentials = can_save_credentials + self.is_password_missing = is_password_missing + self.native_provider = native_provider + self.raw = raw + + @staticmethod + def _parse(client, payment_form: "raw.base.payments.PaymentForm") -> "PaymentForm": + users = {i.id: i for i in payment_form.users} + + return PaymentForm( + id=payment_form.form_id, + bot=types.User._parse(client, users.get(payment_form.bot_id)), + title=payment_form.title, + description=payment_form.description, + invoice=types.Invoice._parse(client, payment_form.invoice), + provider=types.User._parse(client, users.get(getattr(payment_form, "provider_id", None))), + url=getattr(payment_form, "url", None), + can_save_credentials=getattr(payment_form, "can_save_credentials", None), + is_password_missing=getattr(payment_form, "password_missing", None), + native_provider=getattr(payment_form, "native_provider", None), + raw=payment_form + ) diff --git a/pyrogram/types/messages_and_media/story.py b/pyrogram/types/messages_and_media/story.py index 04402bf04..e6f9e9b4f 100644 --- a/pyrogram/types/messages_and_media/story.py +++ b/pyrogram/types/messages_and_media/story.py @@ -104,7 +104,7 @@ class Story(Object, Update): forwards (``int``, *optional*): Stories forwards. - privacy (:obj:`~pyrogram.enums.StoryPrivacyRules`, *optional*): + privacy (:obj:`~pyrogram.enums.StoriesPrivacyRules`, *optional*): Story privacy. allowed_users (List of ``int`` | ``str``, *optional*): @@ -158,7 +158,7 @@ def __init__( caption_entities: List["types.MessageEntity"] = None, views: int = None, forwards: int = None, - privacy: "enums.StoryPrivacyRules" = None, + privacy: "enums.StoriesPrivacyRules" = None, allowed_users: List[Union[int, str]] = None, disallowed_users: List[Union[int, str]] = None, reactions: List["types.Reaction"] = None, @@ -1605,7 +1605,7 @@ async def edit_caption( async def edit_privacy( self, - privacy: "enums.StoriesPrivacyRules" = None, + privacy: "enums.StoriesPrivacyRules" = enums.StoriesPrivacyRules.PUBLIC, allowed_users: List[Union[int, str]] = None, disallowed_users: List[Union[int, str]] = None, ) -> "types.Story": @@ -1627,7 +1627,7 @@ async def edit_privacy( Parameters: privacy (:obj:`~pyrogram.enums.StoriesPrivacyRules`, *optional*): - Story privacy. + Story privacy. Defaults to :obj:`~pyrogram.enums.StoriesPrivacyRules.PUBLIC`. allowed_users (List of ``int`` | ``str``, *optional*): List of user_id or chat_id of chat users who are allowed to view stories. diff --git a/pyrogram/types/messages_and_media/successful_payment.py b/pyrogram/types/messages_and_media/successful_payment.py new file mode 100644 index 000000000..e4b8f119e --- /dev/null +++ b/pyrogram/types/messages_and_media/successful_payment.py @@ -0,0 +1,140 @@ +# 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 Union, Optional +import pyrogram +from pyrogram import raw +from pyrogram import types +from ..object import Object + + +class SuccessfulPayment(Object): + """A service message about a new successful payment. + + Parameters: + currency (``str``): + Three-letter ISO 4217 `currency `_ code, or ``XTR`` for payments in `Telegram Stars `_. + + total_amount (``int``): + Total price in the smallest units of the currency (integer, **not** float/double). For example, for a price of ``US$ 1.45`` pass ``amount = 145``. See the __exp__ parameter in `currencies.json `_, it shows the number of digits past the decimal point for each currency (2 for the majority of currencies). + + invoice_payload (``str``, *optional*): + Bot specified invoice payload. Only available to the bot that received the payment. + + telegram_payment_charge_id (``str``, *optional*): + Telegram payment identifier. Only available to the bot that received the payment. + + provider_payment_charge_id (``str``, *optional*): + Provider payment identifier. Only available to the bot that received the payment. + + shipping_option_id (``str``, *optional*): + Identifier of the shipping option chosen by the user. Only available to the bot that received the payment. + + payment_info (:obj:`~pyrogram.types.PaymentInfo`, *optional*): + Payment information provided by the user. Only available to the bot that received the payment. + + is_recurring (``bool``, *optional*): + True, if this is a recurring payment. + + is_first_recurring (``bool``, *optional*): + True, if this is the first recurring payment. + + invoice_slug (``str``, *optional*): + Name of the invoice. + """ + + def __init__( + self, *, + currency: str, + total_amount: str, + invoice_payload: str, + telegram_payment_charge_id: str, + provider_payment_charge_id: str, + shipping_option_id: Optional[str] = None, + order_info: Optional["types.OrderInfo"] = None, + is_recurring: Optional[bool] = None, + is_first_recurring: Optional[bool] = None, + invoice_slug: Optional[str] = None + ): + super().__init__() + + self.currency = currency + self.total_amount = total_amount + self.invoice_payload = invoice_payload + self.telegram_payment_charge_id = telegram_payment_charge_id + self.provider_payment_charge_id = provider_payment_charge_id + self.shipping_option_id = shipping_option_id + self.order_info = order_info + self.is_recurring = is_recurring + self.is_first_recurring = is_first_recurring + self.invoice_slug = invoice_slug + + @staticmethod + def _parse( + client: "pyrogram.Client", + successful_payment: Union[ + "raw.types.MessageActionPaymentSent", + "raw.types.MessageActionPaymentSentMe" + ]) -> "SuccessfulPayment": + invoice_payload = None + telegram_payment_charge_id = None + provider_payment_charge_id = None + shipping_option_id = None + order_info = None + + if isinstance(successful_payment, raw.types.MessageActionPaymentSentMe): + # Try to decode invoice payload into string. If that fails, fallback to bytes instead of decoding by + # ignoring/replacing errors, this way, button clicks will still work. + try: + invoice_payload = successful_payment.payload.decode() + except (UnicodeDecodeError, AttributeError): + invoice_payload = successful_payment.payload + + telegram_payment_charge_id = successful_payment.charge.id + provider_payment_charge_id = successful_payment.charge.provider_charge_id + shipping_option_id = getattr(successful_payment, "shipping_option_id") + + if successful_payment.info: + payment_info = successful_payment.info + + order_info = types.OrderInfo( + name=getattr(payment_info, "name", None), + phone_number=getattr(payment_info, "phone", None), + email=getattr(payment_info, "email", None), + shipping_address=types.ShippingAddress( + country_code=successful_payment.info.shipping_address.country_iso2, + state=successful_payment.info.shipping_address.state, + city=successful_payment.info.shipping_address.city, + street_line1=successful_payment.info.shipping_address.street_line1, + street_line2=successful_payment.info.shipping_address.street_line2, + post_code=successful_payment.info.shipping_address.post_code + ) + ) + + return SuccessfulPayment( + currency=successful_payment.currency, + total_amount=successful_payment.total_amount, + invoice_payload=invoice_payload, + telegram_payment_charge_id=telegram_payment_charge_id, + provider_payment_charge_id=provider_payment_charge_id, + shipping_option_id=shipping_option_id, + order_info=order_info, + is_recurring=getattr(successful_payment, "recurring_used", None), + is_first_recurring=getattr(successful_payment, "recurring_init", None), + invoice_slug=getattr(successful_payment, "invoice_slug", None), + ) diff --git a/pyrogram/types/user_and_chats/__init__.py b/pyrogram/types/user_and_chats/__init__.py index e5126ac74..756304ccb 100644 --- a/pyrogram/types/user_and_chats/__init__.py +++ b/pyrogram/types/user_and_chats/__init__.py @@ -35,14 +35,15 @@ from .chat_member_updated import ChatMemberUpdated from .chat_permissions import ChatPermissions from .chat_photo import ChatPhoto -from .chat_preview import ChatPreview from .chat_privileges import ChatPrivileges from .chat_reactions import ChatReactions from .dialog import Dialog from .emoji_status import EmojiStatus from .folder import Folder +from .found_contacts import FoundContacts from .group_call_member import GroupCallMember from .invite_link_importer import InviteLinkImporter +from .privacy_rule import PrivacyRule from .restriction import Restriction from .user import User from .username import Username @@ -63,7 +64,6 @@ "ChatMember", "ChatPermissions", "ChatPhoto", - "ChatPreview", "Dialog", "User", "Username", @@ -72,6 +72,7 @@ "ChatEventFilter", "ChatInviteLink", "InviteLinkImporter", + "PrivacyRule", "ChatAdminWithInviteLinks", "ChatColor", "VideoChatStarted", @@ -84,6 +85,7 @@ "ChatJoiner", "EmojiStatus", "Folder", + "FoundContacts", "GroupCallMember", "ChatReactions" ] diff --git a/pyrogram/types/user_and_chats/chat.py b/pyrogram/types/user_and_chats/chat.py index 31bf2ba79..4fa90ae84 100644 --- a/pyrogram/types/user_and_chats/chat.py +++ b/pyrogram/types/user_and_chats/chat.py @@ -30,10 +30,10 @@ class Chat(Object): """A chat. Parameters: - id (``int``): + id (``int``, *optional*): Unique identifier for this chat. - type (:obj:`~pyrogram.enums.ChatType`): + type (:obj:`~pyrogram.enums.ChatType`, *optional*): Type of chat. is_forum (``bool``, *optional*): @@ -76,6 +76,21 @@ class Chat(Object): is_business_bot (``bool``, *optional*): True, if this bot can connect to business account. + is_preview (``bool``, *optional*): + True, if this chat is a preview. + + is_banned (``bool``, *optional*): + True, if you are banned in this chat. + + is_call_active (``bool``, *optional*): + True, if a group call is currently active. + + is_call_not_empty (``bool``, *optional*): + True, if there's anyone in the group call. + + is_public (``bool``, *optional*): + True, if this chat is public. + title (``str``, *optional*): Title, for supergroups, channels and basic group chats. @@ -91,9 +106,6 @@ class Chat(Object): last_name (``str``, *optional*): Last name of the other party in a private chat, for private chats. - full_name (``str``, *property*): - Full name of the other party in a private chat, for private chats and bots. - photo (:obj:`~pyrogram.types.ChatPhoto`, *optional*): Chat photo. Suitable for downloads only. @@ -123,6 +135,12 @@ class Chat(Object): has_protected_content (``bool``, *optional*): True, if messages from the chat can't be forwarded to other chats. + has_visible_history (``bool``, *optional*): + True, if new chat members will have access to old messages; available only to chat administrators. + + has_aggressive_anti_spam_enabled (``bool``, *optional*): + True, if aggressive anti-spam checks are enabled in the supergroup. The field is only available to chat administrators. + invite_link (``str``, *optional*): Chat invite link, for groups, supergroups and channels. Returned only in :meth:`~pyrogram.Client.get_chat`. @@ -135,10 +153,19 @@ class Chat(Object): For supergroups, name of group sticker set. Returned only in :meth:`~pyrogram.Client.get_chat`. + custom_emoji_sticker_set_name (``str``, *optional*): + For supergroups, the name of the group's custom emoji sticker set. Custom emoji from this set can be used by all users and bots in the group. + can_set_sticker_set (``bool``, *optional*): True, if the group sticker set can be changed by you. Returned only in :meth:`~pyrogram.Client.get_chat`. + can_send_paid_media (``bool``, *optional*): + True, if paid media messages can be sent or forwarded to the channel chat. The field is available only for channel chats. + + members (List of :obj:`~pyrogram.types.User`, *optional*): + A few of the participants that are in the group. + members_count (``int``, *optional*): Chat members count, for groups, supergroups and channels only. Returned only in :meth:`~pyrogram.Client.get_chat`. @@ -192,16 +219,43 @@ class Chat(Object): birthday (:obj:`~pyrogram.types.Birthday`, *optional*): Information about user birthday. + message_auto_delete_time (``int``, *optional*): + The time after which all messages sent to the chat will be automatically deleted; in seconds. + + unrestrict_boost_count (``int``, *optional*): + For supergroups, the minimum number of boosts that a non-administrator user needs to add in order to ignore slow mode and chat permissions. + + slow_mode_delay (``int``, *optional*): + For supergroups, the minimum allowed delay between consecutive messages sent by each unpriviledged user; in seconds. + + slowmode_next_send_date (:py:obj:`~datetime.datetime`, *optional*): + Indicates when the user will be allowed to send another message in the chat. For supergroups only. + + join_by_request (``bool``, *optional*): + True, if all users directly joining the supergroup need to be approved by supergroup administrators. + + join_requests_count (``int``, *optional*): + Number of users who requested to join the chat. + + banned_until_date (:py:obj:`~datetime.datetime`, *optional*): + Date when the user will be unbanned. + + reactions_limit (``int``, *optional*): + This flag may be used to impose a custom limit of unique reactions (i.e. a customizable version of appConfig.reactions_uniq_max). + raw (:obj:`~pyrogram.raw.base.Chat` | :obj:`~pyrogram.raw.base.User` | :obj:`~pyrogram.raw.base.ChatFull` | :obj:`~pyrogram.raw.base.UserFull`, *optional*): The raw chat or user object, as received from the Telegram API. + + full_name (``str``, *property*): + Full name of the other party in a private chat, for private chats and bots. """ def __init__( self, *, client: "pyrogram.Client" = None, - id: int, - type: "enums.ChatType", + id: int = None, + type: "enums.ChatType" = None, is_forum: bool = None, is_verified: bool = None, is_members_hidden: bool = None, @@ -215,6 +269,11 @@ def __init__( is_stories_hidden: bool = None, is_stories_unavailable: bool = None, is_business_bot: bool = None, + is_preview: bool = None, + is_banned: bool = None, + is_call_active: bool = None, + is_call_not_empty: bool = None, + is_public: bool = None, title: str = None, username: str = None, usernames: List["types.Username"] = None, @@ -228,10 +287,15 @@ def __init__( dc_id: int = None, folder_id: int = None, has_protected_content: bool = None, + has_visible_history: bool = None, + has_aggressive_anti_spam_enabled: bool = None, invite_link: str = None, pinned_message=None, sticker_set_name: str = None, + custom_emoji_sticker_set_name = None, can_set_sticker_set: bool = None, + can_send_paid_media: bool = None, + members: List["types.User"] = None, members_count: int = None, restrictions: List["types.Restriction"] = None, permissions: "types.ChatPermissions" = None, @@ -247,6 +311,14 @@ def __init__( business_info: "types.BusinessInfo" = None, business_intro: "types.BusinessIntro" = None, birthday: "types.Birthday" = None, + message_auto_delete_time = None, + unrestrict_boost_count = None, + slow_mode_delay = None, + slowmode_next_send_date: datetime = None, + join_by_request: bool = None, + join_requests_count: int = None, + banned_until_date: datetime = None, + reactions_limit: int = None, raw: Union["raw.base.Chat", "raw.base.User", "raw.base.ChatFull", "raw.base.UserFull"] = None ): super().__init__(client) @@ -266,6 +338,11 @@ def __init__( self.is_stories_hidden = is_stories_hidden self.is_stories_unavailable = is_stories_unavailable self.is_business_bot = is_business_bot + self.is_preview = is_preview + self.is_banned = is_banned + self.is_call_active = is_call_active + self.is_call_not_empty = is_call_not_empty + self.is_public = is_public self.title = title self.username = username self.usernames = usernames @@ -279,10 +356,15 @@ def __init__( self.dc_id = dc_id self.folder_id = folder_id self.has_protected_content = has_protected_content + self.has_visible_history = has_visible_history + self.has_aggressive_anti_spam_enabled = has_aggressive_anti_spam_enabled self.invite_link = invite_link self.pinned_message = pinned_message self.sticker_set_name = sticker_set_name + self.custom_emoji_sticker_set_name = custom_emoji_sticker_set_name self.can_set_sticker_set = can_set_sticker_set + self.can_send_paid_media = can_send_paid_media + self.members = members self.members_count = members_count self.restrictions = restrictions self.permissions = permissions @@ -298,6 +380,14 @@ def __init__( self.business_info = business_info self.business_intro = business_intro self.birthday = birthday + self.message_auto_delete_time = message_auto_delete_time + self.unrestrict_boost_count = unrestrict_boost_count + self.slow_mode_delay = slow_mode_delay + self.slowmode_next_send_date = slowmode_next_send_date + self.join_by_request = join_by_request + self.join_requests_count = join_requests_count + self.banned_until_date = banned_until_date + self.reactions_limit = reactions_limit self.raw = raw @staticmethod @@ -334,6 +424,16 @@ def _parse_chat_chat(client, chat: raw.types.Chat) -> "Chat": usernames = getattr(chat, "usernames", []) admin_rights = getattr(chat, "admin_rights", None) + if isinstance(chat, raw.types.ChatForbidden): + return Chat( + id=peer_id, + type=enums.ChatType.GROUP, + title=chat.title, + is_banned=True, + raw=chat, + client=client + ) + return Chat( id=peer_id, type=enums.ChatType.GROUP, @@ -341,6 +441,8 @@ def _parse_chat_chat(client, chat: raw.types.Chat) -> "Chat": is_creator=getattr(chat, "creator", None), is_admin=True if admin_rights else None, is_deactivated=getattr(chat, "deactivated", None), + is_call_active=getattr(chat, "call_active", None), + is_call_not_empty=getattr(chat, "call_not_empty", None), usernames=types.List([types.Username._parse(r) for r in usernames]) or None, photo=types.ChatPhoto._parse(client, getattr(chat, "photo", None), peer_id, 0), permissions=types.ChatPermissions._parse(getattr(chat, "default_banned_rights", None)), @@ -358,6 +460,17 @@ def _parse_channel_chat(client, channel: raw.types.Channel) -> "Chat": usernames = getattr(channel, "usernames", []) admin_rights = getattr(channel, "admin_rights", None) + if isinstance(channel, raw.types.ChannelForbidden): + return Chat( + id=peer_id, + type=enums.ChatType.SUPERGROUP if getattr(channel, "megagroup", None) else enums.ChatType.CHANNEL, + title=channel.title, + is_banned=True, + banned_until_date=utils.timestamp_to_datetime(getattr(channel, "until_date", None)), + raw=channel, + client=client, + ) + return Chat( id=peer_id, type=enums.ChatType.SUPERGROUP if getattr(channel, "megagroup", None) else enums.ChatType.CHANNEL, @@ -370,6 +483,8 @@ def _parse_channel_chat(client, channel: raw.types.Channel) -> "Chat": is_fake=getattr(channel, "fake", None), is_stories_hidden=getattr(channel, "stories_hidden", None), is_stories_unavailable=getattr(channel, "stories_unavailable", None), + is_call_active=getattr(channel, "call_active", None), + is_call_not_empty=getattr(channel, "call_not_empty", None), title=channel.title, username=getattr(channel, "username", None), usernames=types.List([types.Username._parse(r) for r in usernames]) or None, @@ -459,7 +574,7 @@ async def _parse_full(client, chat_full: Union[raw.types.messages.ChatFull, raw. if getattr(full_user, "wallpaper") and isinstance(full_user.wallpaper, raw.types.WallPaper): parsed_chat.wallpaper = types.Document._parse(client, full_user.wallpaper.document, "wallpaper.jpg") else: - full_chat = chat_full.full_chat + full_chat: Union["raw.types.ChatFull", "raw.types.ChannelFull"] = chat_full.full_chat chat_raw = chats[full_chat.id] if isinstance(full_chat, raw.types.ChatFull): @@ -475,8 +590,15 @@ 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) + parsed_chat.custom_emoji_sticker_set_name = getattr(full_chat.emojiset, "short_name", None) parsed_chat.is_members_hidden = full_chat.participants_hidden - parsed_chat.folder_id = getattr(full_chat, "folder_id", None) + parsed_chat.has_visible_history = not getattr(full_chat, "hidden_prehistory", False) + parsed_chat.has_aggressive_anti_spam_enabled = getattr(full_chat, "antispam", False) + parsed_chat.slow_mode_delay = getattr(full_chat, "slowmode_seconds", None) + parsed_chat.slowmode_next_send_date = utils.timestamp_to_datetime( + getattr(full_chat, "slowmode_next_send_date", None) + ) + parsed_chat.can_send_paid_media = getattr(full_chat, "paid_media_allowed", None) linked_chat_raw = chats.get(full_chat.linked_chat_id, None) @@ -517,6 +639,12 @@ async def _parse_full(client, chat_full: Union[raw.types.messages.ChatFull, raw. parsed_chat.invite_link = full_chat.exported_invite.link parsed_chat.available_reactions = types.ChatReactions._parse(client, full_chat.available_reactions) + parsed_chat.folder_id = getattr(full_chat, "folder_id", None) + parsed_chat.message_auto_delete_time = getattr(full_chat, "ttl_period", None) + parsed_chat.unrestrict_boost_count = getattr(full_chat, "boosts_unrestrict", None) + parsed_chat.join_requests_count = getattr(full_chat, "requests_pending", None) + parsed_chat.reactions_limit = getattr(full_chat, "reactions_limit", None) + parsed_chat.raw = full_chat return parsed_chat @@ -530,6 +658,33 @@ def _parse_chat(client, chat: Union[raw.types.Chat, raw.types.User, raw.types.Ch else: return Chat._parse_channel_chat(client, chat) + @staticmethod + def _parse_preview(client, chat_invite: "raw.types.ChatInvite") -> "Chat": + return Chat( + type=( + enums.ChatType.SUPERGROUP if getattr(chat_invite, "megagroup", None) else + enums.ChatType.CHANNEL if getattr(chat_invite, "broadcast", None) else + enums.ChatType.GROUP + ), + is_verified=getattr(chat_invite, "verified", None), + is_scam=getattr(chat_invite, "scam", None), + is_fake=getattr(chat_invite, "fake", None), + is_public=getattr(chat_invite, "public", None), + is_preview=True, + title=chat_invite.title, + photo=types.Photo._parse(client, chat_invite.photo), + members_count=chat_invite.participants_count, + members=[ + types.User._parse(client, user) + for user in getattr(chat_invite, "participants", []) + ] or None, + description=getattr(chat_invite, "about", None), + join_by_request=getattr(chat_invite, "request_needed", None), + profile_color=types.ChatColor._parse(getattr(chat_invite, "color", None)), + raw=chat_invite, + client=client + ) + @property def full_name(self) -> str: return " ".join(filter(None, [self.first_name, self.last_name])) or self.title or None diff --git a/pyrogram/types/user_and_chats/chat_preview.py b/pyrogram/types/user_and_chats/chat_preview.py deleted file mode 100644 index e251c8658..000000000 --- a/pyrogram/types/user_and_chats/chat_preview.py +++ /dev/null @@ -1,79 +0,0 @@ -# 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 - -import pyrogram -from pyrogram import raw -from pyrogram import types -from ..object import Object - - -class ChatPreview(Object): - """A chat preview. - - Parameters: - title (``str``): - Title of the chat. - - type (``str``): - Type of chat, can be either, "group", "supergroup" or "channel". - - members_count (``int``): - Chat members count. - - photo (:obj:`~pyrogram.types.Photo`, *optional*): - Chat photo. - - members (List of :obj:`~pyrogram.types.User`, *optional*): - Preview of some of the chat members. - """ - - def __init__( - self, - *, - client: "pyrogram.Client" = None, - title: str, - type: str, - members_count: int, - photo: "types.Photo" = None, - members: List["types.User"] = None - ): - super().__init__(client) - - self.title = title - self.type = type - self.members_count = members_count - self.photo = photo - self.members = members - - @staticmethod - def _parse(client, chat_invite: "raw.types.ChatInvite") -> "ChatPreview": - return ChatPreview( - title=chat_invite.title, - type=("group" if not chat_invite.channel else - "channel" if chat_invite.broadcast else - "supergroup"), - members_count=chat_invite.participants_count, - photo=types.Photo._parse(client, chat_invite.photo), - members=[types.User._parse(client, user) for user in chat_invite.participants] or None, - client=client - ) - - # TODO: Maybe just merge this object into Chat itself by adding the "members" field. - # get_chat can be used as well instead of get_chat_preview diff --git a/pyrogram/types/user_and_chats/dialog.py b/pyrogram/types/user_and_chats/dialog.py index 7259a89a5..8ebf85a40 100644 --- a/pyrogram/types/user_and_chats/dialog.py +++ b/pyrogram/types/user_and_chats/dialog.py @@ -39,11 +39,23 @@ class Dialog(Object): unread_mentions_count (``int``): Amount of unread messages containing a mention in this dialog. + unread_reactions_count (``int``): + Amount of unread messages containing a reaction in this dialog. + unread_mark (``bool``): True, if the dialog has the unread mark set. is_pinned (``bool``): True, if the dialog is pinned. + + folder_id (``int``, *optional*): + Unique identifier (int) of the folder. + + ttl_period (``int``, *optional*) + Time-to-live of all messages sent in this dialog (in seconds). + + raw (:obj:`~pyrogram.raw.types.Dialog`, *optional*): + The raw object, as received from the Telegram API. """ def __init__( @@ -54,8 +66,12 @@ def __init__( top_message: "types.Message", unread_messages_count: int, unread_mentions_count: int, + unread_reactions_count: int, unread_mark: bool, - is_pinned: bool + is_pinned: bool, + folder_id: int = None, + ttl_period: int = None, + raw: "raw.types.Dialog" = None ): super().__init__(client) @@ -63,8 +79,12 @@ def __init__( self.top_message = top_message self.unread_messages_count = unread_messages_count self.unread_mentions_count = unread_mentions_count + self.unread_reactions_count = unread_reactions_count self.unread_mark = unread_mark self.is_pinned = is_pinned + self.folder_id = folder_id + self.ttl_period = ttl_period + self.raw = raw @staticmethod def _parse(client, dialog: "raw.types.Dialog", messages, users, chats) -> "Dialog": @@ -73,7 +93,11 @@ def _parse(client, dialog: "raw.types.Dialog", messages, users, chats) -> "Dialo top_message=messages.get(utils.get_peer_id(dialog.peer)), unread_messages_count=dialog.unread_count, unread_mentions_count=dialog.unread_mentions_count, + unread_reactions_count=dialog.unread_reactions_count, unread_mark=dialog.unread_mark, is_pinned=dialog.pinned, + folder_id=getattr(dialog, "folder_id", None), + ttl_period=getattr(dialog, "ttl_period", None), + raw=dialog, client=client ) diff --git a/pyrogram/types/user_and_chats/found_contacts.py b/pyrogram/types/user_and_chats/found_contacts.py new file mode 100644 index 000000000..e5342ff36 --- /dev/null +++ b/pyrogram/types/user_and_chats/found_contacts.py @@ -0,0 +1,75 @@ +# 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 Optional + +import pyrogram +from pyrogram import raw +from pyrogram import utils +from pyrogram import types +from ..object import Object + + +class FoundContacts(Object): + """Chats found by name substring and auxiliary data. + + Parameters: + my_results (List of :obj:`~pyrogram.types.Chat`, *optional*): + Personalized results. + + global_results (List of :obj:`~pyrogram.types.Chat`, *optional*): + List of found chats in global search. + """ + + def __init__( + self, + *, + client: "pyrogram.Client" = None, + my_results: Optional["types.Chat"] = None, + global_results: Optional["types.Chat"] = None + ): + super().__init__(client) + + self.my_results = my_results + self.global_results = global_results + + @staticmethod + def _parse(client, found: "raw.types.contacts.Found") -> "FoundContacts": + users = {u.id: u for u in found.users} + chats = {c.id: c for c in found.chats} + + my_results = [] + global_results = [] + + for result in found.my_results: + peer_id = utils.get_raw_peer_id(result) + peer = users.get(peer_id) or chats.get(peer_id) + + my_results.append(types.Chat._parse_chat(client, peer)) + + for result in found.results: + peer_id = utils.get_raw_peer_id(result) + peer = users.get(peer_id) or chats.get(peer_id) + + global_results.append(types.Chat._parse_chat(client, peer)) + + return FoundContacts( + my_results=types.List(my_results) or None, + global_results=types.List(global_results) or None, + client=client + ) diff --git a/pyrogram/types/user_and_chats/privacy_rule.py b/pyrogram/types/user_and_chats/privacy_rule.py new file mode 100644 index 000000000..60404aa51 --- /dev/null +++ b/pyrogram/types/user_and_chats/privacy_rule.py @@ -0,0 +1,90 @@ +# 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, types +from ..object import Object + + +class PrivacyRule(Object): + """A privacy rule. + + Parameters: + allow_all (``bool``, *optional*): + Allow all users. + + allow_chats (``bool``, *optional*): + Allow only participants of certain chats. + + allow_contacts (``bool``, *optional*): + Allow contacts only + + allow_premium (``bool``, *optional*): + Allow only users with a Premium subscription, currently only usable for :obj:`~pyrogram.enums.PrivacyKey.CHAT_INVITE`. + + allow_users (``bool``, *optional*): + Allow only participants of certain users. + + users (List of :obj:`~pyrogram.types.User`, *optional*): + List of users. + + chats (List of :obj:`~pyrogram.types.Chat`, *optional*): + List of chats. + """ + + def __init__( + self, *, + allow_all: Optional[bool] = None, + allow_chats: Optional[bool] = None, + allow_contacts: Optional[bool] = None, + allow_premium: Optional[bool] = None, + allow_users: Optional[bool] = None, + users: Optional[List["types.User"]] = None, + chats: Optional[List["types.Chat"]] = None + ): + super().__init__(None) + + self.allow_all = allow_all + self.allow_chats = allow_chats + self.allow_contacts = allow_contacts + self.allow_premium = allow_premium + self.allow_users = allow_users + self.users = users + self.chats = chats + + @staticmethod + def _parse(client, rule: "raw.base.PrivacyRule", users, chats) -> "PrivacyRule": + parsed_users = None + parsed_chats = None + + if isinstance(rule, (raw.types.PrivacyValueAllowUsers, raw.types.PrivacyValueDisallowUsers)): + parsed_users = types.List(types.User._parse(client, users.get(i)) for i in rule.users) + + if isinstance(rule, (raw.types.PrivacyValueAllowChatParticipants, raw.types.PrivacyValueDisallowChatParticipants)): + parsed_chats = types.List(types.Chat._parse_chat(client, chats.get(i)) for i in rule.chats) + + return PrivacyRule( + allow_all=True if isinstance(rule, raw.types.PrivacyValueAllowAll) else False if isinstance(rule, raw.types.PrivacyValueDisallowAll) else None, + allow_chats=True if isinstance(rule, raw.types.PrivacyValueAllowChatParticipants) else False if isinstance(rule, raw.types.PrivacyValueDisallowChatParticipants) else None, + allow_contacts=True if isinstance(rule, raw.types.PrivacyValueAllowContacts) else False if isinstance(rule, raw.types.PrivacyValueDisallowContacts) else None, + allow_premium=True if isinstance(rule, raw.types.PrivacyValueAllowPremium) else None, + allow_users=True if isinstance(rule, raw.types.PrivacyValueAllowUsers) else False if isinstance(rule, raw.types.PrivacyValueDisallowUsers) else None, + users=parsed_users or None, + chats=parsed_chats or None + ) diff --git a/pyrogram/types/user_and_chats/user.py b/pyrogram/types/user_and_chats/user.py index 30e82a08b..71417d04e 100644 --- a/pyrogram/types/user_and_chats/user.py +++ b/pyrogram/types/user_and_chats/user.py @@ -173,8 +173,44 @@ class User(Object, Update): profile_color (:obj:`~pyrogram.types.ChatColor`, *optional*): Chat profile color. + added_to_attachment_menu (``bool``, *optional*): + True, if this user added the bot to the attachment menu. + + active_users_count (``int``, *optional*): + The number of recently (monthly) active users of the bot. + + inline_need_location (``bool``, *optional*): + True, if the bot supports inline `user location `_ requests. Returned only in get_me. + + inline_query_placeholder (``str``, *optional*): + Placeholder for inline queries (displayed on the application input field). + + can_be_edited (``bool``, *optional*): + True, if the current user can edit this bot's profile picture. + + can_be_added_to_attachment_menu (``bool``, *optional*): + True, if the bot can be added to attachment or side menu. + + can_join_groups (``bool``, *optional*): + True, if the bot can be invited to groups. Returned only in get_me. + + can_read_all_group_messages (``bool``, *optional*): + True, if privacy mode is disabled for the bot. Returned only in get_me. + + has_main_web_app (``bool``, *optional*): + True, if the bot has a main Web App. Returned only in get_me. + raw (:obj:`~pyrogram.raw.base.User` | :obj:`~pyrogram.raw.base.UserStatus`, *optional*): The raw user or user status object, as received from the Telegram API. + + mention (``str``, *property*): + Generate a text mention for this user. + You can use ``user.mention()`` to mention the user using their first name (styled using html), or + ``user.mention("another name")`` for a custom name. To choose a different style + ("html" or "md"/"markdown") use ``user.mention(style="md")``. + + full_name (``str``, *property*): + Full name of the other party in a private chat, for private chats and bots. """ def __init__( @@ -213,6 +249,15 @@ def __init__( restrictions: List["types.Restriction"] = None, reply_color: "types.ChatColor" = None, profile_color: "types.ChatColor" = None, + added_to_attachment_menu: bool = None, + active_users_count: int = None, + inline_need_location: bool = None, + inline_query_placeholder: str = None, + can_be_edited: bool = None, + can_be_added_to_attachment_menu: bool = None, + can_join_groups: bool = None, + can_read_all_group_messages: bool = None, + has_main_web_app: bool = None, raw: Union["raw.base.User", "raw.base.UserStatus"] = None ): super().__init__(client) @@ -249,6 +294,15 @@ def __init__( self.restrictions = restrictions self.reply_color = reply_color self.profile_color = profile_color + self.added_to_attachment_menu = added_to_attachment_menu + self.active_users_count = active_users_count + self.inline_need_location = inline_need_location + self.inline_query_placeholder = inline_query_placeholder + self.can_be_edited = can_be_edited + self.can_be_added_to_attachment_menu = can_be_added_to_attachment_menu + self.can_join_groups = can_join_groups + self.can_read_all_group_messages = can_read_all_group_messages + self.has_main_web_app = has_main_web_app self.raw = raw @property @@ -299,6 +353,15 @@ def _parse(client, user: "raw.base.User") -> Optional["User"]: restrictions=types.List([types.Restriction._parse(r) for r in user.restriction_reason]) or None, reply_color=types.ChatColor._parse(getattr(user, "color", None)), profile_color=types.ChatColor._parse_profile_color(getattr(user, "profile_color", None)), + added_to_attachment_menu=getattr(user, "attach_menu_enabled", None), + active_users_count=getattr(user, "bot_active_users", None), + inline_need_location=getattr(user, "bot_inline_geo", None), + inline_query_placeholder=getattr(user, "bot_inline_placeholder", None), + can_be_edited=getattr(user, "bot_can_edit", None), + can_be_added_to_attachment_menu=getattr(user, "bot_attach_menu", None), + can_join_groups=getattr(user, "bot_nochats", None), + can_read_all_group_messages=getattr(user, "bot_chat_history", None), + has_main_web_app=getattr(user, "bot_has_main_app", None), raw=user, client=client )