From 251df4b193e993adb7dd3c49935645643f990d2c Mon Sep 17 00:00:00 2001 From: JRoot Junior Date: Mon, 2 Mar 2026 01:34:08 +0200 Subject: [PATCH] Update API methods and types for Telegram Bot API 9.5 --- .apiversion | 2 +- .../methods/editMessageChecklist/entity.json | 4 +- .../methods/promoteChatMember/entity.json | 8 + .butcher/methods/sendChecklist/entity.json | 4 +- .butcher/methods/sendMessageDraft/entity.json | 6 +- .butcher/methods/setChatMemberTag/entity.json | 41 +++++ .butcher/schema/schema.json | 158 +++++++++++++++--- .../types/ChatAdministratorRights/entity.json | 8 + .../types/ChatMemberAdministrator/entity.json | 8 + .butcher/types/ChatMemberMember/entity.json | 8 + .../types/ChatMemberRestricted/entity.json | 16 ++ .butcher/types/ChatPermissions/entity.json | 8 + .butcher/types/GameHighScore/entity.json | 6 +- .../InlineQueryResultDocument/entity.json | 4 +- .butcher/types/Message/entity.json | 18 +- .butcher/types/MessageEntity/entity.json | 22 ++- README.rst | 2 +- aiogram/__meta__.py | 4 +- aiogram/client/bot.py | 36 +++- aiogram/enums/content_type.py | 1 + aiogram/enums/message_entity_type.py | 1 + aiogram/methods/__init__.py | 2 + aiogram/methods/edit_message_checklist.py | 2 +- aiogram/methods/promote_chat_member.py | 4 + aiogram/methods/send_checklist.py | 2 +- aiogram/methods/send_message_draft.py | 2 +- aiogram/methods/set_chat_member_tag.py | 40 +++++ aiogram/types/chat.py | 3 + aiogram/types/chat_administrator_rights.py | 4 + aiogram/types/chat_member_administrator.py | 4 + aiogram/types/chat_member_member.py | 7 +- aiogram/types/chat_member_restricted.py | 8 + aiogram/types/chat_permissions.py | 4 + aiogram/types/game_high_score.py | 2 - aiogram/types/inline_query_result_document.py | 2 +- aiogram/types/message.py | 8 +- aiogram/types/message_entity.py | 10 +- aiogram/utils/formatting.py | 22 +++ aiogram/utils/text_decorations.py | 102 +++++++++-- docs/api/methods/get_user_profile_audios.rst | 8 + docs/api/methods/index.rst | 1 + docs/api/methods/set_chat_member_tag.rst | 45 +++++ 42 files changed, 575 insertions(+), 72 deletions(-) create mode 100644 .butcher/methods/setChatMemberTag/entity.json create mode 100644 aiogram/methods/set_chat_member_tag.py create mode 100644 docs/api/methods/set_chat_member_tag.rst diff --git a/.apiversion b/.apiversion index 0359f243..592f36ef 100644 --- a/.apiversion +++ b/.apiversion @@ -1 +1 @@ -9.4 +9.5 diff --git a/.butcher/methods/editMessageChecklist/entity.json b/.butcher/methods/editMessageChecklist/entity.json index 9b5912c5..1c75a0bd 100644 --- a/.butcher/methods/editMessageChecklist/entity.json +++ b/.butcher/methods/editMessageChecklist/entity.json @@ -47,8 +47,8 @@ "type": "InlineKeyboardMarkup", "required": false, "description": "A JSON-serialized object for the new inline keyboard for the message", - "html_description": "A JSON-serialized object for the new inline keyboard for the message", - "rst_description": "A JSON-serialized object for the new inline keyboard for the message\n", + "html_description": "A JSON-serialized object for the new inline keyboard for the message", + "rst_description": "A JSON-serialized object for the new `inline keyboard `_ for the message\n", "name": "reply_markup" } ], diff --git a/.butcher/methods/promoteChatMember/entity.json b/.butcher/methods/promoteChatMember/entity.json index 4f0e4480..5495c781 100644 --- a/.butcher/methods/promoteChatMember/entity.json +++ b/.butcher/methods/promoteChatMember/entity.json @@ -154,6 +154,14 @@ "html_description": "Pass True if the administrator can manage direct messages within the channel and decline suggested posts; for channels only", "rst_description": "Pass :code:`True` if the administrator can manage direct messages within the channel and decline suggested posts; for channels only\n", "name": "can_manage_direct_messages" + }, + { + "type": "Boolean", + "required": false, + "description": "Pass True if the administrator can edit the tags of regular members; for groups and supergroups only", + "html_description": "Pass True if the administrator can edit the tags of regular members; for groups and supergroups only", + "rst_description": "Pass :code:`True` if the administrator can edit the tags of regular members; for groups and supergroups only\n", + "name": "can_manage_tags" } ], "category": "methods" diff --git a/.butcher/methods/sendChecklist/entity.json b/.butcher/methods/sendChecklist/entity.json index 119ee882..31161ac7 100644 --- a/.butcher/methods/sendChecklist/entity.json +++ b/.butcher/methods/sendChecklist/entity.json @@ -71,8 +71,8 @@ "type": "InlineKeyboardMarkup", "required": false, "description": "A JSON-serialized object for an inline keyboard", - "html_description": "A JSON-serialized object for an inline keyboard", - "rst_description": "A JSON-serialized object for an inline keyboard\n", + "html_description": "A JSON-serialized object for an inline keyboard", + "rst_description": "A JSON-serialized object for an `inline keyboard `_\n", "name": "reply_markup" } ], diff --git a/.butcher/methods/sendMessageDraft/entity.json b/.butcher/methods/sendMessageDraft/entity.json index 5d64e874..b84bc368 100644 --- a/.butcher/methods/sendMessageDraft/entity.json +++ b/.butcher/methods/sendMessageDraft/entity.json @@ -7,9 +7,9 @@ "object": { "anchor": "sendmessagedraft", "name": "sendMessageDraft", - "description": "Use this method to stream a partial message to a user while the message is being generated; supported only for bots with forum topic mode enabled. Returns True on success.", - "html_description": "

Use this method to stream a partial message to a user while the message is being generated; supported only for bots with forum topic mode enabled. Returns True on success.

", - "rst_description": "Use this method to stream a partial message to a user while the message is being generated; supported only for bots with forum topic mode enabled. Returns :code:`True` on success.", + "description": "Use this method to stream a partial message to a user while the message is being generated. Returns True on success.", + "html_description": "

Use this method to stream a partial message to a user while the message is being generated. Returns True on success.

", + "rst_description": "Use this method to stream a partial message to a user while the message is being generated. Returns :code:`True` on success.", "annotations": [ { "type": "Integer", diff --git a/.butcher/methods/setChatMemberTag/entity.json b/.butcher/methods/setChatMemberTag/entity.json new file mode 100644 index 00000000..5de6b59f --- /dev/null +++ b/.butcher/methods/setChatMemberTag/entity.json @@ -0,0 +1,41 @@ +{ + "meta": {}, + "group": { + "title": "Available methods", + "anchor": "available-methods" + }, + "object": { + "anchor": "setchatmembertag", + "name": "setChatMemberTag", + "description": "Use this method to set a tag for a regular member in a group or a supergroup. The bot must be an administrator in the chat for this to work and must have the can_manage_tags administrator right. Returns True on success.", + "html_description": "

Use this method to set a tag for a regular member in a group or a supergroup. The bot must be an administrator in the chat for this to work and must have the can_manage_tags administrator right. Returns True on success.

", + "rst_description": "Use this method to set a tag for a regular member in a group or a supergroup. The bot must be an administrator in the chat for this to work and must have the *can_manage_tags* administrator right. Returns :code:`True` on success.", + "annotations": [ + { + "type": "Integer or String", + "required": true, + "description": "Unique identifier for the target chat or username of the target supergroup (in the format @supergroupusername)", + "html_description": "Unique identifier for the target chat or username of the target supergroup (in the format @supergroupusername)", + "rst_description": "Unique identifier for the target chat or username of the target supergroup (in the format :code:`@supergroupusername`)\n", + "name": "chat_id" + }, + { + "type": "Integer", + "required": true, + "description": "Unique identifier of the target user", + "html_description": "Unique identifier of the target user", + "rst_description": "Unique identifier of the target user\n", + "name": "user_id" + }, + { + "type": "String", + "required": false, + "description": "New tag for the member; 0-16 characters, emoji are not allowed", + "html_description": "New tag for the member; 0-16 characters, emoji are not allowed", + "rst_description": "New tag for the member; 0-16 characters, emoji are not allowed\n", + "name": "tag" + } + ], + "category": "methods" + } +} diff --git a/.butcher/schema/schema.json b/.butcher/schema/schema.json index 0fca3099..faa2aee0 100644 --- a/.butcher/schema/schema.json +++ b/.butcher/schema/schema.json @@ -1,7 +1,7 @@ { "api": { - "version": "9.4", - "release_date": "2026-02-09" + "version": "9.5", + "release_date": "2026-03-01" }, "items": [ { @@ -1119,6 +1119,14 @@ "name": "sender_business_bot", "required": false }, + { + "type": "String", + "description": "Tag or custom title of the sender of the message; for supergroups only", + "html_description": "Optional. Tag or custom title of the sender of the message; for supergroups only", + "rst_description": "*Optional*. Tag or custom title of the sender of the message; for supergroups only\n", + "name": "sender_tag", + "required": false + }, { "type": "Integer", "description": "Date the message was sent in Unix time. It is always a positive number, representing a valid date.", @@ -1249,9 +1257,9 @@ }, { "type": "String", - "description": "The unique identifier of a media message group this message belongs to", - "html_description": "Optional. The unique identifier of a media message group this message belongs to", - "rst_description": "*Optional*. The unique identifier of a media message group this message belongs to\n", + "description": "The unique identifier inside this chat of a media message group this message belongs to", + "html_description": "Optional. The unique identifier inside this chat of a media message group this message belongs to", + "rst_description": "*Optional*. The unique identifier inside this chat of a media message group this message belongs to\n", "name": "media_group_id", "required": false }, @@ -1898,8 +1906,8 @@ { "type": "InlineKeyboardMarkup", "description": "Inline keyboard attached to the message. login_url buttons are represented as ordinary url buttons.", - "html_description": "Optional. Inline keyboard attached to the message. login_url buttons are represented as ordinary url buttons.", - "rst_description": "*Optional*. Inline keyboard attached to the message. :code:`login_url` buttons are represented as ordinary :code:`url` buttons.\n", + "html_description": "Optional. Inline keyboard attached to the message. login_url buttons are represented as ordinary url buttons.", + "rst_description": "*Optional*. `Inline keyboard `_ attached to the message. :code:`login_url` buttons are represented as ordinary :code:`url` buttons.\n", "name": "reply_markup", "required": false } @@ -1976,9 +1984,9 @@ "annotations": [ { "type": "String", - "description": "Type of the entity. Currently, can be 'mention' (@username), 'hashtag' (#hashtag or #hashtag@chatusername), 'cashtag' ($USD or $USD@chatusername), 'bot_command' (/start@jobs_bot), 'url' (https://telegram.org), 'email' (do-not-reply@telegram.org), 'phone_number' (+1-212-555-0123), 'bold' (bold text), 'italic' (italic text), 'underline' (underlined text), 'strikethrough' (strikethrough text), 'spoiler' (spoiler message), 'blockquote' (block quotation), 'expandable_blockquote' (collapsed-by-default block quotation), 'code' (monowidth string), 'pre' (monowidth block), 'text_link' (for clickable text URLs), 'text_mention' (for users without usernames), 'custom_emoji' (for inline custom emoji stickers)", - "html_description": "Type of the entity. Currently, can be “mention” (@username), “hashtag” (#hashtag or #hashtag@chatusername), “cashtag” ($USD or $USD@chatusername), “bot_command” (/start@jobs_bot), “url” (https://telegram.org), “email” (do-not-reply@telegram.org), “phone_number” (+1-212-555-0123), “bold” (bold text), “italic” (italic text), “underline” (underlined text), “strikethrough” (strikethrough text), “spoiler” (spoiler message), “blockquote” (block quotation), “expandable_blockquote” (collapsed-by-default block quotation), “code” (monowidth string), “pre” (monowidth block), “text_link” (for clickable text URLs), “text_mention” (for users without usernames), “custom_emoji” (for inline custom emoji stickers)", - "rst_description": "Type of the entity. Currently, can be 'mention' (:code:`@username`), 'hashtag' (:code:`#hashtag` or :code:`#hashtag@chatusername`), 'cashtag' (:code:`$USD` or :code:`$USD@chatusername`), 'bot_command' (:code:`/start@jobs_bot`), 'url' (:code:`https://telegram.org`), 'email' (:code:`do-not-reply@telegram.org`), 'phone_number' (:code:`+1-212-555-0123`), 'bold' (**bold text**), 'italic' (*italic text*), 'underline' (underlined text), 'strikethrough' (strikethrough text), 'spoiler' (spoiler message), 'blockquote' (block quotation), 'expandable_blockquote' (collapsed-by-default block quotation), 'code' (monowidth string), 'pre' (monowidth block), 'text_link' (for clickable text URLs), 'text_mention' (for users `without usernames `_), 'custom_emoji' (for inline custom emoji stickers)\n", + "description": "Type of the entity. Currently, can be 'mention' (@username), 'hashtag' (#hashtag or #hashtag@chatusername), 'cashtag' ($USD or $USD@chatusername), 'bot_command' (/start@jobs_bot), 'url' (https://telegram.org), 'email' (do-not-reply@telegram.org), 'phone_number' (+1-212-555-0123), 'bold' (bold text), 'italic' (italic text), 'underline' (underlined text), 'strikethrough' (strikethrough text), 'spoiler' (spoiler message), 'blockquote' (block quotation), 'expandable_blockquote' (collapsed-by-default block quotation), 'code' (monowidth string), 'pre' (monowidth block), 'text_link' (for clickable text URLs), 'text_mention' (for users without usernames), 'custom_emoji' (for inline custom emoji stickers), or 'date_time' (for formatted date and time)", + "html_description": "Type of the entity. Currently, can be “mention” (@username), “hashtag” (#hashtag or #hashtag@chatusername), “cashtag” ($USD or $USD@chatusername), “bot_command” (/start@jobs_bot), “url” (https://telegram.org), “email” (do-not-reply@telegram.org), “phone_number” (+1-212-555-0123), “bold” (bold text), “italic” (italic text), “underline” (underlined text), “strikethrough” (strikethrough text), “spoiler” (spoiler message), “blockquote” (block quotation), “expandable_blockquote” (collapsed-by-default block quotation), “code” (monowidth string), “pre” (monowidth block), “text_link” (for clickable text URLs), “text_mention” (for users without usernames), “custom_emoji” (for inline custom emoji stickers), or “date_time” (for formatted date and time)", + "rst_description": "Type of the entity. Currently, can be 'mention' (:code:`@username`), 'hashtag' (:code:`#hashtag` or :code:`#hashtag@chatusername`), 'cashtag' (:code:`$USD` or :code:`$USD@chatusername`), 'bot_command' (:code:`/start@jobs_bot`), 'url' (:code:`https://telegram.org`), 'email' (:code:`do-not-reply@telegram.org`), 'phone_number' (:code:`+1-212-555-0123`), 'bold' (**bold text**), 'italic' (*italic text*), 'underline' (underlined text), 'strikethrough' (strikethrough text), 'spoiler' (spoiler message), 'blockquote' (block quotation), 'expandable_blockquote' (collapsed-by-default block quotation), 'code' (monowidth string), 'pre' (monowidth block), 'text_link' (for clickable text URLs), 'text_mention' (for users `without usernames `_), 'custom_emoji' (for inline custom emoji stickers), or 'date_time' (for formatted date and time)\n", "name": "type", "required": true }, @@ -2029,6 +2037,22 @@ "rst_description": "*Optional*. For 'custom_emoji' only, unique identifier of the custom emoji. Use :class:`aiogram.methods.get_custom_emoji_stickers.GetCustomEmojiStickers` to get full information about the sticker\n", "name": "custom_emoji_id", "required": false + }, + { + "type": "Integer", + "description": "For 'date_time' only, the Unix time associated with the entity", + "html_description": "Optional. For “date_time” only, the Unix time associated with the entity", + "rst_description": "*Optional*. For 'date_time' only, the Unix time associated with the entity\n", + "name": "unix_time", + "required": false + }, + { + "type": "String", + "description": "For 'date_time' only, the string that defines the formatting of the date and time. See date-time entity formatting for more details.", + "html_description": "Optional. For “date_time” only, the string that defines the formatting of the date and time. See date-time entity formatting for more details.", + "rst_description": "*Optional*. For 'date_time' only, the string that defines the formatting of the date and time. See `date-time entity formatting `_ for more details.\n", + "name": "date_time_format", + "required": false } ], "category": "types" @@ -6332,6 +6356,14 @@ "rst_description": "*Optional*. :code:`True`, if the administrator can manage direct messages of the channel and decline suggested posts; for channels only\n", "name": "can_manage_direct_messages", "required": false + }, + { + "type": "Boolean", + "description": "True, if the administrator can edit the tags of regular members; for groups and supergroups only. If omitted defaults to the value of can_pin_messages.", + "html_description": "Optional. True, if the administrator can edit the tags of regular members; for groups and supergroups only. If omitted defaults to the value of can_pin_messages.", + "rst_description": "*Optional*. :code:`True`, if the administrator can edit the tags of regular members; for groups and supergroups only. If omitted defaults to the value of can_pin_messages.\n", + "name": "can_manage_tags", + "required": false } ], "category": "types" @@ -6620,6 +6652,14 @@ "name": "can_manage_direct_messages", "required": false }, + { + "type": "Boolean", + "description": "True, if the administrator can edit the tags of regular members; for groups and supergroups only. If omitted defaults to the value of can_pin_messages.", + "html_description": "Optional. True, if the administrator can edit the tags of regular members; for groups and supergroups only. If omitted defaults to the value of can_pin_messages.", + "rst_description": "*Optional*. :code:`True`, if the administrator can edit the tags of regular members; for groups and supergroups only. If omitted defaults to the value of can_pin_messages.\n", + "name": "can_manage_tags", + "required": false + }, { "type": "String", "description": "Custom title for this user", @@ -6646,6 +6686,14 @@ "name": "status", "required": true }, + { + "type": "String", + "description": "Tag of the member", + "html_description": "Optional. Tag of the member", + "rst_description": "*Optional*. Tag of the member\n", + "name": "tag", + "required": false + }, { "type": "User", "description": "Information about the user", @@ -6680,6 +6728,14 @@ "name": "status", "required": true }, + { + "type": "String", + "description": "Tag of the member", + "html_description": "Optional. Tag of the member", + "rst_description": "*Optional*. Tag of the member\n", + "name": "tag", + "required": false + }, { "type": "User", "description": "Information about the user", @@ -6776,6 +6832,14 @@ "name": "can_add_web_page_previews", "required": true }, + { + "type": "Boolean", + "description": "True, if the user is allowed to edit their own tag", + "html_description": "True, if the user is allowed to edit their own tag", + "rst_description": ":code:`True`, if the user is allowed to edit their own tag\n", + "name": "can_edit_tag", + "required": true + }, { "type": "Boolean", "description": "True, if the user is allowed to change the chat title, photo and other settings", @@ -7024,6 +7088,14 @@ "name": "can_add_web_page_previews", "required": false }, + { + "type": "Boolean", + "description": "True, if the user is allowed to edit their own tag", + "html_description": "Optional. True, if the user is allowed to edit their own tag", + "rst_description": "*Optional*. :code:`True`, if the user is allowed to edit their own tag\n", + "name": "can_edit_tag", + "required": false + }, { "type": "Boolean", "description": "True, if the user is allowed to change the chat title, photo and other settings. Ignored in public supergroups", @@ -12959,8 +13031,8 @@ "type": "InlineKeyboardMarkup", "required": false, "description": "A JSON-serialized object for an inline keyboard", - "html_description": "A JSON-serialized object for an inline keyboard", - "rst_description": "A JSON-serialized object for an inline keyboard\n", + "html_description": "A JSON-serialized object for an inline keyboard", + "rst_description": "A JSON-serialized object for an `inline keyboard `_\n", "name": "reply_markup" } ], @@ -13075,9 +13147,9 @@ { "anchor": "sendmessagedraft", "name": "sendMessageDraft", - "description": "Use this method to stream a partial message to a user while the message is being generated; supported only for bots with forum topic mode enabled. Returns True on success.", - "html_description": "

Use this method to stream a partial message to a user while the message is being generated; supported only for bots with forum topic mode enabled. Returns True on success.

", - "rst_description": "Use this method to stream a partial message to a user while the message is being generated; supported only for bots with forum topic mode enabled. Returns :code:`True` on success.", + "description": "Use this method to stream a partial message to a user while the message is being generated. Returns True on success.", + "html_description": "

Use this method to stream a partial message to a user while the message is being generated. Returns True on success.

", + "rst_description": "Use this method to stream a partial message to a user while the message is being generated. Returns :code:`True` on success.", "annotations": [ { "type": "Integer", @@ -13610,6 +13682,14 @@ "html_description": "Pass True if the administrator can manage direct messages within the channel and decline suggested posts; for channels only", "rst_description": "Pass :code:`True` if the administrator can manage direct messages within the channel and decline suggested posts; for channels only\n", "name": "can_manage_direct_messages" + }, + { + "type": "Boolean", + "required": false, + "description": "Pass True if the administrator can edit the tags of regular members; for groups and supergroups only", + "html_description": "Pass True if the administrator can edit the tags of regular members; for groups and supergroups only", + "rst_description": "Pass :code:`True` if the administrator can edit the tags of regular members; for groups and supergroups only\n", + "name": "can_manage_tags" } ], "category": "methods" @@ -13648,6 +13728,40 @@ ], "category": "methods" }, + { + "anchor": "setchatmembertag", + "name": "setChatMemberTag", + "description": "Use this method to set a tag for a regular member in a group or a supergroup. The bot must be an administrator in the chat for this to work and must have the can_manage_tags administrator right. Returns True on success.", + "html_description": "

Use this method to set a tag for a regular member in a group or a supergroup. The bot must be an administrator in the chat for this to work and must have the can_manage_tags administrator right. Returns True on success.

", + "rst_description": "Use this method to set a tag for a regular member in a group or a supergroup. The bot must be an administrator in the chat for this to work and must have the *can_manage_tags* administrator right. Returns :code:`True` on success.", + "annotations": [ + { + "type": "Integer or String", + "required": true, + "description": "Unique identifier for the target chat or username of the target supergroup (in the format @supergroupusername)", + "html_description": "Unique identifier for the target chat or username of the target supergroup (in the format @supergroupusername)", + "rst_description": "Unique identifier for the target chat or username of the target supergroup (in the format :code:`@supergroupusername`)\n", + "name": "chat_id" + }, + { + "type": "Integer", + "required": true, + "description": "Unique identifier of the target user", + "html_description": "Unique identifier of the target user", + "rst_description": "Unique identifier of the target user\n", + "name": "user_id" + }, + { + "type": "String", + "required": false, + "description": "New tag for the member; 0-16 characters, emoji are not allowed", + "html_description": "New tag for the member; 0-16 characters, emoji are not allowed", + "rst_description": "New tag for the member; 0-16 characters, emoji are not allowed\n", + "name": "tag" + } + ], + "category": "methods" + }, { "anchor": "banchatsenderchat", "name": "banChatSenderChat", @@ -16631,8 +16745,8 @@ "type": "InlineKeyboardMarkup", "required": false, "description": "A JSON-serialized object for the new inline keyboard for the message", - "html_description": "A JSON-serialized object for the new inline keyboard for the message", - "rst_description": "A JSON-serialized object for the new inline keyboard for the message\n", + "html_description": "A JSON-serialized object for the new inline keyboard for the message", + "rst_description": "A JSON-serialized object for the new `inline keyboard `_ for the message\n", "name": "reply_markup" } ], @@ -18727,8 +18841,8 @@ { "type": "InlineKeyboardMarkup", "description": "Inline keyboard attached to the message", - "html_description": "Optional. Inline keyboard attached to the message", - "rst_description": "*Optional*. Inline keyboard attached to the message\n", + "html_description": "Optional. Inline keyboard attached to the message", + "rst_description": "*Optional*. `Inline keyboard `_ attached to the message\n", "name": "reply_markup", "required": false }, @@ -22865,9 +22979,9 @@ { "anchor": "gamehighscore", "name": "GameHighScore", - "description": "This object represents one row of the high scores table for a game.\nAnd that's about all we've got for now.\nIf you've got any questions, please check out our Bot FAQ\n-", - "html_description": "

This object represents one row of the high scores table for a game.

And that's about all we've got for now.
\nIf you've got any questions, please check out our Bot FAQ »
\n-

", - "rst_description": "This object represents one row of the high scores table for a game.\nAnd that's about all we've got for now.\n\nIf you've got any questions, please check out our `https://core.telegram.org/bots/faq `_ **Bot FAQ »**\n\n-", + "description": "This object represents one row of the high scores table for a game.\nAnd that's about all we've got for now.\nIf you've got any questions, please check out our Bot FAQ", + "html_description": "

This object represents one row of the high scores table for a game.

And that's about all we've got for now.
\nIf you've got any questions, please check out our Bot FAQ »

", + "rst_description": "This object represents one row of the high scores table for a game.\nAnd that's about all we've got for now.\n\nIf you've got any questions, please check out our `https://core.telegram.org/bots/faq `_ **Bot FAQ »**", "annotations": [ { "type": "Integer", diff --git a/.butcher/types/ChatAdministratorRights/entity.json b/.butcher/types/ChatAdministratorRights/entity.json index 45ebc3b5..f271d1fd 100644 --- a/.butcher/types/ChatAdministratorRights/entity.json +++ b/.butcher/types/ChatAdministratorRights/entity.json @@ -138,6 +138,14 @@ "rst_description": "*Optional*. :code:`True`, if the administrator can manage direct messages of the channel and decline suggested posts; for channels only\n", "name": "can_manage_direct_messages", "required": false + }, + { + "type": "Boolean", + "description": "True, if the administrator can edit the tags of regular members; for groups and supergroups only. If omitted defaults to the value of can_pin_messages.", + "html_description": "Optional. True, if the administrator can edit the tags of regular members; for groups and supergroups only. If omitted defaults to the value of can_pin_messages.", + "rst_description": "*Optional*. :code:`True`, if the administrator can edit the tags of regular members; for groups and supergroups only. If omitted defaults to the value of can_pin_messages.\n", + "name": "can_manage_tags", + "required": false } ], "category": "types" diff --git a/.butcher/types/ChatMemberAdministrator/entity.json b/.butcher/types/ChatMemberAdministrator/entity.json index f1278554..7b55cc7a 100644 --- a/.butcher/types/ChatMemberAdministrator/entity.json +++ b/.butcher/types/ChatMemberAdministrator/entity.json @@ -163,6 +163,14 @@ "name": "can_manage_direct_messages", "required": false }, + { + "type": "Boolean", + "description": "True, if the administrator can edit the tags of regular members; for groups and supergroups only. If omitted defaults to the value of can_pin_messages.", + "html_description": "Optional. True, if the administrator can edit the tags of regular members; for groups and supergroups only. If omitted defaults to the value of can_pin_messages.", + "rst_description": "*Optional*. :code:`True`, if the administrator can edit the tags of regular members; for groups and supergroups only. If omitted defaults to the value of can_pin_messages.\n", + "name": "can_manage_tags", + "required": false + }, { "type": "String", "description": "Custom title for this user", diff --git a/.butcher/types/ChatMemberMember/entity.json b/.butcher/types/ChatMemberMember/entity.json index c9988ee7..ed1a8304 100644 --- a/.butcher/types/ChatMemberMember/entity.json +++ b/.butcher/types/ChatMemberMember/entity.json @@ -19,6 +19,14 @@ "name": "status", "required": true }, + { + "type": "String", + "description": "Tag of the member", + "html_description": "Optional. Tag of the member", + "rst_description": "*Optional*. Tag of the member\n", + "name": "tag", + "required": false + }, { "type": "User", "description": "Information about the user", diff --git a/.butcher/types/ChatMemberRestricted/entity.json b/.butcher/types/ChatMemberRestricted/entity.json index 75ea1fc0..f0572284 100644 --- a/.butcher/types/ChatMemberRestricted/entity.json +++ b/.butcher/types/ChatMemberRestricted/entity.json @@ -19,6 +19,14 @@ "name": "status", "required": true }, + { + "type": "String", + "description": "Tag of the member", + "html_description": "Optional. Tag of the member", + "rst_description": "*Optional*. Tag of the member\n", + "name": "tag", + "required": false + }, { "type": "User", "description": "Information about the user", @@ -115,6 +123,14 @@ "name": "can_add_web_page_previews", "required": true }, + { + "type": "Boolean", + "description": "True, if the user is allowed to edit their own tag", + "html_description": "True, if the user is allowed to edit their own tag", + "rst_description": ":code:`True`, if the user is allowed to edit their own tag\n", + "name": "can_edit_tag", + "required": true + }, { "type": "Boolean", "description": "True, if the user is allowed to change the chat title, photo and other settings", diff --git a/.butcher/types/ChatPermissions/entity.json b/.butcher/types/ChatPermissions/entity.json index c488ef9f..d6ad3cc9 100644 --- a/.butcher/types/ChatPermissions/entity.json +++ b/.butcher/types/ChatPermissions/entity.json @@ -91,6 +91,14 @@ "name": "can_add_web_page_previews", "required": false }, + { + "type": "Boolean", + "description": "True, if the user is allowed to edit their own tag", + "html_description": "Optional. True, if the user is allowed to edit their own tag", + "rst_description": "*Optional*. :code:`True`, if the user is allowed to edit their own tag\n", + "name": "can_edit_tag", + "required": false + }, { "type": "Boolean", "description": "True, if the user is allowed to change the chat title, photo and other settings. Ignored in public supergroups", diff --git a/.butcher/types/GameHighScore/entity.json b/.butcher/types/GameHighScore/entity.json index 21a8a5e7..ce3f52d2 100644 --- a/.butcher/types/GameHighScore/entity.json +++ b/.butcher/types/GameHighScore/entity.json @@ -7,9 +7,9 @@ "object": { "anchor": "gamehighscore", "name": "GameHighScore", - "description": "This object represents one row of the high scores table for a game.\nAnd that's about all we've got for now.\nIf you've got any questions, please check out our Bot FAQ\n-", - "html_description": "

This object represents one row of the high scores table for a game.

And that's about all we've got for now.
\nIf you've got any questions, please check out our Bot FAQ »
\n-

", - "rst_description": "This object represents one row of the high scores table for a game.\nAnd that's about all we've got for now.\n\nIf you've got any questions, please check out our `https://core.telegram.org/bots/faq `_ **Bot FAQ »**\n\n-", + "description": "This object represents one row of the high scores table for a game.\nAnd that's about all we've got for now.\nIf you've got any questions, please check out our Bot FAQ", + "html_description": "

This object represents one row of the high scores table for a game.

And that's about all we've got for now.
\nIf you've got any questions, please check out our Bot FAQ »

", + "rst_description": "This object represents one row of the high scores table for a game.\nAnd that's about all we've got for now.\n\nIf you've got any questions, please check out our `https://core.telegram.org/bots/faq `_ **Bot FAQ »**", "annotations": [ { "type": "Integer", diff --git a/.butcher/types/InlineQueryResultDocument/entity.json b/.butcher/types/InlineQueryResultDocument/entity.json index ff703482..97bb05a6 100644 --- a/.butcher/types/InlineQueryResultDocument/entity.json +++ b/.butcher/types/InlineQueryResultDocument/entity.json @@ -86,8 +86,8 @@ { "type": "InlineKeyboardMarkup", "description": "Inline keyboard attached to the message", - "html_description": "Optional. Inline keyboard attached to the message", - "rst_description": "*Optional*. Inline keyboard attached to the message\n", + "html_description": "Optional. Inline keyboard attached to the message", + "rst_description": "*Optional*. `Inline keyboard `_ attached to the message\n", "name": "reply_markup", "required": false }, diff --git a/.butcher/types/Message/entity.json b/.butcher/types/Message/entity.json index 594442fc..7225d275 100644 --- a/.butcher/types/Message/entity.json +++ b/.butcher/types/Message/entity.json @@ -67,6 +67,14 @@ "name": "sender_business_bot", "required": false }, + { + "type": "String", + "description": "Tag or custom title of the sender of the message; for supergroups only", + "html_description": "Optional. Tag or custom title of the sender of the message; for supergroups only", + "rst_description": "*Optional*. Tag or custom title of the sender of the message; for supergroups only\n", + "name": "sender_tag", + "required": false + }, { "type": "Integer", "description": "Date the message was sent in Unix time. It is always a positive number, representing a valid date.", @@ -197,9 +205,9 @@ }, { "type": "String", - "description": "The unique identifier of a media message group this message belongs to", - "html_description": "Optional. The unique identifier of a media message group this message belongs to", - "rst_description": "*Optional*. The unique identifier of a media message group this message belongs to\n", + "description": "The unique identifier inside this chat of a media message group this message belongs to", + "html_description": "Optional. The unique identifier inside this chat of a media message group this message belongs to", + "rst_description": "*Optional*. The unique identifier inside this chat of a media message group this message belongs to\n", "name": "media_group_id", "required": false }, @@ -846,8 +854,8 @@ { "type": "InlineKeyboardMarkup", "description": "Inline keyboard attached to the message. login_url buttons are represented as ordinary url buttons.", - "html_description": "Optional. Inline keyboard attached to the message. login_url buttons are represented as ordinary url buttons.", - "rst_description": "*Optional*. Inline keyboard attached to the message. :code:`login_url` buttons are represented as ordinary :code:`url` buttons.\n", + "html_description": "Optional. Inline keyboard attached to the message. login_url buttons are represented as ordinary url buttons.", + "rst_description": "*Optional*. `Inline keyboard `_ attached to the message. :code:`login_url` buttons are represented as ordinary :code:`url` buttons.\n", "name": "reply_markup", "required": false }, diff --git a/.butcher/types/MessageEntity/entity.json b/.butcher/types/MessageEntity/entity.json index 8d5a1d13..37dc6cf4 100644 --- a/.butcher/types/MessageEntity/entity.json +++ b/.butcher/types/MessageEntity/entity.json @@ -13,9 +13,9 @@ "annotations": [ { "type": "String", - "description": "Type of the entity. Currently, can be 'mention' (@username), 'hashtag' (#hashtag or #hashtag@chatusername), 'cashtag' ($USD or $USD@chatusername), 'bot_command' (/start@jobs_bot), 'url' (https://telegram.org), 'email' (do-not-reply@telegram.org), 'phone_number' (+1-212-555-0123), 'bold' (bold text), 'italic' (italic text), 'underline' (underlined text), 'strikethrough' (strikethrough text), 'spoiler' (spoiler message), 'blockquote' (block quotation), 'expandable_blockquote' (collapsed-by-default block quotation), 'code' (monowidth string), 'pre' (monowidth block), 'text_link' (for clickable text URLs), 'text_mention' (for users without usernames), 'custom_emoji' (for inline custom emoji stickers)", - "html_description": "Type of the entity. Currently, can be “mention” (@username), “hashtag” (#hashtag or #hashtag@chatusername), “cashtag” ($USD or $USD@chatusername), “bot_command” (/start@jobs_bot), “url” (https://telegram.org), “email” (do-not-reply@telegram.org), “phone_number” (+1-212-555-0123), “bold” (bold text), “italic” (italic text), “underline” (underlined text), “strikethrough” (strikethrough text), “spoiler” (spoiler message), “blockquote” (block quotation), “expandable_blockquote” (collapsed-by-default block quotation), “code” (monowidth string), “pre” (monowidth block), “text_link” (for clickable text URLs), “text_mention” (for users without usernames), “custom_emoji” (for inline custom emoji stickers)", - "rst_description": "Type of the entity. Currently, can be 'mention' (:code:`@username`), 'hashtag' (:code:`#hashtag` or :code:`#hashtag@chatusername`), 'cashtag' (:code:`$USD` or :code:`$USD@chatusername`), 'bot_command' (:code:`/start@jobs_bot`), 'url' (:code:`https://telegram.org`), 'email' (:code:`do-not-reply@telegram.org`), 'phone_number' (:code:`+1-212-555-0123`), 'bold' (**bold text**), 'italic' (*italic text*), 'underline' (underlined text), 'strikethrough' (strikethrough text), 'spoiler' (spoiler message), 'blockquote' (block quotation), 'expandable_blockquote' (collapsed-by-default block quotation), 'code' (monowidth string), 'pre' (monowidth block), 'text_link' (for clickable text URLs), 'text_mention' (for users `without usernames `_), 'custom_emoji' (for inline custom emoji stickers)\n", + "description": "Type of the entity. Currently, can be 'mention' (@username), 'hashtag' (#hashtag or #hashtag@chatusername), 'cashtag' ($USD or $USD@chatusername), 'bot_command' (/start@jobs_bot), 'url' (https://telegram.org), 'email' (do-not-reply@telegram.org), 'phone_number' (+1-212-555-0123), 'bold' (bold text), 'italic' (italic text), 'underline' (underlined text), 'strikethrough' (strikethrough text), 'spoiler' (spoiler message), 'blockquote' (block quotation), 'expandable_blockquote' (collapsed-by-default block quotation), 'code' (monowidth string), 'pre' (monowidth block), 'text_link' (for clickable text URLs), 'text_mention' (for users without usernames), 'custom_emoji' (for inline custom emoji stickers), or 'date_time' (for formatted date and time)", + "html_description": "Type of the entity. Currently, can be “mention” (@username), “hashtag” (#hashtag or #hashtag@chatusername), “cashtag” ($USD or $USD@chatusername), “bot_command” (/start@jobs_bot), “url” (https://telegram.org), “email” (do-not-reply@telegram.org), “phone_number” (+1-212-555-0123), “bold” (bold text), “italic” (italic text), “underline” (underlined text), “strikethrough” (strikethrough text), “spoiler” (spoiler message), “blockquote” (block quotation), “expandable_blockquote” (collapsed-by-default block quotation), “code” (monowidth string), “pre” (monowidth block), “text_link” (for clickable text URLs), “text_mention” (for users without usernames), “custom_emoji” (for inline custom emoji stickers), or “date_time” (for formatted date and time)", + "rst_description": "Type of the entity. Currently, can be 'mention' (:code:`@username`), 'hashtag' (:code:`#hashtag` or :code:`#hashtag@chatusername`), 'cashtag' (:code:`$USD` or :code:`$USD@chatusername`), 'bot_command' (:code:`/start@jobs_bot`), 'url' (:code:`https://telegram.org`), 'email' (:code:`do-not-reply@telegram.org`), 'phone_number' (:code:`+1-212-555-0123`), 'bold' (**bold text**), 'italic' (*italic text*), 'underline' (underlined text), 'strikethrough' (strikethrough text), 'spoiler' (spoiler message), 'blockquote' (block quotation), 'expandable_blockquote' (collapsed-by-default block quotation), 'code' (monowidth string), 'pre' (monowidth block), 'text_link' (for clickable text URLs), 'text_mention' (for users `without usernames `_), 'custom_emoji' (for inline custom emoji stickers), or 'date_time' (for formatted date and time)\n", "name": "type", "required": true }, @@ -66,6 +66,22 @@ "rst_description": "*Optional*. For 'custom_emoji' only, unique identifier of the custom emoji. Use :class:`aiogram.methods.get_custom_emoji_stickers.GetCustomEmojiStickers` to get full information about the sticker\n", "name": "custom_emoji_id", "required": false + }, + { + "type": "Integer", + "description": "For 'date_time' only, the Unix time associated with the entity", + "html_description": "Optional. For “date_time” only, the Unix time associated with the entity", + "rst_description": "*Optional*. For 'date_time' only, the Unix time associated with the entity\n", + "name": "unix_time", + "required": false + }, + { + "type": "String", + "description": "For 'date_time' only, the string that defines the formatting of the date and time. See date-time entity formatting for more details.", + "html_description": "Optional. For “date_time” only, the string that defines the formatting of the date and time. See date-time entity formatting for more details.", + "rst_description": "*Optional*. For 'date_time' only, the string that defines the formatting of the date and time. See `date-time entity formatting `_ for more details.\n", + "name": "date_time_format", + "required": false } ], "category": "types" diff --git a/README.rst b/README.rst index c3b660d3..a04ff797 100644 --- a/README.rst +++ b/README.rst @@ -52,7 +52,7 @@ Features - Asynchronous (`asyncio docs `_, :pep:`492`) - Has type hints (:pep:`484`) and can be used with `mypy `_ - Supports `PyPy `_ -- Supports `Telegram Bot API 9.4 `_ and gets fast updates to the latest versions of the Bot API +- Supports `Telegram Bot API 9.5 `_ and gets fast updates to the latest versions of the Bot API - Telegram Bot API integration code was `autogenerated `_ and can be easily re-generated when API gets updated - Updates router (Blueprints) - Has Finite State Machine diff --git a/aiogram/__meta__.py b/aiogram/__meta__.py index 0c33f1a9..00647de5 100644 --- a/aiogram/__meta__.py +++ b/aiogram/__meta__.py @@ -1,2 +1,2 @@ -__version__ = "3.25.0" -__api_version__ = "9.4" +__version__ = "3.26.0" +__api_version__ = "9.5" diff --git a/aiogram/client/bot.py b/aiogram/client/bot.py index d10429f6..195c06dd 100644 --- a/aiogram/client/bot.py +++ b/aiogram/client/bot.py @@ -144,6 +144,7 @@ from ..methods import ( SetBusinessAccountUsername, SetChatAdministratorCustomTitle, SetChatDescription, + SetChatMemberTag, SetChatMenuButton, SetChatPermissions, SetChatPhoto, @@ -2021,6 +2022,7 @@ class Bot: can_pin_messages: bool | None = None, can_manage_topics: bool | None = None, can_manage_direct_messages: bool | None = None, + can_manage_tags: bool | None = None, request_timeout: int | None = None, ) -> bool: """ @@ -2046,6 +2048,7 @@ class Bot: :param can_pin_messages: Pass :code:`True` if the administrator can pin messages; for supergroups only :param can_manage_topics: Pass :code:`True` if the user is allowed to create, rename, close, and reopen forum topics; for supergroups only :param can_manage_direct_messages: Pass :code:`True` if the administrator can manage direct messages within the channel and decline suggested posts; for channels only + :param can_manage_tags: Pass :code:`True` if the administrator can edit the tags of regular members; for groups and supergroups only :param request_timeout: Request timeout :return: Returns :code:`True` on success. """ @@ -2069,6 +2072,7 @@ class Bot: can_pin_messages=can_pin_messages, can_manage_topics=can_manage_topics, can_manage_direct_messages=can_manage_direct_messages, + can_manage_tags=can_manage_tags, ) return await self(call, request_timeout=request_timeout) @@ -5560,7 +5564,7 @@ class Bot: :param chat_id: Unique identifier for the target chat :param message_id: Unique identifier for the target message :param checklist: A JSON-serialized object for the new checklist - :param reply_markup: A JSON-serialized object for the new inline keyboard for the message + :param reply_markup: A JSON-serialized object for the new `inline keyboard `_ for the message :param request_timeout: Request timeout :return: On success, the edited :class:`aiogram.types.message.Message` is returned. """ @@ -5614,7 +5618,7 @@ class Bot: :param protect_content: Protects the contents of the sent message from forwarding and saving :param message_effect_id: Unique identifier of the message effect to be added to the message :param reply_parameters: A JSON-serialized object for description of the message to reply to - :param reply_markup: A JSON-serialized object for an inline keyboard + :param reply_markup: A JSON-serialized object for an `inline keyboard `_ :param request_timeout: Request timeout :return: On success, the sent :class:`aiogram.types.message.Message` is returned. """ @@ -5823,7 +5827,7 @@ class Bot: request_timeout: int | None = None, ) -> bool: """ - Use this method to stream a partial message to a user while the message is being generated; supported only for bots with forum topic mode enabled. Returns :code:`True` on success. + Use this method to stream a partial message to a user while the message is being generated. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#sendmessagedraft @@ -5908,3 +5912,29 @@ class Bot: photo=photo, ) return await self(call, request_timeout=request_timeout) + + async def set_chat_member_tag( + self, + chat_id: ChatIdUnion, + user_id: int, + tag: str | None = None, + request_timeout: int | None = None, + ) -> bool: + """ + Use this method to set a tag for a regular member in a group or a supergroup. The bot must be an administrator in the chat for this to work and must have the *can_manage_tags* administrator right. Returns :code:`True` on success. + + Source: https://core.telegram.org/bots/api#setchatmembertag + + :param chat_id: Unique identifier for the target chat or username of the target supergroup (in the format :code:`@supergroupusername`) + :param user_id: Unique identifier of the target user + :param tag: New tag for the member; 0-16 characters, emoji are not allowed + :param request_timeout: Request timeout + :return: Returns :code:`True` on success. + """ + + call = SetChatMemberTag( + chat_id=chat_id, + user_id=user_id, + tag=tag, + ) + return await self(call, request_timeout=request_timeout) diff --git a/aiogram/enums/content_type.py b/aiogram/enums/content_type.py index b2a555d4..b90f84e3 100644 --- a/aiogram/enums/content_type.py +++ b/aiogram/enums/content_type.py @@ -8,6 +8,7 @@ class ContentType(str, Enum): UNKNOWN = "unknown" ANY = "any" + SENDER_TAG = "sender_tag" TEXT = "text" ANIMATION = "animation" AUDIO = "audio" diff --git a/aiogram/enums/message_entity_type.py b/aiogram/enums/message_entity_type.py index b67dc039..e1dba489 100644 --- a/aiogram/enums/message_entity_type.py +++ b/aiogram/enums/message_entity_type.py @@ -27,3 +27,4 @@ class MessageEntityType(str, Enum): TEXT_LINK = "text_link" TEXT_MENTION = "text_mention" CUSTOM_EMOJI = "custom_emoji" + DATE_TIME = "date_time" diff --git a/aiogram/methods/__init__.py b/aiogram/methods/__init__.py index 786e53e5..b4c93d6c 100644 --- a/aiogram/methods/__init__.py +++ b/aiogram/methods/__init__.py @@ -126,6 +126,7 @@ from .set_business_account_profile_photo import SetBusinessAccountProfilePhoto from .set_business_account_username import SetBusinessAccountUsername from .set_chat_administrator_custom_title import SetChatAdministratorCustomTitle from .set_chat_description import SetChatDescription +from .set_chat_member_tag import SetChatMemberTag from .set_chat_menu_button import SetChatMenuButton from .set_chat_permissions import SetChatPermissions from .set_chat_photo import SetChatPhoto @@ -295,6 +296,7 @@ __all__ = ( "SetBusinessAccountUsername", "SetChatAdministratorCustomTitle", "SetChatDescription", + "SetChatMemberTag", "SetChatMenuButton", "SetChatPermissions", "SetChatPhoto", diff --git a/aiogram/methods/edit_message_checklist.py b/aiogram/methods/edit_message_checklist.py index 6f7bbf7d..83d3815f 100644 --- a/aiogram/methods/edit_message_checklist.py +++ b/aiogram/methods/edit_message_checklist.py @@ -25,7 +25,7 @@ class EditMessageChecklist(TelegramMethod[Message]): checklist: InputChecklist """A JSON-serialized object for the new checklist""" reply_markup: InlineKeyboardMarkup | None = None - """A JSON-serialized object for the new inline keyboard for the message""" + """A JSON-serialized object for the new `inline keyboard `_ for the message""" if TYPE_CHECKING: # DO NOT EDIT MANUALLY!!! diff --git a/aiogram/methods/promote_chat_member.py b/aiogram/methods/promote_chat_member.py index e26f821e..6f8d4dbf 100644 --- a/aiogram/methods/promote_chat_member.py +++ b/aiogram/methods/promote_chat_member.py @@ -52,6 +52,8 @@ class PromoteChatMember(TelegramMethod[bool]): """Pass :code:`True` if the user is allowed to create, rename, close, and reopen forum topics; for supergroups only""" can_manage_direct_messages: bool | None = None """Pass :code:`True` if the administrator can manage direct messages within the channel and decline suggested posts; for channels only""" + can_manage_tags: bool | None = None + """Pass :code:`True` if the administrator can edit the tags of regular members; for groups and supergroups only""" if TYPE_CHECKING: # DO NOT EDIT MANUALLY!!! @@ -78,6 +80,7 @@ class PromoteChatMember(TelegramMethod[bool]): can_pin_messages: bool | None = None, can_manage_topics: bool | None = None, can_manage_direct_messages: bool | None = None, + can_manage_tags: bool | None = None, **__pydantic_kwargs: Any, ) -> None: # DO NOT EDIT MANUALLY!!! @@ -103,5 +106,6 @@ class PromoteChatMember(TelegramMethod[bool]): can_pin_messages=can_pin_messages, can_manage_topics=can_manage_topics, can_manage_direct_messages=can_manage_direct_messages, + can_manage_tags=can_manage_tags, **__pydantic_kwargs, ) diff --git a/aiogram/methods/send_checklist.py b/aiogram/methods/send_checklist.py index 852c8110..7a00317b 100644 --- a/aiogram/methods/send_checklist.py +++ b/aiogram/methods/send_checklist.py @@ -31,7 +31,7 @@ class SendChecklist(TelegramMethod[Message]): reply_parameters: ReplyParameters | None = None """A JSON-serialized object for description of the message to reply to""" reply_markup: InlineKeyboardMarkup | None = None - """A JSON-serialized object for an inline keyboard""" + """A JSON-serialized object for an `inline keyboard `_""" if TYPE_CHECKING: # DO NOT EDIT MANUALLY!!! diff --git a/aiogram/methods/send_message_draft.py b/aiogram/methods/send_message_draft.py index 6124f73e..b93c286c 100644 --- a/aiogram/methods/send_message_draft.py +++ b/aiogram/methods/send_message_draft.py @@ -8,7 +8,7 @@ from .base import TelegramMethod class SendMessageDraft(TelegramMethod[bool]): """ - Use this method to stream a partial message to a user while the message is being generated; supported only for bots with forum topic mode enabled. Returns :code:`True` on success. + Use this method to stream a partial message to a user while the message is being generated. Returns :code:`True` on success. Source: https://core.telegram.org/bots/api#sendmessagedraft """ diff --git a/aiogram/methods/set_chat_member_tag.py b/aiogram/methods/set_chat_member_tag.py new file mode 100644 index 00000000..de8a2d09 --- /dev/null +++ b/aiogram/methods/set_chat_member_tag.py @@ -0,0 +1,40 @@ +from typing import TYPE_CHECKING, Any + +from ..types import ChatIdUnion +from .base import TelegramMethod + + +class SetChatMemberTag(TelegramMethod[bool]): + """ + Use this method to set a tag for a regular member in a group or a supergroup. The bot must be an administrator in the chat for this to work and must have the *can_manage_tags* administrator right. Returns :code:`True` on success. + + Source: https://core.telegram.org/bots/api#setchatmembertag + """ + + __returning__ = bool + __api_method__ = "setChatMemberTag" + + chat_id: ChatIdUnion + """Unique identifier for the target chat or username of the target supergroup (in the format :code:`@supergroupusername`)""" + user_id: int + """Unique identifier of the target user""" + tag: str | None = None + """New tag for the member; 0-16 characters, emoji are not allowed""" + + if TYPE_CHECKING: + # DO NOT EDIT MANUALLY!!! + # This section was auto-generated via `butcher` + + def __init__( + __pydantic__self__, + *, + chat_id: ChatIdUnion, + user_id: int, + tag: str | None = None, + **__pydantic_kwargs: Any, + ) -> None: + # DO NOT EDIT MANUALLY!!! + # This method was auto-generated via `butcher` + # Is needed only for type checking and IDE support without any additional plugins + + super().__init__(chat_id=chat_id, user_id=user_id, tag=tag, **__pydantic_kwargs) diff --git a/aiogram/types/chat.py b/aiogram/types/chat.py index bea95afb..b956f4ba 100644 --- a/aiogram/types/chat.py +++ b/aiogram/types/chat.py @@ -1018,6 +1018,7 @@ class Chat(TelegramObject): can_pin_messages: bool | None = None, can_manage_topics: bool | None = None, can_manage_direct_messages: bool | None = None, + can_manage_tags: bool | None = None, **kwargs: Any, ) -> PromoteChatMember: """ @@ -1047,6 +1048,7 @@ class Chat(TelegramObject): :param can_pin_messages: Pass :code:`True` if the administrator can pin messages; for supergroups only :param can_manage_topics: Pass :code:`True` if the user is allowed to create, rename, close, and reopen forum topics; for supergroups only :param can_manage_direct_messages: Pass :code:`True` if the administrator can manage direct messages within the channel and decline suggested posts; for channels only + :param can_manage_tags: Pass :code:`True` if the administrator can edit the tags of regular members; for groups and supergroups only :return: instance of method :class:`aiogram.methods.promote_chat_member.PromoteChatMember` """ # DO NOT EDIT MANUALLY!!! @@ -1073,6 +1075,7 @@ class Chat(TelegramObject): can_pin_messages=can_pin_messages, can_manage_topics=can_manage_topics, can_manage_direct_messages=can_manage_direct_messages, + can_manage_tags=can_manage_tags, **kwargs, ).as_(self._bot) diff --git a/aiogram/types/chat_administrator_rights.py b/aiogram/types/chat_administrator_rights.py index cac9ae01..4c0811b9 100644 --- a/aiogram/types/chat_administrator_rights.py +++ b/aiogram/types/chat_administrator_rights.py @@ -47,6 +47,8 @@ class ChatAdministratorRights(TelegramObject): """*Optional*. :code:`True`, if the user is allowed to create, rename, close, and reopen forum topics; for supergroups only""" can_manage_direct_messages: bool | None = None """*Optional*. :code:`True`, if the administrator can manage direct messages of the channel and decline suggested posts; for channels only""" + can_manage_tags: bool | None = None + """*Optional*. :code:`True`, if the administrator can edit the tags of regular members; for groups and supergroups only. If omitted defaults to the value of can_pin_messages.""" if TYPE_CHECKING: # DO NOT EDIT MANUALLY!!! @@ -71,6 +73,7 @@ class ChatAdministratorRights(TelegramObject): can_pin_messages: bool | None = None, can_manage_topics: bool | None = None, can_manage_direct_messages: bool | None = None, + can_manage_tags: bool | None = None, **__pydantic_kwargs: Any, ) -> None: # DO NOT EDIT MANUALLY!!! @@ -94,5 +97,6 @@ class ChatAdministratorRights(TelegramObject): can_pin_messages=can_pin_messages, can_manage_topics=can_manage_topics, can_manage_direct_messages=can_manage_direct_messages, + can_manage_tags=can_manage_tags, **__pydantic_kwargs, ) diff --git a/aiogram/types/chat_member_administrator.py b/aiogram/types/chat_member_administrator.py index b24dece3..1d8915bc 100644 --- a/aiogram/types/chat_member_administrator.py +++ b/aiogram/types/chat_member_administrator.py @@ -54,6 +54,8 @@ class ChatMemberAdministrator(ChatMember): """*Optional*. :code:`True`, if the user is allowed to create, rename, close, and reopen forum topics; for supergroups only""" can_manage_direct_messages: bool | None = None """*Optional*. :code:`True`, if the administrator can manage direct messages of the channel and decline suggested posts; for channels only""" + can_manage_tags: bool | None = None + """*Optional*. :code:`True`, if the administrator can edit the tags of regular members; for groups and supergroups only. If omitted defaults to the value of can_pin_messages.""" custom_title: str | None = None """*Optional*. Custom title for this user""" @@ -83,6 +85,7 @@ class ChatMemberAdministrator(ChatMember): can_pin_messages: bool | None = None, can_manage_topics: bool | None = None, can_manage_direct_messages: bool | None = None, + can_manage_tags: bool | None = None, custom_title: str | None = None, **__pydantic_kwargs: Any, ) -> None: @@ -110,6 +113,7 @@ class ChatMemberAdministrator(ChatMember): can_pin_messages=can_pin_messages, can_manage_topics=can_manage_topics, can_manage_direct_messages=can_manage_direct_messages, + can_manage_tags=can_manage_tags, custom_title=custom_title, **__pydantic_kwargs, ) diff --git a/aiogram/types/chat_member_member.py b/aiogram/types/chat_member_member.py index 5b3ce5e0..0cd89e76 100644 --- a/aiogram/types/chat_member_member.py +++ b/aiogram/types/chat_member_member.py @@ -21,6 +21,8 @@ class ChatMemberMember(ChatMember): """The member's status in the chat, always 'member'""" user: User """Information about the user""" + tag: str | None = None + """*Optional*. Tag of the member""" until_date: DateTime | None = None """*Optional*. Date when the user's subscription will expire; Unix time""" @@ -33,6 +35,7 @@ class ChatMemberMember(ChatMember): *, status: Literal[ChatMemberStatus.MEMBER] = ChatMemberStatus.MEMBER, user: User, + tag: str | None = None, until_date: DateTime | None = None, **__pydantic_kwargs: Any, ) -> None: @@ -40,4 +43,6 @@ class ChatMemberMember(ChatMember): # This method was auto-generated via `butcher` # Is needed only for type checking and IDE support without any additional plugins - super().__init__(status=status, user=user, until_date=until_date, **__pydantic_kwargs) + super().__init__( + status=status, user=user, tag=tag, until_date=until_date, **__pydantic_kwargs + ) diff --git a/aiogram/types/chat_member_restricted.py b/aiogram/types/chat_member_restricted.py index 1466350f..0fc162ff 100644 --- a/aiogram/types/chat_member_restricted.py +++ b/aiogram/types/chat_member_restricted.py @@ -43,6 +43,8 @@ class ChatMemberRestricted(ChatMember): """:code:`True`, if the user is allowed to send animations, games, stickers and use inline bots""" can_add_web_page_previews: bool """:code:`True`, if the user is allowed to add web page previews to their messages""" + can_edit_tag: bool + """:code:`True`, if the user is allowed to edit their own tag""" can_change_info: bool """:code:`True`, if the user is allowed to change the chat title, photo and other settings""" can_invite_users: bool @@ -53,6 +55,8 @@ class ChatMemberRestricted(ChatMember): """:code:`True`, if the user is allowed to create forum topics""" until_date: DateTime """Date when restrictions will be lifted for this user; Unix time. If 0, then the user is restricted forever""" + tag: str | None = None + """*Optional*. Tag of the member""" if TYPE_CHECKING: # DO NOT EDIT MANUALLY!!! @@ -74,11 +78,13 @@ class ChatMemberRestricted(ChatMember): can_send_polls: bool, can_send_other_messages: bool, can_add_web_page_previews: bool, + can_edit_tag: bool, can_change_info: bool, can_invite_users: bool, can_pin_messages: bool, can_manage_topics: bool, until_date: DateTime, + tag: str | None = None, **__pydantic_kwargs: Any, ) -> None: # DO NOT EDIT MANUALLY!!! @@ -99,10 +105,12 @@ class ChatMemberRestricted(ChatMember): can_send_polls=can_send_polls, can_send_other_messages=can_send_other_messages, can_add_web_page_previews=can_add_web_page_previews, + can_edit_tag=can_edit_tag, can_change_info=can_change_info, can_invite_users=can_invite_users, can_pin_messages=can_pin_messages, can_manage_topics=can_manage_topics, until_date=until_date, + tag=tag, **__pydantic_kwargs, ) diff --git a/aiogram/types/chat_permissions.py b/aiogram/types/chat_permissions.py index dfb0fb77..473a38bb 100644 --- a/aiogram/types/chat_permissions.py +++ b/aiogram/types/chat_permissions.py @@ -32,6 +32,8 @@ class ChatPermissions(MutableTelegramObject): """*Optional*. :code:`True`, if the user is allowed to send animations, games, stickers and use inline bots""" can_add_web_page_previews: bool | None = None """*Optional*. :code:`True`, if the user is allowed to add web page previews to their messages""" + can_edit_tag: bool | None = None + """*Optional*. :code:`True`, if the user is allowed to edit their own tag""" can_change_info: bool | None = None """*Optional*. :code:`True`, if the user is allowed to change the chat title, photo and other settings. Ignored in public supergroups""" can_invite_users: bool | None = None @@ -58,6 +60,7 @@ class ChatPermissions(MutableTelegramObject): can_send_polls: bool | None = None, can_send_other_messages: bool | None = None, can_add_web_page_previews: bool | None = None, + can_edit_tag: bool | None = None, can_change_info: bool | None = None, can_invite_users: bool | None = None, can_pin_messages: bool | None = None, @@ -79,6 +82,7 @@ class ChatPermissions(MutableTelegramObject): can_send_polls=can_send_polls, can_send_other_messages=can_send_other_messages, can_add_web_page_previews=can_add_web_page_previews, + can_edit_tag=can_edit_tag, can_change_info=can_change_info, can_invite_users=can_invite_users, can_pin_messages=can_pin_messages, diff --git a/aiogram/types/game_high_score.py b/aiogram/types/game_high_score.py index e8fdcf40..5364be6e 100644 --- a/aiogram/types/game_high_score.py +++ b/aiogram/types/game_high_score.py @@ -15,8 +15,6 @@ class GameHighScore(TelegramObject): If you've got any questions, please check out our `https://core.telegram.org/bots/faq `_ **Bot FAQ »** - - - Source: https://core.telegram.org/bots/api#gamehighscore """ diff --git a/aiogram/types/inline_query_result_document.py b/aiogram/types/inline_query_result_document.py index c40d31b8..1665c8b3 100644 --- a/aiogram/types/inline_query_result_document.py +++ b/aiogram/types/inline_query_result_document.py @@ -38,7 +38,7 @@ class InlineQueryResultDocument(InlineQueryResult): description: str | None = None """*Optional*. Short description of the result""" reply_markup: InlineKeyboardMarkup | None = None - """*Optional*. Inline keyboard attached to the message""" + """*Optional*. `Inline keyboard `_ attached to the message""" input_message_content: InputMessageContentUnion | None = None """*Optional*. Content of the message to be sent instead of the file""" thumbnail_url: str | None = None diff --git a/aiogram/types/message.py b/aiogram/types/message.py index b35fe0fb..1b7f9677 100644 --- a/aiogram/types/message.py +++ b/aiogram/types/message.py @@ -157,6 +157,8 @@ class Message(MaybeInaccessibleMessage): """*Optional*. If the sender of the message boosted the chat, the number of boosts added by the user""" sender_business_bot: User | None = None """*Optional*. The bot that actually sent the message on behalf of the business account. Available only for outgoing messages sent on behalf of the connected business account.""" + sender_tag: str | None = None + """*Optional*. Tag or custom title of the sender of the message; for supergroups only""" business_connection_id: str | None = None """*Optional*. Unique identifier of the business connection from which the message was received. If non-empty, the message belongs to a chat of the corresponding business account that is independent from any potential bot chat which might share the same identifier.""" forward_origin: MessageOriginUnion | None = None @@ -186,7 +188,7 @@ class Message(MaybeInaccessibleMessage): is_paid_post: bool | None = None """*Optional*. :code:`True`, if the message is a paid post. Note that such posts must not be deleted for 24 hours to receive the payment and can't be edited.""" media_group_id: str | None = None - """*Optional*. The unique identifier of a media message group this message belongs to""" + """*Optional*. The unique identifier inside this chat of a media message group this message belongs to""" author_signature: str | None = None """*Optional*. Signature of the post author for messages in channels, or the custom title of an anonymous group administrator""" paid_star_count: int | None = None @@ -348,7 +350,7 @@ class Message(MaybeInaccessibleMessage): web_app_data: WebAppData | None = None """*Optional*. Service message: data sent by a Web App""" reply_markup: InlineKeyboardMarkup | None = None - """*Optional*. Inline keyboard attached to the message. :code:`login_url` buttons are represented as ordinary :code:`url` buttons.""" + """*Optional*. `Inline keyboard `_ attached to the message. :code:`login_url` buttons are represented as ordinary :code:`url` buttons.""" forward_date: DateTime | None = Field(None, json_schema_extra={"deprecated": True}) """*Optional*. For forwarded messages, date the original message was sent in Unix time @@ -401,6 +403,7 @@ class Message(MaybeInaccessibleMessage): sender_chat: Chat | None = None, sender_boost_count: int | None = None, sender_business_bot: User | None = None, + sender_tag: str | None = None, business_connection_id: str | None = None, forward_origin: MessageOriginUnion | None = None, is_topic_message: bool | None = None, @@ -520,6 +523,7 @@ class Message(MaybeInaccessibleMessage): sender_chat=sender_chat, sender_boost_count=sender_boost_count, sender_business_bot=sender_business_bot, + sender_tag=sender_tag, business_connection_id=business_connection_id, forward_origin=forward_origin, is_topic_message=is_topic_message, diff --git a/aiogram/types/message_entity.py b/aiogram/types/message_entity.py index 608b8435..68ae3025 100644 --- a/aiogram/types/message_entity.py +++ b/aiogram/types/message_entity.py @@ -17,7 +17,7 @@ class MessageEntity(MutableTelegramObject): """ type: str - """Type of the entity. Currently, can be 'mention' (:code:`@username`), 'hashtag' (:code:`#hashtag` or :code:`#hashtag@chatusername`), 'cashtag' (:code:`$USD` or :code:`$USD@chatusername`), 'bot_command' (:code:`/start@jobs_bot`), 'url' (:code:`https://telegram.org`), 'email' (:code:`do-not-reply@telegram.org`), 'phone_number' (:code:`+1-212-555-0123`), 'bold' (**bold text**), 'italic' (*italic text*), 'underline' (underlined text), 'strikethrough' (strikethrough text), 'spoiler' (spoiler message), 'blockquote' (block quotation), 'expandable_blockquote' (collapsed-by-default block quotation), 'code' (monowidth string), 'pre' (monowidth block), 'text_link' (for clickable text URLs), 'text_mention' (for users `without usernames `_), 'custom_emoji' (for inline custom emoji stickers)""" + """Type of the entity. Currently, can be 'mention' (:code:`@username`), 'hashtag' (:code:`#hashtag` or :code:`#hashtag@chatusername`), 'cashtag' (:code:`$USD` or :code:`$USD@chatusername`), 'bot_command' (:code:`/start@jobs_bot`), 'url' (:code:`https://telegram.org`), 'email' (:code:`do-not-reply@telegram.org`), 'phone_number' (:code:`+1-212-555-0123`), 'bold' (**bold text**), 'italic' (*italic text*), 'underline' (underlined text), 'strikethrough' (strikethrough text), 'spoiler' (spoiler message), 'blockquote' (block quotation), 'expandable_blockquote' (collapsed-by-default block quotation), 'code' (monowidth string), 'pre' (monowidth block), 'text_link' (for clickable text URLs), 'text_mention' (for users `without usernames `_), 'custom_emoji' (for inline custom emoji stickers), or 'date_time' (for formatted date and time)""" offset: int """Offset in `UTF-16 code units `_ to the start of the entity""" length: int @@ -30,6 +30,10 @@ class MessageEntity(MutableTelegramObject): """*Optional*. For 'pre' only, the programming language of the entity text""" custom_emoji_id: str | None = None """*Optional*. For 'custom_emoji' only, unique identifier of the custom emoji. Use :class:`aiogram.methods.get_custom_emoji_stickers.GetCustomEmojiStickers` to get full information about the sticker""" + unix_time: int | None = None + """*Optional*. For 'date_time' only, the Unix time associated with the entity""" + date_time_format: str | None = None + """*Optional*. For 'date_time' only, the string that defines the formatting of the date and time. See `date-time entity formatting `_ for more details.""" if TYPE_CHECKING: # DO NOT EDIT MANUALLY!!! @@ -45,6 +49,8 @@ class MessageEntity(MutableTelegramObject): user: User | None = None, language: str | None = None, custom_emoji_id: str | None = None, + unix_time: int | None = None, + date_time_format: str | None = None, **__pydantic_kwargs: Any, ) -> None: # DO NOT EDIT MANUALLY!!! @@ -59,6 +65,8 @@ class MessageEntity(MutableTelegramObject): user=user, language=language, custom_emoji_id=custom_emoji_id, + unix_time=unix_time, + date_time_format=date_time_format, **__pydantic_kwargs, ) diff --git a/aiogram/utils/formatting.py b/aiogram/utils/formatting.py index cbfd9758..4dfccd64 100644 --- a/aiogram/utils/formatting.py +++ b/aiogram/utils/formatting.py @@ -2,6 +2,7 @@ from __future__ import annotations import textwrap from collections.abc import Generator, Iterable, Iterator +from datetime import datetime from typing import Any, ClassVar from typing_extensions import Self @@ -534,6 +535,26 @@ class ExpandableBlockQuote(Text): type = MessageEntityType.EXPANDABLE_BLOCKQUOTE +class DateTime(Text): + type = MessageEntityType.DATE_TIME + + def __init__( + self, + *body: NodeType, + unix_time: int | datetime, + date_time_format: str | None = None, + **params: Any, + ) -> None: + if isinstance(unix_time, datetime): + unix_time = int(unix_time.timestamp()) + super().__init__( + *body, + unix_time=unix_time, + date_time_format=date_time_format, + **params, + ) + + NODE_TYPES: dict[str | None, type[Text]] = { Text.type: Text, HashTag.type: HashTag, @@ -554,6 +575,7 @@ NODE_TYPES: dict[str | None, type[Text]] = { CustomEmoji.type: CustomEmoji, BlockQuote.type: BlockQuote, ExpandableBlockQuote.type: ExpandableBlockQuote, + DateTime.type: DateTime, } diff --git a/aiogram/utils/text_decorations.py b/aiogram/utils/text_decorations.py index 00762c0a..b8edead2 100644 --- a/aiogram/utils/text_decorations.py +++ b/aiogram/utils/text_decorations.py @@ -3,9 +3,11 @@ from __future__ import annotations import html import re from abc import ABC, abstractmethod +from datetime import date, datetime, time from typing import TYPE_CHECKING, cast from aiogram.enums import MessageEntityType +from aiogram.utils.link import create_tg_link if TYPE_CHECKING: from collections.abc import Generator @@ -78,6 +80,12 @@ class TextDecoration(ABC): return self.link(value=text, link=cast(str, entity.url)) if entity.type == MessageEntityType.CUSTOM_EMOJI: return self.custom_emoji(value=text, custom_emoji_id=cast(str, entity.custom_emoji_id)) + if entity.type == MessageEntityType.DATE_TIME: + return self.date_time( + value=text, + unix_time=cast(int, entity.unix_time), + date_time_format=entity.date_time_format, + ) # This case is not possible because of `if` above, but if any new entity is added to # API it will be here too @@ -180,54 +188,105 @@ class TextDecoration(ABC): def expandable_blockquote(self, value: str) -> str: pass + @abstractmethod + def date_time( + self, + value: str, + unix_time: int | datetime, + date_time_format: str | None = None, + ) -> str: + pass + class HtmlDecoration(TextDecoration): BOLD_TAG = "b" ITALIC_TAG = "i" UNDERLINE_TAG = "u" STRIKETHROUGH_TAG = "s" + CODE_TAG = "code" + PRE_TAG = "pre" + LINK_TAG = "a" SPOILER_TAG = "tg-spoiler" EMOJI_TAG = "tg-emoji" + DATE_TIME_TAG = "tg-time" BLOCKQUOTE_TAG = "blockquote" + def _tag( + self, + tag: str, + content: str, + *, + attrs: dict[str, str] | None = None, + flags: list[str] | None = None, + ) -> str: + prepared_attrs: list[str] = [] + if attrs: + prepared_attrs.extend(f'{k}="{v}"' for k, v in attrs.items()) + if flags: + prepared_attrs.extend(f"{flag}" for flag in flags) + + attrs_str = " ".join(prepared_attrs) + if attrs_str: + attrs_str = " " + attrs_str + + return f"<{tag}{attrs_str}>{content}" + def link(self, value: str, link: str) -> str: - return f'{value}' + return self._tag(self.LINK_TAG, value, attrs={"href": link}) def bold(self, value: str) -> str: - return f"<{self.BOLD_TAG}>{value}" + return self._tag(self.BOLD_TAG, value) def italic(self, value: str) -> str: - return f"<{self.ITALIC_TAG}>{value}" + return self._tag(self.ITALIC_TAG, value) def code(self, value: str) -> str: - return f"{value}" + return self._tag(self.CODE_TAG, value) def pre(self, value: str) -> str: - return f"
{value}
" + return self._tag(self.PRE_TAG, value) def pre_language(self, value: str, language: str) -> str: - return f'
{value}
' + return self._tag( + self.PRE_TAG, + self._tag(self.CODE_TAG, value, attrs={"language": f"language-{language}"}), + ) def underline(self, value: str) -> str: - return f"<{self.UNDERLINE_TAG}>{value}" + return self._tag(self.UNDERLINE_TAG, value) def strikethrough(self, value: str) -> str: - return f"<{self.STRIKETHROUGH_TAG}>{value}" + return self._tag(self.STRIKETHROUGH_TAG, value) def spoiler(self, value: str) -> str: - return f"<{self.SPOILER_TAG}>{value}" + return self._tag(self.SPOILER_TAG, value) def quote(self, value: str) -> str: return html.escape(value, quote=False) def custom_emoji(self, value: str, custom_emoji_id: str) -> str: - return f'<{self.EMOJI_TAG} emoji-id="{custom_emoji_id}">{value}' + return self._tag(self.EMOJI_TAG, value, attrs={"emoji_id": custom_emoji_id}) def blockquote(self, value: str) -> str: - return f"<{self.BLOCKQUOTE_TAG}>{value}" + return self._tag(self.BLOCKQUOTE_TAG, value) def expandable_blockquote(self, value: str) -> str: - return f"<{self.BLOCKQUOTE_TAG} expandable>{value}" + return self._tag(self.BLOCKQUOTE_TAG, value, flags=["expandable"]) + + def date_time( + self, + value: str, + unix_time: int | datetime, + date_time_format: str | None = None, + ) -> str: + if isinstance(unix_time, datetime): + unix_time = int(unix_time.timestamp()) + + args = {"unix": str(unix_time)} + if date_time_format: + args["format"] = date_time_format + + return self._tag(self.DATE_TIME_TAG, value, attrs=args) class MarkdownDecoration(TextDecoration): @@ -264,7 +323,8 @@ class MarkdownDecoration(TextDecoration): return re.sub(pattern=self.MARKDOWN_QUOTE_PATTERN, repl=r"\\\1", string=value) def custom_emoji(self, value: str, custom_emoji_id: str) -> str: - return f"!{self.link(value=value, link=f'tg://emoji?id={custom_emoji_id}')}" + link = create_tg_link("emoji", emoji_id=custom_emoji_id) + return f"!{self.link(value=value, link=link)}" def blockquote(self, value: str) -> str: return "\n".join(f">{line}" for line in value.splitlines()) @@ -272,6 +332,22 @@ class MarkdownDecoration(TextDecoration): def expandable_blockquote(self, value: str) -> str: return "\n".join(f">{line}" for line in value.splitlines()) + "||" + def date_time( + self, + value: str, + unix_time: int | datetime, + date_time_format: str | None = None, + ) -> str: + if isinstance(unix_time, datetime): + unix_time = int(unix_time.timestamp()) + + link_params = {"unix": str(unix_time)} + if date_time_format: + link_params["format"] = date_time_format + link = create_tg_link("time", **link_params) + + return f"!{self.link(value, link=link)}" + html_decoration = HtmlDecoration() markdown_decoration = MarkdownDecoration() diff --git a/docs/api/methods/get_user_profile_audios.rst b/docs/api/methods/get_user_profile_audios.rst index f9567228..553ab296 100644 --- a/docs/api/methods/get_user_profile_audios.rst +++ b/docs/api/methods/get_user_profile_audios.rst @@ -36,3 +36,11 @@ With specific bot .. code-block:: python result: UserProfileAudios = await bot(GetUserProfileAudios(...)) + + + + +As shortcut from received object +-------------------------------- + +- :meth:`aiogram.types.user.User.get_profile_audios` diff --git a/docs/api/methods/index.rst b/docs/api/methods/index.rst index bbd6303a..f83a4f10 100644 --- a/docs/api/methods/index.rst +++ b/docs/api/methods/index.rst @@ -127,6 +127,7 @@ Available methods set_business_account_username set_chat_administrator_custom_title set_chat_description + set_chat_member_tag set_chat_menu_button set_chat_permissions set_chat_photo diff --git a/docs/api/methods/set_chat_member_tag.rst b/docs/api/methods/set_chat_member_tag.rst new file mode 100644 index 00000000..79090f6f --- /dev/null +++ b/docs/api/methods/set_chat_member_tag.rst @@ -0,0 +1,45 @@ +################ +setChatMemberTag +################ + +Returns: :obj:`bool` + +.. automodule:: aiogram.methods.set_chat_member_tag + :members: + :member-order: bysource + :undoc-members: True + :exclude-members: model_config,model_fields + + +Usage +===== + +As bot method +------------- + +.. code-block:: + + result: bool = await bot.set_chat_member_tag(...) + + +Method as object +---------------- + +Imports: + +- :code:`from aiogram.methods.set_chat_member_tag import SetChatMemberTag` +- alias: :code:`from aiogram.methods import SetChatMemberTag` + +With specific bot +~~~~~~~~~~~~~~~~~ + +.. code-block:: python + + result: bool = await bot(SetChatMemberTag(...)) + +As reply into Webhook in handler +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: python + + return SetChatMemberTag(...)