From 9b43a33b7f3a52d67d3dd9cca80a289be9c0e4d1 Mon Sep 17 00:00:00 2001 From: Alex Root Junior Date: Mon, 8 Nov 2021 02:37:37 +0200 Subject: [PATCH] Dev 3.x api 5.4 (#744) * Re-generate API * Added new modules * Added handling new event type and approve/decline aliases for ChatJoinRequest * Fixed code-coverage * Bump API version * Added patch-notes --- .apiversion | 2 +- CHANGES/744.misc | 2 + README.rst | 2 +- aiogram/__init__.py | 2 +- aiogram/client/bot.py | 182 ++++++++++++------ aiogram/dispatcher/filters/__init__.py | 4 + .../dispatcher/middlewares/user_context.py | 2 + aiogram/dispatcher/router.py | 2 + aiogram/methods/__init__.py | 4 + aiogram/methods/answer_callback_query.py | 2 +- aiogram/methods/answer_pre_checkout_query.py | 2 +- aiogram/methods/answer_shipping_query.py | 6 +- aiogram/methods/approve_chat_join_request.py | 28 +++ aiogram/methods/ban_chat_member.py | 2 +- aiogram/methods/copy_message.py | 2 +- aiogram/methods/create_chat_invite_link.py | 6 +- aiogram/methods/decline_chat_join_request.py | 28 +++ aiogram/methods/delete_chat_photo.py | 2 +- aiogram/methods/delete_chat_sticker_set.py | 2 +- aiogram/methods/edit_chat_invite_link.py | 6 +- aiogram/methods/edit_message_caption.py | 2 +- aiogram/methods/edit_message_media.py | 2 +- aiogram/methods/edit_message_text.py | 2 +- aiogram/methods/export_chat_invite_link.py | 2 +- aiogram/methods/get_me.py | 2 +- aiogram/methods/kick_chat_member.py | 2 +- aiogram/methods/pin_chat_message.py | 2 +- aiogram/methods/promote_chat_member.py | 22 +-- aiogram/methods/restrict_chat_member.py | 2 +- aiogram/methods/revoke_chat_invite_link.py | 2 +- aiogram/methods/send_animation.py | 2 +- aiogram/methods/send_audio.py | 2 +- aiogram/methods/send_chat_action.py | 2 +- aiogram/methods/send_document.py | 2 +- aiogram/methods/send_message.py | 2 +- aiogram/methods/send_photo.py | 2 +- aiogram/methods/send_poll.py | 6 +- aiogram/methods/send_video.py | 2 +- aiogram/methods/send_voice.py | 2 +- aiogram/methods/set_chat_description.py | 2 +- aiogram/methods/set_chat_permissions.py | 4 +- aiogram/methods/set_chat_photo.py | 2 +- aiogram/methods/set_chat_sticker_set.py | 2 +- aiogram/methods/set_chat_title.py | 2 +- aiogram/methods/set_game_score.py | 6 +- aiogram/methods/stop_message_live_location.py | 2 +- aiogram/methods/stop_poll.py | 2 +- aiogram/methods/unpin_all_chat_messages.py | 2 +- aiogram/methods/unpin_chat_message.py | 2 +- aiogram/types/__init__.py | 2 + aiogram/types/animation.py | 2 +- aiogram/types/audio.py | 6 +- aiogram/types/chat.py | 4 +- aiogram/types/chat_invite_link.py | 10 +- aiogram/types/chat_join_request.py | 57 ++++++ aiogram/types/chat_member_administrator.py | 24 +-- aiogram/types/chat_member_banned.py | 2 +- aiogram/types/chat_member_owner.py | 2 +- aiogram/types/chat_member_restricted.py | 20 +- aiogram/types/chat_permissions.py | 16 +- aiogram/types/document.py | 2 +- aiogram/types/file.py | 2 +- aiogram/types/inline_keyboard_button.py | 2 +- aiogram/types/inline_query_result_document.py | 2 +- aiogram/types/inline_query_result_gif.py | 2 +- .../types/inline_query_result_mpeg4_gif.py | 2 +- aiogram/types/inline_query_result_photo.py | 2 +- aiogram/types/inline_query_result_video.py | 2 +- aiogram/types/input_media_animation.py | 2 +- aiogram/types/input_media_document.py | 2 +- aiogram/types/input_media_video.py | 2 +- aiogram/types/location.py | 2 +- aiogram/types/login_url.py | 2 +- .../message_auto_delete_timer_changed.py | 2 +- aiogram/types/passport_file.py | 2 +- aiogram/types/photo_size.py | 2 +- aiogram/types/poll.py | 6 +- aiogram/types/sticker.py | 2 +- aiogram/types/update.py | 5 + aiogram/types/user.py | 8 +- aiogram/types/video.py | 2 +- aiogram/types/video_note.py | 2 +- aiogram/types/voice.py | 2 +- aiogram/types/voice_chat_ended.py | 2 +- aiogram/types/webhook_info.py | 2 +- .../api/methods/approve_chat_join_request.rst | 51 +++++ .../api/methods/decline_chat_join_request.rst | 51 +++++ docs/api/methods/get_chat_administrators.rst | 8 +- docs/api/methods/get_chat_member.rst | 8 +- docs/api/methods/index.rst | 2 + docs/api/types/chat_join_request.rst | 9 + docs/api/types/index.rst | 1 + .../test_approve_chat_join_request.py | 30 +++ .../test_create_chat_invite_link.py | 2 + .../test_decline_chat_join_request.py | 30 +++ .../test_edit_chat_invite_link.py | 4 +- .../test_revoke_chat_invite_link.py | 4 +- .../test_types/test_chat_join_request.py | 32 +++ tests/test_dispatcher/test_dispatcher.py | 14 ++ 99 files changed, 631 insertions(+), 199 deletions(-) create mode 100644 CHANGES/744.misc create mode 100644 aiogram/methods/approve_chat_join_request.py create mode 100644 aiogram/methods/decline_chat_join_request.py create mode 100644 aiogram/types/chat_join_request.py create mode 100644 docs/api/methods/approve_chat_join_request.rst create mode 100644 docs/api/methods/decline_chat_join_request.rst create mode 100644 docs/api/types/chat_join_request.rst create mode 100644 tests/test_api/test_methods/test_approve_chat_join_request.py create mode 100644 tests/test_api/test_methods/test_decline_chat_join_request.py create mode 100644 tests/test_api/test_types/test_chat_join_request.py diff --git a/.apiversion b/.apiversion index d346e2ab..37c2d996 100644 --- a/.apiversion +++ b/.apiversion @@ -1 +1 @@ -5.3 +5.4 diff --git a/CHANGES/744.misc b/CHANGES/744.misc new file mode 100644 index 00000000..d7f17458 --- /dev/null +++ b/CHANGES/744.misc @@ -0,0 +1,2 @@ +Added full support of Bot API 5.4 +https://core.telegram.org/bots/api-changelog#november-5-2021 diff --git a/README.rst b/README.rst index f3b8d7ca..a23a7b99 100644 --- a/README.rst +++ b/README.rst @@ -13,7 +13,7 @@ aiogram :target: https://pypi.python.org/pypi/aiogram :alt: Supported python versions -.. image:: https://img.shields.io/badge/Telegram%20Bot%20API-5.3-blue.svg?logo=telegram +.. image:: https://img.shields.io/badge/Telegram%20Bot%20API-5.4-blue.svg?logo=telegram :target: https://core.telegram.org/bots/api :alt: Telegram Bot API diff --git a/aiogram/__init__.py b/aiogram/__init__.py index 3ad46c80..f1c4813e 100644 --- a/aiogram/__init__.py +++ b/aiogram/__init__.py @@ -38,4 +38,4 @@ __all__ = ( ) __version__ = "3.0.0a18" -__api_version__ = "5.3" +__api_version__ = "5.4" diff --git a/aiogram/client/bot.py b/aiogram/client/bot.py index 96890b1f..c8ececf6 100644 --- a/aiogram/client/bot.py +++ b/aiogram/client/bot.py @@ -27,11 +27,13 @@ from ..methods import ( AnswerInlineQuery, AnswerPreCheckoutQuery, AnswerShippingQuery, + ApproveChatJoinRequest, BanChatMember, Close, CopyMessage, CreateChatInviteLink, CreateNewStickerSet, + DeclineChatJoinRequest, DeleteChatPhoto, DeleteChatStickerSet, DeleteMessage, @@ -480,7 +482,7 @@ class Bot(ContextInstanceMixin["Bot"]): request_timeout: Optional[int] = None, ) -> User: """ - A simple method for testing your bot's auth token. Requires no parameters. Returns basic information about the bot in form of a :class:`aiogram.types.user.User` object. + A simple method for testing your bot's authentication token. Requires no parameters. Returns basic information about the bot in form of a :class:`aiogram.types.user.User` object. Source: https://core.telegram.org/bots/api#getme @@ -544,7 +546,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param chat_id: Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`) :param text: Text of the message to be sent, 1-4096 characters after entities parsing :param parse_mode: Mode for parsing entities in the message text. See `formatting options `_ for more details. - :param entities: List of special entities that appear in message text, which can be specified instead of *parse_mode* + :param entities: A JSON-serialized list of special entities that appear in message text, which can be specified instead of *parse_mode* :param disable_web_page_preview: Disables link previews for links in this message :param disable_notification: Sends the message `silently `_. Users will receive a notification with no sound. :param reply_to_message_id: If the message is a reply, ID of the original message @@ -620,7 +622,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param message_id: Message identifier in the chat specified in *from_chat_id* :param caption: New caption for media, 0-1024 characters after entities parsing. If not specified, the original caption is kept :param parse_mode: Mode for parsing entities in the new caption. See `formatting options `_ for more details. - :param caption_entities: List of special entities that appear in the new caption, which can be specified instead of *parse_mode* + :param caption_entities: A JSON-serialized list of special entities that appear in the new caption, which can be specified instead of *parse_mode* :param disable_notification: Sends the message `silently `_. Users will receive a notification with no sound. :param reply_to_message_id: If the message is a reply, ID of the original message :param allow_sending_without_reply: Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found @@ -666,7 +668,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param photo: Photo to send. Pass a file_id as String to send a photo that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a photo from the Internet, or upload a new photo using multipart/form-data. The photo must be at most 10 MB in size. The photo's width and height must not exceed 10000 in total. Width and height ratio must be at most 20. :ref:`More info on Sending Files » ` :param caption: Photo caption (may also be used when resending photos by *file_id*), 0-1024 characters after entities parsing :param parse_mode: Mode for parsing entities in the photo caption. See `formatting options `_ for more details. - :param caption_entities: List of special entities that appear in the caption, which can be specified instead of *parse_mode* + :param caption_entities: A JSON-serialized list of special entities that appear in the caption, which can be specified instead of *parse_mode* :param disable_notification: Sends the message `silently `_. Users will receive a notification with no sound. :param reply_to_message_id: If the message is a reply, ID of the original message :param allow_sending_without_reply: Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found @@ -716,7 +718,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param audio: Audio file to send. Pass a file_id as String to send an audio file that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get an audio file from the Internet, or upload a new one using multipart/form-data. :ref:`More info on Sending Files » ` :param caption: Audio caption, 0-1024 characters after entities parsing :param parse_mode: Mode for parsing entities in the audio caption. See `formatting options `_ for more details. - :param caption_entities: List of special entities that appear in the caption, which can be specified instead of *parse_mode* + :param caption_entities: A JSON-serialized list of special entities that appear in the caption, which can be specified instead of *parse_mode* :param duration: Duration of the audio in seconds :param performer: Performer :param title: Track name @@ -772,7 +774,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param thumb: Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new file, so you can pass 'attach://' if the thumbnail was uploaded using multipart/form-data under . :ref:`More info on Sending Files » ` :param caption: Document caption (may also be used when resending documents by *file_id*), 0-1024 characters after entities parsing :param parse_mode: Mode for parsing entities in the document caption. See `formatting options `_ for more details. - :param caption_entities: List of special entities that appear in the caption, which can be specified instead of *parse_mode* + :param caption_entities: A JSON-serialized list of special entities that appear in the caption, which can be specified instead of *parse_mode* :param disable_content_type_detection: Disables automatic server-side content type detection for files uploaded using multipart/form-data :param disable_notification: Sends the message `silently `_. Users will receive a notification with no sound. :param reply_to_message_id: If the message is a reply, ID of the original message @@ -829,7 +831,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param thumb: Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new file, so you can pass 'attach://' if the thumbnail was uploaded using multipart/form-data under . :ref:`More info on Sending Files » ` :param caption: Video caption (may also be used when resending videos by *file_id*), 0-1024 characters after entities parsing :param parse_mode: Mode for parsing entities in the video caption. See `formatting options `_ for more details. - :param caption_entities: List of special entities that appear in the caption, which can be specified instead of *parse_mode* + :param caption_entities: A JSON-serialized list of special entities that appear in the caption, which can be specified instead of *parse_mode* :param supports_streaming: Pass :code:`True`, if the uploaded video is suitable for streaming :param disable_notification: Sends the message `silently `_. Users will receive a notification with no sound. :param reply_to_message_id: If the message is a reply, ID of the original message @@ -888,7 +890,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param thumb: Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported server-side. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail's width and height should not exceed 320. Ignored if the file is not uploaded using multipart/form-data. Thumbnails can't be reused and can be only uploaded as a new file, so you can pass 'attach://' if the thumbnail was uploaded using multipart/form-data under . :ref:`More info on Sending Files » ` :param caption: Animation caption (may also be used when resending animation by *file_id*), 0-1024 characters after entities parsing :param parse_mode: Mode for parsing entities in the animation caption. See `formatting options `_ for more details. - :param caption_entities: List of special entities that appear in the caption, which can be specified instead of *parse_mode* + :param caption_entities: A JSON-serialized list of special entities that appear in the caption, which can be specified instead of *parse_mode* :param disable_notification: Sends the message `silently `_. Users will receive a notification with no sound. :param reply_to_message_id: If the message is a reply, ID of the original message :param allow_sending_without_reply: Pass :code:`True`, if the message should be sent even if the specified replied-to message is not found @@ -938,7 +940,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param voice: Audio file to send. Pass a file_id as String to send a file that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. :ref:`More info on Sending Files » ` :param caption: Voice message caption, 0-1024 characters after entities parsing :param parse_mode: Mode for parsing entities in the voice message caption. See `formatting options `_ for more details. - :param caption_entities: List of special entities that appear in the caption, which can be specified instead of *parse_mode* + :param caption_entities: A JSON-serialized list of special entities that appear in the caption, which can be specified instead of *parse_mode* :param duration: Duration of the voice message in seconds :param disable_notification: Sends the message `silently `_. Users will receive a notification with no sound. :param reply_to_message_id: If the message is a reply, ID of the original message @@ -1141,7 +1143,7 @@ class Bot(ContextInstanceMixin["Bot"]): request_timeout: Optional[int] = None, ) -> Union[Message, bool]: """ - Use this method to stop updating a live location message before *live_period* expires. On success, if the message was sent by the bot, the sent :class:`aiogram.types.message.Message` is returned, otherwise :code:`True` is returned. + Use this method to stop updating a live location message before *live_period* expires. On success, if the message is not an inline message, the edited :class:`aiogram.types.message.Message` is returned, otherwise :code:`True` is returned. Source: https://core.telegram.org/bots/api#stopmessagelivelocation @@ -1150,8 +1152,8 @@ class Bot(ContextInstanceMixin["Bot"]): :param inline_message_id: Required if *chat_id* and *message_id* are not specified. Identifier of the inline message :param reply_markup: A JSON-serialized object for a new `inline keyboard `_. :param request_timeout: Request timeout - :return: On success, if the message was sent by the bot, the sent Message is returned, - otherwise True is returned. + :return: On success, if the message is not an inline message, the edited Message is + returned, otherwise True is returned. """ call = StopMessageLiveLocation( chat_id=chat_id, @@ -1294,13 +1296,13 @@ class Bot(ContextInstanceMixin["Bot"]): :param chat_id: Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`) :param question: Poll question, 1-300 characters :param options: A JSON-serialized list of answer options, 2-10 strings 1-100 characters each - :param is_anonymous: True, if the poll needs to be anonymous, defaults to :code:`True` + :param is_anonymous: :code:`True`, if the poll needs to be anonymous, defaults to :code:`True` :param type: Poll type, 'quiz' or 'regular', defaults to 'regular' - :param allows_multiple_answers: True, if the poll allows multiple answers, ignored for polls in quiz mode, defaults to :code:`False` + :param allows_multiple_answers: :code:`True`, if the poll allows multiple answers, ignored for polls in quiz mode, defaults to :code:`False` :param correct_option_id: 0-based identifier of the correct answer option, required for polls in quiz mode :param explanation: Text that is shown when a user chooses an incorrect answer or taps on the lamp icon in a quiz-style poll, 0-200 characters with at most 2 line feeds after entities parsing :param explanation_parse_mode: Mode for parsing entities in the explanation. See `formatting options `_ for more details. - :param explanation_entities: List of special entities that appear in the poll explanation, which can be specified instead of *parse_mode* + :param explanation_entities: A JSON-serialized list of special entities that appear in the poll explanation, which can be specified instead of *parse_mode* :param open_period: Amount of time in seconds the poll will be active after creation, 5-600. Can't be used together with *close_date*. :param close_date: Point in time (Unix timestamp) when the poll will be automatically closed. Must be at least 5 and no more than 600 seconds in the future. Can't be used together with *open_period*. :param is_closed: Pass :code:`True`, if the poll needs to be immediately closed. This can be useful for poll preview. @@ -1384,7 +1386,7 @@ class Bot(ContextInstanceMixin["Bot"]): Source: https://core.telegram.org/bots/api#sendchataction :param chat_id: Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`) - :param action: Type of action to broadcast. Choose one, depending on what the user is about to receive: *typing* for `text messages `_, *upload_photo* for `photos `_, *record_video* or *upload_video* for `videos `_, *record_voice* or *upload_voice* for `voice notes `_, *upload_document* for `general files `_, *find_location* for `location data `_, *record_video_note* or *upload_video_note* for `video notes `_. + :param action: Type of action to broadcast. Choose one, depending on what the user is about to receive: *typing* for `text messages `_, *upload_photo* for `photos `_, *record_video* or *upload_video* for `videos `_, *record_voice* or *upload_voice* for `voice notes `_, *upload_document* for `general files `_, *choose_sticker* for `stickers `_, *find_location* for `location data `_, *record_video_note* or *upload_video_note* for `video notes `_. :param request_timeout: Request timeout :return: Returns True on success. """ @@ -1448,7 +1450,7 @@ class Bot(ContextInstanceMixin["Bot"]): request_timeout: Optional[int] = None, ) -> bool: """ - Use this method to ban a user in a group, a supergroup or a channel. In the case of supergroups and channels, the user will not be able to return to the chat on their own using invite links, etc., unless `unbanned `_ first. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns :code:`True` on success. + Use this method to ban a user in a group, a supergroup or a channel. In the case of supergroups and channels, the user will not be able to return to the chat on their own using invite links, etc., unless `unbanned `_ first. The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#banchatmember @@ -1481,7 +1483,7 @@ class Bot(ContextInstanceMixin["Bot"]): Renamed from :code:`kickChatMember` in 5.3 bot API version and can be removed in near future - Use this method to ban a user in a group, a supergroup or a channel. In the case of supergroups and channels, the user will not be able to return to the chat on their own using invite links, etc., unless `unbanned `_ first. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns :code:`True` on success. + Use this method to ban a user in a group, a supergroup or a channel. In the case of supergroups and channels, the user will not be able to return to the chat on their own using invite links, etc., unless `unbanned `_ first. The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#banchatmember @@ -1536,7 +1538,7 @@ class Bot(ContextInstanceMixin["Bot"]): request_timeout: Optional[int] = None, ) -> bool: """ - Use this method to restrict a user in a supergroup. The bot must be an administrator in the supergroup for this to work and must have the appropriate admin rights. Pass :code:`True` for all permissions to lift restrictions from a user. Returns :code:`True` on success. + Use this method to restrict a user in a supergroup. The bot must be an administrator in the supergroup for this to work and must have the appropriate administrator rights. Pass :code:`True` for all permissions to lift restrictions from a user. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#restrictchatmember @@ -1573,23 +1575,23 @@ class Bot(ContextInstanceMixin["Bot"]): request_timeout: Optional[int] = None, ) -> bool: """ - Use this method to promote or demote a user in a supergroup or a channel. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Pass :code:`False` for all boolean parameters to demote a user. Returns :code:`True` on success. + Use this method to promote or demote a user in a supergroup or a channel. The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. Pass :code:`False` for all boolean parameters to demote a user. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#promotechatmember :param chat_id: Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`) :param user_id: Unique identifier of the target user :param is_anonymous: Pass :code:`True`, if the administrator's presence in the chat is hidden - :param can_manage_chat: Pass True, if the administrator can access the chat event log, chat statistics, message statistics in channels, see channel members, see anonymous administrators in supergroups and ignore slow mode. Implied by any other administrator privilege - :param can_post_messages: Pass True, if the administrator can create channel posts, channels only - :param can_edit_messages: Pass True, if the administrator can edit messages of other users and can pin messages, channels only - :param can_delete_messages: Pass True, if the administrator can delete messages of other users - :param can_manage_voice_chats: Pass True, if the administrator can manage voice chats - :param can_restrict_members: Pass True, if the administrator can restrict, ban or unban chat members - :param can_promote_members: Pass True, if the administrator can add new administrators with a subset of their own privileges or demote administrators that he has promoted, directly or indirectly (promoted by administrators that were appointed by him) - :param can_change_info: Pass True, if the administrator can change chat title, photo and other settings - :param can_invite_users: Pass True, if the administrator can invite new users to the chat - :param can_pin_messages: Pass True, if the administrator can pin messages, supergroups only + :param can_manage_chat: Pass :code:`True`, if the administrator can access the chat event log, chat statistics, message statistics in channels, see channel members, see anonymous administrators in supergroups and ignore slow mode. Implied by any other administrator privilege + :param can_post_messages: Pass :code:`True`, if the administrator can create channel posts, channels only + :param can_edit_messages: Pass :code:`True`, if the administrator can edit messages of other users and can pin messages, channels only + :param can_delete_messages: Pass :code:`True`, if the administrator can delete messages of other users + :param can_manage_voice_chats: Pass :code:`True`, if the administrator can manage voice chats + :param can_restrict_members: Pass :code:`True`, if the administrator can restrict, ban or unban chat members + :param can_promote_members: Pass :code:`True`, if the administrator can add new administrators with a subset of their own privileges or demote administrators that he has promoted, directly or indirectly (promoted by administrators that were appointed by him) + :param can_change_info: Pass :code:`True`, if the administrator can change chat title, photo and other settings + :param can_invite_users: Pass :code:`True`, if the administrator can invite new users to the chat + :param can_pin_messages: Pass :code:`True`, if the administrator can pin messages, supergroups only :param request_timeout: Request timeout :return: Returns True on success. """ @@ -1642,12 +1644,12 @@ class Bot(ContextInstanceMixin["Bot"]): request_timeout: Optional[int] = None, ) -> bool: """ - Use this method to set default chat permissions for all members. The bot must be an administrator in the group or a supergroup for this to work and must have the *can_restrict_members* admin rights. Returns :code:`True` on success. + Use this method to set default chat permissions for all members. The bot must be an administrator in the group or a supergroup for this to work and must have the *can_restrict_members* administrator rights. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#setchatpermissions :param chat_id: Unique identifier for the target chat or username of the target supergroup (in the format :code:`@supergroupusername`) - :param permissions: New default chat permissions + :param permissions: A JSON-serialized object for new default chat permissions :param request_timeout: Request timeout :return: Returns True on success. """ @@ -1663,7 +1665,7 @@ class Bot(ContextInstanceMixin["Bot"]): request_timeout: Optional[int] = None, ) -> str: """ - Use this method to generate a new primary invite link for a chat; any previously generated primary link is revoked. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns the new invite link as *String* on success. + Use this method to generate a new primary invite link for a chat; any previously generated primary link is revoked. The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. Returns the new invite link as *String* on success. Note: Each administrator in a chat generates their own invite links. Bots can't use invite links generated by other administrators. If you want your bot to work with invite links, it will need to generate its own link using :class:`aiogram.methods.export_chat_invite_link.ExportChatInviteLink` or by calling the :class:`aiogram.methods.get_chat.GetChat` method. If your bot needs to generate a new primary invite link replacing its previous one, use :class:`aiogram.methods.export_chat_invite_link.ExportChatInviteLink` again. @@ -1681,25 +1683,31 @@ class Bot(ContextInstanceMixin["Bot"]): async def create_chat_invite_link( self, chat_id: Union[int, str], + name: Optional[str] = None, expire_date: Optional[int] = None, member_limit: Optional[int] = None, + creates_join_request: Optional[bool] = None, request_timeout: Optional[int] = None, ) -> ChatInviteLink: """ - Use this method to create an additional invite link for a chat. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. The link can be revoked using the method :class:`aiogram.methods.revoke_chat_invite_link.RevokeChatInviteLink`. Returns the new invite link as :class:`aiogram.types.chat_invite_link.ChatInviteLink` object. + Use this method to create an additional invite link for a chat. The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. The link can be revoked using the method :class:`aiogram.methods.revoke_chat_invite_link.RevokeChatInviteLink`. Returns the new invite link as :class:`aiogram.types.chat_invite_link.ChatInviteLink` object. Source: https://core.telegram.org/bots/api#createchatinvitelink :param chat_id: Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`) + :param name: Invite link name; 0-32 characters :param expire_date: Point in time (Unix timestamp) when the link will expire :param member_limit: Maximum number of users that can be members of the chat simultaneously after joining the chat via this invite link; 1-99999 + :param creates_join_request: :code:`True`, if users joining the chat via the link need to be approved by chat administrators. If :code:`True`, *member_limit* can't be specified :param request_timeout: Request timeout :return: Returns the new invite link as ChatInviteLink object. """ call = CreateChatInviteLink( chat_id=chat_id, + name=name, expire_date=expire_date, member_limit=member_limit, + creates_join_request=creates_join_request, ) return await self(call, request_timeout=request_timeout) @@ -1707,27 +1715,33 @@ class Bot(ContextInstanceMixin["Bot"]): self, chat_id: Union[int, str], invite_link: str, + name: Optional[str] = None, expire_date: Optional[int] = None, member_limit: Optional[int] = None, + creates_join_request: Optional[bool] = None, request_timeout: Optional[int] = None, ) -> ChatInviteLink: """ - Use this method to edit a non-primary invite link created by the bot. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns the edited invite link as a :class:`aiogram.types.chat_invite_link.ChatInviteLink` object. + Use this method to edit a non-primary invite link created by the bot. The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. Returns the edited invite link as a :class:`aiogram.types.chat_invite_link.ChatInviteLink` object. Source: https://core.telegram.org/bots/api#editchatinvitelink :param chat_id: Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`) :param invite_link: The invite link to edit + :param name: Invite link name; 0-32 characters :param expire_date: Point in time (Unix timestamp) when the link will expire :param member_limit: Maximum number of users that can be members of the chat simultaneously after joining the chat via this invite link; 1-99999 + :param creates_join_request: :code:`True`, if users joining the chat via the link need to be approved by chat administrators. If :code:`True`, *member_limit* can't be specified :param request_timeout: Request timeout :return: Returns the edited invite link as a ChatInviteLink object. """ call = EditChatInviteLink( chat_id=chat_id, invite_link=invite_link, + name=name, expire_date=expire_date, member_limit=member_limit, + creates_join_request=creates_join_request, ) return await self(call, request_timeout=request_timeout) @@ -1738,7 +1752,7 @@ class Bot(ContextInstanceMixin["Bot"]): request_timeout: Optional[int] = None, ) -> ChatInviteLink: """ - Use this method to revoke an invite link created by the bot. If the primary link is revoked, a new link is automatically generated. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns the revoked invite link as :class:`aiogram.types.chat_invite_link.ChatInviteLink` object. + Use this method to revoke an invite link created by the bot. If the primary link is revoked, a new link is automatically generated. The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. Returns the revoked invite link as :class:`aiogram.types.chat_invite_link.ChatInviteLink` object. Source: https://core.telegram.org/bots/api#revokechatinvitelink @@ -1753,6 +1767,50 @@ class Bot(ContextInstanceMixin["Bot"]): ) return await self(call, request_timeout=request_timeout) + async def approve_chat_join_request( + self, + chat_id: Union[int, str], + user_id: int, + request_timeout: Optional[int] = None, + ) -> bool: + """ + Use this method to approve a chat join request. The bot must be an administrator in the chat for this to work and must have the *can_invite_users* administrator right. Returns :code:`True` on success. + + Source: https://core.telegram.org/bots/api#approvechatjoinrequest + + :param chat_id: Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`) + :param user_id: Unique identifier of the target user + :param request_timeout: Request timeout + :return: Returns True on success. + """ + call = ApproveChatJoinRequest( + chat_id=chat_id, + user_id=user_id, + ) + return await self(call, request_timeout=request_timeout) + + async def decline_chat_join_request( + self, + chat_id: Union[int, str], + user_id: int, + request_timeout: Optional[int] = None, + ) -> bool: + """ + Use this method to decline a chat join request. The bot must be an administrator in the chat for this to work and must have the *can_invite_users* administrator right. Returns :code:`True` on success. + + Source: https://core.telegram.org/bots/api#declinechatjoinrequest + + :param chat_id: Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`) + :param user_id: Unique identifier of the target user + :param request_timeout: Request timeout + :return: Returns True on success. + """ + call = DeclineChatJoinRequest( + chat_id=chat_id, + user_id=user_id, + ) + return await self(call, request_timeout=request_timeout) + async def set_chat_photo( self, chat_id: Union[int, str], @@ -1760,7 +1818,7 @@ class Bot(ContextInstanceMixin["Bot"]): request_timeout: Optional[int] = None, ) -> bool: """ - Use this method to set a new profile photo for the chat. Photos can't be changed for private chats. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns :code:`True` on success. + Use this method to set a new profile photo for the chat. Photos can't be changed for private chats. The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#setchatphoto @@ -1781,7 +1839,7 @@ class Bot(ContextInstanceMixin["Bot"]): request_timeout: Optional[int] = None, ) -> bool: """ - Use this method to delete a chat photo. Photos can't be changed for private chats. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns :code:`True` on success. + Use this method to delete a chat photo. Photos can't be changed for private chats. The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#deletechatphoto @@ -1801,7 +1859,7 @@ class Bot(ContextInstanceMixin["Bot"]): request_timeout: Optional[int] = None, ) -> bool: """ - Use this method to change the title of a chat. Titles can't be changed for private chats. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns :code:`True` on success. + Use this method to change the title of a chat. Titles can't be changed for private chats. The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#setchattitle @@ -1823,7 +1881,7 @@ class Bot(ContextInstanceMixin["Bot"]): request_timeout: Optional[int] = None, ) -> bool: """ - Use this method to change the description of a group, a supergroup or a channel. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns :code:`True` on success. + Use this method to change the description of a group, a supergroup or a channel. The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#setchatdescription @@ -1846,7 +1904,7 @@ class Bot(ContextInstanceMixin["Bot"]): request_timeout: Optional[int] = None, ) -> bool: """ - Use this method to add a message to the list of pinned messages in a chat. If the chat is not a private chat, the bot must be an administrator in the chat for this to work and must have the 'can_pin_messages' admin right in a supergroup or 'can_edit_messages' admin right in a channel. Returns :code:`True` on success. + Use this method to add a message to the list of pinned messages in a chat. If the chat is not a private chat, the bot must be an administrator in the chat for this to work and must have the 'can_pin_messages' administrator right in a supergroup or 'can_edit_messages' administrator right in a channel. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#pinchatmessage @@ -1870,7 +1928,7 @@ class Bot(ContextInstanceMixin["Bot"]): request_timeout: Optional[int] = None, ) -> bool: """ - Use this method to remove a message from the list of pinned messages in a chat. If the chat is not a private chat, the bot must be an administrator in the chat for this to work and must have the 'can_pin_messages' admin right in a supergroup or 'can_edit_messages' admin right in a channel. Returns :code:`True` on success. + Use this method to remove a message from the list of pinned messages in a chat. If the chat is not a private chat, the bot must be an administrator in the chat for this to work and must have the 'can_pin_messages' administrator right in a supergroup or 'can_edit_messages' administrator right in a channel. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#unpinchatmessage @@ -1891,7 +1949,7 @@ class Bot(ContextInstanceMixin["Bot"]): request_timeout: Optional[int] = None, ) -> bool: """ - Use this method to clear the list of pinned messages in a chat. If the chat is not a private chat, the bot must be an administrator in the chat for this to work and must have the 'can_pin_messages' admin right in a supergroup or 'can_edit_messages' admin right in a channel. Returns :code:`True` on success. + Use this method to clear the list of pinned messages in a chat. If the chat is not a private chat, the bot must be an administrator in the chat for this to work and must have the 'can_pin_messages' administrator right in a supergroup or 'can_edit_messages' administrator right in a channel. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#unpinallchatmessages @@ -2051,7 +2109,7 @@ class Bot(ContextInstanceMixin["Bot"]): request_timeout: Optional[int] = None, ) -> bool: """ - Use this method to set a new group sticker set for a supergroup. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Use the field *can_set_sticker_set* optionally returned in :class:`aiogram.methods.get_chat.GetChat` requests to check if the bot can use this method. Returns :code:`True` on success. + Use this method to set a new group sticker set for a supergroup. The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. Use the field *can_set_sticker_set* optionally returned in :class:`aiogram.methods.get_chat.GetChat` requests to check if the bot can use this method. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#setchatstickerset @@ -2073,7 +2131,7 @@ class Bot(ContextInstanceMixin["Bot"]): request_timeout: Optional[int] = None, ) -> bool: """ - Use this method to delete a group sticker set from a supergroup. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Use the field *can_set_sticker_set* optionally returned in :class:`aiogram.methods.get_chat.GetChat` requests to check if the bot can use this method. Returns :code:`True` on success. + Use this method to delete a group sticker set from a supergroup. The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. Use the field *can_set_sticker_set* optionally returned in :class:`aiogram.methods.get_chat.GetChat` requests to check if the bot can use this method. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#deletechatstickerset @@ -2105,7 +2163,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param callback_query_id: Unique identifier for the query to be answered :param text: Text of the notification. If not specified, nothing will be shown to the user, 0-200 characters - :param show_alert: If *true*, an alert will be shown by the client instead of a notification at the top of the chat screen. Defaults to *false*. + :param show_alert: If :code:`True`, an alert will be shown by the client instead of a notification at the top of the chat screen. Defaults to *false*. :param url: URL that will be opened by the user's client. If you have created a :class:`aiogram.types.game.Game` and accepted the conditions via `@Botfather `_, specify the URL that opens your game — note that this will only work if the query comes from a `https://core.telegram.org/bots/api#inlinekeyboardbutton `_ *callback_game* button. :param cache_time: The maximum amount of time in seconds that the result of the callback query may be cached client-side. Telegram apps will support caching starting in version 3.14. Defaults to 0. :param request_timeout: Request timeout @@ -2217,7 +2275,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param message_id: Required if *inline_message_id* is not specified. Identifier of the message to edit :param inline_message_id: Required if *chat_id* and *message_id* are not specified. Identifier of the inline message :param parse_mode: Mode for parsing entities in the message text. See `formatting options `_ for more details. - :param entities: List of special entities that appear in message text, which can be specified instead of *parse_mode* + :param entities: A JSON-serialized list of special entities that appear in message text, which can be specified instead of *parse_mode* :param disable_web_page_preview: Disables link previews for links in this message :param reply_markup: A JSON-serialized object for an `inline keyboard `_. :param request_timeout: Request timeout @@ -2257,7 +2315,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param inline_message_id: Required if *chat_id* and *message_id* are not specified. Identifier of the inline message :param caption: New caption of the message, 0-1024 characters after entities parsing :param parse_mode: Mode for parsing entities in the message caption. See `formatting options `_ for more details. - :param caption_entities: List of special entities that appear in the caption, which can be specified instead of *parse_mode* + :param caption_entities: A JSON-serialized list of special entities that appear in the caption, which can be specified instead of *parse_mode* :param reply_markup: A JSON-serialized object for an `inline keyboard `_. :param request_timeout: Request timeout :return: On success, if the edited message is not an inline message, the edited Message is @@ -2284,7 +2342,7 @@ class Bot(ContextInstanceMixin["Bot"]): request_timeout: Optional[int] = None, ) -> Union[Message, bool]: """ - Use this method to edit animation, audio, document, photo, or video messages. If a message is part of a message album, then it can be edited only to an audio for audio albums, only to a document for document albums and to a photo or a video otherwise. When an inline message is edited, a new file can't be uploaded. Use a previously uploaded file via its file_id or specify a URL. On success, if the edited message was sent by the bot, the edited :class:`aiogram.types.message.Message` is returned, otherwise :code:`True` is returned. + Use this method to edit animation, audio, document, photo, or video messages. If a message is part of a message album, then it can be edited only to an audio for audio albums, only to a document for document albums and to a photo or a video otherwise. When an inline message is edited, a new file can't be uploaded; use a previously uploaded file via its file_id or specify a URL. On success, if the edited message is not an inline message, the edited :class:`aiogram.types.message.Message` is returned, otherwise :code:`True` is returned. Source: https://core.telegram.org/bots/api#editmessagemedia @@ -2294,7 +2352,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param inline_message_id: Required if *chat_id* and *message_id* are not specified. Identifier of the inline message :param reply_markup: A JSON-serialized object for a new `inline keyboard `_. :param request_timeout: Request timeout - :return: On success, if the edited message was sent by the bot, the edited Message is + :return: On success, if the edited message is not an inline message, the edited Message is returned, otherwise True is returned. """ call = EditMessageMedia( @@ -2343,7 +2401,7 @@ class Bot(ContextInstanceMixin["Bot"]): request_timeout: Optional[int] = None, ) -> Poll: """ - Use this method to stop a poll which was sent by the bot. On success, the stopped :class:`aiogram.types.poll.Poll` with the final results is returned. + Use this method to stop a poll which was sent by the bot. On success, the stopped :class:`aiogram.types.poll.Poll` is returned. Source: https://core.telegram.org/bots/api#stoppoll @@ -2351,7 +2409,7 @@ class Bot(ContextInstanceMixin["Bot"]): :param message_id: Identifier of the original message with the poll :param reply_markup: A JSON-serialized object for a new message `inline keyboard `_. :param request_timeout: Request timeout - :return: On success, the stopped Poll with the final results is returned. + :return: On success, the stopped Poll is returned. """ call = StopPoll( chat_id=chat_id, @@ -2772,13 +2830,13 @@ class Bot(ContextInstanceMixin["Bot"]): request_timeout: Optional[int] = None, ) -> bool: """ - If you sent an invoice requesting a shipping address and the parameter *is_flexible* was specified, the Bot API will send an :class:`aiogram.types.update.Update` with a *shipping_query* field to the bot. Use this method to reply to shipping queries. On success, True is returned. + If you sent an invoice requesting a shipping address and the parameter *is_flexible* was specified, the Bot API will send an :class:`aiogram.types.update.Update` with a *shipping_query* field to the bot. Use this method to reply to shipping queries. On success, :code:`True` is returned. Source: https://core.telegram.org/bots/api#answershippingquery :param shipping_query_id: Unique identifier for the query to be answered - :param ok: Specify True if delivery to the specified address is possible and False if there are any problems (for example, if delivery to the specified address is not possible) - :param shipping_options: Required if *ok* is True. A JSON-serialized array of available shipping options. + :param ok: Specify :code:`True` if delivery to the specified address is possible and False if there are any problems (for example, if delivery to the specified address is not possible) + :param shipping_options: Required if *ok* is :code:`True`. A JSON-serialized array of available shipping options. :param error_message: Required if *ok* is False. Error message in human readable form that explains why it is impossible to complete the order (e.g. "Sorry, delivery to your desired address is unavailable'). Telegram will display this message to the user. :param request_timeout: Request timeout :return: On success, True is returned. @@ -2799,7 +2857,7 @@ class Bot(ContextInstanceMixin["Bot"]): request_timeout: Optional[int] = None, ) -> bool: """ - Once the user has confirmed their payment and shipping details, the Bot API sends the final confirmation in the form of an :class:`aiogram.types.update.Update` with the field *pre_checkout_query*. Use this method to respond to such pre-checkout queries. On success, True is returned. **Note:** The Bot API must receive an answer within 10 seconds after the pre-checkout query was sent. + Once the user has confirmed their payment and shipping details, the Bot API sends the final confirmation in the form of an :class:`aiogram.types.update.Update` with the field *pre_checkout_query*. Use this method to respond to such pre-checkout queries. On success, :code:`True` is returned. **Note:** The Bot API must receive an answer within 10 seconds after the pre-checkout query was sent. Source: https://core.telegram.org/bots/api#answerprecheckoutquery @@ -2897,21 +2955,21 @@ class Bot(ContextInstanceMixin["Bot"]): request_timeout: Optional[int] = None, ) -> Union[Message, bool]: """ - Use this method to set the score of the specified user in a game. On success, if the message was sent by the bot, returns the edited :class:`aiogram.types.message.Message`, otherwise returns :code:`True`. Returns an error, if the new score is not greater than the user's current score in the chat and *force* is :code:`False`. + Use this method to set the score of the specified user in a game message. On success, if the message is not an inline message, the :class:`aiogram.types.message.Message` is returned, otherwise :code:`True` is returned. Returns an error, if the new score is not greater than the user's current score in the chat and *force* is :code:`False`. Source: https://core.telegram.org/bots/api#setgamescore :param user_id: User identifier :param score: New score, must be non-negative - :param force: Pass True, if the high score is allowed to decrease. This can be useful when fixing mistakes or banning cheaters - :param disable_edit_message: Pass True, if the game message should not be automatically edited to include the current scoreboard + :param force: Pass :code:`True`, if the high score is allowed to decrease. This can be useful when fixing mistakes or banning cheaters + :param disable_edit_message: Pass :code:`True`, if the game message should not be automatically edited to include the current scoreboard :param chat_id: Required if *inline_message_id* is not specified. Unique identifier for the target chat :param message_id: Required if *inline_message_id* is not specified. Identifier of the sent message :param inline_message_id: Required if *chat_id* and *message_id* are not specified. Identifier of the inline message :param request_timeout: Request timeout - :return: On success, if the message was sent by the bot, returns the edited Message, - otherwise returns True. Returns an error, if the new score is not greater than - the user's current score in the chat and force is False. + :return: On success, if the message is not an inline message, the Message is returned, + otherwise True is returned. Returns an error, if the new score is not greater + than the user's current score in the chat and force is False. """ call = SetGameScore( user_id=user_id, diff --git a/aiogram/dispatcher/filters/__init__.py b/aiogram/dispatcher/filters/__init__.py index 9795697a..74f175ac 100644 --- a/aiogram/dispatcher/filters/__init__.py +++ b/aiogram/dispatcher/filters/__init__.py @@ -89,6 +89,10 @@ BUILTIN_FILTERS: Dict[str, Tuple[Type[BaseFilter], ...]] = { *_ALL_EVENTS_FILTERS, *_TELEGRAM_EVENTS_FILTERS, ), + "chat_join_request": ( + *_ALL_EVENTS_FILTERS, + *_TELEGRAM_EVENTS_FILTERS, + ), "error": ( ExceptionMessageFilter, ExceptionTypeFilter, diff --git a/aiogram/dispatcher/middlewares/user_context.py b/aiogram/dispatcher/middlewares/user_context.py index c238332a..3531beb7 100644 --- a/aiogram/dispatcher/middlewares/user_context.py +++ b/aiogram/dispatcher/middlewares/user_context.py @@ -69,4 +69,6 @@ class UserContextMiddleware(BaseMiddleware): return event.my_chat_member.chat, event.my_chat_member.from_user if event.chat_member: return event.chat_member.chat, event.chat_member.from_user + if event.chat_join_request: + return event.chat_join_request.chat, event.chat_join_request.from_user return None, None diff --git a/aiogram/dispatcher/router.py b/aiogram/dispatcher/router.py index 8f2df80b..ae83c1c7 100644 --- a/aiogram/dispatcher/router.py +++ b/aiogram/dispatcher/router.py @@ -58,6 +58,7 @@ class Router: self.poll_answer = TelegramEventObserver(router=self, event_name="poll_answer") self.my_chat_member = TelegramEventObserver(router=self, event_name="my_chat_member") self.chat_member = TelegramEventObserver(router=self, event_name="chat_member") + self.chat_join_request = TelegramEventObserver(router=self, event_name="chat_join_request") self.errors = TelegramEventObserver(router=self, event_name="error") @@ -78,6 +79,7 @@ class Router: "poll_answer": self.poll_answer, "my_chat_member": self.my_chat_member, "chat_member": self.chat_member, + "chat_join_request": self.chat_join_request, "error": self.errors, } diff --git a/aiogram/methods/__init__.py b/aiogram/methods/__init__.py index 54b59e74..2954881f 100644 --- a/aiogram/methods/__init__.py +++ b/aiogram/methods/__init__.py @@ -3,12 +3,14 @@ from .answer_callback_query import AnswerCallbackQuery from .answer_inline_query import AnswerInlineQuery from .answer_pre_checkout_query import AnswerPreCheckoutQuery from .answer_shipping_query import AnswerShippingQuery +from .approve_chat_join_request import ApproveChatJoinRequest from .ban_chat_member import BanChatMember from .base import Request, Response, TelegramMethod from .close import Close from .copy_message import CopyMessage from .create_chat_invite_link import CreateChatInviteLink from .create_new_sticker_set import CreateNewStickerSet +from .decline_chat_join_request import DeclineChatJoinRequest from .delete_chat_photo import DeleteChatPhoto from .delete_chat_sticker_set import DeleteChatStickerSet from .delete_message import DeleteMessage @@ -123,6 +125,8 @@ __all__ = ( "CreateChatInviteLink", "EditChatInviteLink", "RevokeChatInviteLink", + "ApproveChatJoinRequest", + "DeclineChatJoinRequest", "SetChatPhoto", "DeleteChatPhoto", "SetChatTitle", diff --git a/aiogram/methods/answer_callback_query.py b/aiogram/methods/answer_callback_query.py index f56e6704..04f8282c 100644 --- a/aiogram/methods/answer_callback_query.py +++ b/aiogram/methods/answer_callback_query.py @@ -24,7 +24,7 @@ class AnswerCallbackQuery(TelegramMethod[bool]): text: Optional[str] = None """Text of the notification. If not specified, nothing will be shown to the user, 0-200 characters""" show_alert: Optional[bool] = None - """If *true*, an alert will be shown by the client instead of a notification at the top of the chat screen. Defaults to *false*.""" + """If :code:`True`, an alert will be shown by the client instead of a notification at the top of the chat screen. Defaults to *false*.""" url: Optional[str] = None """URL that will be opened by the user's client. If you have created a :class:`aiogram.types.game.Game` and accepted the conditions via `@Botfather `_, specify the URL that opens your game — note that this will only work if the query comes from a `https://core.telegram.org/bots/api#inlinekeyboardbutton `_ *callback_game* button.""" cache_time: Optional[int] = None diff --git a/aiogram/methods/answer_pre_checkout_query.py b/aiogram/methods/answer_pre_checkout_query.py index d6532675..507f8158 100644 --- a/aiogram/methods/answer_pre_checkout_query.py +++ b/aiogram/methods/answer_pre_checkout_query.py @@ -10,7 +10,7 @@ if TYPE_CHECKING: class AnswerPreCheckoutQuery(TelegramMethod[bool]): """ - Once the user has confirmed their payment and shipping details, the Bot API sends the final confirmation in the form of an :class:`aiogram.types.update.Update` with the field *pre_checkout_query*. Use this method to respond to such pre-checkout queries. On success, True is returned. **Note:** The Bot API must receive an answer within 10 seconds after the pre-checkout query was sent. + Once the user has confirmed their payment and shipping details, the Bot API sends the final confirmation in the form of an :class:`aiogram.types.update.Update` with the field *pre_checkout_query*. Use this method to respond to such pre-checkout queries. On success, :code:`True` is returned. **Note:** The Bot API must receive an answer within 10 seconds after the pre-checkout query was sent. Source: https://core.telegram.org/bots/api#answerprecheckoutquery """ diff --git a/aiogram/methods/answer_shipping_query.py b/aiogram/methods/answer_shipping_query.py index 794466d2..60da57c7 100644 --- a/aiogram/methods/answer_shipping_query.py +++ b/aiogram/methods/answer_shipping_query.py @@ -11,7 +11,7 @@ if TYPE_CHECKING: class AnswerShippingQuery(TelegramMethod[bool]): """ - If you sent an invoice requesting a shipping address and the parameter *is_flexible* was specified, the Bot API will send an :class:`aiogram.types.update.Update` with a *shipping_query* field to the bot. Use this method to reply to shipping queries. On success, True is returned. + If you sent an invoice requesting a shipping address and the parameter *is_flexible* was specified, the Bot API will send an :class:`aiogram.types.update.Update` with a *shipping_query* field to the bot. Use this method to reply to shipping queries. On success, :code:`True` is returned. Source: https://core.telegram.org/bots/api#answershippingquery """ @@ -21,9 +21,9 @@ class AnswerShippingQuery(TelegramMethod[bool]): shipping_query_id: str """Unique identifier for the query to be answered""" ok: bool - """Specify True if delivery to the specified address is possible and False if there are any problems (for example, if delivery to the specified address is not possible)""" + """Specify :code:`True` if delivery to the specified address is possible and False if there are any problems (for example, if delivery to the specified address is not possible)""" shipping_options: Optional[List[ShippingOption]] = None - """Required if *ok* is True. A JSON-serialized array of available shipping options.""" + """Required if *ok* is :code:`True`. A JSON-serialized array of available shipping options.""" error_message: Optional[str] = None """Required if *ok* is False. Error message in human readable form that explains why it is impossible to complete the order (e.g. "Sorry, delivery to your desired address is unavailable'). Telegram will display this message to the user.""" diff --git a/aiogram/methods/approve_chat_join_request.py b/aiogram/methods/approve_chat_join_request.py new file mode 100644 index 00000000..5c4008af --- /dev/null +++ b/aiogram/methods/approve_chat_join_request.py @@ -0,0 +1,28 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, Any, Dict, Union + +from .base import Request, TelegramMethod + +if TYPE_CHECKING: + from ..client.bot import Bot + + +class ApproveChatJoinRequest(TelegramMethod[bool]): + """ + Use this method to approve a chat join request. The bot must be an administrator in the chat for this to work and must have the *can_invite_users* administrator right. Returns :code:`True` on success. + + Source: https://core.telegram.org/bots/api#approvechatjoinrequest + """ + + __returning__ = bool + + chat_id: Union[int, str] + """Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`)""" + user_id: int + """Unique identifier of the target user""" + + def build_request(self, bot: Bot) -> Request: + data: Dict[str, Any] = self.dict() + + return Request(method="approveChatJoinRequest", data=data) diff --git a/aiogram/methods/ban_chat_member.py b/aiogram/methods/ban_chat_member.py index 6237b279..3252af1b 100644 --- a/aiogram/methods/ban_chat_member.py +++ b/aiogram/methods/ban_chat_member.py @@ -11,7 +11,7 @@ if TYPE_CHECKING: class BanChatMember(TelegramMethod[bool]): """ - Use this method to ban a user in a group, a supergroup or a channel. In the case of supergroups and channels, the user will not be able to return to the chat on their own using invite links, etc., unless `unbanned `_ first. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns :code:`True` on success. + Use this method to ban a user in a group, a supergroup or a channel. In the case of supergroups and channels, the user will not be able to return to the chat on their own using invite links, etc., unless `unbanned `_ first. The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#banchatmember """ diff --git a/aiogram/methods/copy_message.py b/aiogram/methods/copy_message.py index c2a193e3..3c90baee 100644 --- a/aiogram/methods/copy_message.py +++ b/aiogram/methods/copy_message.py @@ -37,7 +37,7 @@ class CopyMessage(TelegramMethod[MessageId]): parse_mode: Optional[str] = UNSET """Mode for parsing entities in the new caption. See `formatting options `_ for more details.""" caption_entities: Optional[List[MessageEntity]] = None - """List of special entities that appear in the new caption, which can be specified instead of *parse_mode*""" + """A JSON-serialized list of special entities that appear in the new caption, which can be specified instead of *parse_mode*""" disable_notification: Optional[bool] = None """Sends the message `silently `_. Users will receive a notification with no sound.""" reply_to_message_id: Optional[int] = None diff --git a/aiogram/methods/create_chat_invite_link.py b/aiogram/methods/create_chat_invite_link.py index af152444..e96596bb 100644 --- a/aiogram/methods/create_chat_invite_link.py +++ b/aiogram/methods/create_chat_invite_link.py @@ -11,7 +11,7 @@ if TYPE_CHECKING: class CreateChatInviteLink(TelegramMethod[ChatInviteLink]): """ - Use this method to create an additional invite link for a chat. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. The link can be revoked using the method :class:`aiogram.methods.revoke_chat_invite_link.RevokeChatInviteLink`. Returns the new invite link as :class:`aiogram.types.chat_invite_link.ChatInviteLink` object. + Use this method to create an additional invite link for a chat. The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. The link can be revoked using the method :class:`aiogram.methods.revoke_chat_invite_link.RevokeChatInviteLink`. Returns the new invite link as :class:`aiogram.types.chat_invite_link.ChatInviteLink` object. Source: https://core.telegram.org/bots/api#createchatinvitelink """ @@ -20,10 +20,14 @@ class CreateChatInviteLink(TelegramMethod[ChatInviteLink]): chat_id: Union[int, str] """Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`)""" + name: Optional[str] = None + """Invite link name; 0-32 characters""" expire_date: Optional[int] = None """Point in time (Unix timestamp) when the link will expire""" member_limit: Optional[int] = None """Maximum number of users that can be members of the chat simultaneously after joining the chat via this invite link; 1-99999""" + creates_join_request: Optional[bool] = None + """:code:`True`, if users joining the chat via the link need to be approved by chat administrators. If :code:`True`, *member_limit* can't be specified""" def build_request(self, bot: Bot) -> Request: data: Dict[str, Any] = self.dict() diff --git a/aiogram/methods/decline_chat_join_request.py b/aiogram/methods/decline_chat_join_request.py new file mode 100644 index 00000000..6bc03c9e --- /dev/null +++ b/aiogram/methods/decline_chat_join_request.py @@ -0,0 +1,28 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, Any, Dict, Union + +from .base import Request, TelegramMethod + +if TYPE_CHECKING: + from ..client.bot import Bot + + +class DeclineChatJoinRequest(TelegramMethod[bool]): + """ + Use this method to decline a chat join request. The bot must be an administrator in the chat for this to work and must have the *can_invite_users* administrator right. Returns :code:`True` on success. + + Source: https://core.telegram.org/bots/api#declinechatjoinrequest + """ + + __returning__ = bool + + chat_id: Union[int, str] + """Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`)""" + user_id: int + """Unique identifier of the target user""" + + def build_request(self, bot: Bot) -> Request: + data: Dict[str, Any] = self.dict() + + return Request(method="declineChatJoinRequest", data=data) diff --git a/aiogram/methods/delete_chat_photo.py b/aiogram/methods/delete_chat_photo.py index db67e00c..9fe12a65 100644 --- a/aiogram/methods/delete_chat_photo.py +++ b/aiogram/methods/delete_chat_photo.py @@ -10,7 +10,7 @@ if TYPE_CHECKING: class DeleteChatPhoto(TelegramMethod[bool]): """ - Use this method to delete a chat photo. Photos can't be changed for private chats. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns :code:`True` on success. + Use this method to delete a chat photo. Photos can't be changed for private chats. The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#deletechatphoto """ diff --git a/aiogram/methods/delete_chat_sticker_set.py b/aiogram/methods/delete_chat_sticker_set.py index f28fa4fe..18fbaf82 100644 --- a/aiogram/methods/delete_chat_sticker_set.py +++ b/aiogram/methods/delete_chat_sticker_set.py @@ -10,7 +10,7 @@ if TYPE_CHECKING: class DeleteChatStickerSet(TelegramMethod[bool]): """ - Use this method to delete a group sticker set from a supergroup. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Use the field *can_set_sticker_set* optionally returned in :class:`aiogram.methods.get_chat.GetChat` requests to check if the bot can use this method. Returns :code:`True` on success. + Use this method to delete a group sticker set from a supergroup. The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. Use the field *can_set_sticker_set* optionally returned in :class:`aiogram.methods.get_chat.GetChat` requests to check if the bot can use this method. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#deletechatstickerset """ diff --git a/aiogram/methods/edit_chat_invite_link.py b/aiogram/methods/edit_chat_invite_link.py index ff5fe3af..1e02fb3c 100644 --- a/aiogram/methods/edit_chat_invite_link.py +++ b/aiogram/methods/edit_chat_invite_link.py @@ -11,7 +11,7 @@ if TYPE_CHECKING: class EditChatInviteLink(TelegramMethod[ChatInviteLink]): """ - Use this method to edit a non-primary invite link created by the bot. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns the edited invite link as a :class:`aiogram.types.chat_invite_link.ChatInviteLink` object. + Use this method to edit a non-primary invite link created by the bot. The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. Returns the edited invite link as a :class:`aiogram.types.chat_invite_link.ChatInviteLink` object. Source: https://core.telegram.org/bots/api#editchatinvitelink """ @@ -22,10 +22,14 @@ class EditChatInviteLink(TelegramMethod[ChatInviteLink]): """Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`)""" invite_link: str """The invite link to edit""" + name: Optional[str] = None + """Invite link name; 0-32 characters""" expire_date: Optional[int] = None """Point in time (Unix timestamp) when the link will expire""" member_limit: Optional[int] = None """Maximum number of users that can be members of the chat simultaneously after joining the chat via this invite link; 1-99999""" + creates_join_request: Optional[bool] = None + """:code:`True`, if users joining the chat via the link need to be approved by chat administrators. If :code:`True`, *member_limit* can't be specified""" def build_request(self, bot: Bot) -> Request: data: Dict[str, Any] = self.dict() diff --git a/aiogram/methods/edit_message_caption.py b/aiogram/methods/edit_message_caption.py index d9f6f402..40e4459b 100644 --- a/aiogram/methods/edit_message_caption.py +++ b/aiogram/methods/edit_message_caption.py @@ -29,7 +29,7 @@ class EditMessageCaption(TelegramMethod[Union[Message, bool]]): parse_mode: Optional[str] = UNSET """Mode for parsing entities in the message caption. See `formatting options `_ for more details.""" caption_entities: Optional[List[MessageEntity]] = None - """List of special entities that appear in the caption, which can be specified instead of *parse_mode*""" + """A JSON-serialized list of special entities that appear in the caption, which can be specified instead of *parse_mode*""" reply_markup: Optional[InlineKeyboardMarkup] = None """A JSON-serialized object for an `inline keyboard `_.""" diff --git a/aiogram/methods/edit_message_media.py b/aiogram/methods/edit_message_media.py index d77777ad..10882e81 100644 --- a/aiogram/methods/edit_message_media.py +++ b/aiogram/methods/edit_message_media.py @@ -11,7 +11,7 @@ if TYPE_CHECKING: class EditMessageMedia(TelegramMethod[Union[Message, bool]]): """ - Use this method to edit animation, audio, document, photo, or video messages. If a message is part of a message album, then it can be edited only to an audio for audio albums, only to a document for document albums and to a photo or a video otherwise. When an inline message is edited, a new file can't be uploaded. Use a previously uploaded file via its file_id or specify a URL. On success, if the edited message was sent by the bot, the edited :class:`aiogram.types.message.Message` is returned, otherwise :code:`True` is returned. + Use this method to edit animation, audio, document, photo, or video messages. If a message is part of a message album, then it can be edited only to an audio for audio albums, only to a document for document albums and to a photo or a video otherwise. When an inline message is edited, a new file can't be uploaded; use a previously uploaded file via its file_id or specify a URL. On success, if the edited message is not an inline message, the edited :class:`aiogram.types.message.Message` is returned, otherwise :code:`True` is returned. Source: https://core.telegram.org/bots/api#editmessagemedia """ diff --git a/aiogram/methods/edit_message_text.py b/aiogram/methods/edit_message_text.py index 2fdc11ab..92184b90 100644 --- a/aiogram/methods/edit_message_text.py +++ b/aiogram/methods/edit_message_text.py @@ -29,7 +29,7 @@ class EditMessageText(TelegramMethod[Union[Message, bool]]): parse_mode: Optional[str] = UNSET """Mode for parsing entities in the message text. See `formatting options `_ for more details.""" entities: Optional[List[MessageEntity]] = None - """List of special entities that appear in message text, which can be specified instead of *parse_mode*""" + """A JSON-serialized list of special entities that appear in message text, which can be specified instead of *parse_mode*""" disable_web_page_preview: Optional[bool] = None """Disables link previews for links in this message""" reply_markup: Optional[InlineKeyboardMarkup] = None diff --git a/aiogram/methods/export_chat_invite_link.py b/aiogram/methods/export_chat_invite_link.py index 1250ee3a..d4b72e34 100644 --- a/aiogram/methods/export_chat_invite_link.py +++ b/aiogram/methods/export_chat_invite_link.py @@ -10,7 +10,7 @@ if TYPE_CHECKING: class ExportChatInviteLink(TelegramMethod[str]): """ - Use this method to generate a new primary invite link for a chat; any previously generated primary link is revoked. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns the new invite link as *String* on success. + Use this method to generate a new primary invite link for a chat; any previously generated primary link is revoked. The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. Returns the new invite link as *String* on success. Note: Each administrator in a chat generates their own invite links. Bots can't use invite links generated by other administrators. If you want your bot to work with invite links, it will need to generate its own link using :class:`aiogram.methods.export_chat_invite_link.ExportChatInviteLink` or by calling the :class:`aiogram.methods.get_chat.GetChat` method. If your bot needs to generate a new primary invite link replacing its previous one, use :class:`aiogram.methods.export_chat_invite_link.ExportChatInviteLink` again. diff --git a/aiogram/methods/get_me.py b/aiogram/methods/get_me.py index 60d2f0c2..63f901a8 100644 --- a/aiogram/methods/get_me.py +++ b/aiogram/methods/get_me.py @@ -11,7 +11,7 @@ if TYPE_CHECKING: class GetMe(TelegramMethod[User]): """ - A simple method for testing your bot's auth token. Requires no parameters. Returns basic information about the bot in form of a :class:`aiogram.types.user.User` object. + A simple method for testing your bot's authentication token. Requires no parameters. Returns basic information about the bot in form of a :class:`aiogram.types.user.User` object. Source: https://core.telegram.org/bots/api#getme """ diff --git a/aiogram/methods/kick_chat_member.py b/aiogram/methods/kick_chat_member.py index 8f455747..13ab1931 100644 --- a/aiogram/methods/kick_chat_member.py +++ b/aiogram/methods/kick_chat_member.py @@ -15,7 +15,7 @@ class KickChatMember(TelegramMethod[bool]): Renamed from :code:`kickChatMember` in 5.3 bot API version and can be removed in near future - Use this method to ban a user in a group, a supergroup or a channel. In the case of supergroups and channels, the user will not be able to return to the chat on their own using invite links, etc., unless `unbanned `_ first. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns :code:`True` on success. + Use this method to ban a user in a group, a supergroup or a channel. In the case of supergroups and channels, the user will not be able to return to the chat on their own using invite links, etc., unless `unbanned `_ first. The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#banchatmember """ diff --git a/aiogram/methods/pin_chat_message.py b/aiogram/methods/pin_chat_message.py index 60d2795d..7c1ac735 100644 --- a/aiogram/methods/pin_chat_message.py +++ b/aiogram/methods/pin_chat_message.py @@ -10,7 +10,7 @@ if TYPE_CHECKING: class PinChatMessage(TelegramMethod[bool]): """ - Use this method to add a message to the list of pinned messages in a chat. If the chat is not a private chat, the bot must be an administrator in the chat for this to work and must have the 'can_pin_messages' admin right in a supergroup or 'can_edit_messages' admin right in a channel. Returns :code:`True` on success. + Use this method to add a message to the list of pinned messages in a chat. If the chat is not a private chat, the bot must be an administrator in the chat for this to work and must have the 'can_pin_messages' administrator right in a supergroup or 'can_edit_messages' administrator right in a channel. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#pinchatmessage """ diff --git a/aiogram/methods/promote_chat_member.py b/aiogram/methods/promote_chat_member.py index 84dd113b..f2d8374f 100644 --- a/aiogram/methods/promote_chat_member.py +++ b/aiogram/methods/promote_chat_member.py @@ -10,7 +10,7 @@ if TYPE_CHECKING: class PromoteChatMember(TelegramMethod[bool]): """ - Use this method to promote or demote a user in a supergroup or a channel. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Pass :code:`False` for all boolean parameters to demote a user. Returns :code:`True` on success. + Use this method to promote or demote a user in a supergroup or a channel. The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. Pass :code:`False` for all boolean parameters to demote a user. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#promotechatmember """ @@ -24,25 +24,25 @@ class PromoteChatMember(TelegramMethod[bool]): is_anonymous: Optional[bool] = None """Pass :code:`True`, if the administrator's presence in the chat is hidden""" can_manage_chat: Optional[bool] = None - """Pass True, if the administrator can access the chat event log, chat statistics, message statistics in channels, see channel members, see anonymous administrators in supergroups and ignore slow mode. Implied by any other administrator privilege""" + """Pass :code:`True`, if the administrator can access the chat event log, chat statistics, message statistics in channels, see channel members, see anonymous administrators in supergroups and ignore slow mode. Implied by any other administrator privilege""" can_post_messages: Optional[bool] = None - """Pass True, if the administrator can create channel posts, channels only""" + """Pass :code:`True`, if the administrator can create channel posts, channels only""" can_edit_messages: Optional[bool] = None - """Pass True, if the administrator can edit messages of other users and can pin messages, channels only""" + """Pass :code:`True`, if the administrator can edit messages of other users and can pin messages, channels only""" can_delete_messages: Optional[bool] = None - """Pass True, if the administrator can delete messages of other users""" + """Pass :code:`True`, if the administrator can delete messages of other users""" can_manage_voice_chats: Optional[bool] = None - """Pass True, if the administrator can manage voice chats""" + """Pass :code:`True`, if the administrator can manage voice chats""" can_restrict_members: Optional[bool] = None - """Pass True, if the administrator can restrict, ban or unban chat members""" + """Pass :code:`True`, if the administrator can restrict, ban or unban chat members""" can_promote_members: Optional[bool] = None - """Pass True, if the administrator can add new administrators with a subset of their own privileges or demote administrators that he has promoted, directly or indirectly (promoted by administrators that were appointed by him)""" + """Pass :code:`True`, if the administrator can add new administrators with a subset of their own privileges or demote administrators that he has promoted, directly or indirectly (promoted by administrators that were appointed by him)""" can_change_info: Optional[bool] = None - """Pass True, if the administrator can change chat title, photo and other settings""" + """Pass :code:`True`, if the administrator can change chat title, photo and other settings""" can_invite_users: Optional[bool] = None - """Pass True, if the administrator can invite new users to the chat""" + """Pass :code:`True`, if the administrator can invite new users to the chat""" can_pin_messages: Optional[bool] = None - """Pass True, if the administrator can pin messages, supergroups only""" + """Pass :code:`True`, if the administrator can pin messages, supergroups only""" def build_request(self, bot: Bot) -> Request: data: Dict[str, Any] = self.dict() diff --git a/aiogram/methods/restrict_chat_member.py b/aiogram/methods/restrict_chat_member.py index 0021d42e..e7ad4a75 100644 --- a/aiogram/methods/restrict_chat_member.py +++ b/aiogram/methods/restrict_chat_member.py @@ -12,7 +12,7 @@ if TYPE_CHECKING: class RestrictChatMember(TelegramMethod[bool]): """ - Use this method to restrict a user in a supergroup. The bot must be an administrator in the supergroup for this to work and must have the appropriate admin rights. Pass :code:`True` for all permissions to lift restrictions from a user. Returns :code:`True` on success. + Use this method to restrict a user in a supergroup. The bot must be an administrator in the supergroup for this to work and must have the appropriate administrator rights. Pass :code:`True` for all permissions to lift restrictions from a user. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#restrictchatmember """ diff --git a/aiogram/methods/revoke_chat_invite_link.py b/aiogram/methods/revoke_chat_invite_link.py index 1673c9e8..c644d8a4 100644 --- a/aiogram/methods/revoke_chat_invite_link.py +++ b/aiogram/methods/revoke_chat_invite_link.py @@ -11,7 +11,7 @@ if TYPE_CHECKING: class RevokeChatInviteLink(TelegramMethod[ChatInviteLink]): """ - Use this method to revoke an invite link created by the bot. If the primary link is revoked, a new link is automatically generated. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns the revoked invite link as :class:`aiogram.types.chat_invite_link.ChatInviteLink` object. + Use this method to revoke an invite link created by the bot. If the primary link is revoked, a new link is automatically generated. The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. Returns the revoked invite link as :class:`aiogram.types.chat_invite_link.ChatInviteLink` object. Source: https://core.telegram.org/bots/api#revokechatinvitelink """ diff --git a/aiogram/methods/send_animation.py b/aiogram/methods/send_animation.py index 8a374396..1f0971f6 100644 --- a/aiogram/methods/send_animation.py +++ b/aiogram/methods/send_animation.py @@ -44,7 +44,7 @@ class SendAnimation(TelegramMethod[Message]): parse_mode: Optional[str] = UNSET """Mode for parsing entities in the animation caption. See `formatting options `_ for more details.""" caption_entities: Optional[List[MessageEntity]] = None - """List of special entities that appear in the caption, which can be specified instead of *parse_mode*""" + """A JSON-serialized list of special entities that appear in the caption, which can be specified instead of *parse_mode*""" disable_notification: Optional[bool] = None """Sends the message `silently `_. Users will receive a notification with no sound.""" reply_to_message_id: Optional[int] = None diff --git a/aiogram/methods/send_audio.py b/aiogram/methods/send_audio.py index 43606db7..8b61e75b 100644 --- a/aiogram/methods/send_audio.py +++ b/aiogram/methods/send_audio.py @@ -37,7 +37,7 @@ class SendAudio(TelegramMethod[Message]): parse_mode: Optional[str] = UNSET """Mode for parsing entities in the audio caption. See `formatting options `_ for more details.""" caption_entities: Optional[List[MessageEntity]] = None - """List of special entities that appear in the caption, which can be specified instead of *parse_mode*""" + """A JSON-serialized list of special entities that appear in the caption, which can be specified instead of *parse_mode*""" duration: Optional[int] = None """Duration of the audio in seconds""" performer: Optional[str] = None diff --git a/aiogram/methods/send_chat_action.py b/aiogram/methods/send_chat_action.py index 5f0996af..9eb22413 100644 --- a/aiogram/methods/send_chat_action.py +++ b/aiogram/methods/send_chat_action.py @@ -24,7 +24,7 @@ class SendChatAction(TelegramMethod[bool]): chat_id: Union[int, str] """Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`)""" action: str - """Type of action to broadcast. Choose one, depending on what the user is about to receive: *typing* for `text messages `_, *upload_photo* for `photos `_, *record_video* or *upload_video* for `videos `_, *record_voice* or *upload_voice* for `voice notes `_, *upload_document* for `general files `_, *find_location* for `location data `_, *record_video_note* or *upload_video_note* for `video notes `_.""" + """Type of action to broadcast. Choose one, depending on what the user is about to receive: *typing* for `text messages `_, *upload_photo* for `photos `_, *record_video* or *upload_video* for `videos `_, *record_voice* or *upload_voice* for `voice notes `_, *upload_document* for `general files `_, *choose_sticker* for `stickers `_, *find_location* for `location data `_, *record_video_note* or *upload_video_note* for `video notes `_.""" def build_request(self, bot: Bot) -> Request: data: Dict[str, Any] = self.dict() diff --git a/aiogram/methods/send_document.py b/aiogram/methods/send_document.py index aa7c6ea7..9fff7d5e 100644 --- a/aiogram/methods/send_document.py +++ b/aiogram/methods/send_document.py @@ -38,7 +38,7 @@ class SendDocument(TelegramMethod[Message]): parse_mode: Optional[str] = UNSET """Mode for parsing entities in the document caption. See `formatting options `_ for more details.""" caption_entities: Optional[List[MessageEntity]] = None - """List of special entities that appear in the caption, which can be specified instead of *parse_mode*""" + """A JSON-serialized list of special entities that appear in the caption, which can be specified instead of *parse_mode*""" disable_content_type_detection: Optional[bool] = None """Disables automatic server-side content type detection for files uploaded using multipart/form-data""" disable_notification: Optional[bool] = None diff --git a/aiogram/methods/send_message.py b/aiogram/methods/send_message.py index 19ae433a..bd7bfee0 100644 --- a/aiogram/methods/send_message.py +++ b/aiogram/methods/send_message.py @@ -33,7 +33,7 @@ class SendMessage(TelegramMethod[Message]): parse_mode: Optional[str] = UNSET """Mode for parsing entities in the message text. See `formatting options `_ for more details.""" entities: Optional[List[MessageEntity]] = None - """List of special entities that appear in message text, which can be specified instead of *parse_mode*""" + """A JSON-serialized list of special entities that appear in message text, which can be specified instead of *parse_mode*""" disable_web_page_preview: Optional[bool] = None """Disables link previews for links in this message""" disable_notification: Optional[bool] = None diff --git a/aiogram/methods/send_photo.py b/aiogram/methods/send_photo.py index 25b8b52e..82eb06ac 100644 --- a/aiogram/methods/send_photo.py +++ b/aiogram/methods/send_photo.py @@ -36,7 +36,7 @@ class SendPhoto(TelegramMethod[Message]): parse_mode: Optional[str] = UNSET """Mode for parsing entities in the photo caption. See `formatting options `_ for more details.""" caption_entities: Optional[List[MessageEntity]] = None - """List of special entities that appear in the caption, which can be specified instead of *parse_mode*""" + """A JSON-serialized list of special entities that appear in the caption, which can be specified instead of *parse_mode*""" disable_notification: Optional[bool] = None """Sends the message `silently `_. Users will receive a notification with no sound.""" reply_to_message_id: Optional[int] = None diff --git a/aiogram/methods/send_poll.py b/aiogram/methods/send_poll.py index 4ffe4a69..11e0eec2 100644 --- a/aiogram/methods/send_poll.py +++ b/aiogram/methods/send_poll.py @@ -34,11 +34,11 @@ class SendPoll(TelegramMethod[Message]): options: List[str] """A JSON-serialized list of answer options, 2-10 strings 1-100 characters each""" is_anonymous: Optional[bool] = None - """True, if the poll needs to be anonymous, defaults to :code:`True`""" + """:code:`True`, if the poll needs to be anonymous, defaults to :code:`True`""" type: Optional[str] = None """Poll type, 'quiz' or 'regular', defaults to 'regular'""" allows_multiple_answers: Optional[bool] = None - """True, if the poll allows multiple answers, ignored for polls in quiz mode, defaults to :code:`False`""" + """:code:`True`, if the poll allows multiple answers, ignored for polls in quiz mode, defaults to :code:`False`""" correct_option_id: Optional[int] = None """0-based identifier of the correct answer option, required for polls in quiz mode""" explanation: Optional[str] = None @@ -46,7 +46,7 @@ class SendPoll(TelegramMethod[Message]): explanation_parse_mode: Optional[str] = UNSET """Mode for parsing entities in the explanation. See `formatting options `_ for more details.""" explanation_entities: Optional[List[MessageEntity]] = None - """List of special entities that appear in the poll explanation, which can be specified instead of *parse_mode*""" + """A JSON-serialized list of special entities that appear in the poll explanation, which can be specified instead of *parse_mode*""" open_period: Optional[int] = None """Amount of time in seconds the poll will be active after creation, 5-600. Can't be used together with *close_date*.""" close_date: Optional[Union[datetime.datetime, datetime.timedelta, int]] = None diff --git a/aiogram/methods/send_video.py b/aiogram/methods/send_video.py index 81d15da6..6867f37b 100644 --- a/aiogram/methods/send_video.py +++ b/aiogram/methods/send_video.py @@ -44,7 +44,7 @@ class SendVideo(TelegramMethod[Message]): parse_mode: Optional[str] = UNSET """Mode for parsing entities in the video caption. See `formatting options `_ for more details.""" caption_entities: Optional[List[MessageEntity]] = None - """List of special entities that appear in the caption, which can be specified instead of *parse_mode*""" + """A JSON-serialized list of special entities that appear in the caption, which can be specified instead of *parse_mode*""" supports_streaming: Optional[bool] = None """Pass :code:`True`, if the uploaded video is suitable for streaming""" disable_notification: Optional[bool] = None diff --git a/aiogram/methods/send_voice.py b/aiogram/methods/send_voice.py index 7c765e8c..c991c12f 100644 --- a/aiogram/methods/send_voice.py +++ b/aiogram/methods/send_voice.py @@ -36,7 +36,7 @@ class SendVoice(TelegramMethod[Message]): parse_mode: Optional[str] = UNSET """Mode for parsing entities in the voice message caption. See `formatting options `_ for more details.""" caption_entities: Optional[List[MessageEntity]] = None - """List of special entities that appear in the caption, which can be specified instead of *parse_mode*""" + """A JSON-serialized list of special entities that appear in the caption, which can be specified instead of *parse_mode*""" duration: Optional[int] = None """Duration of the voice message in seconds""" disable_notification: Optional[bool] = None diff --git a/aiogram/methods/set_chat_description.py b/aiogram/methods/set_chat_description.py index ab4eff13..a4014f79 100644 --- a/aiogram/methods/set_chat_description.py +++ b/aiogram/methods/set_chat_description.py @@ -10,7 +10,7 @@ if TYPE_CHECKING: class SetChatDescription(TelegramMethod[bool]): """ - Use this method to change the description of a group, a supergroup or a channel. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns :code:`True` on success. + Use this method to change the description of a group, a supergroup or a channel. The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#setchatdescription """ diff --git a/aiogram/methods/set_chat_permissions.py b/aiogram/methods/set_chat_permissions.py index 58cd77b2..9ca0267f 100644 --- a/aiogram/methods/set_chat_permissions.py +++ b/aiogram/methods/set_chat_permissions.py @@ -11,7 +11,7 @@ if TYPE_CHECKING: class SetChatPermissions(TelegramMethod[bool]): """ - Use this method to set default chat permissions for all members. The bot must be an administrator in the group or a supergroup for this to work and must have the *can_restrict_members* admin rights. Returns :code:`True` on success. + Use this method to set default chat permissions for all members. The bot must be an administrator in the group or a supergroup for this to work and must have the *can_restrict_members* administrator rights. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#setchatpermissions """ @@ -21,7 +21,7 @@ class SetChatPermissions(TelegramMethod[bool]): chat_id: Union[int, str] """Unique identifier for the target chat or username of the target supergroup (in the format :code:`@supergroupusername`)""" permissions: ChatPermissions - """New default chat permissions""" + """A JSON-serialized object for new default chat permissions""" def build_request(self, bot: Bot) -> Request: data: Dict[str, Any] = self.dict() diff --git a/aiogram/methods/set_chat_photo.py b/aiogram/methods/set_chat_photo.py index 62d857bb..dc9aef57 100644 --- a/aiogram/methods/set_chat_photo.py +++ b/aiogram/methods/set_chat_photo.py @@ -11,7 +11,7 @@ if TYPE_CHECKING: class SetChatPhoto(TelegramMethod[bool]): """ - Use this method to set a new profile photo for the chat. Photos can't be changed for private chats. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns :code:`True` on success. + Use this method to set a new profile photo for the chat. Photos can't be changed for private chats. The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#setchatphoto """ diff --git a/aiogram/methods/set_chat_sticker_set.py b/aiogram/methods/set_chat_sticker_set.py index 639ac5dc..089083f6 100644 --- a/aiogram/methods/set_chat_sticker_set.py +++ b/aiogram/methods/set_chat_sticker_set.py @@ -10,7 +10,7 @@ if TYPE_CHECKING: class SetChatStickerSet(TelegramMethod[bool]): """ - Use this method to set a new group sticker set for a supergroup. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Use the field *can_set_sticker_set* optionally returned in :class:`aiogram.methods.get_chat.GetChat` requests to check if the bot can use this method. Returns :code:`True` on success. + Use this method to set a new group sticker set for a supergroup. The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. Use the field *can_set_sticker_set* optionally returned in :class:`aiogram.methods.get_chat.GetChat` requests to check if the bot can use this method. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#setchatstickerset """ diff --git a/aiogram/methods/set_chat_title.py b/aiogram/methods/set_chat_title.py index dfe2a7d5..c4793233 100644 --- a/aiogram/methods/set_chat_title.py +++ b/aiogram/methods/set_chat_title.py @@ -10,7 +10,7 @@ if TYPE_CHECKING: class SetChatTitle(TelegramMethod[bool]): """ - Use this method to change the title of a chat. Titles can't be changed for private chats. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns :code:`True` on success. + Use this method to change the title of a chat. Titles can't be changed for private chats. The bot must be an administrator in the chat for this to work and must have the appropriate administrator rights. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#setchattitle """ diff --git a/aiogram/methods/set_game_score.py b/aiogram/methods/set_game_score.py index 92063d7d..f1fe949b 100644 --- a/aiogram/methods/set_game_score.py +++ b/aiogram/methods/set_game_score.py @@ -11,7 +11,7 @@ if TYPE_CHECKING: class SetGameScore(TelegramMethod[Union[Message, bool]]): """ - Use this method to set the score of the specified user in a game. On success, if the message was sent by the bot, returns the edited :class:`aiogram.types.message.Message`, otherwise returns :code:`True`. Returns an error, if the new score is not greater than the user's current score in the chat and *force* is :code:`False`. + Use this method to set the score of the specified user in a game message. On success, if the message is not an inline message, the :class:`aiogram.types.message.Message` is returned, otherwise :code:`True` is returned. Returns an error, if the new score is not greater than the user's current score in the chat and *force* is :code:`False`. Source: https://core.telegram.org/bots/api#setgamescore """ @@ -23,9 +23,9 @@ class SetGameScore(TelegramMethod[Union[Message, bool]]): score: int """New score, must be non-negative""" force: Optional[bool] = None - """Pass True, if the high score is allowed to decrease. This can be useful when fixing mistakes or banning cheaters""" + """Pass :code:`True`, if the high score is allowed to decrease. This can be useful when fixing mistakes or banning cheaters""" disable_edit_message: Optional[bool] = None - """Pass True, if the game message should not be automatically edited to include the current scoreboard""" + """Pass :code:`True`, if the game message should not be automatically edited to include the current scoreboard""" chat_id: Optional[int] = None """Required if *inline_message_id* is not specified. Unique identifier for the target chat""" message_id: Optional[int] = None diff --git a/aiogram/methods/stop_message_live_location.py b/aiogram/methods/stop_message_live_location.py index 1909b57e..7b2ddca4 100644 --- a/aiogram/methods/stop_message_live_location.py +++ b/aiogram/methods/stop_message_live_location.py @@ -11,7 +11,7 @@ if TYPE_CHECKING: class StopMessageLiveLocation(TelegramMethod[Union[Message, bool]]): """ - Use this method to stop updating a live location message before *live_period* expires. On success, if the message was sent by the bot, the sent :class:`aiogram.types.message.Message` is returned, otherwise :code:`True` is returned. + Use this method to stop updating a live location message before *live_period* expires. On success, if the message is not an inline message, the edited :class:`aiogram.types.message.Message` is returned, otherwise :code:`True` is returned. Source: https://core.telegram.org/bots/api#stopmessagelivelocation """ diff --git a/aiogram/methods/stop_poll.py b/aiogram/methods/stop_poll.py index f36f18de..fa90766a 100644 --- a/aiogram/methods/stop_poll.py +++ b/aiogram/methods/stop_poll.py @@ -11,7 +11,7 @@ if TYPE_CHECKING: class StopPoll(TelegramMethod[Poll]): """ - Use this method to stop a poll which was sent by the bot. On success, the stopped :class:`aiogram.types.poll.Poll` with the final results is returned. + Use this method to stop a poll which was sent by the bot. On success, the stopped :class:`aiogram.types.poll.Poll` is returned. Source: https://core.telegram.org/bots/api#stoppoll """ diff --git a/aiogram/methods/unpin_all_chat_messages.py b/aiogram/methods/unpin_all_chat_messages.py index 13b06fe6..99a3a1f2 100644 --- a/aiogram/methods/unpin_all_chat_messages.py +++ b/aiogram/methods/unpin_all_chat_messages.py @@ -10,7 +10,7 @@ if TYPE_CHECKING: class UnpinAllChatMessages(TelegramMethod[bool]): """ - Use this method to clear the list of pinned messages in a chat. If the chat is not a private chat, the bot must be an administrator in the chat for this to work and must have the 'can_pin_messages' admin right in a supergroup or 'can_edit_messages' admin right in a channel. Returns :code:`True` on success. + Use this method to clear the list of pinned messages in a chat. If the chat is not a private chat, the bot must be an administrator in the chat for this to work and must have the 'can_pin_messages' administrator right in a supergroup or 'can_edit_messages' administrator right in a channel. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#unpinallchatmessages """ diff --git a/aiogram/methods/unpin_chat_message.py b/aiogram/methods/unpin_chat_message.py index b7ff0c48..098dba48 100644 --- a/aiogram/methods/unpin_chat_message.py +++ b/aiogram/methods/unpin_chat_message.py @@ -10,7 +10,7 @@ if TYPE_CHECKING: class UnpinChatMessage(TelegramMethod[bool]): """ - Use this method to remove a message from the list of pinned messages in a chat. If the chat is not a private chat, the bot must be an administrator in the chat for this to work and must have the 'can_pin_messages' admin right in a supergroup or 'can_edit_messages' admin right in a channel. Returns :code:`True` on success. + Use this method to remove a message from the list of pinned messages in a chat. If the chat is not a private chat, the bot must be an administrator in the chat for this to work and must have the 'can_pin_messages' administrator right in a supergroup or 'can_edit_messages' administrator right in a channel. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#unpinchatmessage """ diff --git a/aiogram/types/__init__.py b/aiogram/types/__init__.py index bfa7d6f8..ebf4c839 100644 --- a/aiogram/types/__init__.py +++ b/aiogram/types/__init__.py @@ -14,6 +14,7 @@ from .callback_game import CallbackGame from .callback_query import CallbackQuery from .chat import Chat from .chat_invite_link import ChatInviteLink +from .chat_join_request import ChatJoinRequest from .chat_location import ChatLocation from .chat_member import ChatMember from .chat_member_administrator import ChatMemberAdministrator @@ -181,6 +182,7 @@ __all__ = ( "ChatMemberLeft", "ChatMemberBanned", "ChatMemberUpdated", + "ChatJoinRequest", "ChatPermissions", "ChatLocation", "BotCommand", diff --git a/aiogram/types/animation.py b/aiogram/types/animation.py index 5cc59ff5..54c8f4d2 100644 --- a/aiogram/types/animation.py +++ b/aiogram/types/animation.py @@ -32,4 +32,4 @@ class Animation(TelegramObject): mime_type: Optional[str] = None """*Optional*. MIME type of the file as defined by sender""" file_size: Optional[int] = None - """*Optional*. File size""" + """*Optional*. File size in bytes""" diff --git a/aiogram/types/audio.py b/aiogram/types/audio.py index 9fb4b1b8..20c60abc 100644 --- a/aiogram/types/audio.py +++ b/aiogram/types/audio.py @@ -8,6 +8,7 @@ if TYPE_CHECKING: from .photo_size import PhotoSize +# === Generated region: Audio === class Audio(TelegramObject): """ This object represents an audio file to be treated as music by the Telegram clients. @@ -30,6 +31,9 @@ class Audio(TelegramObject): mime_type: Optional[str] = None """*Optional*. MIME type of the file as defined by sender""" file_size: Optional[int] = None - """*Optional*. File size""" + """*Optional*. File size in bytes""" thumb: Optional[PhotoSize] = None """*Optional*. Thumbnail of the album cover to which the music file belongs""" + + +# === End of generated region: Audio === diff --git a/aiogram/types/chat.py b/aiogram/types/chat.py index 7f17d9b5..b12fbd28 100644 --- a/aiogram/types/chat.py +++ b/aiogram/types/chat.py @@ -43,13 +43,13 @@ class Chat(TelegramObject): permissions: Optional[ChatPermissions] = None """*Optional*. Default chat member permissions, for groups and supergroups. Returned only in :class:`aiogram.methods.get_chat.GetChat`.""" slow_mode_delay: Optional[int] = None - """*Optional*. For supergroups, the minimum allowed delay between consecutive messages sent by each unpriviledged user. Returned only in :class:`aiogram.methods.get_chat.GetChat`.""" + """*Optional*. For supergroups, the minimum allowed delay between consecutive messages sent by each unpriviledged user; in seconds. Returned only in :class:`aiogram.methods.get_chat.GetChat`.""" message_auto_delete_time: Optional[int] = None """*Optional*. The time after which all messages sent to the chat will be automatically deleted; in seconds. Returned only in :class:`aiogram.methods.get_chat.GetChat`.""" sticker_set_name: Optional[str] = None """*Optional*. For supergroups, name of group sticker set. Returned only in :class:`aiogram.methods.get_chat.GetChat`.""" can_set_sticker_set: Optional[bool] = None - """*Optional*. True, if the bot can change the group sticker set. Returned only in :class:`aiogram.methods.get_chat.GetChat`.""" + """*Optional*. :code:`True`, if the bot can change the group sticker set. Returned only in :class:`aiogram.methods.get_chat.GetChat`.""" linked_chat_id: Optional[int] = None """*Optional*. Unique identifier for the linked chat, i.e. the discussion group identifier for a channel and vice versa; for supergroups and channel chats. This identifier may be greater than 32 bits and some programming languages may have difficulty/silent defects in interpreting it. But it is smaller than 52 bits, so a signed 64 bit integer or double-precision float type are safe for storing this identifier. Returned only in :class:`aiogram.methods.get_chat.GetChat`.""" location: Optional[ChatLocation] = None diff --git a/aiogram/types/chat_invite_link.py b/aiogram/types/chat_invite_link.py index 0d610424..e1f9fc25 100644 --- a/aiogram/types/chat_invite_link.py +++ b/aiogram/types/chat_invite_link.py @@ -19,11 +19,17 @@ class ChatInviteLink(TelegramObject): """The invite link. If the link was created by another chat administrator, then the second part of the link will be replaced with '…'.""" creator: User """Creator of the link""" + creates_join_request: bool + """:code:`True`, if users joining the chat via the link need to be approved by chat administrators""" is_primary: bool - """True, if the link is primary""" + """:code:`True`, if the link is primary""" is_revoked: bool - """True, if the link is revoked""" + """:code:`True`, if the link is revoked""" + name: Optional[str] = None + """*Optional*. Invite link name""" expire_date: Optional[int] = None """*Optional*. Point in time (Unix timestamp) when the link will expire or has been expired""" member_limit: Optional[int] = None """*Optional*. Maximum number of users that can be members of the chat simultaneously after joining the chat via this invite link; 1-99999""" + pending_join_request_count: Optional[int] = None + """*Optional*. Number of pending join requests created using this link""" diff --git a/aiogram/types/chat_join_request.py b/aiogram/types/chat_join_request.py new file mode 100644 index 00000000..b9c862ee --- /dev/null +++ b/aiogram/types/chat_join_request.py @@ -0,0 +1,57 @@ +from __future__ import annotations + +import datetime +from typing import TYPE_CHECKING, Optional + +from pydantic import Field + +from .base import TelegramObject + +if TYPE_CHECKING: + from ..methods import ApproveChatJoinRequest, DeclineChatJoinRequest + +if TYPE_CHECKING: + from .chat import Chat + from .chat_invite_link import ChatInviteLink + from .user import User + + +class ChatJoinRequest(TelegramObject): + """ + Represents a join request sent to a chat. + + Source: https://core.telegram.org/bots/api#chatjoinrequest + """ + + chat: Chat + """Chat to which the request was sent""" + from_user: User = Field(..., alias="from") + """User that sent the join request""" + date: datetime.datetime + """Date the request was sent in Unix time""" + bio: Optional[str] = None + """*Optional*. Bio of the user.""" + invite_link: Optional[ChatInviteLink] = None + """*Optional*. Chat invite link that was used by the user to send the join request""" + + def approve(self) -> ApproveChatJoinRequest: + """ + Use this method to approve a chat join request. + """ + from ..methods import ApproveChatJoinRequest + + return ApproveChatJoinRequest( + chat_id=self.chat.id, + user_id=self.from_user.id, + ) + + def decline(self) -> DeclineChatJoinRequest: + """ + Use this method to decline a chat join request. + """ + from ..methods import DeclineChatJoinRequest + + return DeclineChatJoinRequest( + chat_id=self.chat.id, + user_id=self.from_user.id, + ) diff --git a/aiogram/types/chat_member_administrator.py b/aiogram/types/chat_member_administrator.py index 4678284a..a27156f9 100644 --- a/aiogram/types/chat_member_administrator.py +++ b/aiogram/types/chat_member_administrator.py @@ -22,28 +22,28 @@ class ChatMemberAdministrator(ChatMember): user: User """Information about the user""" can_be_edited: bool - """True, if the bot is allowed to edit administrator privileges of that user""" + """:code:`True`, if the bot is allowed to edit administrator privileges of that user""" is_anonymous: bool - """True, if the user's presence in the chat is hidden""" + """:code:`True`, if the user's presence in the chat is hidden""" can_manage_chat: bool - """True, if the administrator can access the chat event log, chat statistics, message statistics in channels, see channel members, see anonymous administrators in supergroups and ignore slow mode. Implied by any other administrator privilege""" + """:code:`True`, if the administrator can access the chat event log, chat statistics, message statistics in channels, see channel members, see anonymous administrators in supergroups and ignore slow mode. Implied by any other administrator privilege""" can_delete_messages: bool - """True, if the administrator can delete messages of other users""" + """:code:`True`, if the administrator can delete messages of other users""" can_manage_voice_chats: bool - """True, if the administrator can manage voice chats""" + """:code:`True`, if the administrator can manage voice chats""" can_restrict_members: bool - """True, if the administrator can restrict, ban or unban chat members""" + """:code:`True`, if the administrator can restrict, ban or unban chat members""" can_promote_members: bool - """True, if the administrator can add new administrators with a subset of their own privileges or demote administrators that he has promoted, directly or indirectly (promoted by administrators that were appointed by the user)""" + """:code:`True`, if the administrator can add new administrators with a subset of their own privileges or demote administrators that he has promoted, directly or indirectly (promoted by administrators that were appointed by the user)""" can_change_info: bool - """True, if the user is allowed to change the chat title, photo and other settings""" + """:code:`True`, if the user is allowed to change the chat title, photo and other settings""" can_invite_users: bool - """True, if the user is allowed to invite new users to the chat""" + """:code:`True`, if the user is allowed to invite new users to the chat""" can_post_messages: Optional[bool] = None - """*Optional*. True, if the administrator can post in the channel; channels only""" + """*Optional*. :code:`True`, if the administrator can post in the channel; channels only""" can_edit_messages: Optional[bool] = None - """*Optional*. True, if the administrator can edit messages of other users and can pin messages; channels only""" + """*Optional*. :code:`True`, if the administrator can edit messages of other users and can pin messages; channels only""" can_pin_messages: Optional[bool] = None - """*Optional*. True, if the user is allowed to pin messages; groups and supergroups only""" + """*Optional*. :code:`True`, if the user is allowed to pin messages; groups and supergroups only""" custom_title: Optional[str] = None """*Optional*. Custom title for this user""" diff --git a/aiogram/types/chat_member_banned.py b/aiogram/types/chat_member_banned.py index d1004825..21b725e8 100644 --- a/aiogram/types/chat_member_banned.py +++ b/aiogram/types/chat_member_banned.py @@ -23,4 +23,4 @@ class ChatMemberBanned(ChatMember): user: User """Information about the user""" until_date: Union[datetime.datetime, datetime.timedelta, int] - """Date when restrictions will be lifted for this user; unix time""" + """Date when restrictions will be lifted for this user; unix time. If 0, then the user is banned forever""" diff --git a/aiogram/types/chat_member_owner.py b/aiogram/types/chat_member_owner.py index 3494af80..30853996 100644 --- a/aiogram/types/chat_member_owner.py +++ b/aiogram/types/chat_member_owner.py @@ -22,6 +22,6 @@ class ChatMemberOwner(ChatMember): user: User """Information about the user""" is_anonymous: bool - """True, if the user's presence in the chat is hidden""" + """:code:`True`, if the user's presence in the chat is hidden""" custom_title: Optional[str] = None """*Optional*. Custom title for this user""" diff --git a/aiogram/types/chat_member_restricted.py b/aiogram/types/chat_member_restricted.py index d2b694a7..7e244024 100644 --- a/aiogram/types/chat_member_restricted.py +++ b/aiogram/types/chat_member_restricted.py @@ -23,22 +23,22 @@ class ChatMemberRestricted(ChatMember): user: User """Information about the user""" is_member: bool - """True, if the user is a member of the chat at the moment of the request""" + """:code:`True`, if the user is a member of the chat at the moment of the request""" can_change_info: bool - """True, if the user is allowed to change the chat title, photo and other settings""" + """:code:`True`, if the user is allowed to change the chat title, photo and other settings""" can_invite_users: bool - """True, if the user is allowed to invite new users to the chat""" + """:code:`True`, if the user is allowed to invite new users to the chat""" can_pin_messages: bool - """True, if the user is allowed to pin messages; groups and supergroups only""" + """:code:`True`, if the user is allowed to pin messages""" can_send_messages: bool - """True, if the user is allowed to send text messages, contacts, locations and venues""" + """:code:`True`, if the user is allowed to send text messages, contacts, locations and venues""" can_send_media_messages: bool - """True, if the user is allowed to send audios, documents, photos, videos, video notes and voice notes""" + """:code:`True`, if the user is allowed to send audios, documents, photos, videos, video notes and voice notes""" can_send_polls: bool - """True, if the user is allowed to send polls""" + """:code:`True`, if the user is allowed to send polls""" can_send_other_messages: bool - """True, if the user is allowed to send animations, games, stickers and use inline bots""" + """:code:`True`, if the user is allowed to send animations, games, stickers and use inline bots""" can_add_web_page_previews: bool - """True, if the user is allowed to add web page previews to their messages""" + """:code:`True`, if the user is allowed to add web page previews to their messages""" until_date: Union[datetime.datetime, datetime.timedelta, int] - """Date when restrictions will be lifted for this user; unix time""" + """Date when restrictions will be lifted for this user; unix time. If 0, then the user is restricted forever""" diff --git a/aiogram/types/chat_permissions.py b/aiogram/types/chat_permissions.py index 348d5bbc..15ddaba4 100644 --- a/aiogram/types/chat_permissions.py +++ b/aiogram/types/chat_permissions.py @@ -13,18 +13,18 @@ class ChatPermissions(MutableTelegramObject): """ can_send_messages: Optional[bool] = None - """*Optional*. True, if the user is allowed to send text messages, contacts, locations and venues""" + """*Optional*. :code:`True`, if the user is allowed to send text messages, contacts, locations and venues""" can_send_media_messages: Optional[bool] = None - """*Optional*. True, if the user is allowed to send audios, documents, photos, videos, video notes and voice notes, implies can_send_messages""" + """*Optional*. :code:`True`, if the user is allowed to send audios, documents, photos, videos, video notes and voice notes, implies can_send_messages""" can_send_polls: Optional[bool] = None - """*Optional*. True, if the user is allowed to send polls, implies can_send_messages""" + """*Optional*. :code:`True`, if the user is allowed to send polls, implies can_send_messages""" can_send_other_messages: Optional[bool] = None - """*Optional*. True, if the user is allowed to send animations, games, stickers and use inline bots, implies can_send_media_messages""" + """*Optional*. :code:`True`, if the user is allowed to send animations, games, stickers and use inline bots, implies can_send_media_messages""" can_add_web_page_previews: Optional[bool] = None - """*Optional*. True, if the user is allowed to add web page previews to their messages, implies can_send_media_messages""" + """*Optional*. :code:`True`, if the user is allowed to add web page previews to their messages, implies can_send_media_messages""" can_change_info: Optional[bool] = None - """*Optional*. True, if the user is allowed to change the chat title, photo and other settings. Ignored in public supergroups""" + """*Optional*. :code:`True`, if the user is allowed to change the chat title, photo and other settings. Ignored in public supergroups""" can_invite_users: Optional[bool] = None - """*Optional*. True, if the user is allowed to invite new users to the chat""" + """*Optional*. :code:`True`, if the user is allowed to invite new users to the chat""" can_pin_messages: Optional[bool] = None - """*Optional*. True, if the user is allowed to pin messages. Ignored in public supergroups""" + """*Optional*. :code:`True`, if the user is allowed to pin messages. Ignored in public supergroups""" diff --git a/aiogram/types/document.py b/aiogram/types/document.py index a2eaa34b..377241d3 100644 --- a/aiogram/types/document.py +++ b/aiogram/types/document.py @@ -26,4 +26,4 @@ class Document(TelegramObject): mime_type: Optional[str] = None """*Optional*. MIME type of the file as defined by sender""" file_size: Optional[int] = None - """*Optional*. File size""" + """*Optional*. File size in bytes""" diff --git a/aiogram/types/file.py b/aiogram/types/file.py index 34ec4a8a..9a0e3206 100644 --- a/aiogram/types/file.py +++ b/aiogram/types/file.py @@ -19,6 +19,6 @@ class File(TelegramObject): file_unique_id: str """Unique identifier for this file, which is supposed to be the same over time and for different bots. Can't be used to download or reuse the file.""" file_size: Optional[int] = None - """*Optional*. File size, if known""" + """*Optional*. File size in bytes, if known""" file_path: Optional[str] = None """*Optional*. File path. Use :code:`https://api.telegram.org/file/bot/` to get the file.""" diff --git a/aiogram/types/inline_keyboard_button.py b/aiogram/types/inline_keyboard_button.py index 28cebcaa..2e4142ca 100644 --- a/aiogram/types/inline_keyboard_button.py +++ b/aiogram/types/inline_keyboard_button.py @@ -31,4 +31,4 @@ class InlineKeyboardButton(MutableTelegramObject): callback_game: Optional[CallbackGame] = None """*Optional*. Description of the game that will be launched when the user presses the button.""" pay: Optional[bool] = None - """*Optional*. Specify True, to send a `Pay button `_.""" + """*Optional*. Specify :code:`True`, to send a `Pay button `_.""" diff --git a/aiogram/types/inline_query_result_document.py b/aiogram/types/inline_query_result_document.py index 4e28ba91..40052009 100644 --- a/aiogram/types/inline_query_result_document.py +++ b/aiogram/types/inline_query_result_document.py @@ -44,7 +44,7 @@ class InlineQueryResultDocument(InlineQueryResult): input_message_content: Optional[InputMessageContent] = None """*Optional*. Content of the message to be sent instead of the file""" thumb_url: Optional[str] = None - """*Optional*. URL of the thumbnail (jpeg only) for the file""" + """*Optional*. URL of the thumbnail (JPEG only) for the file""" thumb_width: Optional[int] = None """*Optional*. Thumbnail width""" thumb_height: Optional[int] = None diff --git a/aiogram/types/inline_query_result_gif.py b/aiogram/types/inline_query_result_gif.py index 3832aec4..2946437c 100644 --- a/aiogram/types/inline_query_result_gif.py +++ b/aiogram/types/inline_query_result_gif.py @@ -33,7 +33,7 @@ class InlineQueryResultGif(InlineQueryResult): gif_height: Optional[int] = None """*Optional*. Height of the GIF""" gif_duration: Optional[int] = None - """*Optional*. Duration of the GIF""" + """*Optional*. Duration of the GIF in seconds""" thumb_mime_type: Optional[str] = None """*Optional*. MIME type of the thumbnail, must be one of 'image/jpeg', 'image/gif', or 'video/mp4'. Defaults to 'image/jpeg'""" title: Optional[str] = None diff --git a/aiogram/types/inline_query_result_mpeg4_gif.py b/aiogram/types/inline_query_result_mpeg4_gif.py index c301668d..dc93b16a 100644 --- a/aiogram/types/inline_query_result_mpeg4_gif.py +++ b/aiogram/types/inline_query_result_mpeg4_gif.py @@ -33,7 +33,7 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult): mpeg4_height: Optional[int] = None """*Optional*. Video height""" mpeg4_duration: Optional[int] = None - """*Optional*. Video duration""" + """*Optional*. Video duration in seconds""" thumb_mime_type: Optional[str] = None """*Optional*. MIME type of the thumbnail, must be one of 'image/jpeg', 'image/gif', or 'video/mp4'. Defaults to 'image/jpeg'""" title: Optional[str] = None diff --git a/aiogram/types/inline_query_result_photo.py b/aiogram/types/inline_query_result_photo.py index 158f1914..c150ace7 100644 --- a/aiogram/types/inline_query_result_photo.py +++ b/aiogram/types/inline_query_result_photo.py @@ -25,7 +25,7 @@ class InlineQueryResultPhoto(InlineQueryResult): id: str """Unique identifier for this result, 1-64 bytes""" photo_url: str - """A valid URL of the photo. Photo must be in **jpeg** format. Photo size must not exceed 5MB""" + """A valid URL of the photo. Photo must be in **JPEG** format. Photo size must not exceed 5MB""" thumb_url: str """URL of the thumbnail for the photo""" photo_width: Optional[int] = None diff --git a/aiogram/types/inline_query_result_video.py b/aiogram/types/inline_query_result_video.py index a1ed726e..3e8ef3f0 100644 --- a/aiogram/types/inline_query_result_video.py +++ b/aiogram/types/inline_query_result_video.py @@ -31,7 +31,7 @@ class InlineQueryResultVideo(InlineQueryResult): mime_type: str """Mime type of the content of video url, 'text/html' or 'video/mp4'""" thumb_url: str - """URL of the thumbnail (jpeg only) for the video""" + """URL of the thumbnail (JPEG only) for the video""" title: str """Title for the result""" caption: Optional[str] = None diff --git a/aiogram/types/input_media_animation.py b/aiogram/types/input_media_animation.py index 4f1f25b0..35f28509 100644 --- a/aiogram/types/input_media_animation.py +++ b/aiogram/types/input_media_animation.py @@ -36,4 +36,4 @@ class InputMediaAnimation(InputMedia): height: Optional[int] = None """*Optional*. Animation height""" duration: Optional[int] = None - """*Optional*. Animation duration""" + """*Optional*. Animation duration in seconds""" diff --git a/aiogram/types/input_media_document.py b/aiogram/types/input_media_document.py index 72552ab6..f8b3b681 100644 --- a/aiogram/types/input_media_document.py +++ b/aiogram/types/input_media_document.py @@ -32,4 +32,4 @@ class InputMediaDocument(InputMedia): caption_entities: Optional[List[MessageEntity]] = None """*Optional*. List of special entities that appear in the caption, which can be specified instead of *parse_mode*""" disable_content_type_detection: Optional[bool] = None - """*Optional*. Disables automatic server-side content type detection for files uploaded using multipart/form-data. Always true, if the document is sent as part of an album.""" + """*Optional*. Disables automatic server-side content type detection for files uploaded using multipart/form-data. Always :code:`True`, if the document is sent as part of an album.""" diff --git a/aiogram/types/input_media_video.py b/aiogram/types/input_media_video.py index cd32ee2c..b66a16c3 100644 --- a/aiogram/types/input_media_video.py +++ b/aiogram/types/input_media_video.py @@ -36,6 +36,6 @@ class InputMediaVideo(InputMedia): height: Optional[int] = None """*Optional*. Video height""" duration: Optional[int] = None - """*Optional*. Video duration""" + """*Optional*. Video duration in seconds""" supports_streaming: Optional[bool] = None """*Optional*. Pass :code:`True`, if the uploaded video is suitable for streaming""" diff --git a/aiogram/types/location.py b/aiogram/types/location.py index e86c56f3..2c4a1f88 100644 --- a/aiogram/types/location.py +++ b/aiogram/types/location.py @@ -19,7 +19,7 @@ class Location(TelegramObject): horizontal_accuracy: Optional[float] = None """*Optional*. The radius of uncertainty for the location, measured in meters; 0-1500""" live_period: Optional[int] = None - """*Optional*. Time relative to the message sending date, during which the location can be updated, in seconds. For active live locations only.""" + """*Optional*. Time relative to the message sending date, during which the location can be updated; in seconds. For active live locations only.""" heading: Optional[int] = None """*Optional*. The direction in which user is moving, in degrees; 1-360. For active live locations only.""" proximity_alert_radius: Optional[int] = None diff --git a/aiogram/types/login_url.py b/aiogram/types/login_url.py index ff969643..f367845e 100644 --- a/aiogram/types/login_url.py +++ b/aiogram/types/login_url.py @@ -22,4 +22,4 @@ class LoginUrl(TelegramObject): bot_username: Optional[str] = None """*Optional*. Username of a bot, which will be used for user authorization. See `Setting up a bot `_ for more details. If not specified, the current bot's username will be assumed. The *url*'s domain must be the same as the domain linked with the bot. See `Linking your domain to the bot `_ for more details.""" request_write_access: Optional[bool] = None - """*Optional*. Pass True to request the permission for your bot to send messages to the user.""" + """*Optional*. Pass :code:`True` to request the permission for your bot to send messages to the user.""" diff --git a/aiogram/types/message_auto_delete_timer_changed.py b/aiogram/types/message_auto_delete_timer_changed.py index ed5a251f..4957f08e 100644 --- a/aiogram/types/message_auto_delete_timer_changed.py +++ b/aiogram/types/message_auto_delete_timer_changed.py @@ -11,4 +11,4 @@ class MessageAutoDeleteTimerChanged(TelegramObject): """ message_auto_delete_time: int - """New auto-delete time for messages in the chat""" + """New auto-delete time for messages in the chat; in seconds""" diff --git a/aiogram/types/passport_file.py b/aiogram/types/passport_file.py index 4ec8b6ec..11a388f8 100644 --- a/aiogram/types/passport_file.py +++ b/aiogram/types/passport_file.py @@ -15,6 +15,6 @@ class PassportFile(TelegramObject): file_unique_id: str """Unique identifier for this file, which is supposed to be the same over time and for different bots. Can't be used to download or reuse the file.""" file_size: int - """File size""" + """File size in bytes""" file_date: int """Unix time when the file was uploaded""" diff --git a/aiogram/types/photo_size.py b/aiogram/types/photo_size.py index 2bc2e5b1..0b23b377 100644 --- a/aiogram/types/photo_size.py +++ b/aiogram/types/photo_size.py @@ -21,4 +21,4 @@ class PhotoSize(TelegramObject): height: int """Photo height""" file_size: Optional[int] = None - """*Optional*. File size""" + """*Optional*. File size in bytes""" diff --git a/aiogram/types/poll.py b/aiogram/types/poll.py index 70142353..2301235d 100644 --- a/aiogram/types/poll.py +++ b/aiogram/types/poll.py @@ -26,13 +26,13 @@ class Poll(TelegramObject): total_voter_count: int """Total number of users that voted in the poll""" is_closed: bool - """True, if the poll is closed""" + """:code:`True`, if the poll is closed""" is_anonymous: bool - """True, if the poll is anonymous""" + """:code:`True`, if the poll is anonymous""" type: str """Poll type, currently can be 'regular' or 'quiz'""" allows_multiple_answers: bool - """True, if the poll allows multiple answers""" + """:code:`True`, if the poll allows multiple answers""" correct_option_id: Optional[int] = None """*Optional*. 0-based identifier of the correct answer option. Available only for polls in the quiz mode, which are closed, or was sent (not forwarded) by the bot or to the private chat with the bot.""" explanation: Optional[str] = None diff --git a/aiogram/types/sticker.py b/aiogram/types/sticker.py index be5fc10a..2379d547 100644 --- a/aiogram/types/sticker.py +++ b/aiogram/types/sticker.py @@ -35,4 +35,4 @@ class Sticker(TelegramObject): mask_position: Optional[MaskPosition] = None """*Optional*. For mask stickers, the position where the mask should be placed""" file_size: Optional[int] = None - """*Optional*. File size""" + """*Optional*. File size in bytes""" diff --git a/aiogram/types/update.py b/aiogram/types/update.py index e567894f..493d95d5 100644 --- a/aiogram/types/update.py +++ b/aiogram/types/update.py @@ -7,6 +7,7 @@ from .base import TelegramObject if TYPE_CHECKING: from .callback_query import CallbackQuery + from .chat_join_request import ChatJoinRequest from .chat_member_updated import ChatMemberUpdated from .chosen_inline_result import ChosenInlineResult from .inline_query import InlineQuery @@ -54,6 +55,8 @@ class Update(TelegramObject): """*Optional*. The bot's chat member status was updated in a chat. For private chats, this update is received only when the bot is blocked or unblocked by the user.""" chat_member: Optional[ChatMemberUpdated] = None """*Optional*. A chat member's status was updated in a chat. The bot must be an administrator in the chat and must explicitly specify 'chat_member' in the list of *allowed_updates* to receive these updates.""" + chat_join_request: Optional[ChatJoinRequest] = None + """*Optional*. A request to join the chat has been sent. The bot must have the *can_invite_users* administrator right in the chat to receive these updates.""" def __hash__(self) -> int: return hash((type(self), self.update_id)) @@ -93,6 +96,8 @@ class Update(TelegramObject): return "my_chat_member" if self.chat_member: return "chat_member" + if self.chat_join_request: + return "chat_join_request" raise UpdateTypeLookupError("Update does not contain any known event type.") diff --git a/aiogram/types/user.py b/aiogram/types/user.py index 4d65ce71..3f700040 100644 --- a/aiogram/types/user.py +++ b/aiogram/types/user.py @@ -15,7 +15,7 @@ class User(TelegramObject): id: int """Unique identifier for this user or bot. This number may have more than 32 significant bits and some programming languages may have difficulty/silent defects in interpreting it. But it has at most 52 significant bits, so a 64-bit integer or double-precision float type are safe for storing this identifier.""" is_bot: bool - """True, if this user is a bot""" + """:code:`True`, if this user is a bot""" first_name: str """User's or bot's first name""" last_name: Optional[str] = None @@ -25,11 +25,11 @@ class User(TelegramObject): language_code: Optional[str] = None """*Optional*. `IETF language tag `_ of the user's language""" can_join_groups: Optional[bool] = None - """*Optional*. True, if the bot can be invited to groups. Returned only in :class:`aiogram.methods.get_me.GetMe`.""" + """*Optional*. :code:`True`, if the bot can be invited to groups. Returned only in :class:`aiogram.methods.get_me.GetMe`.""" can_read_all_group_messages: Optional[bool] = None - """*Optional*. True, if `privacy mode `_ is disabled for the bot. Returned only in :class:`aiogram.methods.get_me.GetMe`.""" + """*Optional*. :code:`True`, if `privacy mode `_ is disabled for the bot. Returned only in :class:`aiogram.methods.get_me.GetMe`.""" supports_inline_queries: Optional[bool] = None - """*Optional*. True, if the bot supports inline queries. Returned only in :class:`aiogram.methods.get_me.GetMe`.""" + """*Optional*. :code:`True`, if the bot supports inline queries. Returned only in :class:`aiogram.methods.get_me.GetMe`.""" @property def full_name(self) -> str: diff --git a/aiogram/types/video.py b/aiogram/types/video.py index de0a22c3..f245c53c 100644 --- a/aiogram/types/video.py +++ b/aiogram/types/video.py @@ -32,4 +32,4 @@ class Video(TelegramObject): mime_type: Optional[str] = None """*Optional*. Mime type of a file as defined by sender""" file_size: Optional[int] = None - """*Optional*. File size""" + """*Optional*. File size in bytes""" diff --git a/aiogram/types/video_note.py b/aiogram/types/video_note.py index 6356bfdc..c2488336 100644 --- a/aiogram/types/video_note.py +++ b/aiogram/types/video_note.py @@ -26,4 +26,4 @@ class VideoNote(TelegramObject): thumb: Optional[PhotoSize] = None """*Optional*. Video thumbnail""" file_size: Optional[int] = None - """*Optional*. File size""" + """*Optional*. File size in bytes""" diff --git a/aiogram/types/voice.py b/aiogram/types/voice.py index 79fd8d6f..ed940ce8 100644 --- a/aiogram/types/voice.py +++ b/aiogram/types/voice.py @@ -21,4 +21,4 @@ class Voice(TelegramObject): mime_type: Optional[str] = None """*Optional*. MIME type of the file as defined by sender""" file_size: Optional[int] = None - """*Optional*. File size""" + """*Optional*. File size in bytes""" diff --git a/aiogram/types/voice_chat_ended.py b/aiogram/types/voice_chat_ended.py index 2b1ae161..12c705c9 100644 --- a/aiogram/types/voice_chat_ended.py +++ b/aiogram/types/voice_chat_ended.py @@ -11,4 +11,4 @@ class VoiceChatEnded(TelegramObject): """ duration: int - """Voice chat duration; in seconds""" + """Voice chat duration in seconds""" diff --git a/aiogram/types/webhook_info.py b/aiogram/types/webhook_info.py index b6f4747d..956c99fb 100644 --- a/aiogram/types/webhook_info.py +++ b/aiogram/types/webhook_info.py @@ -15,7 +15,7 @@ class WebhookInfo(TelegramObject): url: str """Webhook URL, may be empty if webhook is not set up""" has_custom_certificate: bool - """True, if a custom certificate was provided for webhook certificate checks""" + """:code:`True`, if a custom certificate was provided for webhook certificate checks""" pending_update_count: int """Number of updates awaiting delivery""" ip_address: Optional[str] = None diff --git a/docs/api/methods/approve_chat_join_request.rst b/docs/api/methods/approve_chat_join_request.rst new file mode 100644 index 00000000..8ac4643a --- /dev/null +++ b/docs/api/methods/approve_chat_join_request.rst @@ -0,0 +1,51 @@ +###################### +approveChatJoinRequest +###################### + +Returns: :obj:`bool` + +.. automodule:: aiogram.methods.approve_chat_join_request + :members: + :member-order: bysource + :undoc-members: True + + +Usage +===== + +As bot method +------------- + +.. code-block:: + + result: bool = await bot.approve_chat_join_request(...) + + +Method as object +---------------- + +Imports: + +- :code:`from aiogram.methods.approve_chat_join_request import ApproveChatJoinRequest` +- alias: :code:`from aiogram.methods import ApproveChatJoinRequest` + +In handlers with current bot +---------------------------- + +.. code-block:: python + + result: bool = await ApproveChatJoinRequest(...) + +With specific bot +~~~~~~~~~~~~~~~~~ + +.. code-block:: python + + result: bool = await bot(ApproveChatJoinRequest(...)) + +As reply into Webhook in handler +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: python + + return ApproveChatJoinRequest(...) diff --git a/docs/api/methods/decline_chat_join_request.rst b/docs/api/methods/decline_chat_join_request.rst new file mode 100644 index 00000000..f367ec36 --- /dev/null +++ b/docs/api/methods/decline_chat_join_request.rst @@ -0,0 +1,51 @@ +###################### +declineChatJoinRequest +###################### + +Returns: :obj:`bool` + +.. automodule:: aiogram.methods.decline_chat_join_request + :members: + :member-order: bysource + :undoc-members: True + + +Usage +===== + +As bot method +------------- + +.. code-block:: + + result: bool = await bot.decline_chat_join_request(...) + + +Method as object +---------------- + +Imports: + +- :code:`from aiogram.methods.decline_chat_join_request import DeclineChatJoinRequest` +- alias: :code:`from aiogram.methods import DeclineChatJoinRequest` + +In handlers with current bot +---------------------------- + +.. code-block:: python + + result: bool = await DeclineChatJoinRequest(...) + +With specific bot +~~~~~~~~~~~~~~~~~ + +.. code-block:: python + + result: bool = await bot(DeclineChatJoinRequest(...)) + +As reply into Webhook in handler +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: python + + return DeclineChatJoinRequest(...) diff --git a/docs/api/methods/get_chat_administrators.rst b/docs/api/methods/get_chat_administrators.rst index 39bc46ee..558c948a 100644 --- a/docs/api/methods/get_chat_administrators.rst +++ b/docs/api/methods/get_chat_administrators.rst @@ -2,7 +2,7 @@ getChatAdministrators ##################### -Returns: :obj:`List[ChatMember]` +Returns: :obj:`List[Union[ChatMemberOwner, ChatMemberAdministrator, ChatMemberMember, ChatMemberRestricted, ChatMemberLeft, ChatMemberBanned]]` .. automodule:: aiogram.methods.get_chat_administrators :members: @@ -18,7 +18,7 @@ As bot method .. code-block:: - result: List[ChatMember] = await bot.get_chat_administrators(...) + result: List[Union[ChatMemberOwner, ChatMemberAdministrator, ChatMemberMember, ChatMemberRestricted, ChatMemberLeft, ChatMemberBanned]] = await bot.get_chat_administrators(...) Method as object @@ -34,11 +34,11 @@ In handlers with current bot .. code-block:: python - result: List[ChatMember] = await GetChatAdministrators(...) + result: List[Union[ChatMemberOwner, ChatMemberAdministrator, ChatMemberMember, ChatMemberRestricted, ChatMemberLeft, ChatMemberBanned]] = await GetChatAdministrators(...) With specific bot ~~~~~~~~~~~~~~~~~ .. code-block:: python - result: List[ChatMember] = await bot(GetChatAdministrators(...)) + result: List[Union[ChatMemberOwner, ChatMemberAdministrator, ChatMemberMember, ChatMemberRestricted, ChatMemberLeft, ChatMemberBanned]] = await bot(GetChatAdministrators(...)) diff --git a/docs/api/methods/get_chat_member.rst b/docs/api/methods/get_chat_member.rst index 0fcf67d3..13b58321 100644 --- a/docs/api/methods/get_chat_member.rst +++ b/docs/api/methods/get_chat_member.rst @@ -2,7 +2,7 @@ getChatMember ############# -Returns: :obj:`ChatMember` +Returns: :obj:`Union[ChatMemberOwner, ChatMemberAdministrator, ChatMemberMember, ChatMemberRestricted, ChatMemberLeft, ChatMemberBanned]` .. automodule:: aiogram.methods.get_chat_member :members: @@ -18,7 +18,7 @@ As bot method .. code-block:: - result: ChatMember = await bot.get_chat_member(...) + result: Union[ChatMemberOwner, ChatMemberAdministrator, ChatMemberMember, ChatMemberRestricted, ChatMemberLeft, ChatMemberBanned] = await bot.get_chat_member(...) Method as object @@ -34,11 +34,11 @@ In handlers with current bot .. code-block:: python - result: ChatMember = await GetChatMember(...) + result: Union[ChatMemberOwner, ChatMemberAdministrator, ChatMemberMember, ChatMemberRestricted, ChatMemberLeft, ChatMemberBanned] = await GetChatMember(...) With specific bot ~~~~~~~~~~~~~~~~~ .. code-block:: python - result: ChatMember = await bot(GetChatMember(...)) + result: Union[ChatMemberOwner, ChatMemberAdministrator, ChatMemberMember, ChatMemberRestricted, ChatMemberLeft, ChatMemberBanned] = await bot(GetChatMember(...)) diff --git a/docs/api/methods/index.rst b/docs/api/methods/index.rst index 22fbff3e..4d9735a5 100644 --- a/docs/api/methods/index.rst +++ b/docs/api/methods/index.rst @@ -59,6 +59,8 @@ Available methods create_chat_invite_link edit_chat_invite_link revoke_chat_invite_link + approve_chat_join_request + decline_chat_join_request set_chat_photo delete_chat_photo set_chat_title diff --git a/docs/api/types/chat_join_request.rst b/docs/api/types/chat_join_request.rst new file mode 100644 index 00000000..236a472a --- /dev/null +++ b/docs/api/types/chat_join_request.rst @@ -0,0 +1,9 @@ +############### +ChatJoinRequest +############### + + +.. automodule:: aiogram.types.chat_join_request + :members: + :member-order: bysource + :undoc-members: True diff --git a/docs/api/types/index.rst b/docs/api/types/index.rst index 2309261b..f9b1bfc2 100644 --- a/docs/api/types/index.rst +++ b/docs/api/types/index.rst @@ -67,6 +67,7 @@ Available types chat_member_left chat_member_banned chat_member_updated + chat_join_request chat_permissions chat_location bot_command diff --git a/tests/test_api/test_methods/test_approve_chat_join_request.py b/tests/test_api/test_methods/test_approve_chat_join_request.py new file mode 100644 index 00000000..52d6554a --- /dev/null +++ b/tests/test_api/test_methods/test_approve_chat_join_request.py @@ -0,0 +1,30 @@ +import pytest + +from aiogram.methods import ApproveChatJoinRequest, Request +from tests.mocked_bot import MockedBot + + +class TestApproveChatJoinRequest: + @pytest.mark.asyncio + async def test_method(self, bot: MockedBot): + prepare_result = bot.add_result_for(ApproveChatJoinRequest, ok=True, result=True) + + response: bool = await ApproveChatJoinRequest( + chat_id=-42, + user_id=42, + ) + request: Request = bot.get_request() + assert request.method == "approveChatJoinRequest" + assert response == prepare_result.result + + @pytest.mark.asyncio + async def test_bot_method(self, bot: MockedBot): + prepare_result = bot.add_result_for(ApproveChatJoinRequest, ok=True, result=None) + + response: bool = await bot.approve_chat_join_request( + chat_id=-42, + user_id=42, + ) + request: Request = bot.get_request() + assert request.method == "approveChatJoinRequest" + assert response == prepare_result.result diff --git a/tests/test_api/test_methods/test_create_chat_invite_link.py b/tests/test_api/test_methods/test_create_chat_invite_link.py index 0241a60c..c07c55bc 100644 --- a/tests/test_api/test_methods/test_create_chat_invite_link.py +++ b/tests/test_api/test_methods/test_create_chat_invite_link.py @@ -17,6 +17,7 @@ class TestCreateChatInviteLink: creator=User(id=42, is_bot=False, first_name="User"), is_primary=False, is_revoked=False, + creates_join_request=False, ), ) @@ -37,6 +38,7 @@ class TestCreateChatInviteLink: creator=User(id=42, is_bot=False, first_name="User"), is_primary=False, is_revoked=False, + creates_join_request=False, ), ) diff --git a/tests/test_api/test_methods/test_decline_chat_join_request.py b/tests/test_api/test_methods/test_decline_chat_join_request.py new file mode 100644 index 00000000..e6e60ca5 --- /dev/null +++ b/tests/test_api/test_methods/test_decline_chat_join_request.py @@ -0,0 +1,30 @@ +import pytest + +from aiogram.methods import DeclineChatJoinRequest, Request +from tests.mocked_bot import MockedBot + + +class TestDeclineChatJoinRequest: + @pytest.mark.asyncio + async def test_method(self, bot: MockedBot): + prepare_result = bot.add_result_for(DeclineChatJoinRequest, ok=True, result=True) + + response: bool = await DeclineChatJoinRequest( + chat_id=-42, + user_id=42, + ) + request: Request = bot.get_request() + assert request.method == "declineChatJoinRequest" + assert response == prepare_result.result + + @pytest.mark.asyncio + async def test_bot_method(self, bot: MockedBot): + prepare_result = bot.add_result_for(DeclineChatJoinRequest, ok=True, result=True) + + response: bool = await bot.decline_chat_join_request( + chat_id=-42, + user_id=42, + ) + request: Request = bot.get_request() + assert request.method == "declineChatJoinRequest" + assert response == prepare_result.result diff --git a/tests/test_api/test_methods/test_edit_chat_invite_link.py b/tests/test_api/test_methods/test_edit_chat_invite_link.py index b0c055c7..a1fd6a10 100644 --- a/tests/test_api/test_methods/test_edit_chat_invite_link.py +++ b/tests/test_api/test_methods/test_edit_chat_invite_link.py @@ -17,6 +17,7 @@ class TestEditChatInviteLink: creator=User(id=42, is_bot=False, first_name="User"), is_primary=False, is_revoked=False, + creates_join_request=False, ), ) @@ -25,7 +26,6 @@ class TestEditChatInviteLink: ) request: Request = bot.get_request() assert request.method == "editChatInviteLink" - # assert request.data == {} assert response == prepare_result.result async def test_bot_method(self, bot: MockedBot): @@ -37,6 +37,7 @@ class TestEditChatInviteLink: creator=User(id=42, is_bot=False, first_name="User"), is_primary=False, is_revoked=False, + creates_join_request=False, ), ) @@ -45,5 +46,4 @@ class TestEditChatInviteLink: ) request: Request = bot.get_request() assert request.method == "editChatInviteLink" - # assert request.data == {} assert response == prepare_result.result diff --git a/tests/test_api/test_methods/test_revoke_chat_invite_link.py b/tests/test_api/test_methods/test_revoke_chat_invite_link.py index fc30ff69..b26b5d11 100644 --- a/tests/test_api/test_methods/test_revoke_chat_invite_link.py +++ b/tests/test_api/test_methods/test_revoke_chat_invite_link.py @@ -17,6 +17,7 @@ class TestRevokeChatInviteLink: creator=User(id=42, is_bot=False, first_name="User"), is_primary=False, is_revoked=True, + creates_join_request=False, ), ) @@ -26,7 +27,6 @@ class TestRevokeChatInviteLink: ) request: Request = bot.get_request() assert request.method == "revokeChatInviteLink" - # assert request.data == {} assert response == prepare_result.result async def test_bot_method(self, bot: MockedBot): @@ -38,6 +38,7 @@ class TestRevokeChatInviteLink: creator=User(id=42, is_bot=False, first_name="User"), is_primary=False, is_revoked=True, + creates_join_request=False, ), ) @@ -47,5 +48,4 @@ class TestRevokeChatInviteLink: ) request: Request = bot.get_request() assert request.method == "revokeChatInviteLink" - # assert request.data == {} assert response == prepare_result.result diff --git a/tests/test_api/test_types/test_chat_join_request.py b/tests/test_api/test_types/test_chat_join_request.py new file mode 100644 index 00000000..b5d124a3 --- /dev/null +++ b/tests/test_api/test_types/test_chat_join_request.py @@ -0,0 +1,32 @@ +import datetime + +from aiogram.methods import ApproveChatJoinRequest, DeclineChatJoinRequest +from aiogram.types import Chat, ChatJoinRequest, User + + +class TestChatJoinRequest: + def test_approve_alias(self): + chat_join_request = ChatJoinRequest( + chat=Chat(id=-42, type="supergroup"), + from_user=User(id=42, is_bot=False, first_name="Test"), + date=datetime.datetime.now(), + ) + + api_method = chat_join_request.approve() + + assert isinstance(api_method, ApproveChatJoinRequest) + assert api_method.chat_id == chat_join_request.chat.id + assert api_method.user_id == chat_join_request.from_user.id + + def test_decline_alias(self): + chat_join_request = ChatJoinRequest( + chat=Chat(id=-42, type="supergroup"), + from_user=User(id=42, is_bot=False, first_name="Test"), + date=datetime.datetime.now(), + ) + + api_method = chat_join_request.decline() + + assert isinstance(api_method, DeclineChatJoinRequest) + assert api_method.chat_id == chat_join_request.chat.id + assert api_method.user_id == chat_join_request.from_user.id diff --git a/tests/test_dispatcher/test_dispatcher.py b/tests/test_dispatcher/test_dispatcher.py index 30f10970..f04ba06a 100644 --- a/tests/test_dispatcher/test_dispatcher.py +++ b/tests/test_dispatcher/test_dispatcher.py @@ -15,6 +15,7 @@ from aiogram.methods import GetMe, GetUpdates, SendMessage from aiogram.types import ( CallbackQuery, Chat, + ChatJoinRequest, ChatMemberMember, ChatMemberUpdated, ChosenInlineResult, @@ -418,6 +419,19 @@ class TestDispatcher: True, True, ), + pytest.param( + "chat_join_request", + Update( + update_id=42, + chat_join_request=ChatJoinRequest( + chat=Chat(id=42, type="private"), + from_user=User(id=42, is_bot=False, first_name="Test"), + date=datetime.datetime.now(), + ), + ), + True, + True, + ), ], ) async def test_listen_update(