mirror of
https://github.com/aiogram/aiogram.git
synced 2026-04-08 16:37:47 +00:00
Merge branch 'dev-3.x'
This commit is contained in:
commit
860dd5cab8
281 changed files with 2741 additions and 1029 deletions
|
|
@ -1 +1 @@
|
|||
9.3
|
||||
9.4
|
||||
|
|
|
|||
12
.butcher/enums/ButtonStyle.yml
Normal file
12
.butcher/enums/ButtonStyle.yml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
name: ButtonStyle
|
||||
description: |
|
||||
This object represents a button style (inline- or reply-keyboard).
|
||||
|
||||
Sources:
|
||||
* https://core.telegram.org/bots/api#inlinekeyboardbutton
|
||||
* https://core.telegram.org/bots/api#keyboardbutton
|
||||
|
||||
parse:
|
||||
entity: InlineKeyboardButton
|
||||
attribute: style
|
||||
regexp: "'([a-z]+)'"
|
||||
6
.butcher/methods/createForumTopic/entity.json
generated
6
.butcher/methods/createForumTopic/entity.json
generated
|
|
@ -7,9 +7,9 @@
|
|||
"object": {
|
||||
"anchor": "createforumtopic",
|
||||
"name": "createForumTopic",
|
||||
"description": "Use this method to create a topic in a forum supergroup chat. The bot must be an administrator in the chat for this to work and must have the can_manage_topics administrator rights. Returns information about the created topic as a ForumTopic object.",
|
||||
"html_description": "<p>Use this method to create a topic in a forum supergroup chat. The bot must be an administrator in the chat for this to work and must have the <em>can_manage_topics</em> administrator rights. Returns information about the created topic as a <a href=\"#forumtopic\">ForumTopic</a> object.</p>",
|
||||
"rst_description": "Use this method to create a topic in a forum supergroup chat. The bot must be an administrator in the chat for this to work and must have the *can_manage_topics* administrator rights. Returns information about the created topic as a :class:`aiogram.types.forum_topic.ForumTopic` object.",
|
||||
"description": "Use this method to create a topic in a forum supergroup chat or a private chat with a user. In the case of a supergroup chat the bot must be an administrator in the chat for this to work and must have the can_manage_topics administrator right. Returns information about the created topic as a ForumTopic object.",
|
||||
"html_description": "<p>Use this method to create a topic in a forum supergroup chat or a private chat with a user. In the case of a supergroup chat the bot must be an administrator in the chat for this to work and must have the <em>can_manage_topics</em> administrator right. Returns information about the created topic as a <a href=\"#forumtopic\">ForumTopic</a> object.</p>",
|
||||
"rst_description": "Use this method to create a topic in a forum supergroup chat or a private chat with a user. In the case of a supergroup chat the bot must be an administrator in the chat for this to work and must have the *can_manage_topics* administrator right. Returns information about the created topic as a :class:`aiogram.types.forum_topic.ForumTopic` object.",
|
||||
"annotations": [
|
||||
{
|
||||
"type": "Integer or String",
|
||||
|
|
|
|||
41
.butcher/methods/getUserProfileAudios/entity.json
generated
Normal file
41
.butcher/methods/getUserProfileAudios/entity.json
generated
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"meta": {},
|
||||
"group": {
|
||||
"title": "Available methods",
|
||||
"anchor": "available-methods"
|
||||
},
|
||||
"object": {
|
||||
"anchor": "getuserprofileaudios",
|
||||
"name": "getUserProfileAudios",
|
||||
"description": "Use this method to get a list of profile audios for a user. Returns a UserProfileAudios object.",
|
||||
"html_description": "<p>Use this method to get a list of profile audios for a user. Returns a <a href=\"#userprofileaudios\">UserProfileAudios</a> object.</p>",
|
||||
"rst_description": "Use this method to get a list of profile audios for a user. Returns a :class:`aiogram.types.user_profile_audios.UserProfileAudios` object.",
|
||||
"annotations": [
|
||||
{
|
||||
"type": "Integer",
|
||||
"required": true,
|
||||
"description": "Unique identifier of the target user",
|
||||
"html_description": "<td>Unique identifier of the target user</td>",
|
||||
"rst_description": "Unique identifier of the target user\n",
|
||||
"name": "user_id"
|
||||
},
|
||||
{
|
||||
"type": "Integer",
|
||||
"required": false,
|
||||
"description": "Sequential number of the first audio to be returned. By default, all audios are returned.",
|
||||
"html_description": "<td>Sequential number of the first audio to be returned. By default, all audios are returned.</td>",
|
||||
"rst_description": "Sequential number of the first audio to be returned. By default, all audios are returned.\n",
|
||||
"name": "offset"
|
||||
},
|
||||
{
|
||||
"type": "Integer",
|
||||
"required": false,
|
||||
"description": "Limits the number of audios to be retrieved. Values between 1-100 are accepted. Defaults to 100.",
|
||||
"html_description": "<td>Limits the number of audios to be retrieved. Values between 1-100 are accepted. Defaults to 100.</td>",
|
||||
"rst_description": "Limits the number of audios to be retrieved. Values between 1-100 are accepted. Defaults to 100.\n",
|
||||
"name": "limit"
|
||||
}
|
||||
],
|
||||
"category": "methods"
|
||||
}
|
||||
}
|
||||
16
.butcher/methods/removeMyProfilePhoto/entity.json
generated
Normal file
16
.butcher/methods/removeMyProfilePhoto/entity.json
generated
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"meta": {},
|
||||
"group": {
|
||||
"title": "Available methods",
|
||||
"anchor": "available-methods"
|
||||
},
|
||||
"object": {
|
||||
"anchor": "removemyprofilephoto",
|
||||
"name": "removeMyProfilePhoto",
|
||||
"description": "Removes the profile photo of the bot. Requires no parameters. Returns True on success.",
|
||||
"html_description": "<p>Removes the profile photo of the bot. Requires no parameters. Returns <em>True</em> on success.</p>",
|
||||
"rst_description": "Removes the profile photo of the bot. Requires no parameters. Returns :code:`True` on success.",
|
||||
"annotations": [],
|
||||
"category": "methods"
|
||||
}
|
||||
}
|
||||
25
.butcher/methods/setMyProfilePhoto/entity.json
generated
Normal file
25
.butcher/methods/setMyProfilePhoto/entity.json
generated
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"meta": {},
|
||||
"group": {
|
||||
"title": "Available methods",
|
||||
"anchor": "available-methods"
|
||||
},
|
||||
"object": {
|
||||
"anchor": "setmyprofilephoto",
|
||||
"name": "setMyProfilePhoto",
|
||||
"description": "Changes the profile photo of the bot. Returns True on success.",
|
||||
"html_description": "<p>Changes the profile photo of the bot. Returns <em>True</em> on success.</p>",
|
||||
"rst_description": "Changes the profile photo of the bot. Returns :code:`True` on success.",
|
||||
"annotations": [
|
||||
{
|
||||
"type": "InputProfilePhoto",
|
||||
"required": true,
|
||||
"description": "The new profile photo to set",
|
||||
"html_description": "<td>The new profile photo to set</td>",
|
||||
"rst_description": "The new profile photo to set\n",
|
||||
"name": "photo"
|
||||
}
|
||||
],
|
||||
"category": "methods"
|
||||
}
|
||||
}
|
||||
309
.butcher/schema/schema.json
generated
309
.butcher/schema/schema.json
generated
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"api": {
|
||||
"version": "9.3",
|
||||
"release_date": "2025-12-31"
|
||||
"version": "9.4",
|
||||
"release_date": "2026-02-09"
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
|
|
@ -552,6 +552,14 @@
|
|||
"rst_description": "*Optional*. :code:`True`, if the bot has forum topic mode enabled in private chats. Returned only in :class:`aiogram.methods.get_me.GetMe`.\n",
|
||||
"name": "has_topics_enabled",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "Boolean",
|
||||
"description": "True, if the bot allows users to create and delete topics in private chats. Returned only in getMe.",
|
||||
"html_description": "<td><em>Optional</em>. <em>True</em>, if the bot allows users to create and delete topics in private chats. Returned only in <a href=\"#getme\">getMe</a>.</td>",
|
||||
"rst_description": "*Optional*. :code:`True`, if the bot allows users to create and delete topics in private chats. Returned only in :class:`aiogram.methods.get_me.GetMe`.\n",
|
||||
"name": "allows_users_to_create_topics",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"category": "types"
|
||||
|
|
@ -1021,6 +1029,14 @@
|
|||
"name": "rating",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "Audio",
|
||||
"description": "For private chats, the first audio added to the profile of the user",
|
||||
"html_description": "<td><em>Optional</em>. For private chats, the first audio added to the profile of the user</td>",
|
||||
"rst_description": "*Optional*. For private chats, the first audio added to the profile of the user\n",
|
||||
"name": "first_profile_audio",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "UniqueGiftColors",
|
||||
"description": "The color scheme based on a unique gift that must be used for the chat's name, message replies and link previews",
|
||||
|
|
@ -1479,6 +1495,22 @@
|
|||
"name": "left_chat_member",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "ChatOwnerLeft",
|
||||
"description": "Service message: chat owner has left",
|
||||
"html_description": "<td><em>Optional</em>. Service message: chat owner has left</td>",
|
||||
"rst_description": "*Optional*. Service message: chat owner has left\n",
|
||||
"name": "chat_owner_left",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "ChatOwnerChanged",
|
||||
"description": "Service message: chat owner has changed",
|
||||
"html_description": "<td><em>Optional</em>. Service message: chat owner has changed</td>",
|
||||
"rst_description": "*Optional*. Service message: chat owner has changed\n",
|
||||
"name": "chat_owner_changed",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "String",
|
||||
"description": "A chat title was changed to this value",
|
||||
|
|
@ -2794,6 +2826,64 @@
|
|||
],
|
||||
"category": "types"
|
||||
},
|
||||
{
|
||||
"anchor": "videoquality",
|
||||
"name": "VideoQuality",
|
||||
"description": "This object represents a video file of a specific quality.",
|
||||
"html_description": "<p>This object represents a video file of a specific quality.</p>",
|
||||
"rst_description": "This object represents a video file of a specific quality.",
|
||||
"annotations": [
|
||||
{
|
||||
"type": "String",
|
||||
"description": "Identifier for this file, which can be used to download or reuse the file",
|
||||
"html_description": "<td>Identifier for this file, which can be used to download or reuse the file</td>",
|
||||
"rst_description": "Identifier for this file, which can be used to download or reuse the file\n",
|
||||
"name": "file_id",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "String",
|
||||
"description": "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.",
|
||||
"html_description": "<td>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.</td>",
|
||||
"rst_description": "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.\n",
|
||||
"name": "file_unique_id",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "Integer",
|
||||
"description": "Video width",
|
||||
"html_description": "<td>Video width</td>",
|
||||
"rst_description": "Video width\n",
|
||||
"name": "width",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "Integer",
|
||||
"description": "Video height",
|
||||
"html_description": "<td>Video height</td>",
|
||||
"rst_description": "Video height\n",
|
||||
"name": "height",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "String",
|
||||
"description": "Codec that was used to encode the video, for example, 'h264', 'h265', or 'av01'",
|
||||
"html_description": "<td>Codec that was used to encode the video, for example, “h264”, “h265”, or “av01”</td>",
|
||||
"rst_description": "Codec that was used to encode the video, for example, 'h264', 'h265', or 'av01'\n",
|
||||
"name": "codec",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "Integer",
|
||||
"description": "File size in bytes. It can be bigger than 2^31 and some programming languages may have difficulty/silent defects in interpreting it. But it has at most 52 significant bits, so a signed 64-bit integer or double-precision float type are safe for storing this value.",
|
||||
"html_description": "<td><em>Optional</em>. File size in bytes. It can be bigger than 2^31 and some programming languages may have difficulty/silent defects in interpreting it. But it has at most 52 significant bits, so a signed 64-bit integer or double-precision float type are safe for storing this value.</td>",
|
||||
"rst_description": "*Optional*. File size in bytes. It can be bigger than 2^31 and some programming languages may have difficulty/silent defects in interpreting it. But it has at most 52 significant bits, so a signed 64-bit integer or double-precision float type are safe for storing this value.\n",
|
||||
"name": "file_size",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"category": "types"
|
||||
},
|
||||
{
|
||||
"anchor": "video",
|
||||
"name": "Video",
|
||||
|
|
@ -2865,6 +2955,14 @@
|
|||
"name": "start_timestamp",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "Array of VideoQuality",
|
||||
"description": "List of available qualities of the video",
|
||||
"html_description": "<td><em>Optional</em>. List of available qualities of the video</td>",
|
||||
"rst_description": "*Optional*. List of available qualities of the video\n",
|
||||
"name": "qualities",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "String",
|
||||
"description": "Original filename as defined by the sender",
|
||||
|
|
@ -5184,6 +5282,32 @@
|
|||
],
|
||||
"category": "types"
|
||||
},
|
||||
{
|
||||
"anchor": "userprofileaudios",
|
||||
"name": "UserProfileAudios",
|
||||
"description": "This object represents the audios displayed on a user's profile.",
|
||||
"html_description": "<p>This object represents the audios displayed on a user's profile.</p>",
|
||||
"rst_description": "This object represents the audios displayed on a user's profile.",
|
||||
"annotations": [
|
||||
{
|
||||
"type": "Integer",
|
||||
"description": "Total number of profile audios for the target user",
|
||||
"html_description": "<td>Total number of profile audios for the target user</td>",
|
||||
"rst_description": "Total number of profile audios for the target user\n",
|
||||
"name": "total_count",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "Array of Audio",
|
||||
"description": "Requested profile audios",
|
||||
"html_description": "<td>Requested profile audios</td>",
|
||||
"rst_description": "Requested profile audios\n",
|
||||
"name": "audios",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"category": "types"
|
||||
},
|
||||
{
|
||||
"anchor": "file",
|
||||
"name": "File",
|
||||
|
|
@ -5305,18 +5429,34 @@
|
|||
{
|
||||
"anchor": "keyboardbutton",
|
||||
"name": "KeyboardButton",
|
||||
"description": "This object represents one button of the reply keyboard. At most one of the optional fields must be used to specify type of the button. For simple text buttons, String can be used instead of this object to specify the button text.\nNote: request_users and request_chat options will only work in Telegram versions released after 3 February, 2023. Older clients will display unsupported message.",
|
||||
"html_description": "<p>This object represents one button of the reply keyboard. At most one of the optional fields must be used to specify type of the button. For simple text buttons, <em>String</em> can be used instead of this object to specify the button text.</p><p><strong>Note:</strong> <em>request_users</em> and <em>request_chat</em> options will only work in Telegram versions released after 3 February, 2023. Older clients will display <em>unsupported message</em>.</p>",
|
||||
"rst_description": "This object represents one button of the reply keyboard. At most one of the optional fields must be used to specify type of the button. For simple text buttons, *String* can be used instead of this object to specify the button text.\n**Note:** *request_users* and *request_chat* options will only work in Telegram versions released after 3 February, 2023. Older clients will display *unsupported message*.",
|
||||
"description": "This object represents one button of the reply keyboard. At most one of the fields other than text, icon_custom_emoji_id, and style must be used to specify the type of the button. For simple text buttons, String can be used instead of this object to specify the button text.",
|
||||
"html_description": "<p>This object represents one button of the reply keyboard. At most one of the fields other than <em>text</em>, <em>icon_custom_emoji_id</em>, and <em>style</em> must be used to specify the type of the button. For simple text buttons, <em>String</em> can be used instead of this object to specify the button text.</p>",
|
||||
"rst_description": "This object represents one button of the reply keyboard. At most one of the fields other than *text*, *icon_custom_emoji_id*, and *style* must be used to specify the type of the button. For simple text buttons, *String* can be used instead of this object to specify the button text.",
|
||||
"annotations": [
|
||||
{
|
||||
"type": "String",
|
||||
"description": "Text of the button. If none of the optional fields are used, it will be sent as a message when the button is pressed",
|
||||
"html_description": "<td>Text of the button. If none of the optional fields are used, it will be sent as a message when the button is pressed</td>",
|
||||
"rst_description": "Text of the button. If none of the optional fields are used, it will be sent as a message when the button is pressed\n",
|
||||
"description": "Text of the button. If none of the fields other than text, icon_custom_emoji_id, and style are used, it will be sent as a message when the button is pressed",
|
||||
"html_description": "<td>Text of the button. If none of the fields other than <em>text</em>, <em>icon_custom_emoji_id</em>, and <em>style</em> are used, it will be sent as a message when the button is pressed</td>",
|
||||
"rst_description": "Text of the button. If none of the fields other than *text*, *icon_custom_emoji_id*, and *style* are used, it will be sent as a message when the button is pressed\n",
|
||||
"name": "text",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "String",
|
||||
"description": "Unique identifier of the custom emoji shown before the text of the button. Can only be used by bots that purchased additional usernames on Fragment or in the messages directly sent by the bot to private, group and supergroup chats if the owner of the bot has a Telegram Premium subscription.",
|
||||
"html_description": "<td><em>Optional</em>. Unique identifier of the custom emoji shown before the text of the button. Can only be used by bots that purchased additional usernames on <a href=\"https://fragment.com\">Fragment</a> or in the messages directly sent by the bot to private, group and supergroup chats if the owner of the bot has a Telegram Premium subscription.</td>",
|
||||
"rst_description": "*Optional*. Unique identifier of the custom emoji shown before the text of the button. Can only be used by bots that purchased additional usernames on `Fragment <https://fragment.com>`_ or in the messages directly sent by the bot to private, group and supergroup chats if the owner of the bot has a Telegram Premium subscription.\n",
|
||||
"name": "icon_custom_emoji_id",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "String",
|
||||
"description": "Style of the button. Must be one of 'danger' (red), 'success' (green) or 'primary' (blue). If omitted, then an app-specific style is used.",
|
||||
"html_description": "<td><em>Optional</em>. Style of the button. Must be one of “danger” (red), “success” (green) or “primary” (blue). If omitted, then an app-specific style is used.</td>",
|
||||
"rst_description": "*Optional*. Style of the button. Must be one of 'danger' (red), 'success' (green) or 'primary' (blue). If omitted, then an app-specific style is used.\n",
|
||||
"name": "style",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "KeyboardButtonRequestUsers",
|
||||
"description": "If specified, pressing the button will open a list of suitable users. Identifiers of selected users will be sent to the bot in a 'users_shared' service message. Available in private chats only.",
|
||||
|
|
@ -5597,9 +5737,9 @@
|
|||
{
|
||||
"anchor": "inlinekeyboardbutton",
|
||||
"name": "InlineKeyboardButton",
|
||||
"description": "This object represents one button of an inline keyboard. Exactly one of the optional fields must be used to specify type of the button.",
|
||||
"html_description": "<p>This object represents one button of an inline keyboard. Exactly one of the optional fields must be used to specify type of the button.</p>",
|
||||
"rst_description": "This object represents one button of an inline keyboard. Exactly one of the optional fields must be used to specify type of the button.",
|
||||
"description": "This object represents one button of an inline keyboard. Exactly one of the fields other than text, icon_custom_emoji_id, and style must be used to specify the type of the button.",
|
||||
"html_description": "<p>This object represents one button of an inline keyboard. Exactly one of the fields other than <em>text</em>, <em>icon_custom_emoji_id</em>, and <em>style</em> must be used to specify the type of the button.</p>",
|
||||
"rst_description": "This object represents one button of an inline keyboard. Exactly one of the fields other than *text*, *icon_custom_emoji_id*, and *style* must be used to specify the type of the button.",
|
||||
"annotations": [
|
||||
{
|
||||
"type": "String",
|
||||
|
|
@ -5609,6 +5749,22 @@
|
|||
"name": "text",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "String",
|
||||
"description": "Unique identifier of the custom emoji shown before the text of the button. Can only be used by bots that purchased additional usernames on Fragment or in the messages directly sent by the bot to private, group and supergroup chats if the owner of the bot has a Telegram Premium subscription.",
|
||||
"html_description": "<td><em>Optional</em>. Unique identifier of the custom emoji shown before the text of the button. Can only be used by bots that purchased additional usernames on <a href=\"https://fragment.com\">Fragment</a> or in the messages directly sent by the bot to private, group and supergroup chats if the owner of the bot has a Telegram Premium subscription.</td>",
|
||||
"rst_description": "*Optional*. Unique identifier of the custom emoji shown before the text of the button. Can only be used by bots that purchased additional usernames on `Fragment <https://fragment.com>`_ or in the messages directly sent by the bot to private, group and supergroup chats if the owner of the bot has a Telegram Premium subscription.\n",
|
||||
"name": "icon_custom_emoji_id",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "String",
|
||||
"description": "Style of the button. Must be one of 'danger' (red), 'success' (green) or 'primary' (blue). If omitted, then an app-specific style is used.",
|
||||
"html_description": "<td><em>Optional</em>. Style of the button. Must be one of “danger” (red), “success” (green) or “primary” (blue). If omitted, then an app-specific style is used.</td>",
|
||||
"rst_description": "*Optional*. Style of the button. Must be one of 'danger' (red), 'success' (green) or 'primary' (blue). If omitted, then an app-specific style is used.\n",
|
||||
"name": "style",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "String",
|
||||
"description": "HTTP or tg:// URL to be opened when the button is pressed. Links tg://user?id=<user_id> can be used to mention a user by their identifier without using a username, if this is allowed by their privacy settings.",
|
||||
|
|
@ -7884,11 +8040,19 @@
|
|||
},
|
||||
{
|
||||
"type": "Integer",
|
||||
"description": "The number of unique gifts that receive this model for every 1000 gifts upgraded",
|
||||
"html_description": "<td>The number of unique gifts that receive this model for every 1000 gifts upgraded</td>",
|
||||
"rst_description": "The number of unique gifts that receive this model for every 1000 gifts upgraded\n",
|
||||
"description": "The number of unique gifts that receive this model for every 1000 gift upgrades. Always 0 for crafted gifts.",
|
||||
"html_description": "<td>The number of unique gifts that receive this model for every 1000 gift upgrades. Always 0 for crafted gifts.</td>",
|
||||
"rst_description": "The number of unique gifts that receive this model for every 1000 gift upgrades. Always 0 for crafted gifts.\n",
|
||||
"name": "rarity_per_mille",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "String",
|
||||
"description": "Rarity of the model if it is a crafted model. Currently, can be 'uncommon', 'rare', 'epic', or 'legendary'.",
|
||||
"html_description": "<td><em>Optional</em>. Rarity of the model if it is a crafted model. Currently, can be “uncommon”, “rare”, “epic”, or “legendary”.</td>",
|
||||
"rst_description": "*Optional*. Rarity of the model if it is a crafted model. Currently, can be 'uncommon', 'rare', 'epic', or 'legendary'.\n",
|
||||
"name": "rarity",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"category": "types"
|
||||
|
|
@ -8132,6 +8296,14 @@
|
|||
"name": "is_premium",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "True",
|
||||
"description": "True, if the gift was used to craft another gift and isn't available anymore",
|
||||
"html_description": "<td><em>Optional</em>. <em>True</em>, if the gift was used to craft another gift and isn't available anymore</td>",
|
||||
"rst_description": "*Optional*. :code:`True`, if the gift was used to craft another gift and isn't available anymore\n",
|
||||
"name": "is_burned",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "True",
|
||||
"description": "True, if the gift is assigned from the TON blockchain and can't be resold or transferred in Telegram",
|
||||
|
|
@ -9193,6 +9365,42 @@
|
|||
],
|
||||
"category": "types"
|
||||
},
|
||||
{
|
||||
"anchor": "chatownerleft",
|
||||
"name": "ChatOwnerLeft",
|
||||
"description": "Describes a service message about the chat owner leaving the chat.",
|
||||
"html_description": "<p>Describes a service message about the chat owner leaving the chat.</p>",
|
||||
"rst_description": "Describes a service message about the chat owner leaving the chat.",
|
||||
"annotations": [
|
||||
{
|
||||
"type": "User",
|
||||
"description": "The user which will be the new owner of the chat if the previous owner does not return to the chat",
|
||||
"html_description": "<td><em>Optional</em>. The user which will be the new owner of the chat if the previous owner does not return to the chat</td>",
|
||||
"rst_description": "*Optional*. The user which will be the new owner of the chat if the previous owner does not return to the chat\n",
|
||||
"name": "new_owner",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"category": "types"
|
||||
},
|
||||
{
|
||||
"anchor": "chatownerchanged",
|
||||
"name": "ChatOwnerChanged",
|
||||
"description": "Describes a service message about an ownership change in the chat.",
|
||||
"html_description": "<p>Describes a service message about an ownership change in the chat.</p>",
|
||||
"rst_description": "Describes a service message about an ownership change in the chat.",
|
||||
"annotations": [
|
||||
{
|
||||
"type": "User",
|
||||
"description": "The new owner of the chat",
|
||||
"html_description": "<td>The new owner of the chat</td>",
|
||||
"rst_description": "The new owner of the chat\n",
|
||||
"name": "new_owner",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"category": "types"
|
||||
},
|
||||
{
|
||||
"anchor": "userchatboosts",
|
||||
"name": "UserChatBoosts",
|
||||
|
|
@ -13040,6 +13248,40 @@
|
|||
],
|
||||
"category": "methods"
|
||||
},
|
||||
{
|
||||
"anchor": "getuserprofileaudios",
|
||||
"name": "getUserProfileAudios",
|
||||
"description": "Use this method to get a list of profile audios for a user. Returns a UserProfileAudios object.",
|
||||
"html_description": "<p>Use this method to get a list of profile audios for a user. Returns a <a href=\"#userprofileaudios\">UserProfileAudios</a> object.</p>",
|
||||
"rst_description": "Use this method to get a list of profile audios for a user. Returns a :class:`aiogram.types.user_profile_audios.UserProfileAudios` object.",
|
||||
"annotations": [
|
||||
{
|
||||
"type": "Integer",
|
||||
"required": true,
|
||||
"description": "Unique identifier of the target user",
|
||||
"html_description": "<td>Unique identifier of the target user</td>",
|
||||
"rst_description": "Unique identifier of the target user\n",
|
||||
"name": "user_id"
|
||||
},
|
||||
{
|
||||
"type": "Integer",
|
||||
"required": false,
|
||||
"description": "Sequential number of the first audio to be returned. By default, all audios are returned.",
|
||||
"html_description": "<td>Sequential number of the first audio to be returned. By default, all audios are returned.</td>",
|
||||
"rst_description": "Sequential number of the first audio to be returned. By default, all audios are returned.\n",
|
||||
"name": "offset"
|
||||
},
|
||||
{
|
||||
"type": "Integer",
|
||||
"required": false,
|
||||
"description": "Limits the number of audios to be retrieved. Values between 1-100 are accepted. Defaults to 100.",
|
||||
"html_description": "<td>Limits the number of audios to be retrieved. Values between 1-100 are accepted. Defaults to 100.</td>",
|
||||
"rst_description": "Limits the number of audios to be retrieved. Values between 1-100 are accepted. Defaults to 100.\n",
|
||||
"name": "limit"
|
||||
}
|
||||
],
|
||||
"category": "methods"
|
||||
},
|
||||
{
|
||||
"anchor": "setuseremojistatus",
|
||||
"name": "setUserEmojiStatus",
|
||||
|
|
@ -14116,9 +14358,9 @@
|
|||
{
|
||||
"anchor": "createforumtopic",
|
||||
"name": "createForumTopic",
|
||||
"description": "Use this method to create a topic in a forum supergroup chat. The bot must be an administrator in the chat for this to work and must have the can_manage_topics administrator rights. Returns information about the created topic as a ForumTopic object.",
|
||||
"html_description": "<p>Use this method to create a topic in a forum supergroup chat. The bot must be an administrator in the chat for this to work and must have the <em>can_manage_topics</em> administrator rights. Returns information about the created topic as a <a href=\"#forumtopic\">ForumTopic</a> object.</p>",
|
||||
"rst_description": "Use this method to create a topic in a forum supergroup chat. The bot must be an administrator in the chat for this to work and must have the *can_manage_topics* administrator rights. Returns information about the created topic as a :class:`aiogram.types.forum_topic.ForumTopic` object.",
|
||||
"description": "Use this method to create a topic in a forum supergroup chat or a private chat with a user. In the case of a supergroup chat the bot must be an administrator in the chat for this to work and must have the can_manage_topics administrator right. Returns information about the created topic as a ForumTopic object.",
|
||||
"html_description": "<p>Use this method to create a topic in a forum supergroup chat or a private chat with a user. In the case of a supergroup chat the bot must be an administrator in the chat for this to work and must have the <em>can_manage_topics</em> administrator right. Returns information about the created topic as a <a href=\"#forumtopic\">ForumTopic</a> object.</p>",
|
||||
"rst_description": "Use this method to create a topic in a forum supergroup chat or a private chat with a user. In the case of a supergroup chat the bot must be an administrator in the chat for this to work and must have the *can_manage_topics* administrator right. Returns information about the created topic as a :class:`aiogram.types.forum_topic.ForumTopic` object.",
|
||||
"annotations": [
|
||||
{
|
||||
"type": "Integer or String",
|
||||
|
|
@ -14729,6 +14971,33 @@
|
|||
],
|
||||
"category": "methods"
|
||||
},
|
||||
{
|
||||
"anchor": "setmyprofilephoto",
|
||||
"name": "setMyProfilePhoto",
|
||||
"description": "Changes the profile photo of the bot. Returns True on success.",
|
||||
"html_description": "<p>Changes the profile photo of the bot. Returns <em>True</em> on success.</p>",
|
||||
"rst_description": "Changes the profile photo of the bot. Returns :code:`True` on success.",
|
||||
"annotations": [
|
||||
{
|
||||
"type": "InputProfilePhoto",
|
||||
"required": true,
|
||||
"description": "The new profile photo to set",
|
||||
"html_description": "<td>The new profile photo to set</td>",
|
||||
"rst_description": "The new profile photo to set\n",
|
||||
"name": "photo"
|
||||
}
|
||||
],
|
||||
"category": "methods"
|
||||
},
|
||||
{
|
||||
"anchor": "removemyprofilephoto",
|
||||
"name": "removeMyProfilePhoto",
|
||||
"description": "Removes the profile photo of the bot. Requires no parameters. Returns True on success.",
|
||||
"html_description": "<p>Removes the profile photo of the bot. Requires no parameters. Returns <em>True</em> on success.</p>",
|
||||
"rst_description": "Removes the profile photo of the bot. Requires no parameters. Returns :code:`True` on success.",
|
||||
"annotations": [],
|
||||
"category": "methods"
|
||||
},
|
||||
{
|
||||
"anchor": "setchatmenubutton",
|
||||
"name": "setChatMenuButton",
|
||||
|
|
@ -22596,9 +22865,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",
|
||||
"html_description": "<p>This object represents one row of the high scores table for a game.</p><p>And that's about all we've got for now.<br/>\nIf you've got any questions, please check out our <a href=\"/bots/faq\"><strong>Bot FAQ »</strong></a></p>",
|
||||
"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 <https://core.telegram.org/bots/faq>`_ **Bot FAQ »**",
|
||||
"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": "<p>This object represents one row of the high scores table for a game.</p><p>And that's about all we've got for now.<br/>\nIf you've got any questions, please check out our <a href=\"/bots/faq\"><strong>Bot FAQ »</strong></a><br/>\n-</p>",
|
||||
"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 <https://core.telegram.org/bots/faq>`_ **Bot FAQ »**\n\n-",
|
||||
"annotations": [
|
||||
{
|
||||
"type": "Integer",
|
||||
|
|
|
|||
8
.butcher/types/ChatFullInfo/entity.json
generated
8
.butcher/types/ChatFullInfo/entity.json
generated
|
|
@ -395,6 +395,14 @@
|
|||
"name": "rating",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "Audio",
|
||||
"description": "For private chats, the first audio added to the profile of the user",
|
||||
"html_description": "<td><em>Optional</em>. For private chats, the first audio added to the profile of the user</td>",
|
||||
"rst_description": "*Optional*. For private chats, the first audio added to the profile of the user\n",
|
||||
"name": "first_profile_audio",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "UniqueGiftColors",
|
||||
"description": "The color scheme based on a unique gift that must be used for the chat's name, message replies and link previews",
|
||||
|
|
|
|||
25
.butcher/types/ChatOwnerChanged/entity.json
generated
Normal file
25
.butcher/types/ChatOwnerChanged/entity.json
generated
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"meta": {},
|
||||
"group": {
|
||||
"title": "Available types",
|
||||
"anchor": "available-types"
|
||||
},
|
||||
"object": {
|
||||
"anchor": "chatownerchanged",
|
||||
"name": "ChatOwnerChanged",
|
||||
"description": "Describes a service message about an ownership change in the chat.",
|
||||
"html_description": "<p>Describes a service message about an ownership change in the chat.</p>",
|
||||
"rst_description": "Describes a service message about an ownership change in the chat.",
|
||||
"annotations": [
|
||||
{
|
||||
"type": "User",
|
||||
"description": "The new owner of the chat",
|
||||
"html_description": "<td>The new owner of the chat</td>",
|
||||
"rst_description": "The new owner of the chat\n",
|
||||
"name": "new_owner",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"category": "types"
|
||||
}
|
||||
}
|
||||
25
.butcher/types/ChatOwnerLeft/entity.json
generated
Normal file
25
.butcher/types/ChatOwnerLeft/entity.json
generated
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"meta": {},
|
||||
"group": {
|
||||
"title": "Available types",
|
||||
"anchor": "available-types"
|
||||
},
|
||||
"object": {
|
||||
"anchor": "chatownerleft",
|
||||
"name": "ChatOwnerLeft",
|
||||
"description": "Describes a service message about the chat owner leaving the chat.",
|
||||
"html_description": "<p>Describes a service message about the chat owner leaving the chat.</p>",
|
||||
"rst_description": "Describes a service message about the chat owner leaving the chat.",
|
||||
"annotations": [
|
||||
{
|
||||
"type": "User",
|
||||
"description": "The user which will be the new owner of the chat if the previous owner does not return to the chat",
|
||||
"html_description": "<td><em>Optional</em>. The user which will be the new owner of the chat if the previous owner does not return to the chat</td>",
|
||||
"rst_description": "*Optional*. The user which will be the new owner of the chat if the previous owner does not return to the chat\n",
|
||||
"name": "new_owner",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"category": "types"
|
||||
}
|
||||
}
|
||||
6
.butcher/types/GameHighScore/entity.json
generated
6
.butcher/types/GameHighScore/entity.json
generated
|
|
@ -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",
|
||||
"html_description": "<p>This object represents one row of the high scores table for a game.</p><p>And that's about all we've got for now.<br/>\nIf you've got any questions, please check out our <a href=\"/bots/faq\"><strong>Bot FAQ »</strong></a></p>",
|
||||
"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 <https://core.telegram.org/bots/faq>`_ **Bot FAQ »**",
|
||||
"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": "<p>This object represents one row of the high scores table for a game.</p><p>And that's about all we've got for now.<br/>\nIf you've got any questions, please check out our <a href=\"/bots/faq\"><strong>Bot FAQ »</strong></a><br/>\n-</p>",
|
||||
"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 <https://core.telegram.org/bots/faq>`_ **Bot FAQ »**\n\n-",
|
||||
"annotations": [
|
||||
{
|
||||
"type": "Integer",
|
||||
|
|
|
|||
22
.butcher/types/InlineKeyboardButton/entity.json
generated
22
.butcher/types/InlineKeyboardButton/entity.json
generated
|
|
@ -7,9 +7,9 @@
|
|||
"object": {
|
||||
"anchor": "inlinekeyboardbutton",
|
||||
"name": "InlineKeyboardButton",
|
||||
"description": "This object represents one button of an inline keyboard. Exactly one of the optional fields must be used to specify type of the button.",
|
||||
"html_description": "<p>This object represents one button of an inline keyboard. Exactly one of the optional fields must be used to specify type of the button.</p>",
|
||||
"rst_description": "This object represents one button of an inline keyboard. Exactly one of the optional fields must be used to specify type of the button.",
|
||||
"description": "This object represents one button of an inline keyboard. Exactly one of the fields other than text, icon_custom_emoji_id, and style must be used to specify the type of the button.",
|
||||
"html_description": "<p>This object represents one button of an inline keyboard. Exactly one of the fields other than <em>text</em>, <em>icon_custom_emoji_id</em>, and <em>style</em> must be used to specify the type of the button.</p>",
|
||||
"rst_description": "This object represents one button of an inline keyboard. Exactly one of the fields other than *text*, *icon_custom_emoji_id*, and *style* must be used to specify the type of the button.",
|
||||
"annotations": [
|
||||
{
|
||||
"type": "String",
|
||||
|
|
@ -19,6 +19,22 @@
|
|||
"name": "text",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "String",
|
||||
"description": "Unique identifier of the custom emoji shown before the text of the button. Can only be used by bots that purchased additional usernames on Fragment or in the messages directly sent by the bot to private, group and supergroup chats if the owner of the bot has a Telegram Premium subscription.",
|
||||
"html_description": "<td><em>Optional</em>. Unique identifier of the custom emoji shown before the text of the button. Can only be used by bots that purchased additional usernames on <a href=\"https://fragment.com\">Fragment</a> or in the messages directly sent by the bot to private, group and supergroup chats if the owner of the bot has a Telegram Premium subscription.</td>",
|
||||
"rst_description": "*Optional*. Unique identifier of the custom emoji shown before the text of the button. Can only be used by bots that purchased additional usernames on `Fragment <https://fragment.com>`_ or in the messages directly sent by the bot to private, group and supergroup chats if the owner of the bot has a Telegram Premium subscription.\n",
|
||||
"name": "icon_custom_emoji_id",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "String",
|
||||
"description": "Style of the button. Must be one of 'danger' (red), 'success' (green) or 'primary' (blue). If omitted, then an app-specific style is used.",
|
||||
"html_description": "<td><em>Optional</em>. Style of the button. Must be one of “danger” (red), “success” (green) or “primary” (blue). If omitted, then an app-specific style is used.</td>",
|
||||
"rst_description": "*Optional*. Style of the button. Must be one of 'danger' (red), 'success' (green) or 'primary' (blue). If omitted, then an app-specific style is used.\n",
|
||||
"name": "style",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "String",
|
||||
"description": "HTTP or tg:// URL to be opened when the button is pressed. Links tg://user?id=<user_id> can be used to mention a user by their identifier without using a username, if this is allowed by their privacy settings.",
|
||||
|
|
|
|||
28
.butcher/types/KeyboardButton/entity.json
generated
28
.butcher/types/KeyboardButton/entity.json
generated
|
|
@ -7,18 +7,34 @@
|
|||
"object": {
|
||||
"anchor": "keyboardbutton",
|
||||
"name": "KeyboardButton",
|
||||
"description": "This object represents one button of the reply keyboard. At most one of the optional fields must be used to specify type of the button. For simple text buttons, String can be used instead of this object to specify the button text.\nNote: request_users and request_chat options will only work in Telegram versions released after 3 February, 2023. Older clients will display unsupported message.",
|
||||
"html_description": "<p>This object represents one button of the reply keyboard. At most one of the optional fields must be used to specify type of the button. For simple text buttons, <em>String</em> can be used instead of this object to specify the button text.</p><p><strong>Note:</strong> <em>request_users</em> and <em>request_chat</em> options will only work in Telegram versions released after 3 February, 2023. Older clients will display <em>unsupported message</em>.</p>",
|
||||
"rst_description": "This object represents one button of the reply keyboard. At most one of the optional fields must be used to specify type of the button. For simple text buttons, *String* can be used instead of this object to specify the button text.\n**Note:** *request_users* and *request_chat* options will only work in Telegram versions released after 3 February, 2023. Older clients will display *unsupported message*.",
|
||||
"description": "This object represents one button of the reply keyboard. At most one of the fields other than text, icon_custom_emoji_id, and style must be used to specify the type of the button. For simple text buttons, String can be used instead of this object to specify the button text.",
|
||||
"html_description": "<p>This object represents one button of the reply keyboard. At most one of the fields other than <em>text</em>, <em>icon_custom_emoji_id</em>, and <em>style</em> must be used to specify the type of the button. For simple text buttons, <em>String</em> can be used instead of this object to specify the button text.</p>",
|
||||
"rst_description": "This object represents one button of the reply keyboard. At most one of the fields other than *text*, *icon_custom_emoji_id*, and *style* must be used to specify the type of the button. For simple text buttons, *String* can be used instead of this object to specify the button text.",
|
||||
"annotations": [
|
||||
{
|
||||
"type": "String",
|
||||
"description": "Text of the button. If none of the optional fields are used, it will be sent as a message when the button is pressed",
|
||||
"html_description": "<td>Text of the button. If none of the optional fields are used, it will be sent as a message when the button is pressed</td>",
|
||||
"rst_description": "Text of the button. If none of the optional fields are used, it will be sent as a message when the button is pressed\n",
|
||||
"description": "Text of the button. If none of the fields other than text, icon_custom_emoji_id, and style are used, it will be sent as a message when the button is pressed",
|
||||
"html_description": "<td>Text of the button. If none of the fields other than <em>text</em>, <em>icon_custom_emoji_id</em>, and <em>style</em> are used, it will be sent as a message when the button is pressed</td>",
|
||||
"rst_description": "Text of the button. If none of the fields other than *text*, *icon_custom_emoji_id*, and *style* are used, it will be sent as a message when the button is pressed\n",
|
||||
"name": "text",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "String",
|
||||
"description": "Unique identifier of the custom emoji shown before the text of the button. Can only be used by bots that purchased additional usernames on Fragment or in the messages directly sent by the bot to private, group and supergroup chats if the owner of the bot has a Telegram Premium subscription.",
|
||||
"html_description": "<td><em>Optional</em>. Unique identifier of the custom emoji shown before the text of the button. Can only be used by bots that purchased additional usernames on <a href=\"https://fragment.com\">Fragment</a> or in the messages directly sent by the bot to private, group and supergroup chats if the owner of the bot has a Telegram Premium subscription.</td>",
|
||||
"rst_description": "*Optional*. Unique identifier of the custom emoji shown before the text of the button. Can only be used by bots that purchased additional usernames on `Fragment <https://fragment.com>`_ or in the messages directly sent by the bot to private, group and supergroup chats if the owner of the bot has a Telegram Premium subscription.\n",
|
||||
"name": "icon_custom_emoji_id",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "String",
|
||||
"description": "Style of the button. Must be one of 'danger' (red), 'success' (green) or 'primary' (blue). If omitted, then an app-specific style is used.",
|
||||
"html_description": "<td><em>Optional</em>. Style of the button. Must be one of “danger” (red), “success” (green) or “primary” (blue). If omitted, then an app-specific style is used.</td>",
|
||||
"rst_description": "*Optional*. Style of the button. Must be one of 'danger' (red), 'success' (green) or 'primary' (blue). If omitted, then an app-specific style is used.\n",
|
||||
"name": "style",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "KeyboardButtonRequestUsers",
|
||||
"description": "If specified, pressing the button will open a list of suitable users. Identifiers of selected users will be sent to the bot in a 'users_shared' service message. Available in private chats only.",
|
||||
|
|
|
|||
16
.butcher/types/Message/entity.json
generated
16
.butcher/types/Message/entity.json
generated
|
|
@ -443,6 +443,22 @@
|
|||
"name": "left_chat_member",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "ChatOwnerLeft",
|
||||
"description": "Service message: chat owner has left",
|
||||
"html_description": "<td><em>Optional</em>. Service message: chat owner has left</td>",
|
||||
"rst_description": "*Optional*. Service message: chat owner has left\n",
|
||||
"name": "chat_owner_left",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "ChatOwnerChanged",
|
||||
"description": "Service message: chat owner has changed",
|
||||
"html_description": "<td><em>Optional</em>. Service message: chat owner has changed</td>",
|
||||
"rst_description": "*Optional*. Service message: chat owner has changed\n",
|
||||
"name": "chat_owner_changed",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "String",
|
||||
"description": "A chat title was changed to this value",
|
||||
|
|
|
|||
8
.butcher/types/UniqueGift/entity.json
generated
8
.butcher/types/UniqueGift/entity.json
generated
|
|
@ -75,6 +75,14 @@
|
|||
"name": "is_premium",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "True",
|
||||
"description": "True, if the gift was used to craft another gift and isn't available anymore",
|
||||
"html_description": "<td><em>Optional</em>. <em>True</em>, if the gift was used to craft another gift and isn't available anymore</td>",
|
||||
"rst_description": "*Optional*. :code:`True`, if the gift was used to craft another gift and isn't available anymore\n",
|
||||
"name": "is_burned",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "True",
|
||||
"description": "True, if the gift is assigned from the TON blockchain and can't be resold or transferred in Telegram",
|
||||
|
|
|
|||
14
.butcher/types/UniqueGiftModel/entity.json
generated
14
.butcher/types/UniqueGiftModel/entity.json
generated
|
|
@ -29,11 +29,19 @@
|
|||
},
|
||||
{
|
||||
"type": "Integer",
|
||||
"description": "The number of unique gifts that receive this model for every 1000 gifts upgraded",
|
||||
"html_description": "<td>The number of unique gifts that receive this model for every 1000 gifts upgraded</td>",
|
||||
"rst_description": "The number of unique gifts that receive this model for every 1000 gifts upgraded\n",
|
||||
"description": "The number of unique gifts that receive this model for every 1000 gift upgrades. Always 0 for crafted gifts.",
|
||||
"html_description": "<td>The number of unique gifts that receive this model for every 1000 gift upgrades. Always 0 for crafted gifts.</td>",
|
||||
"rst_description": "The number of unique gifts that receive this model for every 1000 gift upgrades. Always 0 for crafted gifts.\n",
|
||||
"name": "rarity_per_mille",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "String",
|
||||
"description": "Rarity of the model if it is a crafted model. Currently, can be 'uncommon', 'rare', 'epic', or 'legendary'.",
|
||||
"html_description": "<td><em>Optional</em>. Rarity of the model if it is a crafted model. Currently, can be “uncommon”, “rare”, “epic”, or “legendary”.</td>",
|
||||
"rst_description": "*Optional*. Rarity of the model if it is a crafted model. Currently, can be 'uncommon', 'rare', 'epic', or 'legendary'.\n",
|
||||
"name": "rarity",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"category": "types"
|
||||
|
|
|
|||
|
|
@ -2,3 +2,7 @@ get_profile_photos:
|
|||
method: getUserProfilePhotos
|
||||
fill:
|
||||
user_id: self.id
|
||||
get_profile_audios:
|
||||
method: getUserProfileAudios
|
||||
fill:
|
||||
user_id: self.id
|
||||
|
|
|
|||
8
.butcher/types/User/entity.json
generated
8
.butcher/types/User/entity.json
generated
|
|
@ -122,6 +122,14 @@
|
|||
"rst_description": "*Optional*. :code:`True`, if the bot has forum topic mode enabled in private chats. Returned only in :class:`aiogram.methods.get_me.GetMe`.\n",
|
||||
"name": "has_topics_enabled",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "Boolean",
|
||||
"description": "True, if the bot allows users to create and delete topics in private chats. Returned only in getMe.",
|
||||
"html_description": "<td><em>Optional</em>. <em>True</em>, if the bot allows users to create and delete topics in private chats. Returned only in <a href=\"#getme\">getMe</a>.</td>",
|
||||
"rst_description": "*Optional*. :code:`True`, if the bot allows users to create and delete topics in private chats. Returned only in :class:`aiogram.methods.get_me.GetMe`.\n",
|
||||
"name": "allows_users_to_create_topics",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"category": "types"
|
||||
|
|
|
|||
33
.butcher/types/UserProfileAudios/entity.json
generated
Normal file
33
.butcher/types/UserProfileAudios/entity.json
generated
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"meta": {},
|
||||
"group": {
|
||||
"title": "Available types",
|
||||
"anchor": "available-types"
|
||||
},
|
||||
"object": {
|
||||
"anchor": "userprofileaudios",
|
||||
"name": "UserProfileAudios",
|
||||
"description": "This object represents the audios displayed on a user's profile.",
|
||||
"html_description": "<p>This object represents the audios displayed on a user's profile.</p>",
|
||||
"rst_description": "This object represents the audios displayed on a user's profile.",
|
||||
"annotations": [
|
||||
{
|
||||
"type": "Integer",
|
||||
"description": "Total number of profile audios for the target user",
|
||||
"html_description": "<td>Total number of profile audios for the target user</td>",
|
||||
"rst_description": "Total number of profile audios for the target user\n",
|
||||
"name": "total_count",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "Array of Audio",
|
||||
"description": "Requested profile audios",
|
||||
"html_description": "<td>Requested profile audios</td>",
|
||||
"rst_description": "Requested profile audios\n",
|
||||
"name": "audios",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"category": "types"
|
||||
}
|
||||
}
|
||||
8
.butcher/types/Video/entity.json
generated
8
.butcher/types/Video/entity.json
generated
|
|
@ -75,6 +75,14 @@
|
|||
"name": "start_timestamp",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "Array of VideoQuality",
|
||||
"description": "List of available qualities of the video",
|
||||
"html_description": "<td><em>Optional</em>. List of available qualities of the video</td>",
|
||||
"rst_description": "*Optional*. List of available qualities of the video\n",
|
||||
"name": "qualities",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"type": "String",
|
||||
"description": "Original filename as defined by the sender",
|
||||
|
|
|
|||
65
.butcher/types/VideoQuality/entity.json
generated
Normal file
65
.butcher/types/VideoQuality/entity.json
generated
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
{
|
||||
"meta": {},
|
||||
"group": {
|
||||
"title": "Available types",
|
||||
"anchor": "available-types"
|
||||
},
|
||||
"object": {
|
||||
"anchor": "videoquality",
|
||||
"name": "VideoQuality",
|
||||
"description": "This object represents a video file of a specific quality.",
|
||||
"html_description": "<p>This object represents a video file of a specific quality.</p>",
|
||||
"rst_description": "This object represents a video file of a specific quality.",
|
||||
"annotations": [
|
||||
{
|
||||
"type": "String",
|
||||
"description": "Identifier for this file, which can be used to download or reuse the file",
|
||||
"html_description": "<td>Identifier for this file, which can be used to download or reuse the file</td>",
|
||||
"rst_description": "Identifier for this file, which can be used to download or reuse the file\n",
|
||||
"name": "file_id",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "String",
|
||||
"description": "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.",
|
||||
"html_description": "<td>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.</td>",
|
||||
"rst_description": "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.\n",
|
||||
"name": "file_unique_id",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "Integer",
|
||||
"description": "Video width",
|
||||
"html_description": "<td>Video width</td>",
|
||||
"rst_description": "Video width\n",
|
||||
"name": "width",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "Integer",
|
||||
"description": "Video height",
|
||||
"html_description": "<td>Video height</td>",
|
||||
"rst_description": "Video height\n",
|
||||
"name": "height",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "String",
|
||||
"description": "Codec that was used to encode the video, for example, 'h264', 'h265', or 'av01'",
|
||||
"html_description": "<td>Codec that was used to encode the video, for example, “h264”, “h265”, or “av01”</td>",
|
||||
"rst_description": "Codec that was used to encode the video, for example, 'h264', 'h265', or 'av01'\n",
|
||||
"name": "codec",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "Integer",
|
||||
"description": "File size in bytes. It can be bigger than 2^31 and some programming languages may have difficulty/silent defects in interpreting it. But it has at most 52 significant bits, so a signed 64-bit integer or double-precision float type are safe for storing this value.",
|
||||
"html_description": "<td><em>Optional</em>. File size in bytes. It can be bigger than 2^31 and some programming languages may have difficulty/silent defects in interpreting it. But it has at most 52 significant bits, so a signed 64-bit integer or double-precision float type are safe for storing this value.</td>",
|
||||
"rst_description": "*Optional*. File size in bytes. It can be bigger than 2^31 and some programming languages may have difficulty/silent defects in interpreting it. But it has at most 52 significant bits, so a signed 64-bit integer or double-precision float type are safe for storing this value.\n",
|
||||
"name": "file_size",
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"category": "types"
|
||||
}
|
||||
}
|
||||
2
.github/workflows/tests.yml
vendored
2
.github/workflows/tests.yml
vendored
|
|
@ -72,7 +72,7 @@ jobs:
|
|||
run: |
|
||||
uv run ruff check --output-format=github aiogram examples
|
||||
uv run mypy aiogram
|
||||
uv run black --check --diff aiogram tests
|
||||
uv run ruff format --check --diff aiogram tests scripts examples
|
||||
|
||||
- name: Setup redis
|
||||
if: ${{ env.IS_WINDOWS == 'false' }}
|
||||
|
|
|
|||
|
|
@ -13,13 +13,10 @@ repos:
|
|||
- id: "check-toml"
|
||||
- id: "check-json"
|
||||
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 25.9.0
|
||||
hooks:
|
||||
- id: black
|
||||
files: &files '^(aiogram|tests|examples)'
|
||||
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: 'v0.14.0'
|
||||
hooks:
|
||||
- id: ruff
|
||||
files: &files '^(aiogram|tests|examples)'
|
||||
- id: ruff-format
|
||||
files: *files
|
||||
|
|
|
|||
82
CHANGES.rst
82
CHANGES.rst
|
|
@ -16,6 +16,88 @@ Changelog
|
|||
|
||||
.. towncrier release notes start
|
||||
|
||||
3.25.0 (2026-02-10)
|
||||
====================
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- Add full_name property to Contact and corresponding tests
|
||||
`#1758 <https://github.com/aiogram/aiogram/issues/1758>`_
|
||||
- Updated to `Bot API 9.4 (February 9, 2026) <https://core.telegram.org/bots/api-changelog#february-9-2026>`_
|
||||
|
||||
**New Features:**
|
||||
|
||||
- Bots with Premium subscriptions can now use custom emoji directly in messages to private, group, and supergroup chats
|
||||
- Bots can create topics in private chats via the :class:`aiogram.methods.create_forum_topic.CreateForumTopic` method
|
||||
- Bots can prevent users from creating/deleting topics in private chats through BotFather settings
|
||||
|
||||
**New Fields:**
|
||||
|
||||
- Added :code:`allows_users_to_create_topics` field to :class:`aiogram.types.user.User` class - indicates whether the user allows others to create topics in chats with them
|
||||
- Added :code:`icon_custom_emoji_id` field to :class:`aiogram.types.keyboard_button.KeyboardButton` and :class:`aiogram.types.inline_keyboard_button.InlineKeyboardButton` classes - allows displaying custom emoji icons on buttons
|
||||
- Added :code:`style` field to :class:`aiogram.types.keyboard_button.KeyboardButton` and :class:`aiogram.types.inline_keyboard_button.InlineKeyboardButton` classes - changes button color/style
|
||||
- Added :code:`chat_owner_left` field to :class:`aiogram.types.message.Message` class - service message indicating chat owner has left (type: :class:`aiogram.types.chat_owner_left.ChatOwnerLeft`)
|
||||
- Added :code:`chat_owner_changed` field to :class:`aiogram.types.message.Message` class - service message indicating chat ownership has transferred (type: :class:`aiogram.types.chat_owner_changed.ChatOwnerChanged`)
|
||||
- Added :code:`qualities` field to :class:`aiogram.types.video.Video` class - list of available video quality options (type: :code:`list[`:class:`aiogram.types.video_quality.VideoQuality`:code:`]`)
|
||||
- Added :code:`first_profile_audio` field to :class:`aiogram.types.chat_full_info.ChatFullInfo` class - user's first profile audio
|
||||
- Added :code:`rarity` field to :class:`aiogram.types.unique_gift_model.UniqueGiftModel` class
|
||||
- Added :code:`is_burned` field to :class:`aiogram.types.unique_gift.UniqueGift` class
|
||||
|
||||
**New Methods:**
|
||||
|
||||
- Added :class:`aiogram.methods.set_my_profile_photo.SetMyProfilePhoto` method - allows bots to set their profile photo
|
||||
- Added :class:`aiogram.methods.remove_my_profile_photo.RemoveMyProfilePhoto` method - allows bots to remove their profile photo
|
||||
- Added :class:`aiogram.methods.get_user_profile_audios.GetUserProfileAudios` method - retrieves a user's profile audio list
|
||||
- Added :meth:`aiogram.types.user.User.get_profile_audios` shortcut - creates a prefilled :class:`aiogram.methods.get_user_profile_audios.GetUserProfileAudios` request with :code:`user_id`
|
||||
|
||||
**New Types:**
|
||||
|
||||
- Added :class:`aiogram.types.chat_owner_left.ChatOwnerLeft` type - describes a service message about the chat owner leaving the chat
|
||||
- Added :class:`aiogram.types.chat_owner_changed.ChatOwnerChanged` type - describes a service message about an ownership change in the chat
|
||||
- Added :class:`aiogram.types.video_quality.VideoQuality` type - describes available video quality options
|
||||
- Added :class:`aiogram.types.user_profile_audios.UserProfileAudios` type - represents the collection of audios displayed on a user's profile
|
||||
|
||||
`#1761 <https://github.com/aiogram/aiogram/issues/1761>`_
|
||||
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Fixed scene handling for ``channel_post`` and ``edited_channel_post`` when Scenes are registered but FSM state is unavailable, and added channel-scoped FSM context support for ``CHAT``/``CHAT_TOPIC`` strategies.
|
||||
`#1743 <https://github.com/aiogram/aiogram/issues/1743>`_
|
||||
|
||||
|
||||
Misc
|
||||
----
|
||||
|
||||
- Migrated from Black and isort to Ruff for code formatting and linting, a modern, blazingly fast formatter and linter written in Rust.
|
||||
|
||||
Enabled additional ruff rule sets.
|
||||
|
||||
**For end users:**
|
||||
|
||||
No changes required. This is purely a development tooling change that doesn't affect the library API or behavior.
|
||||
|
||||
**For contributors:**
|
||||
|
||||
- Use ``make reformat`` or ``uv run ruff format`` to format code (replaces ``black`` and ``isort``)
|
||||
- Use ``make lint`` to check code quality (now includes formatting, linting, and type checking)
|
||||
- Pre-commit hooks automatically updated to use ``ruff`` and ``ruff-format``
|
||||
- CI/CD pipelines updated to use ruff in GitHub Actions workflows
|
||||
|
||||
**Benefits:**
|
||||
|
||||
- 10-100x faster formatting and linting compared to Black + isort + flake8
|
||||
- Single tool for formatting, import sorting, and linting
|
||||
- More comprehensive code quality checks out of the box
|
||||
- Auto-fixes for many common issues (33 issues auto-fixed during migration)
|
||||
- Better integration with modern Python development workflows
|
||||
|
||||
This change improves the developer experience and code quality while maintaining the same code style standards.
|
||||
`#1750 <https://github.com/aiogram/aiogram/issues/1750>`_
|
||||
|
||||
|
||||
3.24.0 (2026-01-02)
|
||||
====================
|
||||
|
||||
|
|
|
|||
7
Makefile
7
Makefile
|
|
@ -37,15 +37,14 @@ install: clean
|
|||
|
||||
.PHONY: lint
|
||||
lint:
|
||||
uv run isort --check-only $(code_dir)
|
||||
uv run black --check --diff $(code_dir)
|
||||
uv run ruff format --check --diff $(package_dir)
|
||||
uv run ruff check --show-fixes --preview $(package_dir) $(examples_dir)
|
||||
uv run mypy $(package_dir)
|
||||
|
||||
.PHONY: reformat
|
||||
reformat:
|
||||
uv run black $(code_dir)
|
||||
uv run isort $(code_dir)
|
||||
uv run ruff format $(code_dir)
|
||||
uv run ruff check --fix $(code_dir)
|
||||
|
||||
# =================================================================================================
|
||||
# Tests
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ Features
|
|||
- Asynchronous (`asyncio docs <https://docs.python.org/3/library/asyncio.html>`_, :pep:`492`)
|
||||
- Has type hints (:pep:`484`) and can be used with `mypy <http://mypy-lang.org/>`_
|
||||
- Supports `PyPy <https://www.pypy.org/>`_
|
||||
- Supports `Telegram Bot API 9.3 <https://core.telegram.org/bots/api>`_ and gets fast updates to the latest versions of the Bot API
|
||||
- Supports `Telegram Bot API 9.4 <https://core.telegram.org/bots/api>`_ and gets fast updates to the latest versions of the Bot API
|
||||
- Telegram Bot API integration code was `autogenerated <https://github.com/aiogram/tg-codegen>`_ and can be easily re-generated when API gets updated
|
||||
- Updates router (Blueprints)
|
||||
- Has Finite State Machine
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
__version__ = "3.24.0"
|
||||
__api_version__ = "9.3"
|
||||
__version__ = "3.25.0"
|
||||
__api_version__ = "9.4"
|
||||
|
|
|
|||
|
|
@ -2,12 +2,11 @@ from __future__ import annotations
|
|||
|
||||
import io
|
||||
import pathlib
|
||||
from collections.abc import AsyncGenerator, AsyncIterator
|
||||
from contextlib import asynccontextmanager
|
||||
from types import TracebackType
|
||||
from typing import (
|
||||
Any,
|
||||
AsyncGenerator,
|
||||
AsyncIterator,
|
||||
BinaryIO,
|
||||
TypeVar,
|
||||
cast,
|
||||
|
|
@ -93,6 +92,7 @@ from ..methods import (
|
|||
GetUpdates,
|
||||
GetUserChatBoosts,
|
||||
GetUserGifts,
|
||||
GetUserProfileAudios,
|
||||
GetUserProfilePhotos,
|
||||
GetWebhookInfo,
|
||||
GiftPremiumSubscription,
|
||||
|
|
@ -106,6 +106,7 @@ from ..methods import (
|
|||
RefundStarPayment,
|
||||
RemoveBusinessAccountProfilePhoto,
|
||||
RemoveChatVerification,
|
||||
RemoveMyProfilePhoto,
|
||||
RemoveUserVerification,
|
||||
ReopenForumTopic,
|
||||
ReopenGeneralForumTopic,
|
||||
|
|
@ -155,6 +156,7 @@ from ..methods import (
|
|||
SetMyDefaultAdministratorRights,
|
||||
SetMyDescription,
|
||||
SetMyName,
|
||||
SetMyProfilePhoto,
|
||||
SetMyShortDescription,
|
||||
SetPassportDataErrors,
|
||||
SetStickerEmojiList,
|
||||
|
|
@ -242,6 +244,7 @@ from ..types import (
|
|||
Update,
|
||||
User,
|
||||
UserChatBoosts,
|
||||
UserProfileAudios,
|
||||
UserProfilePhotos,
|
||||
WebhookInfo,
|
||||
)
|
||||
|
|
@ -283,9 +286,9 @@ class Bot:
|
|||
# Few arguments are completely removed in 3.7.0 version
|
||||
# Temporary solution to raise an error if user passed these arguments
|
||||
# with explanation how to fix it
|
||||
parse_mode = kwargs.get("parse_mode", None)
|
||||
link_preview_is_disabled = kwargs.get("disable_web_page_preview", None)
|
||||
protect_content = kwargs.get("protect_content", None)
|
||||
parse_mode = kwargs.get("parse_mode")
|
||||
link_preview_is_disabled = kwargs.get("disable_web_page_preview")
|
||||
protect_content = kwargs.get("protect_content")
|
||||
if (
|
||||
parse_mode is not None
|
||||
or link_preview_is_disabled is not None
|
||||
|
|
@ -310,7 +313,7 @@ class Bot:
|
|||
self.__token = token
|
||||
self._me: User | None = None
|
||||
|
||||
async def __aenter__(self) -> "Bot":
|
||||
async def __aenter__(self) -> Bot:
|
||||
return self
|
||||
|
||||
async def __aexit__(
|
||||
|
|
@ -912,7 +915,7 @@ class Bot:
|
|||
request_timeout: int | None = None,
|
||||
) -> ForumTopic:
|
||||
"""
|
||||
Use this method to create a topic in a forum supergroup chat. The bot must be an administrator in the chat for this to work and must have the *can_manage_topics* administrator rights. Returns information about the created topic as a :class:`aiogram.types.forum_topic.ForumTopic` object.
|
||||
Use this method to create a topic in a forum supergroup chat or a private chat with a user. In the case of a supergroup chat the bot must be an administrator in the chat for this to work and must have the *can_manage_topics* administrator right. Returns information about the created topic as a :class:`aiogram.types.forum_topic.ForumTopic` object.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#createforumtopic
|
||||
|
||||
|
|
@ -5843,3 +5846,65 @@ class Bot:
|
|||
entities=entities,
|
||||
)
|
||||
return await self(call, request_timeout=request_timeout)
|
||||
|
||||
async def get_user_profile_audios(
|
||||
self,
|
||||
user_id: int,
|
||||
offset: int | None = None,
|
||||
limit: int | None = None,
|
||||
request_timeout: int | None = None,
|
||||
) -> UserProfileAudios:
|
||||
"""
|
||||
Use this method to get a list of profile audios for a user. Returns a :class:`aiogram.types.user_profile_audios.UserProfileAudios` object.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#getuserprofileaudios
|
||||
|
||||
:param user_id: Unique identifier of the target user
|
||||
:param offset: Sequential number of the first audio to be returned. By default, all audios are returned.
|
||||
:param limit: Limits the number of audios to be retrieved. Values between 1-100 are accepted. Defaults to 100.
|
||||
:param request_timeout: Request timeout
|
||||
:return: Returns a :class:`aiogram.types.user_profile_audios.UserProfileAudios` object.
|
||||
"""
|
||||
|
||||
call = GetUserProfileAudios(
|
||||
user_id=user_id,
|
||||
offset=offset,
|
||||
limit=limit,
|
||||
)
|
||||
return await self(call, request_timeout=request_timeout)
|
||||
|
||||
async def remove_my_profile_photo(
|
||||
self,
|
||||
request_timeout: int | None = None,
|
||||
) -> bool:
|
||||
"""
|
||||
Removes the profile photo of the bot. Requires no parameters. Returns :code:`True` on success.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#removemyprofilephoto
|
||||
|
||||
:param request_timeout: Request timeout
|
||||
:return: Returns :code:`True` on success.
|
||||
"""
|
||||
|
||||
call = RemoveMyProfilePhoto()
|
||||
return await self(call, request_timeout=request_timeout)
|
||||
|
||||
async def set_my_profile_photo(
|
||||
self,
|
||||
photo: InputProfilePhotoUnion,
|
||||
request_timeout: int | None = None,
|
||||
) -> bool:
|
||||
"""
|
||||
Changes the profile photo of the bot. Returns :code:`True` on success.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#setmyprofilephoto
|
||||
|
||||
:param photo: The new profile photo to set
|
||||
:param request_timeout: Request timeout
|
||||
:return: Returns :code:`True` on success.
|
||||
"""
|
||||
|
||||
call = SetMyProfilePhoto(
|
||||
photo=photo,
|
||||
)
|
||||
return await self(call, request_timeout=request_timeout)
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ def _prepare_connector(chain_or_plain: _ProxyType) -> tuple[type[TCPConnector],
|
|||
# since tuple is Iterable(compatible with _ProxyChain) object, we assume that
|
||||
# user wants chained proxies if tuple is a pair of string(url) and BasicAuth
|
||||
if isinstance(chain_or_plain, str) or (
|
||||
isinstance(chain_or_plain, tuple) and len(chain_or_plain) == 2
|
||||
isinstance(chain_or_plain, tuple) and len(chain_or_plain) == 2 # noqa: PLR2004
|
||||
):
|
||||
chain_or_plain = cast(_ProxyBasic, chain_or_plain)
|
||||
return ProxyConnector, _retrieve_basic(chain_or_plain)
|
||||
|
|
@ -170,10 +170,10 @@ class AiohttpSession(BaseSession):
|
|||
timeout=self.timeout if timeout is None else timeout,
|
||||
) as resp:
|
||||
raw_result = await resp.text()
|
||||
except asyncio.TimeoutError:
|
||||
raise TelegramNetworkError(method=method, message="Request timeout error")
|
||||
except asyncio.TimeoutError as e:
|
||||
raise TelegramNetworkError(method=method, message="Request timeout error") from e
|
||||
except ClientError as e:
|
||||
raise TelegramNetworkError(method=method, message=f"{type(e).__name__}: {e}")
|
||||
raise TelegramNetworkError(method=method, message=f"{type(e).__name__}: {e}") from e
|
||||
response = self.check_response(
|
||||
bot=bot,
|
||||
method=method,
|
||||
|
|
|
|||
|
|
@ -90,14 +90,14 @@ class BaseSession(abc.ABC):
|
|||
# in due to decoder can be customized and raise any exception
|
||||
|
||||
msg = "Failed to decode object"
|
||||
raise ClientDecodeError(msg, e, content)
|
||||
raise ClientDecodeError(msg, e, content) from e
|
||||
|
||||
try:
|
||||
response_type = Response[method.__returning__] # type: ignore
|
||||
response = response_type.model_validate(json_data, context={"bot": bot})
|
||||
except ValidationError as e:
|
||||
msg = "Failed to deserialize object"
|
||||
raise ClientDecodeError(msg, e, json_data)
|
||||
raise ClientDecodeError(msg, e, json_data) from e
|
||||
|
||||
if HTTPStatus.OK <= status_code <= HTTPStatus.IM_USED and response.ok:
|
||||
return response
|
||||
|
|
|
|||
|
|
@ -21,10 +21,10 @@ class FlagDecorator:
|
|||
flag: Flag
|
||||
|
||||
@classmethod
|
||||
def _with_flag(cls, flag: Flag) -> "FlagDecorator":
|
||||
def _with_flag(cls, flag: Flag) -> FlagDecorator:
|
||||
return cls(flag)
|
||||
|
||||
def _with_value(self, value: Any) -> "FlagDecorator":
|
||||
def _with_value(self, value: Any) -> FlagDecorator:
|
||||
new_flag = Flag(self.flag.name, value)
|
||||
return self._with_flag(new_flag)
|
||||
|
||||
|
|
@ -33,11 +33,11 @@ class FlagDecorator:
|
|||
pass
|
||||
|
||||
@overload
|
||||
def __call__(self, value: Any, /) -> "FlagDecorator":
|
||||
def __call__(self, value: Any, /) -> FlagDecorator:
|
||||
pass
|
||||
|
||||
@overload
|
||||
def __call__(self, **kwargs: Any) -> "FlagDecorator":
|
||||
def __call__(self, **kwargs: Any) -> FlagDecorator:
|
||||
pass
|
||||
|
||||
def __call__(
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
from .bot_command_scope_type import BotCommandScopeType
|
||||
from .button_style import ButtonStyle
|
||||
from .chat_action import ChatAction
|
||||
from .chat_boost_source_type import ChatBoostSourceType
|
||||
from .chat_member_status import ChatMemberStatus
|
||||
|
|
@ -36,6 +37,7 @@ from .update_type import UpdateType
|
|||
|
||||
__all__ = (
|
||||
"BotCommandScopeType",
|
||||
"ButtonStyle",
|
||||
"ChatAction",
|
||||
"ChatBoostSourceType",
|
||||
"ChatMemberStatus",
|
||||
|
|
|
|||
15
aiogram/enums/button_style.py
Normal file
15
aiogram/enums/button_style.py
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
from enum import Enum
|
||||
|
||||
|
||||
class ButtonStyle(str, Enum):
|
||||
"""
|
||||
This object represents a button style (inline- or reply-keyboard).
|
||||
|
||||
Sources:
|
||||
* https://core.telegram.org/bots/api#inlinekeyboardbutton
|
||||
* https://core.telegram.org/bots/api#keyboardbutton
|
||||
"""
|
||||
|
||||
DANGER = "danger"
|
||||
SUCCESS = "success"
|
||||
PRIMARY = "primary"
|
||||
|
|
@ -28,6 +28,8 @@ class ContentType(str, Enum):
|
|||
LOCATION = "location"
|
||||
NEW_CHAT_MEMBERS = "new_chat_members"
|
||||
LEFT_CHAT_MEMBER = "left_chat_member"
|
||||
CHAT_OWNER_LEFT = "chat_owner_left"
|
||||
CHAT_OWNER_CHANGED = "chat_owner_changed"
|
||||
NEW_CHAT_TITLE = "new_chat_title"
|
||||
NEW_CHAT_PHOTO = "new_chat_photo"
|
||||
DELETE_CHAT_PHOTO = "delete_chat_photo"
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ class _MemberStatusMarker:
|
|||
def __or__(
|
||||
self,
|
||||
other: _MemberStatusMarker | _MemberStatusGroupMarker,
|
||||
) -> "_MemberStatusGroupMarker":
|
||||
) -> _MemberStatusGroupMarker:
|
||||
if isinstance(other, _MemberStatusMarker):
|
||||
return _MemberStatusGroupMarker(self, other)
|
||||
if isinstance(other, _MemberStatusGroupMarker):
|
||||
|
|
@ -53,7 +53,7 @@ class _MemberStatusMarker:
|
|||
def __rshift__(
|
||||
self,
|
||||
other: _MemberStatusMarker | _MemberStatusGroupMarker,
|
||||
) -> "_MemberStatusTransition":
|
||||
) -> _MemberStatusTransition:
|
||||
old = _MemberStatusGroupMarker(self)
|
||||
if isinstance(other, _MemberStatusMarker):
|
||||
return _MemberStatusTransition(old=old, new=_MemberStatusGroupMarker(other))
|
||||
|
|
@ -68,7 +68,7 @@ class _MemberStatusMarker:
|
|||
def __lshift__(
|
||||
self,
|
||||
other: _MemberStatusMarker | _MemberStatusGroupMarker,
|
||||
) -> "_MemberStatusTransition":
|
||||
) -> _MemberStatusTransition:
|
||||
new = _MemberStatusGroupMarker(self)
|
||||
if isinstance(other, _MemberStatusMarker):
|
||||
return _MemberStatusTransition(old=_MemberStatusGroupMarker(other), new=new)
|
||||
|
|
@ -118,7 +118,7 @@ class _MemberStatusGroupMarker:
|
|||
def __rshift__(
|
||||
self,
|
||||
other: _MemberStatusMarker | _MemberStatusGroupMarker,
|
||||
) -> "_MemberStatusTransition":
|
||||
) -> _MemberStatusTransition:
|
||||
if isinstance(other, _MemberStatusMarker):
|
||||
return _MemberStatusTransition(old=self, new=_MemberStatusGroupMarker(other))
|
||||
if isinstance(other, _MemberStatusGroupMarker):
|
||||
|
|
@ -132,7 +132,7 @@ class _MemberStatusGroupMarker:
|
|||
def __lshift__(
|
||||
self,
|
||||
other: _MemberStatusMarker | _MemberStatusGroupMarker,
|
||||
) -> "_MemberStatusTransition":
|
||||
) -> _MemberStatusTransition:
|
||||
if isinstance(other, _MemberStatusMarker):
|
||||
return _MemberStatusTransition(old=_MemberStatusGroupMarker(other), new=self)
|
||||
if isinstance(other, _MemberStatusGroupMarker):
|
||||
|
|
|
|||
|
|
@ -123,14 +123,15 @@ class Command(Filter):
|
|||
result.update(command.magic_result)
|
||||
return result
|
||||
|
||||
def extract_command(self, text: str) -> CommandObject:
|
||||
@classmethod
|
||||
def extract_command(cls, text: str) -> CommandObject:
|
||||
# First step: separate command with arguments
|
||||
# "/command@mention arg1 arg2" -> "/command@mention", ["arg1 arg2"]
|
||||
try:
|
||||
full_command, *args = text.split(maxsplit=1)
|
||||
except ValueError:
|
||||
except ValueError as e:
|
||||
msg = "not enough values to unpack"
|
||||
raise CommandException(msg)
|
||||
raise CommandException(msg) from e
|
||||
|
||||
# Separate command into valuable parts
|
||||
# "/command@mention" -> "/", ("command", "@", "mention")
|
||||
|
|
@ -292,6 +293,6 @@ class CommandStart(Command):
|
|||
args = decode_payload(args)
|
||||
except UnicodeDecodeError as e:
|
||||
msg = f"Failed to decode Base64: {e}"
|
||||
raise CommandException(msg)
|
||||
raise CommandException(msg) from e
|
||||
return replace(command, args=args)
|
||||
return command
|
||||
|
|
|
|||
|
|
@ -70,6 +70,9 @@ class FSMContextMiddleware(BaseMiddleware):
|
|||
) -> FSMContext | None:
|
||||
if chat_id is None:
|
||||
chat_id = user_id
|
||||
elif user_id is None and self.strategy in {FSMStrategy.CHAT, FSMStrategy.CHAT_TOPIC}:
|
||||
# CHAT/CHAT_TOPIC are chat-scoped, so missing user_id can fallback to chat_id.
|
||||
user_id = chat_id
|
||||
|
||||
if chat_id is not None and user_id is not None:
|
||||
chat_id, user_id, thread_id = apply_strategy(
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ class ObserverDecorator:
|
|||
handlers = getattr(target, "__aiogram_handler__", None)
|
||||
if not handlers:
|
||||
handlers = []
|
||||
setattr(target, "__aiogram_handler__", handlers)
|
||||
target.__aiogram_handler__ = handlers # type: ignore[union-attr]
|
||||
|
||||
handlers.append(
|
||||
HandlerContainer(
|
||||
|
|
@ -137,7 +137,7 @@ class ObserverDecorator:
|
|||
action = getattr(target, "__aiogram_action__", None)
|
||||
if action is None:
|
||||
action = defaultdict(dict)
|
||||
setattr(target, "__aiogram_action__", action)
|
||||
target.__aiogram_action__ = action # type: ignore[attr-defined]
|
||||
action[self.action][self.name] = CallableObject(target)
|
||||
|
||||
def __call__(self, target: CallbackType) -> CallbackType:
|
||||
|
|
@ -248,8 +248,16 @@ class SceneHandlerWrapper:
|
|||
event: TelegramObject,
|
||||
**kwargs: Any,
|
||||
) -> Any:
|
||||
state: FSMContext = kwargs["state"]
|
||||
scenes: ScenesManager = kwargs["scenes"]
|
||||
try:
|
||||
state: FSMContext = kwargs["state"]
|
||||
scenes: ScenesManager = kwargs["scenes"]
|
||||
except KeyError as error:
|
||||
missing_key = error.args[0]
|
||||
msg = (
|
||||
f"Scene context key {missing_key!r} is not available. "
|
||||
"Ensure FSM is enabled and pipeline is intact."
|
||||
)
|
||||
raise SceneException(msg) from None
|
||||
event_update: Update = kwargs["event_update"]
|
||||
scene = self.scene(
|
||||
wizard=SceneWizard(
|
||||
|
|
@ -768,12 +776,15 @@ class SceneRegistry:
|
|||
data: dict[str, Any],
|
||||
) -> Any:
|
||||
assert isinstance(event, Update), "Event must be an Update instance"
|
||||
state = data.get("state")
|
||||
if state is None:
|
||||
return await handler(event, data)
|
||||
|
||||
data["scenes"] = ScenesManager(
|
||||
registry=self,
|
||||
update_type=event.event_type,
|
||||
event=event.event,
|
||||
state=data["state"],
|
||||
state=state,
|
||||
data=data,
|
||||
)
|
||||
return await handler(event, data)
|
||||
|
|
@ -784,12 +795,16 @@ class SceneRegistry:
|
|||
event: TelegramObject,
|
||||
data: dict[str, Any],
|
||||
) -> Any:
|
||||
state = data.get("state")
|
||||
if state is None:
|
||||
return await handler(event, data)
|
||||
|
||||
update: Update = data["event_update"]
|
||||
data["scenes"] = ScenesManager(
|
||||
registry=self,
|
||||
update_type=update.event_type,
|
||||
event=event,
|
||||
state=data["state"],
|
||||
state=state,
|
||||
data=data,
|
||||
)
|
||||
return await handler(event, data)
|
||||
|
|
@ -865,7 +880,7 @@ class SceneRegistry:
|
|||
return self._scenes[scene]
|
||||
except KeyError:
|
||||
msg = f"Scene {scene!r} is not registered"
|
||||
raise SceneException(msg)
|
||||
raise SceneException(msg) from None
|
||||
|
||||
|
||||
@dataclass
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ from .get_sticker_set import GetStickerSet
|
|||
from .get_updates import GetUpdates
|
||||
from .get_user_chat_boosts import GetUserChatBoosts
|
||||
from .get_user_gifts import GetUserGifts
|
||||
from .get_user_profile_audios import GetUserProfileAudios
|
||||
from .get_user_profile_photos import GetUserProfilePhotos
|
||||
from .get_webhook_info import GetWebhookInfo
|
||||
from .gift_premium_subscription import GiftPremiumSubscription
|
||||
|
|
@ -87,6 +88,7 @@ from .read_business_message import ReadBusinessMessage
|
|||
from .refund_star_payment import RefundStarPayment
|
||||
from .remove_business_account_profile_photo import RemoveBusinessAccountProfilePhoto
|
||||
from .remove_chat_verification import RemoveChatVerification
|
||||
from .remove_my_profile_photo import RemoveMyProfilePhoto
|
||||
from .remove_user_verification import RemoveUserVerification
|
||||
from .reopen_forum_topic import ReopenForumTopic
|
||||
from .reopen_general_forum_topic import ReopenGeneralForumTopic
|
||||
|
|
@ -136,6 +138,7 @@ from .set_my_commands import SetMyCommands
|
|||
from .set_my_default_administrator_rights import SetMyDefaultAdministratorRights
|
||||
from .set_my_description import SetMyDescription
|
||||
from .set_my_name import SetMyName
|
||||
from .set_my_profile_photo import SetMyProfilePhoto
|
||||
from .set_my_short_description import SetMyShortDescription
|
||||
from .set_passport_data_errors import SetPassportDataErrors
|
||||
from .set_sticker_emoji_list import SetStickerEmojiList
|
||||
|
|
@ -238,6 +241,7 @@ __all__ = (
|
|||
"GetUpdates",
|
||||
"GetUserChatBoosts",
|
||||
"GetUserGifts",
|
||||
"GetUserProfileAudios",
|
||||
"GetUserProfilePhotos",
|
||||
"GetWebhookInfo",
|
||||
"GiftPremiumSubscription",
|
||||
|
|
@ -251,6 +255,7 @@ __all__ = (
|
|||
"RefundStarPayment",
|
||||
"RemoveBusinessAccountProfilePhoto",
|
||||
"RemoveChatVerification",
|
||||
"RemoveMyProfilePhoto",
|
||||
"RemoveUserVerification",
|
||||
"ReopenForumTopic",
|
||||
"ReopenGeneralForumTopic",
|
||||
|
|
@ -302,6 +307,7 @@ __all__ = (
|
|||
"SetMyDefaultAdministratorRights",
|
||||
"SetMyDescription",
|
||||
"SetMyName",
|
||||
"SetMyProfilePhoto",
|
||||
"SetMyShortDescription",
|
||||
"SetPassportDataErrors",
|
||||
"SetStickerEmojiList",
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
from collections.abc import Generator
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
Any,
|
||||
ClassVar,
|
||||
Generator,
|
||||
Generic,
|
||||
TypeVar,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ from .base import TelegramMethod
|
|||
|
||||
class CreateForumTopic(TelegramMethod[ForumTopic]):
|
||||
"""
|
||||
Use this method to create a topic in a forum supergroup chat. The bot must be an administrator in the chat for this to work and must have the *can_manage_topics* administrator rights. Returns information about the created topic as a :class:`aiogram.types.forum_topic.ForumTopic` object.
|
||||
Use this method to create a topic in a forum supergroup chat or a private chat with a user. In the case of a supergroup chat the bot must be an administrator in the chat for this to work and must have the *can_manage_topics* administrator right. Returns information about the created topic as a :class:`aiogram.types.forum_topic.ForumTopic` object.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#createforumtopic
|
||||
"""
|
||||
|
|
|
|||
42
aiogram/methods/get_user_profile_audios.py
Normal file
42
aiogram/methods/get_user_profile_audios.py
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from ..types import UserProfileAudios
|
||||
from .base import TelegramMethod
|
||||
|
||||
|
||||
class GetUserProfileAudios(TelegramMethod[UserProfileAudios]):
|
||||
"""
|
||||
Use this method to get a list of profile audios for a user. Returns a :class:`aiogram.types.user_profile_audios.UserProfileAudios` object.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#getuserprofileaudios
|
||||
"""
|
||||
|
||||
__returning__ = UserProfileAudios
|
||||
__api_method__ = "getUserProfileAudios"
|
||||
|
||||
user_id: int
|
||||
"""Unique identifier of the target user"""
|
||||
offset: int | None = None
|
||||
"""Sequential number of the first audio to be returned. By default, all audios are returned."""
|
||||
limit: int | None = None
|
||||
"""Limits the number of audios to be retrieved. Values between 1-100 are accepted. Defaults to 100."""
|
||||
|
||||
if TYPE_CHECKING:
|
||||
# DO NOT EDIT MANUALLY!!!
|
||||
# This section was auto-generated via `butcher`
|
||||
|
||||
def __init__(
|
||||
__pydantic__self__,
|
||||
*,
|
||||
user_id: int,
|
||||
offset: int | None = None,
|
||||
limit: int | 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__(user_id=user_id, offset=offset, limit=limit, **__pydantic_kwargs)
|
||||
14
aiogram/methods/remove_my_profile_photo.py
Normal file
14
aiogram/methods/remove_my_profile_photo.py
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from .base import TelegramMethod
|
||||
|
||||
|
||||
class RemoveMyProfilePhoto(TelegramMethod[bool]):
|
||||
"""
|
||||
Removes the profile photo of the bot. Requires no parameters. Returns :code:`True` on success.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#removemyprofilephoto
|
||||
"""
|
||||
|
||||
__returning__ = bool
|
||||
__api_method__ = "removeMyProfilePhoto"
|
||||
33
aiogram/methods/set_my_profile_photo.py
Normal file
33
aiogram/methods/set_my_profile_photo.py
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from ..types import InputProfilePhotoUnion
|
||||
from .base import TelegramMethod
|
||||
|
||||
|
||||
class SetMyProfilePhoto(TelegramMethod[bool]):
|
||||
"""
|
||||
Changes the profile photo of the bot. Returns :code:`True` on success.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#setmyprofilephoto
|
||||
"""
|
||||
|
||||
__returning__ = bool
|
||||
__api_method__ = "setMyProfilePhoto"
|
||||
|
||||
photo: InputProfilePhotoUnion
|
||||
"""The new profile photo to set"""
|
||||
|
||||
if TYPE_CHECKING:
|
||||
# DO NOT EDIT MANUALLY!!!
|
||||
# This section was auto-generated via `butcher`
|
||||
|
||||
def __init__(
|
||||
__pydantic__self__, *, photo: InputProfilePhotoUnion, **__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__(photo=photo, **__pydantic_kwargs)
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
from typing import List, Literal, Optional, Union
|
||||
from typing import Literal, Optional, Union
|
||||
|
||||
from .accepted_gift_types import AcceptedGiftTypes
|
||||
from .affiliate_info import AffiliateInfo
|
||||
|
|
@ -387,6 +387,8 @@ __all__ = (
|
|||
"ChatMemberRestricted",
|
||||
"ChatMemberUnion",
|
||||
"ChatMemberUpdated",
|
||||
"ChatOwnerChanged",
|
||||
"ChatOwnerLeft",
|
||||
"ChatPermissions",
|
||||
"ChatPhoto",
|
||||
"ChatShared",
|
||||
|
|
@ -627,6 +629,7 @@ __all__ = (
|
|||
"Update",
|
||||
"User",
|
||||
"UserChatBoosts",
|
||||
"UserProfileAudios",
|
||||
"UserProfilePhotos",
|
||||
"UserRating",
|
||||
"UserShared",
|
||||
|
|
@ -638,6 +641,7 @@ __all__ = (
|
|||
"VideoChatScheduled",
|
||||
"VideoChatStarted",
|
||||
"VideoNote",
|
||||
"VideoQuality",
|
||||
"Voice",
|
||||
"WebAppData",
|
||||
"WebAppInfo",
|
||||
|
|
@ -646,6 +650,10 @@ __all__ = (
|
|||
)
|
||||
|
||||
from ..client.default import Default as _Default
|
||||
from .chat_owner_changed import ChatOwnerChanged
|
||||
from .chat_owner_left import ChatOwnerLeft
|
||||
from .user_profile_audios import UserProfileAudios
|
||||
from .video_quality import VideoQuality
|
||||
|
||||
# Load typing forward refs for every TelegramObject
|
||||
for _entity_name in __all__:
|
||||
|
|
@ -654,7 +662,7 @@ for _entity_name in __all__:
|
|||
continue
|
||||
_entity.model_rebuild(
|
||||
_types_namespace={
|
||||
"List": List,
|
||||
"List": list,
|
||||
"Optional": Optional,
|
||||
"Union": Union,
|
||||
"Literal": Literal,
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ from .custom import DateTime
|
|||
|
||||
if TYPE_CHECKING:
|
||||
from .accepted_gift_types import AcceptedGiftTypes
|
||||
from .audio import Audio
|
||||
from .birthdate import Birthdate
|
||||
from .business_intro import BusinessIntro
|
||||
from .business_location import BusinessLocation
|
||||
|
|
@ -125,6 +126,8 @@ class ChatFullInfo(Chat):
|
|||
"""*Optional*. For supergroups, the location to which the supergroup is connected"""
|
||||
rating: UserRating | None = None
|
||||
"""*Optional*. For private chats, the rating of the user if any"""
|
||||
first_profile_audio: Audio | None = None
|
||||
"""*Optional*. For private chats, the first audio added to the profile of the user"""
|
||||
unique_gift_colors: UniqueGiftColors | None = None
|
||||
"""*Optional*. The color scheme based on a unique gift that must be used for the chat's name, message replies and link previews"""
|
||||
paid_message_star_count: int | None = None
|
||||
|
|
@ -190,6 +193,7 @@ class ChatFullInfo(Chat):
|
|||
linked_chat_id: int | None = None,
|
||||
location: ChatLocation | None = None,
|
||||
rating: UserRating | None = None,
|
||||
first_profile_audio: Audio | None = None,
|
||||
unique_gift_colors: UniqueGiftColors | None = None,
|
||||
paid_message_star_count: int | None = None,
|
||||
can_send_gift: bool | None = None,
|
||||
|
|
@ -248,6 +252,7 @@ class ChatFullInfo(Chat):
|
|||
linked_chat_id=linked_chat_id,
|
||||
location=location,
|
||||
rating=rating,
|
||||
first_profile_audio=first_profile_audio,
|
||||
unique_gift_colors=unique_gift_colors,
|
||||
paid_message_star_count=paid_message_star_count,
|
||||
can_send_gift=can_send_gift,
|
||||
|
|
|
|||
30
aiogram/types/chat_owner_changed.py
Normal file
30
aiogram/types/chat_owner_changed.py
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from .base import TelegramObject
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .user import User
|
||||
|
||||
|
||||
class ChatOwnerChanged(TelegramObject):
|
||||
"""
|
||||
Describes a service message about an ownership change in the chat.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#chatownerchanged
|
||||
"""
|
||||
|
||||
new_owner: User
|
||||
"""The new owner of the chat"""
|
||||
|
||||
if TYPE_CHECKING:
|
||||
# DO NOT EDIT MANUALLY!!!
|
||||
# This section was auto-generated via `butcher`
|
||||
|
||||
def __init__(__pydantic__self__, *, new_owner: User, **__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__(new_owner=new_owner, **__pydantic_kwargs)
|
||||
32
aiogram/types/chat_owner_left.py
Normal file
32
aiogram/types/chat_owner_left.py
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from .base import TelegramObject
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .user import User
|
||||
|
||||
|
||||
class ChatOwnerLeft(TelegramObject):
|
||||
"""
|
||||
Describes a service message about the chat owner leaving the chat.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#chatownerleft
|
||||
"""
|
||||
|
||||
new_owner: User | None = None
|
||||
"""*Optional*. The user which will be the new owner of the chat if the previous owner does not return to the chat"""
|
||||
|
||||
if TYPE_CHECKING:
|
||||
# DO NOT EDIT MANUALLY!!!
|
||||
# This section was auto-generated via `butcher`
|
||||
|
||||
def __init__(
|
||||
__pydantic__self__, *, new_owner: User | 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__(new_owner=new_owner, **__pydantic_kwargs)
|
||||
|
|
@ -49,3 +49,9 @@ class Contact(TelegramObject):
|
|||
vcard=vcard,
|
||||
**__pydantic_kwargs,
|
||||
)
|
||||
|
||||
@property
|
||||
def full_name(self) -> str:
|
||||
if self.last_name:
|
||||
return f"{self.first_name} {self.last_name}"
|
||||
return self.first_name
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import sys
|
||||
from datetime import datetime, timezone
|
||||
from typing import Annotated
|
||||
|
||||
from pydantic import PlainSerializer
|
||||
from typing_extensions import Annotated
|
||||
|
||||
if sys.platform == "win32": # pragma: no cover
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ class GameHighScore(TelegramObject):
|
|||
|
||||
If you've got any questions, please check out our `https://core.telegram.org/bots/faq <https://core.telegram.org/bots/faq>`_ **Bot FAQ »**
|
||||
|
||||
-
|
||||
|
||||
Source: https://core.telegram.org/bots/api#gamehighscore
|
||||
"""
|
||||
|
||||
|
|
|
|||
|
|
@ -130,9 +130,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendMessage
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendMessage(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -208,9 +208,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendMessage
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendMessage(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -298,9 +298,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendAnimation
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendAnimation(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -391,9 +391,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendAnimation
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendAnimation(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -483,9 +483,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendAudio
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendAudio(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -571,9 +571,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendAudio
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendAudio(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -652,9 +652,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendContact
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendContact(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -727,9 +727,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendContact
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendContact(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -808,9 +808,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendDocument
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendDocument(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -889,9 +889,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendDocument
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendDocument(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -958,9 +958,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendGame
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendGame(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -1018,9 +1018,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendGame
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendGame(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -1122,9 +1122,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendInvoice
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendInvoice(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -1245,9 +1245,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendInvoice
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendInvoice(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -1342,9 +1342,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendLocation
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendLocation(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -1423,9 +1423,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendLocation
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendLocation(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -1492,9 +1492,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendMediaGroup
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendMediaGroup(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -1552,9 +1552,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendMediaGroup
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendMediaGroup(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -1628,9 +1628,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendPhoto
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendPhoto(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -1709,9 +1709,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendPhoto
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendPhoto(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -1804,9 +1804,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendPoll
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendPoll(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -1903,9 +1903,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendPoll
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendPoll(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -1982,9 +1982,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendDice
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendDice(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -2048,9 +2048,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendDice
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendDice(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -2118,9 +2118,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendSticker
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendSticker(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -2187,9 +2187,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendSticker
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendSticker(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -2270,9 +2270,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendVenue
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendVenue(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -2357,9 +2357,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendVenue
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendVenue(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -2456,9 +2456,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendVideo
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendVideo(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -2558,9 +2558,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendVideo
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendVideo(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -2644,9 +2644,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendVideoNote
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendVideoNote(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -2719,9 +2719,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendVideoNote
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendVideoNote(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -2798,9 +2798,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendVoice
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendVoice(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -2876,9 +2876,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendVoice
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendVoice(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -2954,9 +2954,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendPaidMedia
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendPaidMedia(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -3031,9 +3031,9 @@ class InaccessibleMessage(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendPaidMedia
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendPaidMedia(
|
||||
chat_id=self.chat.id,
|
||||
|
|
|
|||
|
|
@ -14,13 +14,17 @@ if TYPE_CHECKING:
|
|||
|
||||
class InlineKeyboardButton(MutableTelegramObject):
|
||||
"""
|
||||
This object represents one button of an inline keyboard. Exactly one of the optional fields must be used to specify type of the button.
|
||||
This object represents one button of an inline keyboard. Exactly one of the fields other than *text*, *icon_custom_emoji_id*, and *style* must be used to specify the type of the button.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#inlinekeyboardbutton
|
||||
"""
|
||||
|
||||
text: str
|
||||
"""Label text on the button"""
|
||||
icon_custom_emoji_id: str | None = None
|
||||
"""*Optional*. Unique identifier of the custom emoji shown before the text of the button. Can only be used by bots that purchased additional usernames on `Fragment <https://fragment.com>`_ or in the messages directly sent by the bot to private, group and supergroup chats if the owner of the bot has a Telegram Premium subscription."""
|
||||
style: str | None = None
|
||||
"""*Optional*. Style of the button. Must be one of 'danger' (red), 'success' (green) or 'primary' (blue). If omitted, then an app-specific style is used."""
|
||||
url: str | None = None
|
||||
"""*Optional*. HTTP or tg:// URL to be opened when the button is pressed. Links :code:`tg://user?id=<user_id>` can be used to mention a user by their identifier without using a username, if this is allowed by their privacy settings."""
|
||||
callback_data: str | None = None
|
||||
|
|
@ -50,6 +54,8 @@ class InlineKeyboardButton(MutableTelegramObject):
|
|||
__pydantic__self__,
|
||||
*,
|
||||
text: str,
|
||||
icon_custom_emoji_id: str | None = None,
|
||||
style: str | None = None,
|
||||
url: str | None = None,
|
||||
callback_data: str | None = None,
|
||||
web_app: WebAppInfo | None = None,
|
||||
|
|
@ -68,6 +74,8 @@ class InlineKeyboardButton(MutableTelegramObject):
|
|||
|
||||
super().__init__(
|
||||
text=text,
|
||||
icon_custom_emoji_id=icon_custom_emoji_id,
|
||||
style=style,
|
||||
url=url,
|
||||
callback_data=callback_data,
|
||||
web_app=web_app,
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ from __future__ import annotations
|
|||
import io
|
||||
import os
|
||||
from abc import ABC, abstractmethod
|
||||
from collections.abc import AsyncGenerator
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, Any, AsyncGenerator
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
import aiofiles
|
||||
|
||||
|
|
@ -33,7 +34,7 @@ class InputFile(ABC):
|
|||
self.chunk_size = chunk_size
|
||||
|
||||
@abstractmethod
|
||||
async def read(self, bot: "Bot") -> AsyncGenerator[bytes, None]: # pragma: no cover
|
||||
async def read(self, bot: Bot) -> AsyncGenerator[bytes, None]: # pragma: no cover
|
||||
yield b""
|
||||
|
||||
|
||||
|
|
@ -72,7 +73,7 @@ class BufferedInputFile(InputFile):
|
|||
data = f.read()
|
||||
return cls(data, filename=filename, chunk_size=chunk_size)
|
||||
|
||||
async def read(self, bot: "Bot") -> AsyncGenerator[bytes, None]:
|
||||
async def read(self, bot: Bot) -> AsyncGenerator[bytes, None]:
|
||||
buffer = io.BytesIO(self.data)
|
||||
while chunk := buffer.read(self.chunk_size):
|
||||
yield chunk
|
||||
|
|
@ -99,7 +100,7 @@ class FSInputFile(InputFile):
|
|||
|
||||
self.path = path
|
||||
|
||||
async def read(self, bot: "Bot") -> AsyncGenerator[bytes, None]:
|
||||
async def read(self, bot: Bot) -> AsyncGenerator[bytes, None]:
|
||||
async with aiofiles.open(self.path, "rb") as f:
|
||||
while chunk := await f.read(self.chunk_size):
|
||||
yield chunk
|
||||
|
|
@ -135,7 +136,7 @@ class URLInputFile(InputFile):
|
|||
self.timeout = timeout
|
||||
self.bot = bot
|
||||
|
||||
async def read(self, bot: "Bot") -> AsyncGenerator[bytes, None]:
|
||||
async def read(self, bot: Bot) -> AsyncGenerator[bytes, None]:
|
||||
bot = self.bot or bot
|
||||
stream = bot.session.stream_content(
|
||||
url=self.url,
|
||||
|
|
|
|||
|
|
@ -16,14 +16,17 @@ if TYPE_CHECKING:
|
|||
|
||||
class KeyboardButton(MutableTelegramObject):
|
||||
"""
|
||||
This object represents one button of the reply keyboard. At most one of the optional fields must be used to specify type of the button. For simple text buttons, *String* can be used instead of this object to specify the button text.
|
||||
**Note:** *request_users* and *request_chat* options will only work in Telegram versions released after 3 February, 2023. Older clients will display *unsupported message*.
|
||||
This object represents one button of the reply keyboard. At most one of the fields other than *text*, *icon_custom_emoji_id*, and *style* must be used to specify the type of the button. For simple text buttons, *String* can be used instead of this object to specify the button text.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#keyboardbutton
|
||||
"""
|
||||
|
||||
text: str
|
||||
"""Text of the button. If none of the optional fields are used, it will be sent as a message when the button is pressed"""
|
||||
"""Text of the button. If none of the fields other than *text*, *icon_custom_emoji_id*, and *style* are used, it will be sent as a message when the button is pressed"""
|
||||
icon_custom_emoji_id: str | None = None
|
||||
"""*Optional*. Unique identifier of the custom emoji shown before the text of the button. Can only be used by bots that purchased additional usernames on `Fragment <https://fragment.com>`_ or in the messages directly sent by the bot to private, group and supergroup chats if the owner of the bot has a Telegram Premium subscription."""
|
||||
style: str | None = None
|
||||
"""*Optional*. Style of the button. Must be one of 'danger' (red), 'success' (green) or 'primary' (blue). If omitted, then an app-specific style is used."""
|
||||
request_users: KeyboardButtonRequestUsers | None = None
|
||||
"""*Optional*. If specified, pressing the button will open a list of suitable users. Identifiers of selected users will be sent to the bot in a 'users_shared' service message. Available in private chats only."""
|
||||
request_chat: KeyboardButtonRequestChat | None = None
|
||||
|
|
@ -52,6 +55,8 @@ class KeyboardButton(MutableTelegramObject):
|
|||
__pydantic__self__,
|
||||
*,
|
||||
text: str,
|
||||
icon_custom_emoji_id: str | None = None,
|
||||
style: str | None = None,
|
||||
request_users: KeyboardButtonRequestUsers | None = None,
|
||||
request_chat: KeyboardButtonRequestChat | None = None,
|
||||
request_contact: bool | None = None,
|
||||
|
|
@ -67,6 +72,8 @@ class KeyboardButton(MutableTelegramObject):
|
|||
|
||||
super().__init__(
|
||||
text=text,
|
||||
icon_custom_emoji_id=icon_custom_emoji_id,
|
||||
style=style,
|
||||
request_users=request_users,
|
||||
request_chat=request_chat,
|
||||
request_contact=request_contact,
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@ if TYPE_CHECKING:
|
|||
from .chat_background import ChatBackground
|
||||
from .chat_boost_added import ChatBoostAdded
|
||||
from .chat_id_union import ChatIdUnion
|
||||
from .chat_owner_changed import ChatOwnerChanged
|
||||
from .chat_owner_left import ChatOwnerLeft
|
||||
from .chat_shared import ChatShared
|
||||
from .checklist import Checklist
|
||||
from .checklist_tasks_added import ChecklistTasksAdded
|
||||
|
|
@ -245,6 +247,10 @@ class Message(MaybeInaccessibleMessage):
|
|||
"""*Optional*. New members that were added to the group or supergroup and information about them (the bot itself may be one of these members)"""
|
||||
left_chat_member: User | None = None
|
||||
"""*Optional*. A member was removed from the group, information about them (this member may be the bot itself)"""
|
||||
chat_owner_left: ChatOwnerLeft | None = None
|
||||
"""*Optional*. Service message: chat owner has left"""
|
||||
chat_owner_changed: ChatOwnerChanged | None = None
|
||||
"""*Optional*. Service message: chat owner has changed"""
|
||||
new_chat_title: str | None = None
|
||||
"""*Optional*. A chat title was changed to this value"""
|
||||
new_chat_photo: list[PhotoSize] | None = None
|
||||
|
|
@ -440,6 +446,8 @@ class Message(MaybeInaccessibleMessage):
|
|||
location: Location | None = None,
|
||||
new_chat_members: list[User] | None = None,
|
||||
left_chat_member: User | None = None,
|
||||
chat_owner_left: ChatOwnerLeft | None = None,
|
||||
chat_owner_changed: ChatOwnerChanged | None = None,
|
||||
new_chat_title: str | None = None,
|
||||
new_chat_photo: list[PhotoSize] | None = None,
|
||||
delete_chat_photo: bool | None = None,
|
||||
|
|
@ -557,6 +565,8 @@ class Message(MaybeInaccessibleMessage):
|
|||
location=location,
|
||||
new_chat_members=new_chat_members,
|
||||
left_chat_member=left_chat_member,
|
||||
chat_owner_left=chat_owner_left,
|
||||
chat_owner_changed=chat_owner_changed,
|
||||
new_chat_title=new_chat_title,
|
||||
new_chat_photo=new_chat_photo,
|
||||
delete_chat_photo=delete_chat_photo,
|
||||
|
|
@ -650,6 +660,10 @@ class Message(MaybeInaccessibleMessage):
|
|||
return ContentType.NEW_CHAT_MEMBERS
|
||||
if self.left_chat_member:
|
||||
return ContentType.LEFT_CHAT_MEMBER
|
||||
if self.chat_owner_left:
|
||||
return ContentType.CHAT_OWNER_LEFT
|
||||
if self.chat_owner_changed:
|
||||
return ContentType.CHAT_OWNER_CHANGED
|
||||
if self.invoice:
|
||||
return ContentType.INVOICE
|
||||
if self.successful_payment:
|
||||
|
|
@ -851,9 +865,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendAnimation
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendAnimation(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -944,9 +958,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendAnimation
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendAnimation(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -1032,9 +1046,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendAudio
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendAudio(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -1120,9 +1134,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendAudio
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendAudio(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -1197,9 +1211,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendContact
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendContact(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -1272,9 +1286,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendContact
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendContact(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -1349,9 +1363,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendDocument
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendDocument(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -1430,9 +1444,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendDocument
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendDocument(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -1495,9 +1509,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendGame
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendGame(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -1555,9 +1569,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendGame
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendGame(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -1657,9 +1671,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendInvoice
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendInvoice(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -1783,9 +1797,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendInvoice
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendInvoice(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -1877,9 +1891,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendLocation
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendLocation(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -1958,9 +1972,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendLocation
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendLocation(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -2023,9 +2037,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendMediaGroup
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendMediaGroup(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -2083,9 +2097,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendMediaGroup
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendMediaGroup(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -2153,9 +2167,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendMessage
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendMessage(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -2231,9 +2245,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendMessage
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendMessage(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -2309,9 +2323,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendPhoto
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendPhoto(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -2390,9 +2404,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendPhoto
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendPhoto(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -2481,9 +2495,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendPoll
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendPoll(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -2580,9 +2594,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendPoll
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendPoll(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -2655,9 +2669,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendDice
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendDice(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -2721,9 +2735,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendDice
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendDice(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -2787,9 +2801,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendSticker
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendSticker(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -2856,9 +2870,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendSticker
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendSticker(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -2935,9 +2949,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendVenue
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendVenue(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -3022,9 +3036,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendVenue
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendVenue(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -3117,9 +3131,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendVideo
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendVideo(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -3219,9 +3233,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendVideo
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendVideo(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -3301,9 +3315,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendVideoNote
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendVideoNote(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -3376,9 +3390,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendVideoNote
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendVideoNote(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -3451,9 +3465,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendVoice
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendVoice(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -3529,9 +3543,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendVoice
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendVoice(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -3808,9 +3822,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import CopyMessage
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return CopyMessage(
|
||||
from_chat_id=self.chat.id,
|
||||
|
|
@ -3872,9 +3886,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import EditMessageText
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return EditMessageText(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -3928,9 +3942,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import ForwardMessage
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return ForwardMessage(
|
||||
from_chat_id=self.chat.id,
|
||||
|
|
@ -3975,9 +3989,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import EditMessageMedia
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return EditMessageMedia(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -4016,9 +4030,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import EditMessageReplyMarkup
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return EditMessageReplyMarkup(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -4055,9 +4069,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import EditMessageReplyMarkup
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return EditMessageReplyMarkup(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -4107,9 +4121,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import EditMessageLiveLocation
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return EditMessageLiveLocation(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -4153,9 +4167,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import StopMessageLiveLocation
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return StopMessageLiveLocation(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -4201,9 +4215,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import EditMessageCaption
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return EditMessageCaption(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -4261,9 +4275,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import DeleteMessage
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return DeleteMessage(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -4297,9 +4311,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import PinChatMessage
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return PinChatMessage(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -4332,9 +4346,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import UnpinChatMessage
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return UnpinChatMessage(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -4353,7 +4367,7 @@ class Message(MaybeInaccessibleMessage):
|
|||
:param include_thread_id: if set, adds chat thread id to URL and returns like https://t.me/username/thread_id/message_id
|
||||
:return: string with full message URL
|
||||
"""
|
||||
if self.chat.type in ("private", "group"):
|
||||
if self.chat.type in {"private", "group"}:
|
||||
return None
|
||||
|
||||
chat_value = (
|
||||
|
|
@ -4397,9 +4411,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SetMessageReaction
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SetMessageReaction(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -4461,9 +4475,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendPaidMedia
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendPaidMedia(
|
||||
chat_id=self.chat.id,
|
||||
|
|
@ -4536,9 +4550,9 @@ class Message(MaybeInaccessibleMessage):
|
|||
|
||||
from aiogram.methods import SendPaidMedia
|
||||
|
||||
assert (
|
||||
self.chat is not None
|
||||
), "This method can be used only if chat is present in the message."
|
||||
assert self.chat is not None, (
|
||||
"This method can be used only if chat is present in the message."
|
||||
)
|
||||
|
||||
return SendPaidMedia(
|
||||
chat_id=self.chat.id,
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ class UniqueGift(TelegramObject):
|
|||
"""Backdrop of the gift"""
|
||||
is_premium: bool | None = None
|
||||
"""*Optional*. :code:`True`, if the original regular gift was exclusively purchaseable by Telegram Premium subscribers"""
|
||||
is_burned: bool | None = None
|
||||
"""*Optional*. :code:`True`, if the gift was used to craft another gift and isn't available anymore"""
|
||||
is_from_blockchain: bool | None = None
|
||||
"""*Optional*. :code:`True`, if the gift is assigned from the TON blockchain and can't be resold or transferred in Telegram"""
|
||||
colors: UniqueGiftColors | None = None
|
||||
|
|
@ -57,6 +59,7 @@ class UniqueGift(TelegramObject):
|
|||
symbol: UniqueGiftSymbol,
|
||||
backdrop: UniqueGiftBackdrop,
|
||||
is_premium: bool | None = None,
|
||||
is_burned: bool | None = None,
|
||||
is_from_blockchain: bool | None = None,
|
||||
colors: UniqueGiftColors | None = None,
|
||||
publisher_chat: Chat | None = None,
|
||||
|
|
@ -75,6 +78,7 @@ class UniqueGift(TelegramObject):
|
|||
symbol=symbol,
|
||||
backdrop=backdrop,
|
||||
is_premium=is_premium,
|
||||
is_burned=is_burned,
|
||||
is_from_blockchain=is_from_blockchain,
|
||||
colors=colors,
|
||||
publisher_chat=publisher_chat,
|
||||
|
|
|
|||
|
|
@ -20,7 +20,9 @@ class UniqueGiftModel(TelegramObject):
|
|||
sticker: Sticker
|
||||
"""The sticker that represents the unique gift"""
|
||||
rarity_per_mille: int
|
||||
"""The number of unique gifts that receive this model for every 1000 gifts upgraded"""
|
||||
"""The number of unique gifts that receive this model for every 1000 gift upgrades. Always 0 for crafted gifts."""
|
||||
rarity: str | None = None
|
||||
"""*Optional*. Rarity of the model if it is a crafted model. Currently, can be 'uncommon', 'rare', 'epic', or 'legendary'."""
|
||||
|
||||
if TYPE_CHECKING:
|
||||
# DO NOT EDIT MANUALLY!!!
|
||||
|
|
@ -32,6 +34,7 @@ class UniqueGiftModel(TelegramObject):
|
|||
name: str,
|
||||
sticker: Sticker,
|
||||
rarity_per_mille: int,
|
||||
rarity: str | None = None,
|
||||
**__pydantic_kwargs: Any,
|
||||
) -> None:
|
||||
# DO NOT EDIT MANUALLY!!!
|
||||
|
|
@ -39,5 +42,9 @@ class UniqueGiftModel(TelegramObject):
|
|||
# Is needed only for type checking and IDE support without any additional plugins
|
||||
|
||||
super().__init__(
|
||||
name=name, sticker=sticker, rarity_per_mille=rarity_per_mille, **__pydantic_kwargs
|
||||
name=name,
|
||||
sticker=sticker,
|
||||
rarity_per_mille=rarity_per_mille,
|
||||
rarity=rarity,
|
||||
**__pydantic_kwargs,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from ..utils.link import create_tg_link
|
|||
from .base import TelegramObject
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ..methods import GetUserProfilePhotos
|
||||
from ..methods import GetUserProfileAudios, GetUserProfilePhotos
|
||||
|
||||
|
||||
class User(TelegramObject):
|
||||
|
|
@ -45,6 +45,8 @@ class User(TelegramObject):
|
|||
"""*Optional*. :code:`True`, if the bot has a main Web App. Returned only in :class:`aiogram.methods.get_me.GetMe`."""
|
||||
has_topics_enabled: bool | None = None
|
||||
"""*Optional*. :code:`True`, if the bot has forum topic mode enabled in private chats. Returned only in :class:`aiogram.methods.get_me.GetMe`."""
|
||||
allows_users_to_create_topics: bool | None = None
|
||||
"""*Optional*. :code:`True`, if the bot allows users to create and delete topics in private chats. Returned only in :class:`aiogram.methods.get_me.GetMe`."""
|
||||
|
||||
if TYPE_CHECKING:
|
||||
# DO NOT EDIT MANUALLY!!!
|
||||
|
|
@ -67,6 +69,7 @@ class User(TelegramObject):
|
|||
can_connect_to_business: bool | None = None,
|
||||
has_main_web_app: bool | None = None,
|
||||
has_topics_enabled: bool | None = None,
|
||||
allows_users_to_create_topics: bool | None = None,
|
||||
**__pydantic_kwargs: Any,
|
||||
) -> None:
|
||||
# DO NOT EDIT MANUALLY!!!
|
||||
|
|
@ -88,6 +91,7 @@ class User(TelegramObject):
|
|||
can_connect_to_business=can_connect_to_business,
|
||||
has_main_web_app=has_main_web_app,
|
||||
has_topics_enabled=has_topics_enabled,
|
||||
allows_users_to_create_topics=allows_users_to_create_topics,
|
||||
**__pydantic_kwargs,
|
||||
)
|
||||
|
||||
|
|
@ -142,3 +146,35 @@ class User(TelegramObject):
|
|||
limit=limit,
|
||||
**kwargs,
|
||||
).as_(self._bot)
|
||||
|
||||
def get_profile_audios(
|
||||
self,
|
||||
offset: int | None = None,
|
||||
limit: int | None = None,
|
||||
**kwargs: Any,
|
||||
) -> GetUserProfileAudios:
|
||||
"""
|
||||
Shortcut for method :class:`aiogram.methods.get_user_profile_audios.GetUserProfileAudios`
|
||||
will automatically fill method attributes:
|
||||
|
||||
- :code:`user_id`
|
||||
|
||||
Use this method to get a list of profile audios for a user. Returns a :class:`aiogram.types.user_profile_audios.UserProfileAudios` object.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#getuserprofileaudios
|
||||
|
||||
:param offset: Sequential number of the first audio to be returned. By default, all audios are returned.
|
||||
:param limit: Limits the number of audios to be retrieved. Values between 1-100 are accepted. Defaults to 100.
|
||||
:return: instance of method :class:`aiogram.methods.get_user_profile_audios.GetUserProfileAudios`
|
||||
"""
|
||||
# DO NOT EDIT MANUALLY!!!
|
||||
# This method was auto-generated via `butcher`
|
||||
|
||||
from aiogram.methods import GetUserProfileAudios
|
||||
|
||||
return GetUserProfileAudios(
|
||||
user_id=self.id,
|
||||
offset=offset,
|
||||
limit=limit,
|
||||
**kwargs,
|
||||
).as_(self._bot)
|
||||
|
|
|
|||
34
aiogram/types/user_profile_audios.py
Normal file
34
aiogram/types/user_profile_audios.py
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from .base import TelegramObject
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .audio import Audio
|
||||
|
||||
|
||||
class UserProfileAudios(TelegramObject):
|
||||
"""
|
||||
This object represents the audios displayed on a user's profile.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#userprofileaudios
|
||||
"""
|
||||
|
||||
total_count: int
|
||||
"""Total number of profile audios for the target user"""
|
||||
audios: list[Audio]
|
||||
"""Requested profile audios"""
|
||||
|
||||
if TYPE_CHECKING:
|
||||
# DO NOT EDIT MANUALLY!!!
|
||||
# This section was auto-generated via `butcher`
|
||||
|
||||
def __init__(
|
||||
__pydantic__self__, *, total_count: int, audios: list[Audio], **__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__(total_count=total_count, audios=audios, **__pydantic_kwargs)
|
||||
|
|
@ -7,6 +7,7 @@ from .base import TelegramObject
|
|||
|
||||
if TYPE_CHECKING:
|
||||
from .photo_size import PhotoSize
|
||||
from .video_quality import VideoQuality
|
||||
|
||||
|
||||
class Video(TelegramObject):
|
||||
|
|
@ -32,6 +33,8 @@ class Video(TelegramObject):
|
|||
"""*Optional*. Available sizes of the cover of the video in the message"""
|
||||
start_timestamp: datetime.datetime | None = None
|
||||
"""*Optional*. Timestamp in seconds from which the video will play in the message"""
|
||||
qualities: list[VideoQuality] | None = None
|
||||
"""*Optional*. List of available qualities of the video"""
|
||||
file_name: str | None = None
|
||||
"""*Optional*. Original filename as defined by the sender"""
|
||||
mime_type: str | None = None
|
||||
|
|
@ -54,6 +57,7 @@ class Video(TelegramObject):
|
|||
thumbnail: PhotoSize | None = None,
|
||||
cover: list[PhotoSize] | None = None,
|
||||
start_timestamp: datetime.datetime | None = None,
|
||||
qualities: list[VideoQuality] | None = None,
|
||||
file_name: str | None = None,
|
||||
mime_type: str | None = None,
|
||||
file_size: int | None = None,
|
||||
|
|
@ -72,6 +76,7 @@ class Video(TelegramObject):
|
|||
thumbnail=thumbnail,
|
||||
cover=cover,
|
||||
start_timestamp=start_timestamp,
|
||||
qualities=qualities,
|
||||
file_name=file_name,
|
||||
mime_type=mime_type,
|
||||
file_size=file_size,
|
||||
|
|
|
|||
55
aiogram/types/video_quality.py
Normal file
55
aiogram/types/video_quality.py
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from .base import TelegramObject
|
||||
|
||||
|
||||
class VideoQuality(TelegramObject):
|
||||
"""
|
||||
This object represents a video file of a specific quality.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#videoquality
|
||||
"""
|
||||
|
||||
file_id: str
|
||||
"""Identifier for this file, which can be used to download or reuse the file"""
|
||||
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."""
|
||||
width: int
|
||||
"""Video width"""
|
||||
height: int
|
||||
"""Video height"""
|
||||
codec: str
|
||||
"""Codec that was used to encode the video, for example, 'h264', 'h265', or 'av01'"""
|
||||
file_size: int | None = None
|
||||
"""*Optional*. File size in bytes. It can be bigger than 2^31 and some programming languages may have difficulty/silent defects in interpreting it. But it has at most 52 significant bits, so a signed 64-bit integer or double-precision float type are safe for storing this value."""
|
||||
|
||||
if TYPE_CHECKING:
|
||||
# DO NOT EDIT MANUALLY!!!
|
||||
# This section was auto-generated via `butcher`
|
||||
|
||||
def __init__(
|
||||
__pydantic__self__,
|
||||
*,
|
||||
file_id: str,
|
||||
file_unique_id: str,
|
||||
width: int,
|
||||
height: int,
|
||||
codec: str,
|
||||
file_size: int | 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__(
|
||||
file_id=file_id,
|
||||
file_unique_id=file_unique_id,
|
||||
width=width,
|
||||
height=height,
|
||||
codec=codec,
|
||||
file_size=file_size,
|
||||
**__pydantic_kwargs,
|
||||
)
|
||||
|
|
@ -22,6 +22,7 @@ if TYPE_CHECKING:
|
|||
from aiogram import Bot
|
||||
|
||||
BAD_PATTERN = re.compile(r"[^a-zA-Z0-9-_]")
|
||||
DEEPLINK_PAYLOAD_LENGTH = 64
|
||||
|
||||
|
||||
async def create_start_link(
|
||||
|
|
@ -145,8 +146,8 @@ def create_deep_link(
|
|||
)
|
||||
raise ValueError(msg)
|
||||
|
||||
if len(payload) > 64:
|
||||
msg = "Payload must be up to 64 characters long."
|
||||
if len(payload) > DEEPLINK_PAYLOAD_LENGTH:
|
||||
msg = f"Payload must be up to {DEEPLINK_PAYLOAD_LENGTH} characters long."
|
||||
raise ValueError(msg)
|
||||
|
||||
if not app_name:
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ class DataMixin:
|
|||
data: dict[str, Any] | None = getattr(self, "_data", None)
|
||||
if data is None:
|
||||
data = {}
|
||||
setattr(self, "_data", data)
|
||||
self._data = data
|
||||
return data
|
||||
|
||||
def __getitem__(self, key: str) -> Any:
|
||||
|
|
|
|||
9
docs/api/enums/button_style.rst
Normal file
9
docs/api/enums/button_style.rst
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
###########
|
||||
ButtonStyle
|
||||
###########
|
||||
|
||||
|
||||
.. automodule:: aiogram.enums.button_style
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: True
|
||||
|
|
@ -11,6 +11,7 @@ Here is list of all available enums:
|
|||
:maxdepth: 1
|
||||
|
||||
bot_command_scope_type
|
||||
button_style
|
||||
chat_action
|
||||
chat_boost_source_type
|
||||
chat_member_status
|
||||
|
|
|
|||
38
docs/api/methods/get_user_profile_audios.rst
Normal file
38
docs/api/methods/get_user_profile_audios.rst
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
####################
|
||||
getUserProfileAudios
|
||||
####################
|
||||
|
||||
Returns: :obj:`UserProfileAudios`
|
||||
|
||||
.. automodule:: aiogram.methods.get_user_profile_audios
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: True
|
||||
:exclude-members: model_config,model_fields
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
As bot method
|
||||
-------------
|
||||
|
||||
.. code-block::
|
||||
|
||||
result: UserProfileAudios = await bot.get_user_profile_audios(...)
|
||||
|
||||
|
||||
Method as object
|
||||
----------------
|
||||
|
||||
Imports:
|
||||
|
||||
- :code:`from aiogram.methods.get_user_profile_audios import GetUserProfileAudios`
|
||||
- alias: :code:`from aiogram.methods import GetUserProfileAudios`
|
||||
|
||||
With specific bot
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
result: UserProfileAudios = await bot(GetUserProfileAudios(...))
|
||||
|
|
@ -82,6 +82,7 @@ Available methods
|
|||
get_my_short_description
|
||||
get_user_chat_boosts
|
||||
get_user_gifts
|
||||
get_user_profile_audios
|
||||
get_user_profile_photos
|
||||
gift_premium_subscription
|
||||
hide_general_forum_topic
|
||||
|
|
@ -93,6 +94,7 @@ Available methods
|
|||
read_business_message
|
||||
remove_business_account_profile_photo
|
||||
remove_chat_verification
|
||||
remove_my_profile_photo
|
||||
remove_user_verification
|
||||
reopen_forum_topic
|
||||
reopen_general_forum_topic
|
||||
|
|
@ -135,6 +137,7 @@ Available methods
|
|||
set_my_default_administrator_rights
|
||||
set_my_description
|
||||
set_my_name
|
||||
set_my_profile_photo
|
||||
set_my_short_description
|
||||
set_user_emoji_status
|
||||
transfer_business_account_stars
|
||||
|
|
|
|||
45
docs/api/methods/remove_my_profile_photo.rst
Normal file
45
docs/api/methods/remove_my_profile_photo.rst
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
####################
|
||||
removeMyProfilePhoto
|
||||
####################
|
||||
|
||||
Returns: :obj:`bool`
|
||||
|
||||
.. automodule:: aiogram.methods.remove_my_profile_photo
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: True
|
||||
:exclude-members: model_config,model_fields
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
As bot method
|
||||
-------------
|
||||
|
||||
.. code-block::
|
||||
|
||||
result: bool = await bot.remove_my_profile_photo(...)
|
||||
|
||||
|
||||
Method as object
|
||||
----------------
|
||||
|
||||
Imports:
|
||||
|
||||
- :code:`from aiogram.methods.remove_my_profile_photo import RemoveMyProfilePhoto`
|
||||
- alias: :code:`from aiogram.methods import RemoveMyProfilePhoto`
|
||||
|
||||
With specific bot
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
result: bool = await bot(RemoveMyProfilePhoto(...))
|
||||
|
||||
As reply into Webhook in handler
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
return RemoveMyProfilePhoto(...)
|
||||
45
docs/api/methods/set_my_profile_photo.rst
Normal file
45
docs/api/methods/set_my_profile_photo.rst
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
#################
|
||||
setMyProfilePhoto
|
||||
#################
|
||||
|
||||
Returns: :obj:`bool`
|
||||
|
||||
.. automodule:: aiogram.methods.set_my_profile_photo
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: True
|
||||
:exclude-members: model_config,model_fields
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
As bot method
|
||||
-------------
|
||||
|
||||
.. code-block::
|
||||
|
||||
result: bool = await bot.set_my_profile_photo(...)
|
||||
|
||||
|
||||
Method as object
|
||||
----------------
|
||||
|
||||
Imports:
|
||||
|
||||
- :code:`from aiogram.methods.set_my_profile_photo import SetMyProfilePhoto`
|
||||
- alias: :code:`from aiogram.methods import SetMyProfilePhoto`
|
||||
|
||||
With specific bot
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
result: bool = await bot(SetMyProfilePhoto(...))
|
||||
|
||||
As reply into Webhook in handler
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
return SetMyProfilePhoto(...)
|
||||
10
docs/api/types/chat_owner_changed.rst
Normal file
10
docs/api/types/chat_owner_changed.rst
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
################
|
||||
ChatOwnerChanged
|
||||
################
|
||||
|
||||
|
||||
.. automodule:: aiogram.types.chat_owner_changed
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: True
|
||||
:exclude-members: model_config,model_fields
|
||||
10
docs/api/types/chat_owner_left.rst
Normal file
10
docs/api/types/chat_owner_left.rst
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#############
|
||||
ChatOwnerLeft
|
||||
#############
|
||||
|
||||
|
||||
.. automodule:: aiogram.types.chat_owner_left
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: True
|
||||
:exclude-members: model_config,model_fields
|
||||
|
|
@ -67,6 +67,8 @@ Available types
|
|||
chat_member_owner
|
||||
chat_member_restricted
|
||||
chat_member_updated
|
||||
chat_owner_changed
|
||||
chat_owner_left
|
||||
chat_permissions
|
||||
chat_photo
|
||||
chat_shared
|
||||
|
|
@ -199,6 +201,7 @@ Available types
|
|||
unique_gift_symbol
|
||||
user
|
||||
user_chat_boosts
|
||||
user_profile_audios
|
||||
user_profile_photos
|
||||
user_rating
|
||||
user_shared
|
||||
|
|
@ -210,6 +213,7 @@ Available types
|
|||
video_chat_scheduled
|
||||
video_chat_started
|
||||
video_note
|
||||
video_quality
|
||||
voice
|
||||
web_app_data
|
||||
web_app_info
|
||||
|
|
|
|||
10
docs/api/types/user_profile_audios.rst
Normal file
10
docs/api/types/user_profile_audios.rst
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#################
|
||||
UserProfileAudios
|
||||
#################
|
||||
|
||||
|
||||
.. automodule:: aiogram.types.user_profile_audios
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: True
|
||||
:exclude-members: model_config,model_fields
|
||||
10
docs/api/types/video_quality.rst
Normal file
10
docs/api/types/video_quality.rst
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
############
|
||||
VideoQuality
|
||||
############
|
||||
|
||||
|
||||
.. automodule:: aiogram.types.video_quality
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: True
|
||||
:exclude-members: model_config,model_fields
|
||||
|
|
@ -148,8 +148,8 @@ When using :code:`uv`, prefix commands with :code:`uv run` to execute them in th
|
|||
.. code-block:: bash
|
||||
|
||||
# Format code
|
||||
uv run black aiogram tests examples
|
||||
uv run isort aiogram tests examples
|
||||
uv run ruff format aiogram tests scripts examples
|
||||
uv run ruff check --fix aiogram tests scripts examples
|
||||
|
||||
# Run tests
|
||||
uv run pytest tests
|
||||
|
|
@ -180,22 +180,22 @@ implementing new features or experimenting.
|
|||
Format the code (code-style)
|
||||
----------------------------
|
||||
|
||||
Note that this project is Black-formatted, so you should follow that code-style,
|
||||
too be sure You're correctly doing this let's reformat the code automatically:
|
||||
Note that this project uses Ruff for formatting and linting, so you should follow that code-style.
|
||||
To be sure you're correctly doing this, let's reformat the code automatically:
|
||||
|
||||
Using traditional approach:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
black aiogram tests examples
|
||||
isort aiogram tests examples
|
||||
ruff format aiogram tests scripts examples
|
||||
ruff check --fix aiogram tests scripts examples
|
||||
|
||||
Or with uv:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
uv run black aiogram tests examples
|
||||
uv run isort aiogram tests examples
|
||||
uv run ruff format aiogram tests scripts examples
|
||||
uv run ruff check --fix aiogram tests scripts examples
|
||||
|
||||
Or simply use Makefile:
|
||||
|
||||
|
|
|
|||
|
|
@ -94,9 +94,61 @@ Bot API
|
|||
However, all errors are classified by HTTP status codes, and for each method,
|
||||
only one type of error can be associated with a given code.
|
||||
Therefore, in most cases, you should check only the error type (by status code)
|
||||
without inspecting the error message.
|
||||
without inspecting the error message. More details can be found in the
|
||||
:ref:`exceptions section » <exceptions>`.
|
||||
|
||||
|
||||
Exceptions
|
||||
==========
|
||||
|
||||
Mapping (v2 -> v3)
|
||||
-------------------
|
||||
|
||||
- RetryAfter -> :class:`TelegramRetryAfter` (:mod:`aiogram.exceptions`)
|
||||
- Important attribute in v3: ``retry_after`` (int).
|
||||
|
||||
- ChatMigrated / MigrateToChat -> :class:`TelegramMigrateToChat`
|
||||
- Important attribute in v3: ``migrate_to_chat_id`` (int).
|
||||
|
||||
- ClientDecodeError -> :class:`ClientDecodeError`
|
||||
- Important attributes in v3: ``original`` (Exception) and ``data`` (response body).
|
||||
|
||||
- BadRequest -> :class:`TelegramBadRequest`
|
||||
- Unauthorized -> :class:`TelegramUnauthorizedError`
|
||||
- Forbidden -> :class:`TelegramForbiddenError`
|
||||
- NotFound -> :class:`TelegramNotFound`
|
||||
- Conflict -> :class:`TelegramConflictError`
|
||||
- ServerError -> :class:`TelegramServerError`
|
||||
- NetworkError -> :class:`TelegramNetworkError`
|
||||
- EntityTooLarge -> :class:`TelegramEntityTooLarge`
|
||||
|
||||
|
||||
Exceptions removed in v3 (from v2)
|
||||
----------------------------------
|
||||
|
||||
The list below contains common exception names that appeared in aiogram v2 but
|
||||
are not defined as separate classes in the v3 codebase. For each v2 name, a
|
||||
recommended v3 replacement (or handling) is provided — keep your migration
|
||||
logic simple and rely on the v3 exception classes and their attributes.
|
||||
|
||||
- MessageNotModified -> :class:`TelegramBadRequest`
|
||||
- MessageToEditNotFound -> :class:`TelegramNotFound`
|
||||
- MessageToDeleteNotFound -> :class:`TelegramNotFound`
|
||||
- MessageCantBeDeleted -> :class:`TelegramForbiddenError` / :class:`TelegramBadRequest`
|
||||
- CantParseEntities -> :class:`TelegramBadRequest`
|
||||
- MessageIsTooLong -> :class:`TelegramEntityTooLarge`
|
||||
- MessageIdentifierNotFound -> :class:`TelegramNotFound`
|
||||
- UserDeactivated -> :class:`TelegramForbiddenError`
|
||||
- CantInitiateConversation -> :class:`TelegramBadRequest`
|
||||
- StickerSetNameInvalid -> :class:`TelegramBadRequest`
|
||||
- ChatAdminRequired -> :class:`TelegramForbiddenError`
|
||||
|
||||
Use these replacements when migrating exception handling from v2 to v3. If
|
||||
you relied on catching very specific v2 exception classes, replace those
|
||||
handlers with the corresponding v3 class above (or catch a broader v3 class
|
||||
such as :class:`TelegramBadRequest` / :class:`TelegramAPIError`) and inspect
|
||||
available attributes (see "Mapping (v2 -> v3)") for any required details.
|
||||
|
||||
|
||||
Middlewares
|
||||
===========
|
||||
|
|
|
|||
|
|
@ -2,12 +2,11 @@ import asyncio
|
|||
import logging
|
||||
from os import getenv
|
||||
|
||||
from handlers.echo import echo_router
|
||||
from handlers.start import start_router
|
||||
|
||||
from aiogram import Bot, Dispatcher
|
||||
from aiogram.client.default import DefaultBotProperties
|
||||
from aiogram.enums import ParseMode
|
||||
from handlers.echo import echo_router
|
||||
from handlers.start import start_router
|
||||
|
||||
# Bot token can be obtained via https://t.me/BotFather
|
||||
TOKEN = getenv("BOT_TOKEN")
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ from os import getenv
|
|||
from typing import Any
|
||||
|
||||
from aiohttp import web
|
||||
from finite_state_machine import form_router
|
||||
|
||||
from aiogram import Bot, Dispatcher, F, Router
|
||||
from aiogram.client.session.aiohttp import AiohttpSession
|
||||
|
|
@ -19,6 +18,7 @@ from aiogram.webhook.aiohttp_server import (
|
|||
TokenBasedRequestHandler,
|
||||
setup_application,
|
||||
)
|
||||
from finite_state_machine import form_router
|
||||
|
||||
main_router = Router()
|
||||
|
||||
|
|
|
|||
|
|
@ -4,14 +4,14 @@ from os import getenv
|
|||
|
||||
from aiohttp.web import run_app
|
||||
from aiohttp.web_app import Application
|
||||
from handlers import my_router
|
||||
from routes import check_data_handler, demo_handler, send_message_handler
|
||||
|
||||
from aiogram import Bot, Dispatcher
|
||||
from aiogram.client.default import DefaultBotProperties
|
||||
from aiogram.enums.parse_mode import ParseMode
|
||||
from aiogram.types import MenuButtonWebApp, WebAppInfo
|
||||
from aiogram.webhook.aiohttp_server import SimpleRequestHandler, setup_application
|
||||
from handlers import my_router
|
||||
from routes import check_data_handler, demo_handler, send_message_handler
|
||||
|
||||
TOKEN = getenv("BOT_TOKEN")
|
||||
|
||||
|
|
|
|||
|
|
@ -94,8 +94,6 @@ docs = [
|
|||
|
||||
[dependency-groups]
|
||||
dev = [
|
||||
"black~=25.9",
|
||||
"isort~=7.0",
|
||||
"ruff~=0.14",
|
||||
"mypy==1.10.1",
|
||||
"toml~=0.10.2",
|
||||
|
|
@ -139,16 +137,38 @@ exclude = [
|
|||
[tool.ruff.lint]
|
||||
select = [
|
||||
# "C", # TODO: mccabe - code complecity
|
||||
"C4",
|
||||
"E",
|
||||
"F",
|
||||
"Q",
|
||||
"RET",
|
||||
"T10",
|
||||
"T20",
|
||||
"A", # flake8-annotations
|
||||
"B", # flake8-bugbear
|
||||
"C4", # flake8-comprehensions
|
||||
"DTZ", # flake8-datetimez
|
||||
"E", # pycodestyle errors
|
||||
"F", # pyflakes
|
||||
"I", # isort
|
||||
"PERF", # perflint
|
||||
"PL", # pylint
|
||||
"Q", # flake8-quotes
|
||||
"RET", # flake8-return
|
||||
"SIM", # flake8-simplify
|
||||
"T10", # flake8-debugger
|
||||
"T20", # flake8-print
|
||||
"UP", # pyupgrade
|
||||
]
|
||||
ignore = [
|
||||
"F401",
|
||||
"F401", # unused-import (handled by other tools)
|
||||
"A002", # builtin-argument-shadowing (common in API: type, id, format, etc.)
|
||||
"A005", # stdlib-module-shadowing (Module `types` shadows a Python standard-library module)
|
||||
"B008", # function-call-in-default-argument (Pydantic Field() defaults)
|
||||
"PLC0415", # import-outside-top-level (needed for circular imports)
|
||||
"PLC1901", # compare-to-empty-string (sometimes more explicit is better)
|
||||
"PLR0904", # too-many-public-methods (Bot class has many API methods)
|
||||
"PLR0911", # too-many-return-statements
|
||||
"PLR0912", # too-many-branches
|
||||
"PLR0913", # too-many-arguments (Telegram API methods have many params)
|
||||
"PLR0915", # too-many-statements
|
||||
"PLR0917", # too-many-positional-arguments (Telegram API design)
|
||||
"PLR6301", # no-self-use (sometimes methods are intentionally not static)
|
||||
"PLW2901", # redefined-loop-name (intentional pattern in this codebase)
|
||||
"PLW3201", # bad-dunder-method-name (custom dunders for framework design)
|
||||
]
|
||||
|
||||
[tool.ruff.lint.isort]
|
||||
|
|
@ -164,6 +184,20 @@ known-first-party = [
|
|||
"aiogram/types/*" = ["E501"]
|
||||
"aiogram/methods/*" = ["E501"]
|
||||
"aiogram/enums/*" = ["E501"]
|
||||
"tests/**" = [
|
||||
"PLR0124",
|
||||
"PLR2004",
|
||||
"DTZ005",
|
||||
"DTZ006",
|
||||
"A001",
|
||||
"A004",
|
||||
"B018",
|
||||
"B020",
|
||||
"B904",
|
||||
"E501",
|
||||
"F821",
|
||||
"UP",
|
||||
]
|
||||
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
|
|
@ -174,7 +208,6 @@ testpaths = [
|
|||
filterwarnings = [
|
||||
"error",
|
||||
"ignore::pytest.PytestUnraisableExceptionWarning",
|
||||
|
||||
# Remove when uvloop fixes the issue
|
||||
# https://github.com/MagicStack/uvloop/issues/703
|
||||
# https://github.com/MagicStack/uvloop/pull/705
|
||||
|
|
@ -235,23 +268,10 @@ module = [
|
|||
ignore_missing_imports = true
|
||||
disallow_untyped_defs = true
|
||||
|
||||
[tool.black]
|
||||
line-length = 99
|
||||
target-version = ['py310', 'py311', 'py312', 'py313']
|
||||
exclude = '''
|
||||
(
|
||||
\.eggs
|
||||
| \.git
|
||||
| \.tox
|
||||
| build
|
||||
| dist
|
||||
| venv
|
||||
| docs
|
||||
)
|
||||
'''
|
||||
|
||||
[tool.isort]
|
||||
profile = "black"
|
||||
[tool.ruff.format]
|
||||
quote-style = "double"
|
||||
indent-style = "space"
|
||||
line-ending = "auto"
|
||||
|
||||
[tool.towncrier]
|
||||
package = "aiogram"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Version bumping script for aiogram (replaces hatch version)."""
|
||||
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
|
@ -44,9 +45,9 @@ def bump_version(part: str) -> str:
|
|||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) != 2:
|
||||
print("Usage: python scripts/bump_version.py [major|minor|patch|to:X.Y.Z]")
|
||||
if len(sys.argv) != 2: # noqa: PLR2004
|
||||
print("Usage: python scripts/bump_version.py [major|minor|patch|to:X.Y.Z]") # noqa: T201
|
||||
sys.exit(1)
|
||||
|
||||
new_version = bump_version(sys.argv[1])
|
||||
print(f"Bumped version to {new_version}")
|
||||
print(f"Bumped version to {new_version}") # noqa: T201
|
||||
|
|
|
|||
|
|
@ -45,8 +45,7 @@ def get_telegram_api_version() -> str:
|
|||
|
||||
|
||||
def replace_line(content: str, pattern: re.Pattern, new_value: str) -> str:
|
||||
result = pattern.sub(f"\\g<1>{new_value}\\g<2>", content)
|
||||
return result
|
||||
return pattern.sub(f"\\g<1>{new_value}\\g<2>", content)
|
||||
|
||||
|
||||
def write_package_meta(api_version: str) -> None:
|
||||
|
|
@ -55,7 +54,7 @@ def write_package_meta(api_version: str) -> None:
|
|||
|
||||
content = replace_line(content, API_VERSION, api_version)
|
||||
|
||||
print(f"Write {path}")
|
||||
print(f"Write {path}") # noqa: T201
|
||||
path.write_text(content)
|
||||
|
||||
|
||||
|
|
@ -64,7 +63,7 @@ def write_readme(api_version: str) -> None:
|
|||
content = path.read_text()
|
||||
content = replace_line(content, API_VERSION_BADGE, api_version)
|
||||
content = replace_line(content, API_VERSION_LINE, api_version)
|
||||
print(f"Write {path}")
|
||||
print(f"Write {path}") # noqa: T201
|
||||
path.write_text(content)
|
||||
|
||||
|
||||
|
|
@ -72,14 +71,14 @@ def write_docs_index(api_version: str) -> None:
|
|||
path = Path.cwd() / "docs" / "index.rst"
|
||||
content = path.read_text()
|
||||
content = replace_line(content, API_VERSION_BADGE, api_version)
|
||||
print(f"Write {path}")
|
||||
print(f"Write {path}") # noqa: T201
|
||||
path.write_text(content)
|
||||
|
||||
|
||||
def main():
|
||||
api_version = get_telegram_api_version()
|
||||
|
||||
print(f"Telegram Bot API version: {api_version}")
|
||||
print(f"Telegram Bot API version: {api_version}") # noqa: T201
|
||||
write_package_meta(api_version=api_version)
|
||||
write_readme(api_version=api_version)
|
||||
write_docs_index(api_version=api_version)
|
||||
|
|
|
|||
|
|
@ -144,8 +144,7 @@ async def memory_storage():
|
|||
|
||||
@pytest.fixture()
|
||||
async def redis_isolation(redis_storage):
|
||||
isolation = redis_storage.create_isolation()
|
||||
return isolation
|
||||
return redis_storage.create_isolation()
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
from contextlib import contextmanager
|
||||
from typing import Type
|
||||
|
||||
import pytest
|
||||
from packaging import version
|
||||
|
|
@ -10,8 +9,8 @@ import aiogram
|
|||
@contextmanager
|
||||
def check_deprecated(
|
||||
max_version: str,
|
||||
exception: Type[Exception],
|
||||
warning: Type[Warning] = DeprecationWarning,
|
||||
exception: type[Exception],
|
||||
warning: type[Warning] = DeprecationWarning,
|
||||
) -> None:
|
||||
"""
|
||||
Should be used for modules that are being deprecated or already removed from aiogram
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
from collections import deque
|
||||
from typing import TYPE_CHECKING, Any, AsyncGenerator, Deque, Dict, Optional, Type
|
||||
from collections.abc import AsyncGenerator
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from aiogram import Bot
|
||||
from aiogram.client.session.base import BaseSession
|
||||
|
|
@ -10,9 +11,9 @@ from aiogram.types import UNSET_PARSE_MODE, ResponseParameters, User
|
|||
|
||||
class MockedSession(BaseSession):
|
||||
def __init__(self):
|
||||
super(MockedSession, self).__init__()
|
||||
self.responses: Deque[Response[TelegramType]] = deque()
|
||||
self.requests: Deque[TelegramMethod[TelegramType]] = deque()
|
||||
super().__init__()
|
||||
self.responses: deque[Response[TelegramType]] = deque()
|
||||
self.requests: deque[TelegramMethod[TelegramType]] = deque()
|
||||
self.closed = True
|
||||
|
||||
def add_result(self, response: Response[TelegramType]) -> Response[TelegramType]:
|
||||
|
|
@ -29,7 +30,7 @@ class MockedSession(BaseSession):
|
|||
self,
|
||||
bot: Bot,
|
||||
method: TelegramMethod[TelegramType],
|
||||
timeout: Optional[int] = UNSET_PARSE_MODE,
|
||||
timeout: int | None = UNSET_PARSE_MODE,
|
||||
) -> TelegramType:
|
||||
self.closed = False
|
||||
self.requests.append(method)
|
||||
|
|
@ -45,7 +46,7 @@ class MockedSession(BaseSession):
|
|||
async def stream_content(
|
||||
self,
|
||||
url: str,
|
||||
headers: Optional[Dict[str, Any]] = None,
|
||||
headers: dict[str, Any] | None = None,
|
||||
timeout: int = 30,
|
||||
chunk_size: int = 65536,
|
||||
raise_for_status: bool = True,
|
||||
|
|
@ -58,9 +59,7 @@ class MockedBot(Bot):
|
|||
session: MockedSession
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super(MockedBot, self).__init__(
|
||||
kwargs.pop("token", "42:TEST"), session=MockedSession(), **kwargs
|
||||
)
|
||||
super().__init__(kwargs.pop("token", "42:TEST"), session=MockedSession(), **kwargs)
|
||||
self._me = User(
|
||||
id=self.id,
|
||||
is_bot=True,
|
||||
|
|
@ -72,13 +71,13 @@ class MockedBot(Bot):
|
|||
|
||||
def add_result_for(
|
||||
self,
|
||||
method: Type[TelegramMethod[TelegramType]],
|
||||
method: type[TelegramMethod[TelegramType]],
|
||||
ok: bool,
|
||||
result: TelegramType = None,
|
||||
description: Optional[str] = None,
|
||||
description: str | None = None,
|
||||
error_code: int = 200,
|
||||
migrate_to_chat_id: Optional[int] = None,
|
||||
retry_after: Optional[int] = None,
|
||||
migrate_to_chat_id: int | None = None,
|
||||
retry_after: int | None = None,
|
||||
) -> Response[TelegramType]:
|
||||
response = Response[method.__returning__]( # type: ignore
|
||||
ok=ok,
|
||||
|
|
|
|||
|
|
@ -1,12 +1,8 @@
|
|||
import asyncio
|
||||
from collections.abc import AsyncGenerator, AsyncIterable
|
||||
from typing import (
|
||||
Any,
|
||||
AsyncContextManager,
|
||||
AsyncGenerator,
|
||||
AsyncIterable,
|
||||
Dict,
|
||||
List,
|
||||
Union,
|
||||
)
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
|
|
@ -115,10 +111,10 @@ class TestAiohttpSession:
|
|||
str_: str
|
||||
int_: int
|
||||
bool_: bool
|
||||
unset_: Union[str, Default] = Default("parse_mode")
|
||||
unset_: str | Default = Default("parse_mode")
|
||||
null_: None
|
||||
list_: List[str]
|
||||
dict_: Dict[str, Any]
|
||||
list_: list[str]
|
||||
dict_: dict[str, Any]
|
||||
|
||||
session = AiohttpSession()
|
||||
form = session.build_form_data(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import datetime
|
||||
import json
|
||||
from typing import Any, AsyncContextManager, AsyncGenerator, Dict, Optional
|
||||
from collections.abc import AsyncGenerator
|
||||
from typing import Any, AsyncContextManager
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
import pytest
|
||||
|
|
@ -39,7 +40,7 @@ class CustomSession(BaseSession):
|
|||
self,
|
||||
token: str,
|
||||
method: TelegramMethod[TelegramType],
|
||||
timeout: Optional[int] = UNSET_PARSE_MODE,
|
||||
timeout: int | None = UNSET_PARSE_MODE,
|
||||
) -> None: # type: ignore
|
||||
assert isinstance(token, str)
|
||||
assert isinstance(method, TelegramMethod)
|
||||
|
|
@ -47,7 +48,7 @@ class CustomSession(BaseSession):
|
|||
async def stream_content(
|
||||
self,
|
||||
url: str,
|
||||
headers: Optional[Dict[str, Any]] = None,
|
||||
headers: dict[str, Any] | None = None,
|
||||
timeout: int = 30,
|
||||
chunk_size: int = 65536,
|
||||
raise_for_status: bool = True,
|
||||
|
|
|
|||
|
|
@ -15,5 +15,5 @@ class TestAddStickerToSet:
|
|||
sticker="file id", format=StickerFormat.STATIC, emoji_list=[":)"]
|
||||
),
|
||||
)
|
||||
request = bot.get_request()
|
||||
bot.get_request()
|
||||
assert response == prepare_result.result
|
||||
|
|
|
|||
|
|
@ -7,5 +7,5 @@ class TestAnswerCallbackQuery:
|
|||
prepare_result = bot.add_result_for(AnswerCallbackQuery, ok=True, result=True)
|
||||
|
||||
response: bool = await bot.answer_callback_query(callback_query_id="cq id", text="OK")
|
||||
request = bot.get_request()
|
||||
bot.get_request()
|
||||
assert response == prepare_result.result
|
||||
|
|
|
|||
|
|
@ -17,5 +17,5 @@ class TestAnswerInlineQuery:
|
|||
)
|
||||
],
|
||||
)
|
||||
request = bot.get_request()
|
||||
bot.get_request()
|
||||
assert response == prepare_result.result
|
||||
|
|
|
|||
|
|
@ -9,5 +9,5 @@ class TestAnswerPreCheckoutQuery:
|
|||
response: bool = await bot.answer_pre_checkout_query(
|
||||
pre_checkout_query_id="query id", ok=True
|
||||
)
|
||||
request = bot.get_request()
|
||||
bot.get_request()
|
||||
assert response == prepare_result.result
|
||||
|
|
|
|||
|
|
@ -7,5 +7,5 @@ class TestAnswerShippingQuery:
|
|||
prepare_result = bot.add_result_for(AnswerShippingQuery, ok=True, result=True)
|
||||
|
||||
response: bool = await bot.answer_shipping_query(shipping_query_id="query id", ok=True)
|
||||
request = bot.get_request()
|
||||
bot.get_request()
|
||||
assert response == prepare_result.result
|
||||
|
|
|
|||
|
|
@ -15,5 +15,5 @@ class TestAnswerWebAppQuery:
|
|||
thumbnail_url="test",
|
||||
),
|
||||
)
|
||||
request = bot.get_request()
|
||||
bot.get_request()
|
||||
assert response == prepare_result.result
|
||||
|
|
|
|||
|
|
@ -10,5 +10,5 @@ class TestApproveChatJoinRequest:
|
|||
chat_id=-42,
|
||||
user_id=42,
|
||||
)
|
||||
request = bot.get_request()
|
||||
bot.get_request()
|
||||
assert response == prepare_result.result
|
||||
|
|
|
|||
|
|
@ -10,5 +10,5 @@ class TestApproveSuggestedPost:
|
|||
chat_id=-42,
|
||||
message_id=42,
|
||||
)
|
||||
request = bot.get_request()
|
||||
bot.get_request()
|
||||
assert response == prepare_result.result
|
||||
|
|
|
|||
|
|
@ -7,5 +7,5 @@ class TestKickChatMember:
|
|||
prepare_result = bot.add_result_for(BanChatMember, ok=True, result=True)
|
||||
|
||||
response: bool = await bot.ban_chat_member(chat_id=-42, user_id=42)
|
||||
request = bot.get_request()
|
||||
bot.get_request()
|
||||
assert response == prepare_result.result
|
||||
|
|
|
|||
|
|
@ -10,5 +10,5 @@ class TestBanChatSenderChat:
|
|||
chat_id=-42,
|
||||
sender_chat_id=-1337,
|
||||
)
|
||||
request = bot.get_request()
|
||||
bot.get_request()
|
||||
assert response == prepare_result.result
|
||||
|
|
|
|||
|
|
@ -7,5 +7,5 @@ class TestClose:
|
|||
prepare_result = bot.add_result_for(Close, ok=True, result=True)
|
||||
|
||||
response: bool = await bot.close()
|
||||
request = bot.get_request()
|
||||
bot.get_request()
|
||||
assert response == prepare_result.result
|
||||
|
|
|
|||
|
|
@ -10,5 +10,5 @@ class TestCloseForumTopic:
|
|||
chat_id=42,
|
||||
message_thread_id=42,
|
||||
)
|
||||
request = bot.get_request()
|
||||
bot.get_request()
|
||||
assert response == prepare_result.result
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue