Verifies a user on behalf of the organization which is represented by the bot. Returns True on success.
",
+ "rst_description": "Verifies a user on behalf of the organization which is represented by the bot. Returns :code:`True` on success.",
+ "annotations": [
+ {
+ "type": "Integer",
+ "required": true,
+ "description": "Unique identifier of the target user",
+ "html_description": "Verifies a chat on behalf of the organization which is represented by the bot. Returns True on success.
",
+ "rst_description": "Verifies a chat on behalf of the organization which is represented by the bot. Returns :code:`True` on success.",
+ "annotations": [
+ {
+ "type": "Integer or String",
+ "required": true,
+ "description": "Unique identifier for the target chat or username of the target channel (in the format @channelusername)",
+ "html_description": "Removes verification from a user who is currently verified on behalf of the organization represented by the bot. Returns True on success.
",
+ "rst_description": "Removes verification from a user who is currently verified on behalf of the organization represented by the bot. Returns :code:`True` on success.",
+ "annotations": [
+ {
+ "type": "Integer",
+ "required": true,
+ "description": "Unique identifier of the target user",
+ "html_description": "Removes verification from a chat that is currently verified on behalf of the organization represented by the bot. Returns True on success.
",
+ "rst_description": "Removes verification from a chat that is currently verified on behalf of the organization represented by the bot. Returns :code:`True` on success.",
+ "annotations": [
+ {
+ "type": "Integer or String",
+ "required": true,
+ "description": "Unique identifier for the target chat or username of the target channel (in the format @channelusername)",
+ "html_description": "`_ only.\n",
"name": "business_connection_id"
},
{
@@ -16400,9 +16496,9 @@
{
"type": "Integer",
"required": false,
- "description": "The number of seconds the subscription will be active for before the next payment. The currency must be set to 'XTR' (Telegram Stars) if the parameter is used. Currently, it must always be 2592000 (30 days) if specified.",
- "html_description": "The number of seconds the subscription will be active for before the next payment. The currency must be set to “XTR” (Telegram Stars) if the parameter is used. Currently, it must always be 2592000 (30 days) if specified. | ",
- "rst_description": "The number of seconds the subscription will be active for before the next payment. The currency must be set to 'XTR' (Telegram Stars) if the parameter is used. Currently, it must always be 2592000 (30 days) if specified.\n",
+ "description": "The number of seconds the subscription will be active for before the next payment. The currency must be set to 'XTR' (Telegram Stars) if the parameter is used. Currently, it must always be 2592000 (30 days) if specified. Any number of subscriptions can be active for a given bot at the same time, including multiple concurrent subscriptions from the same user. Subscription price must no exceed 2500 Telegram Stars.",
+ "html_description": "The number of seconds the subscription will be active for before the next payment. The currency must be set to “XTR” (Telegram Stars) if the parameter is used. Currently, it must always be 2592000 (30 days) if specified. Any number of subscriptions can be active for a given bot at the same time, including multiple concurrent subscriptions from the same user. Subscription price must no exceed 2500 Telegram Stars. | ",
+ "rst_description": "The number of seconds the subscription will be active for before the next payment. The currency must be set to 'XTR' (Telegram Stars) if the parameter is used. Currently, it must always be 2592000 (30 days) if specified. Any number of subscriptions can be active for a given bot at the same time, including multiple concurrent subscriptions from the same user. Subscription price must no exceed 2500 Telegram Stars.\n",
"name": "subscription_period"
},
{
@@ -17245,12 +17341,62 @@
],
"category": "types"
},
+ {
+ "anchor": "affiliateinfo",
+ "name": "AffiliateInfo",
+ "description": "Contains information about the affiliate that received a commission via this transaction.",
+ "html_description": "Contains information about the affiliate that received a commission via this transaction.
",
+ "rst_description": "Contains information about the affiliate that received a commission via this transaction.",
+ "annotations": [
+ {
+ "type": "User",
+ "description": "The bot or the user that received an affiliate commission if it was received by a bot or a user",
+ "html_description": "Optional. The bot or the user that received an affiliate commission if it was received by a bot or a user | ",
+ "rst_description": "*Optional*. The bot or the user that received an affiliate commission if it was received by a bot or a user\n",
+ "name": "affiliate_user",
+ "required": false
+ },
+ {
+ "type": "Chat",
+ "description": "The chat that received an affiliate commission if it was received by a chat",
+ "html_description": "Optional. The chat that received an affiliate commission if it was received by a chat | ",
+ "rst_description": "*Optional*. The chat that received an affiliate commission if it was received by a chat\n",
+ "name": "affiliate_chat",
+ "required": false
+ },
+ {
+ "type": "Integer",
+ "description": "The number of Telegram Stars received by the affiliate for each 1000 Telegram Stars received by the bot from referred users",
+ "html_description": "The number of Telegram Stars received by the affiliate for each 1000 Telegram Stars received by the bot from referred users | ",
+ "rst_description": "The number of Telegram Stars received by the affiliate for each 1000 Telegram Stars received by the bot from referred users\n",
+ "name": "commission_per_mille",
+ "required": true
+ },
+ {
+ "type": "Integer",
+ "description": "Integer amount of Telegram Stars received by the affiliate from the transaction, rounded to 0; can be negative for refunds",
+ "html_description": "Integer amount of Telegram Stars received by the affiliate from the transaction, rounded to 0; can be negative for refunds | ",
+ "rst_description": "Integer amount of Telegram Stars received by the affiliate from the transaction, rounded to 0; can be negative for refunds\n",
+ "name": "amount",
+ "required": true
+ },
+ {
+ "type": "Integer",
+ "description": "The number of 1/1000000000 shares of Telegram Stars received by the affiliate; from -999999999 to 999999999; can be negative for refunds",
+ "html_description": "Optional. The number of 1/1000000000 shares of Telegram Stars received by the affiliate; from -999999999 to 999999999; can be negative for refunds | ",
+ "rst_description": "*Optional*. The number of 1/1000000000 shares of Telegram Stars received by the affiliate; from -999999999 to 999999999; can be negative for refunds\n",
+ "name": "nanostar_amount",
+ "required": false
+ }
+ ],
+ "category": "types"
+ },
{
"anchor": "transactionpartner",
"name": "TransactionPartner",
- "description": "This object describes the source of a transaction, or its recipient for outgoing transactions. Currently, it can be one of\n - TransactionPartnerUser\n - TransactionPartnerFragment\n - TransactionPartnerTelegramAds\n - TransactionPartnerTelegramApi\n - TransactionPartnerOther",
- "html_description": "This object describes the source of a transaction, or its recipient for outgoing transactions. Currently, it can be one of
",
- "rst_description": "This object describes the source of a transaction, or its recipient for outgoing transactions. Currently, it can be one of\n\n - :class:`aiogram.types.transaction_partner_user.TransactionPartnerUser`\n - :class:`aiogram.types.transaction_partner_fragment.TransactionPartnerFragment`\n - :class:`aiogram.types.transaction_partner_telegram_ads.TransactionPartnerTelegramAds`\n - :class:`aiogram.types.transaction_partner_telegram_api.TransactionPartnerTelegramApi`\n - :class:`aiogram.types.transaction_partner_other.TransactionPartnerOther`",
+ "description": "This object describes the source of a transaction, or its recipient for outgoing transactions. Currently, it can be one of\n - TransactionPartnerUser\n - TransactionPartnerAffiliateProgram\n - TransactionPartnerFragment\n - TransactionPartnerTelegramAds\n - TransactionPartnerTelegramApi\n - TransactionPartnerOther",
+ "html_description": "This object describes the source of a transaction, or its recipient for outgoing transactions. Currently, it can be one of
",
+ "rst_description": "This object describes the source of a transaction, or its recipient for outgoing transactions. Currently, it can be one of\n\n - :class:`aiogram.types.transaction_partner_user.TransactionPartnerUser`\n - :class:`aiogram.types.transaction_partner_affiliate_program.TransactionPartnerAffiliateProgram`\n - :class:`aiogram.types.transaction_partner_fragment.TransactionPartnerFragment`\n - :class:`aiogram.types.transaction_partner_telegram_ads.TransactionPartnerTelegramAds`\n - :class:`aiogram.types.transaction_partner_telegram_api.TransactionPartnerTelegramApi`\n - :class:`aiogram.types.transaction_partner_other.TransactionPartnerOther`",
"annotations": [],
"category": "types"
},
@@ -17277,6 +17423,14 @@
"name": "user",
"required": true
},
+ {
+ "type": "AffiliateInfo",
+ "description": "Information about the affiliate that received a commission via this transaction",
+ "html_description": "Optional. Information about the affiliate that received a commission via this transaction | ",
+ "rst_description": "*Optional*. Information about the affiliate that received a commission via this transaction\n",
+ "name": "affiliate",
+ "required": false
+ },
{
"type": "String",
"description": "Bot-specified invoice payload",
@@ -17310,7 +17464,7 @@
"required": false
},
{
- "type": "String",
+ "type": "Gift",
"description": "The gift sent to the user by the bot",
"html_description": "Optional. The gift sent to the user by the bot | ",
"rst_description": "*Optional*. The gift sent to the user by the bot\n",
@@ -17320,6 +17474,40 @@
],
"category": "types"
},
+ {
+ "anchor": "transactionpartneraffiliateprogram",
+ "name": "TransactionPartnerAffiliateProgram",
+ "description": "Describes the affiliate program that issued the affiliate commission received via this transaction.",
+ "html_description": "Describes the affiliate program that issued the affiliate commission received via this transaction.
",
+ "rst_description": "Describes the affiliate program that issued the affiliate commission received via this transaction.",
+ "annotations": [
+ {
+ "type": "String",
+ "description": "Type of the transaction partner, always 'affiliate_program'",
+ "html_description": "Type of the transaction partner, always “affiliate_program” | ",
+ "rst_description": "Type of the transaction partner, always 'affiliate_program'\n",
+ "name": "type",
+ "required": true
+ },
+ {
+ "type": "User",
+ "description": "Information about the bot that sponsored the affiliate program",
+ "html_description": "Optional. Information about the bot that sponsored the affiliate program | ",
+ "rst_description": "*Optional*. Information about the bot that sponsored the affiliate program\n",
+ "name": "sponsor_user",
+ "required": false
+ },
+ {
+ "type": "Integer",
+ "description": "The number of Telegram Stars received by the bot for each 1000 Telegram Stars received by the affiliate program sponsor from referred users",
+ "html_description": "The number of Telegram Stars received by the bot for each 1000 Telegram Stars received by the affiliate program sponsor from referred users | ",
+ "rst_description": "The number of Telegram Stars received by the bot for each 1000 Telegram Stars received by the affiliate program sponsor from referred users\n",
+ "name": "commission_per_mille",
+ "required": true
+ }
+ ],
+ "category": "types"
+ },
{
"anchor": "transactionpartnerfragment",
"name": "TransactionPartnerFragment",
@@ -17425,12 +17613,20 @@
},
{
"type": "Integer",
- "description": "Number of Telegram Stars transferred by the transaction",
- "html_description": "Number of Telegram Stars transferred by the transaction | ",
- "rst_description": "Number of Telegram Stars transferred by the transaction\n",
+ "description": "Integer amount of Telegram Stars transferred by the transaction",
+ "html_description": "Integer amount of Telegram Stars transferred by the transaction | ",
+ "rst_description": "Integer amount of Telegram Stars transferred by the transaction\n",
"name": "amount",
"required": true
},
+ {
+ "type": "Integer",
+ "description": "The number of 1/1000000000 shares of Telegram Stars transferred by the transaction; from 0 to 999999999",
+ "html_description": "Optional. The number of 1/1000000000 shares of Telegram Stars transferred by the transaction; from 0 to 999999999 | ",
+ "rst_description": "*Optional*. The number of 1/1000000000 shares of Telegram Stars transferred by the transaction; from 0 to 999999999\n",
+ "name": "nanostar_amount",
+ "required": false
+ },
{
"type": "Integer",
"description": "Date the transaction was created in Unix time",
diff --git a/.butcher/types/AffiliateInfo/entity.json b/.butcher/types/AffiliateInfo/entity.json
new file mode 100644
index 00000000..f73a4f24
--- /dev/null
+++ b/.butcher/types/AffiliateInfo/entity.json
@@ -0,0 +1,57 @@
+{
+ "meta": {},
+ "group": {
+ "title": "Payments",
+ "anchor": "payments"
+ },
+ "object": {
+ "anchor": "affiliateinfo",
+ "name": "AffiliateInfo",
+ "description": "Contains information about the affiliate that received a commission via this transaction.",
+ "html_description": "Contains information about the affiliate that received a commission via this transaction.
",
+ "rst_description": "Contains information about the affiliate that received a commission via this transaction.",
+ "annotations": [
+ {
+ "type": "User",
+ "description": "The bot or the user that received an affiliate commission if it was received by a bot or a user",
+ "html_description": "Optional. The bot or the user that received an affiliate commission if it was received by a bot or a user | ",
+ "rst_description": "*Optional*. The bot or the user that received an affiliate commission if it was received by a bot or a user\n",
+ "name": "affiliate_user",
+ "required": false
+ },
+ {
+ "type": "Chat",
+ "description": "The chat that received an affiliate commission if it was received by a chat",
+ "html_description": "Optional. The chat that received an affiliate commission if it was received by a chat | ",
+ "rst_description": "*Optional*. The chat that received an affiliate commission if it was received by a chat\n",
+ "name": "affiliate_chat",
+ "required": false
+ },
+ {
+ "type": "Integer",
+ "description": "The number of Telegram Stars received by the affiliate for each 1000 Telegram Stars received by the bot from referred users",
+ "html_description": "The number of Telegram Stars received by the affiliate for each 1000 Telegram Stars received by the bot from referred users | ",
+ "rst_description": "The number of Telegram Stars received by the affiliate for each 1000 Telegram Stars received by the bot from referred users\n",
+ "name": "commission_per_mille",
+ "required": true
+ },
+ {
+ "type": "Integer",
+ "description": "Integer amount of Telegram Stars received by the affiliate from the transaction, rounded to 0; can be negative for refunds",
+ "html_description": "Integer amount of Telegram Stars received by the affiliate from the transaction, rounded to 0; can be negative for refunds | ",
+ "rst_description": "Integer amount of Telegram Stars received by the affiliate from the transaction, rounded to 0; can be negative for refunds\n",
+ "name": "amount",
+ "required": true
+ },
+ {
+ "type": "Integer",
+ "description": "The number of 1/1000000000 shares of Telegram Stars received by the affiliate; from -999999999 to 999999999; can be negative for refunds",
+ "html_description": "Optional. The number of 1/1000000000 shares of Telegram Stars received by the affiliate; from -999999999 to 999999999; can be negative for refunds | ",
+ "rst_description": "*Optional*. The number of 1/1000000000 shares of Telegram Stars received by the affiliate; from -999999999 to 999999999; can be negative for refunds\n",
+ "name": "nanostar_amount",
+ "required": false
+ }
+ ],
+ "category": "types"
+ }
+}
diff --git a/.butcher/types/BackgroundTypePattern/entity.json b/.butcher/types/BackgroundTypePattern/entity.json
index 1f286b9f..336bed87 100644
--- a/.butcher/types/BackgroundTypePattern/entity.json
+++ b/.butcher/types/BackgroundTypePattern/entity.json
@@ -7,9 +7,9 @@
"object": {
"anchor": "backgroundtypepattern",
"name": "BackgroundTypePattern",
- "description": "The background is a PNG or TGV (gzipped subset of SVG with MIME type 'application/x-tgwallpattern') pattern to be combined with the background fill chosen by the user.",
- "html_description": "The background is a PNG or TGV (gzipped subset of SVG with MIME type “application/x-tgwallpattern”) pattern to be combined with the background fill chosen by the user.
",
- "rst_description": "The background is a PNG or TGV (gzipped subset of SVG with MIME type 'application/x-tgwallpattern') pattern to be combined with the background fill chosen by the user.",
+ "description": "The background is a .PNG or .TGV (gzipped subset of SVG with MIME type 'application/x-tgwallpattern') pattern to be combined with the background fill chosen by the user.",
+ "html_description": "The background is a .PNG or .TGV (gzipped subset of SVG with MIME type “application/x-tgwallpattern”) pattern to be combined with the background fill chosen by the user.
",
+ "rst_description": "The background is a .PNG or .TGV (gzipped subset of SVG with MIME type 'application/x-tgwallpattern') pattern to be combined with the background fill chosen by the user.",
"annotations": [
{
"type": "String",
diff --git a/.butcher/types/Gift/entity.json b/.butcher/types/Gift/entity.json
index ce7728d6..46454a3e 100644
--- a/.butcher/types/Gift/entity.json
+++ b/.butcher/types/Gift/entity.json
@@ -35,6 +35,14 @@
"name": "star_count",
"required": true
},
+ {
+ "type": "Integer",
+ "description": "The number of Telegram Stars that must be paid to upgrade the gift to a unique one",
+ "html_description": "Optional. The number of Telegram Stars that must be paid to upgrade the gift to a unique one | ",
+ "rst_description": "*Optional*. The number of Telegram Stars that must be paid to upgrade the gift to a unique one\n",
+ "name": "upgrade_star_count",
+ "required": false
+ },
{
"type": "Integer",
"description": "The total number of the gifts of this type that can be sent; for limited gifts only",
diff --git a/.butcher/types/InlineQueryResultArticle/entity.json b/.butcher/types/InlineQueryResultArticle/entity.json
index eba5d318..c9622b2a 100644
--- a/.butcher/types/InlineQueryResultArticle/entity.json
+++ b/.butcher/types/InlineQueryResultArticle/entity.json
@@ -59,14 +59,6 @@
"name": "url",
"required": false
},
- {
- "type": "Boolean",
- "description": "Pass True if you don't want the URL to be shown in the message",
- "html_description": "Optional. Pass True if you don't want the URL to be shown in the message | ",
- "rst_description": "*Optional*. Pass :code:`True` if you don't want the URL to be shown in the message\n",
- "name": "hide_url",
- "required": false
- },
{
"type": "String",
"description": "Short description of the result",
@@ -98,6 +90,18 @@
"rst_description": "*Optional*. Thumbnail height\n",
"name": "thumbnail_height",
"required": false
+ },
+ {
+ "type": "Boolean",
+ "description": "Pass True if you don't want the URL to be shown in the message",
+ "html_description": "Optional. Pass True if you don't want the URL to be shown in the message | ",
+ "rst_description": "*Optional*. Pass :code:`True` if you don't want the URL to be shown in the message\n",
+ "name": "hide_url",
+ "required": false,
+ "deprecated": {
+ "version": "8.2",
+ "release_date": "2025-01-01"
+ }
}
],
"category": "types"
diff --git a/.butcher/types/InlineQueryResultGif/entity.json b/.butcher/types/InlineQueryResultGif/entity.json
index 7c104615..ee825305 100644
--- a/.butcher/types/InlineQueryResultGif/entity.json
+++ b/.butcher/types/InlineQueryResultGif/entity.json
@@ -29,9 +29,9 @@
},
{
"type": "String",
- "description": "A valid URL for the GIF file. File size must not exceed 1MB",
- "html_description": "A valid URL for the GIF file. File size must not exceed 1MB | ",
- "rst_description": "A valid URL for the GIF file. File size must not exceed 1MB\n",
+ "description": "A valid URL for the GIF file",
+ "html_description": "A valid URL for the GIF file | ",
+ "rst_description": "A valid URL for the GIF file\n",
"name": "gif_url",
"required": true
},
diff --git a/.butcher/types/InlineQueryResultMpeg4Gif/entity.json b/.butcher/types/InlineQueryResultMpeg4Gif/entity.json
index fa4c3e81..fc309461 100644
--- a/.butcher/types/InlineQueryResultMpeg4Gif/entity.json
+++ b/.butcher/types/InlineQueryResultMpeg4Gif/entity.json
@@ -29,9 +29,9 @@
},
{
"type": "String",
- "description": "A valid URL for the MPEG4 file. File size must not exceed 1MB",
- "html_description": "A valid URL for the MPEG4 file. File size must not exceed 1MB | ",
- "rst_description": "A valid URL for the MPEG4 file. File size must not exceed 1MB\n",
+ "description": "A valid URL for the MPEG4 file",
+ "html_description": "A valid URL for the MPEG4 file | ",
+ "rst_description": "A valid URL for the MPEG4 file\n",
"name": "mpeg4_url",
"required": true
},
diff --git a/.butcher/types/InputSticker/entity.json b/.butcher/types/InputSticker/entity.json
index 2df660ae..0ec7ae40 100644
--- a/.butcher/types/InputSticker/entity.json
+++ b/.butcher/types/InputSticker/entity.json
@@ -21,9 +21,9 @@
},
{
"type": "String",
- "description": "Format of the added sticker, must be one of 'static' for a .WEBP or .PNG image, 'animated' for a .TGS animation, 'video' for a WEBM video",
- "html_description": "Format of the added sticker, must be one of “static” for a .WEBP or .PNG image, “animated” for a .TGS animation, “video” for a WEBM video | ",
- "rst_description": "Format of the added sticker, must be one of 'static' for a **.WEBP** or **.PNG** image, 'animated' for a **.TGS** animation, 'video' for a **WEBM** video\n",
+ "description": "Format of the added sticker, must be one of 'static' for a .WEBP or .PNG image, 'animated' for a .TGS animation, 'video' for a .WEBM video",
+ "html_description": "Format of the added sticker, must be one of “static” for a .WEBP or .PNG image, “animated” for a .TGS animation, “video” for a .WEBM video | ",
+ "rst_description": "Format of the added sticker, must be one of 'static' for a **.WEBP** or **.PNG** image, 'animated' for a **.TGS** animation, 'video' for a **.WEBM** video\n",
"name": "format",
"required": true
},
diff --git a/.butcher/types/StarTransaction/entity.json b/.butcher/types/StarTransaction/entity.json
index 775b96ca..4186788a 100644
--- a/.butcher/types/StarTransaction/entity.json
+++ b/.butcher/types/StarTransaction/entity.json
@@ -21,12 +21,20 @@
},
{
"type": "Integer",
- "description": "Number of Telegram Stars transferred by the transaction",
- "html_description": "Number of Telegram Stars transferred by the transaction | ",
- "rst_description": "Number of Telegram Stars transferred by the transaction\n",
+ "description": "Integer amount of Telegram Stars transferred by the transaction",
+ "html_description": "Integer amount of Telegram Stars transferred by the transaction | ",
+ "rst_description": "Integer amount of Telegram Stars transferred by the transaction\n",
"name": "amount",
"required": true
},
+ {
+ "type": "Integer",
+ "description": "The number of 1/1000000000 shares of Telegram Stars transferred by the transaction; from 0 to 999999999",
+ "html_description": "Optional. The number of 1/1000000000 shares of Telegram Stars transferred by the transaction; from 0 to 999999999 | ",
+ "rst_description": "*Optional*. The number of 1/1000000000 shares of Telegram Stars transferred by the transaction; from 0 to 999999999\n",
+ "name": "nanostar_amount",
+ "required": false
+ },
{
"type": "Integer",
"description": "Date the transaction was created in Unix time",
diff --git a/.butcher/types/TransactionPartner/entity.json b/.butcher/types/TransactionPartner/entity.json
index d8e38c67..8c01706b 100644
--- a/.butcher/types/TransactionPartner/entity.json
+++ b/.butcher/types/TransactionPartner/entity.json
@@ -7,9 +7,9 @@
"object": {
"anchor": "transactionpartner",
"name": "TransactionPartner",
- "description": "This object describes the source of a transaction, or its recipient for outgoing transactions. Currently, it can be one of\n - TransactionPartnerUser\n - TransactionPartnerFragment\n - TransactionPartnerTelegramAds\n - TransactionPartnerTelegramApi\n - TransactionPartnerOther",
- "html_description": "This object describes the source of a transaction, or its recipient for outgoing transactions. Currently, it can be one of
",
- "rst_description": "This object describes the source of a transaction, or its recipient for outgoing transactions. Currently, it can be one of\n\n - :class:`aiogram.types.transaction_partner_user.TransactionPartnerUser`\n - :class:`aiogram.types.transaction_partner_fragment.TransactionPartnerFragment`\n - :class:`aiogram.types.transaction_partner_telegram_ads.TransactionPartnerTelegramAds`\n - :class:`aiogram.types.transaction_partner_telegram_api.TransactionPartnerTelegramApi`\n - :class:`aiogram.types.transaction_partner_other.TransactionPartnerOther`",
+ "description": "This object describes the source of a transaction, or its recipient for outgoing transactions. Currently, it can be one of\n - TransactionPartnerUser\n - TransactionPartnerAffiliateProgram\n - TransactionPartnerFragment\n - TransactionPartnerTelegramAds\n - TransactionPartnerTelegramApi\n - TransactionPartnerOther",
+ "html_description": "This object describes the source of a transaction, or its recipient for outgoing transactions. Currently, it can be one of
",
+ "rst_description": "This object describes the source of a transaction, or its recipient for outgoing transactions. Currently, it can be one of\n\n - :class:`aiogram.types.transaction_partner_user.TransactionPartnerUser`\n - :class:`aiogram.types.transaction_partner_affiliate_program.TransactionPartnerAffiliateProgram`\n - :class:`aiogram.types.transaction_partner_fragment.TransactionPartnerFragment`\n - :class:`aiogram.types.transaction_partner_telegram_ads.TransactionPartnerTelegramAds`\n - :class:`aiogram.types.transaction_partner_telegram_api.TransactionPartnerTelegramApi`\n - :class:`aiogram.types.transaction_partner_other.TransactionPartnerOther`",
"annotations": [],
"category": "types"
}
diff --git a/.butcher/types/TransactionPartnerAffiliateProgram/entity.json b/.butcher/types/TransactionPartnerAffiliateProgram/entity.json
new file mode 100644
index 00000000..a637836c
--- /dev/null
+++ b/.butcher/types/TransactionPartnerAffiliateProgram/entity.json
@@ -0,0 +1,41 @@
+{
+ "meta": {},
+ "group": {
+ "title": "Payments",
+ "anchor": "payments"
+ },
+ "object": {
+ "anchor": "transactionpartneraffiliateprogram",
+ "name": "TransactionPartnerAffiliateProgram",
+ "description": "Describes the affiliate program that issued the affiliate commission received via this transaction.",
+ "html_description": "Describes the affiliate program that issued the affiliate commission received via this transaction.
",
+ "rst_description": "Describes the affiliate program that issued the affiliate commission received via this transaction.",
+ "annotations": [
+ {
+ "type": "String",
+ "description": "Type of the transaction partner, always 'affiliate_program'",
+ "html_description": "Type of the transaction partner, always “affiliate_program” | ",
+ "rst_description": "Type of the transaction partner, always 'affiliate_program'\n",
+ "name": "type",
+ "required": true
+ },
+ {
+ "type": "User",
+ "description": "Information about the bot that sponsored the affiliate program",
+ "html_description": "Optional. Information about the bot that sponsored the affiliate program | ",
+ "rst_description": "*Optional*. Information about the bot that sponsored the affiliate program\n",
+ "name": "sponsor_user",
+ "required": false
+ },
+ {
+ "type": "Integer",
+ "description": "The number of Telegram Stars received by the bot for each 1000 Telegram Stars received by the affiliate program sponsor from referred users",
+ "html_description": "The number of Telegram Stars received by the bot for each 1000 Telegram Stars received by the affiliate program sponsor from referred users | ",
+ "rst_description": "The number of Telegram Stars received by the bot for each 1000 Telegram Stars received by the affiliate program sponsor from referred users\n",
+ "name": "commission_per_mille",
+ "required": true
+ }
+ ],
+ "category": "types"
+ }
+}
diff --git a/.butcher/types/TransactionPartnerUser/entity.json b/.butcher/types/TransactionPartnerUser/entity.json
index f8064da9..b830a190 100644
--- a/.butcher/types/TransactionPartnerUser/entity.json
+++ b/.butcher/types/TransactionPartnerUser/entity.json
@@ -27,6 +27,14 @@
"name": "user",
"required": true
},
+ {
+ "type": "AffiliateInfo",
+ "description": "Information about the affiliate that received a commission via this transaction",
+ "html_description": "Optional. Information about the affiliate that received a commission via this transaction | ",
+ "rst_description": "*Optional*. Information about the affiliate that received a commission via this transaction\n",
+ "name": "affiliate",
+ "required": false
+ },
{
"type": "String",
"description": "Bot-specified invoice payload",
@@ -60,7 +68,7 @@
"required": false
},
{
- "type": "String",
+ "type": "Gift",
"description": "The gift sent to the user by the bot",
"html_description": "Optional. The gift sent to the user by the bot | ",
"rst_description": "*Optional*. The gift sent to the user by the bot\n",
diff --git a/CHANGES.rst b/CHANGES.rst
index 045fb873..3afc290d 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -16,6 +16,53 @@ Changelog
.. towncrier release notes start
+3.17.0 (2025-01-02)
+====================
+
+Features
+--------
+
+- Added full support of the `Bot API 8.2 `_
+
+ - Added the methods :class:`aiogram.methods.verify_user.VerifyUser`, :class:`aiogram.methods.verify_chat.VerifyChat`, :class:`aiogram.methods.remove_user_verification.RemoveUserVerification` and :class:`aiogram.methods.remove_chat_verification.RemoveChatVerification`, allowing bots to manage verifications on behalf of an organization.
+ - Added the field :code:`upgrade_star_count` to the class :class:`aiogram.types.gift.Gift`.
+ - Added the parameter :code:`pay_for_upgrade` to the method :class:`aiogram.methods.send_gift.SendGift`.
+ - Removed the field :code:`hide_url` from the class :class:`aiogram.types.inline_query_result_article.InlineQueryResultArticle`. Pass an empty string as :code:`url` instead.
+ `#1623 `_
+
+
+3.16.0 (2024-12-21)
+====================
+
+Features
+--------
+
+- Added full support of `Bot API 8.1 `_:
+
+ - Added the field :code:`nanostar_amount` to the class :class:`aiogram.types.star_transaction.StarTransaction`.
+ - Added the class :class:`aiogram.types.transaction_partner_affiliate_program.TransactionPartnerAffiliateProgram` for transactions pertaining to incoming affiliate commissions.
+ - Added the class :class:`aiogram.types.affiliate_info.AffiliateInfo` and the field :code:`affiliate` to the class :class:`aiogram.types.transaction_partner_user.TransactionPartnerUser`, allowing bots to identify the relevant affiliate in transactions with an affiliate commission.
+ `#1617 `_
+
+
+Bugfixes
+--------
+
+- Corrected the exception text of `aiogram.methods.base.TelegramMethod.__await__` method.
+ `#1616 `_
+
+
+Misc
+----
+
+- Increased max :code:`pydantic` version support from “<2.10” to “<2.11”
+ `#1607 `_
+- Fixed closing tag for :code:`tg-emoji` in the :class:`aiogram.utils.text_decoration.HtmlDecoration`: use the same constant as for tag opening
+ `#1608 `_
+- Increased max :code:`aiohttp` version support from “<3.11” to “<3.12”
+ `#1615 `_
+
+
3.15.0 (2024-11-17)
====================
diff --git a/CHANGES/1607.misc.rst b/CHANGES/1607.misc.rst
deleted file mode 100644
index f9095214..00000000
--- a/CHANGES/1607.misc.rst
+++ /dev/null
@@ -1 +0,0 @@
-Increased max :code:`pydantic` version support from “<2.10” to “<2.11”
diff --git a/CHANGES/1608.misc.rst b/CHANGES/1608.misc.rst
deleted file mode 100644
index 2641bb8c..00000000
--- a/CHANGES/1608.misc.rst
+++ /dev/null
@@ -1 +0,0 @@
-Fixed closing tag for :code:`tg-emoji` in the :class:`aiogram.utils.text_decoration.HtmlDecoration`: use the same constant as for tag opening
diff --git a/CHANGES/1612.misc.rst b/CHANGES/1612.misc.rst
new file mode 100644
index 00000000..e34e2023
--- /dev/null
+++ b/CHANGES/1612.misc.rst
@@ -0,0 +1 @@
+Removed redundant :code:`Path` to :code:`str` convertion on file download.
diff --git a/CHANGES/1628.bugfix.rst b/CHANGES/1628.bugfix.rst
new file mode 100644
index 00000000..ee5d7299
--- /dev/null
+++ b/CHANGES/1628.bugfix.rst
@@ -0,0 +1 @@
+Change the :code:`Downloadable` protocol to be non-writable to shut up type checking that checks code that uses the :code:`bot.download(...)` method
diff --git a/CHANGES/1630.bugfix.rst b/CHANGES/1630.bugfix.rst
new file mode 100644
index 00000000..e083dc1f
--- /dev/null
+++ b/CHANGES/1630.bugfix.rst
@@ -0,0 +1 @@
+Fix the regex pattern that finds the "bad characters" for deeplink payload.
\ No newline at end of file
diff --git a/CHANGES/1631.misc.rst b/CHANGES/1631.misc.rst
new file mode 100644
index 00000000..76e2fa47
--- /dev/null
+++ b/CHANGES/1631.misc.rst
@@ -0,0 +1 @@
+ Increased max :code:`redis` version support from “<5.1.0” to “<5.3.0”
diff --git a/README.rst b/README.rst
index acc48f8b..af938312 100644
--- a/README.rst
+++ b/README.rst
@@ -52,7 +52,7 @@ Features
- Asynchronous (`asyncio docs `_, :pep:`492`)
- Has type hints (:pep:`484`) and can be used with `mypy `_
- Supports `PyPy `_
-- Supports `Telegram Bot API 8.0 `_ and gets fast updates to the latest versions of the Bot API
+- Supports `Telegram Bot API 8.2 `_ and gets fast updates to the latest versions of the Bot API
- Telegram Bot API integration code was `autogenerated `_ and can be easily re-generated when API gets updated
- Updates router (Blueprints)
- Has Finite State Machine
diff --git a/aiogram/__meta__.py b/aiogram/__meta__.py
index befb7cb6..b04fd4ce 100644
--- a/aiogram/__meta__.py
+++ b/aiogram/__meta__.py
@@ -1,2 +1,2 @@
-__version__ = "3.15.0"
-__api_version__ = "8.0"
+__version__ = "3.17.0"
+__api_version__ = "8.2"
diff --git a/aiogram/client/bot.py b/aiogram/client/bot.py
index b538485f..9848d7bb 100644
--- a/aiogram/client/bot.py
+++ b/aiogram/client/bot.py
@@ -93,6 +93,8 @@ from ..methods import (
PinChatMessage,
PromoteChatMember,
RefundStarPayment,
+ RemoveChatVerification,
+ RemoveUserVerification,
ReopenForumTopic,
ReopenGeneralForumTopic,
ReplaceStickerInSet,
@@ -154,6 +156,8 @@ from ..methods import (
UnpinAllGeneralForumTopicMessages,
UnpinChatMessage,
UploadStickerFile,
+ VerifyChat,
+ VerifyUser,
)
from ..types import (
BotCommand,
@@ -387,7 +391,7 @@ class Bot:
@classmethod
async def __aiofiles_reader(
- cls, file: str, chunk_size: int = 65536
+ cls, file: Union[str, pathlib.Path], chunk_size: int = 65536
) -> AsyncGenerator[bytes, None]:
async with aiofiles.open(file, "rb") as f:
while chunk := await f.read(chunk_size):
@@ -395,7 +399,7 @@ class Bot:
async def download_file(
self,
- file_path: str,
+ file_path: Union[str, pathlib.Path],
destination: Optional[Union[BinaryIO, pathlib.Path, str]] = None,
timeout: int = 30,
chunk_size: int = 65536,
@@ -419,7 +423,7 @@ class Bot:
close_stream = False
if self.session.api.is_local:
stream = self.__aiofiles_reader(
- str(self.session.api.wrap_local_file.to_local(file_path)), chunk_size=chunk_size
+ self.session.api.wrap_local_file.to_local(file_path), chunk_size=chunk_size
)
close_stream = True
else:
@@ -1014,9 +1018,9 @@ class Bot:
:param payload: Bot-defined invoice payload, 1-128 bytes. This will not be displayed to the user, use it for your internal processes.
:param currency: Three-letter ISO 4217 currency code, see `more on currencies `_. Pass 'XTR' for payments in `Telegram Stars `_.
:param prices: Price breakdown, a JSON-serialized list of components (e.g. product price, tax, discount, delivery cost, delivery tax, bonus, etc.). Must contain exactly one item for payments in `Telegram Stars `_.
- :param business_connection_id: Unique identifier of the business connection on behalf of which the link will be created
+ :param business_connection_id: Unique identifier of the business connection on behalf of which the link will be created. For payments in `Telegram Stars `_ only.
:param provider_token: Payment provider token, obtained via `@BotFather `_. Pass an empty string for payments in `Telegram Stars `_.
- :param subscription_period: The number of seconds the subscription will be active for before the next payment. The currency must be set to 'XTR' (Telegram Stars) if the parameter is used. Currently, it must always be 2592000 (30 days) if specified.
+ :param subscription_period: The number of seconds the subscription will be active for before the next payment. The currency must be set to 'XTR' (Telegram Stars) if the parameter is used. Currently, it must always be 2592000 (30 days) if specified. Any number of subscriptions can be active for a given bot at the same time, including multiple concurrent subscriptions from the same user. Subscription price must no exceed 2500 Telegram Stars.
:param max_tip_amount: The maximum accepted amount for tips in the *smallest units* of the currency (integer, **not** float/double). For example, for a maximum tip of :code:`US$ 1.45` pass :code:`max_tip_amount = 145`. See the *exp* parameter in `currencies.json `_, it shows the number of digits past the decimal point for each currency (2 for the majority of currencies). Defaults to 0. Not supported for payments in `Telegram Stars `_.
:param suggested_tip_amounts: A JSON-serialized array of suggested amounts of tips in the *smallest units* of the currency (integer, **not** float/double). At most 4 suggested tip amounts can be specified. The suggested tip amounts must be positive, passed in a strictly increased order and must not exceed *max_tip_amount*.
:param provider_data: JSON-serialized data about the invoice, which will be shared with the payment provider. A detailed description of required fields should be provided by the payment provider.
@@ -3816,7 +3820,7 @@ class Bot:
request_timeout: Optional[int] = None,
) -> bool:
"""
- Use this method to specify a URL and receive incoming updates via an outgoing webhook. Whenever there is an update for the bot, we will send an HTTPS POST request to the specified URL, containing a JSON-serialized :class:`aiogram.types.update.Update`. In case of an unsuccessful request, we will give up after a reasonable amount of attempts. Returns :code:`True` on success.
+ Use this method to specify a URL and receive incoming updates via an outgoing webhook. Whenever there is an update for the bot, we will send an HTTPS POST request to the specified URL, containing a JSON-serialized :class:`aiogram.types.update.Update`. In case of an unsuccessful request (a request with response `HTTP status code `_ different from :code:`2XY`), we will repeat the request and give up after a reasonable amount of attempts. Returns :code:`True` on success.
If you'd like to make sure that the webhook was set by you, you can specify secret data in the parameter *secret_token*. If specified, the request will contain a header 'X-Telegram-Bot-Api-Secret-Token' with the secret token as content.
**Notes**
@@ -4373,8 +4377,8 @@ class Bot:
:param name: Sticker set name
:param user_id: User identifier of the sticker set owner
- :param format: Format of the thumbnail, must be one of 'static' for a **.WEBP** or **.PNG** image, 'animated' for a **.TGS** animation, or 'video' for a **WEBM** video
- :param thumbnail: A **.WEBP** or **.PNG** image with the thumbnail, must be up to 128 kilobytes in size and have a width and height of exactly 100px, or a **.TGS** animation with a thumbnail up to 32 kilobytes in size (see `https://core.telegram.org/stickers#animation-requirements `_`https://core.telegram.org/stickers#animation-requirements `_ for animated sticker technical requirements), or a **WEBM** video with the thumbnail up to 32 kilobytes in size; see `https://core.telegram.org/stickers#video-requirements `_`https://core.telegram.org/stickers#video-requirements `_ for video sticker technical requirements. Pass a *file_id* as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. :ref:`More information on Sending Files » `. Animated and video sticker set thumbnails can't be uploaded via HTTP URL. If omitted, then the thumbnail is dropped and the first sticker is used as the thumbnail.
+ :param format: Format of the thumbnail, must be one of 'static' for a **.WEBP** or **.PNG** image, 'animated' for a **.TGS** animation, or 'video' for a **.WEBM** video
+ :param thumbnail: A **.WEBP** or **.PNG** image with the thumbnail, must be up to 128 kilobytes in size and have a width and height of exactly 100px, or a **.TGS** animation with a thumbnail up to 32 kilobytes in size (see `https://core.telegram.org/stickers#animation-requirements `_`https://core.telegram.org/stickers#animation-requirements `_ for animated sticker technical requirements), or a **.WEBM** video with the thumbnail up to 32 kilobytes in size; see `https://core.telegram.org/stickers#video-requirements `_`https://core.telegram.org/stickers#video-requirements `_ for video sticker technical requirements. Pass a *file_id* as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. :ref:`More information on Sending Files » `. Animated and video sticker set thumbnails can't be uploaded via HTTP URL. If omitted, then the thumbnail is dropped and the first sticker is used as the thumbnail.
:param request_timeout: Request timeout
:return: Returns :code:`True` on success.
"""
@@ -4936,6 +4940,7 @@ class Bot:
self,
user_id: int,
gift_id: str,
+ pay_for_upgrade: Optional[bool] = None,
text: Optional[str] = None,
text_parse_mode: Optional[str] = None,
text_entities: Optional[list[MessageEntity]] = None,
@@ -4948,6 +4953,7 @@ class Bot:
:param user_id: Unique identifier of the target user that will receive the gift
:param gift_id: Identifier of the gift
+ :param pay_for_upgrade: Pass :code:`True` to pay for the gift upgrade from the bot's balance, thereby making the upgrade free for the receiver
:param text: Text that will be shown along with the gift; 0-255 characters
:param text_parse_mode: Mode for parsing entities in the text. See `formatting options `_ for more details. Entities other than 'bold', 'italic', 'underline', 'strikethrough', 'spoiler', and 'custom_emoji' are ignored.
:param text_entities: A JSON-serialized list of special entities that appear in the gift text. It can be specified instead of *text_parse_mode*. Entities other than 'bold', 'italic', 'underline', 'strikethrough', 'spoiler', and 'custom_emoji' are ignored.
@@ -4958,6 +4964,7 @@ class Bot:
call = SendGift(
user_id=user_id,
gift_id=gift_id,
+ pay_for_upgrade=pay_for_upgrade,
text=text,
text_parse_mode=text_parse_mode,
text_entities=text_entities,
@@ -4991,3 +4998,89 @@ class Bot:
emoji_status_expiration_date=emoji_status_expiration_date,
)
return await self(call, request_timeout=request_timeout)
+
+ async def remove_chat_verification(
+ self,
+ chat_id: Union[int, str],
+ request_timeout: Optional[int] = None,
+ ) -> bool:
+ """
+ Removes verification from a chat that is currently verified on behalf of the organization represented by the bot. Returns :code:`True` on success.
+
+ Source: https://core.telegram.org/bots/api#removechatverification
+
+ :param chat_id: Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`)
+ :param request_timeout: Request timeout
+ :return: Returns :code:`True` on success.
+ """
+
+ call = RemoveChatVerification(
+ chat_id=chat_id,
+ )
+ return await self(call, request_timeout=request_timeout)
+
+ async def remove_user_verification(
+ self,
+ user_id: int,
+ request_timeout: Optional[int] = None,
+ ) -> bool:
+ """
+ Removes verification from a user who is currently verified on behalf of the organization represented by the bot. Returns :code:`True` on success.
+
+ Source: https://core.telegram.org/bots/api#removeuserverification
+
+ :param user_id: Unique identifier of the target user
+ :param request_timeout: Request timeout
+ :return: Returns :code:`True` on success.
+ """
+
+ call = RemoveUserVerification(
+ user_id=user_id,
+ )
+ return await self(call, request_timeout=request_timeout)
+
+ async def verify_chat(
+ self,
+ chat_id: Union[int, str],
+ custom_description: Optional[str] = None,
+ request_timeout: Optional[int] = None,
+ ) -> bool:
+ """
+ Verifies a chat on behalf of the organization which is represented by the bot. Returns :code:`True` on success.
+
+ Source: https://core.telegram.org/bots/api#verifychat
+
+ :param chat_id: Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`)
+ :param custom_description: Custom description for the verification; 0-70 characters. Must be empty if the organization isn't allowed to provide a custom verification description.
+ :param request_timeout: Request timeout
+ :return: Returns :code:`True` on success.
+ """
+
+ call = VerifyChat(
+ chat_id=chat_id,
+ custom_description=custom_description,
+ )
+ return await self(call, request_timeout=request_timeout)
+
+ async def verify_user(
+ self,
+ user_id: int,
+ custom_description: Optional[str] = None,
+ request_timeout: Optional[int] = None,
+ ) -> bool:
+ """
+ Verifies a user on behalf of the organization which is represented by the bot. Returns :code:`True` on success.
+
+ Source: https://core.telegram.org/bots/api#verifyuser
+
+ :param user_id: Unique identifier of the target user
+ :param custom_description: Custom description for the verification; 0-70 characters. Must be empty if the organization isn't allowed to provide a custom verification description.
+ :param request_timeout: Request timeout
+ :return: Returns :code:`True` on success.
+ """
+
+ call = VerifyUser(
+ user_id=user_id,
+ custom_description=custom_description,
+ )
+ return await self(call, request_timeout=request_timeout)
diff --git a/aiogram/client/telegram.py b/aiogram/client/telegram.py
index 5e29722f..cfb3c49d 100644
--- a/aiogram/client/telegram.py
+++ b/aiogram/client/telegram.py
@@ -67,7 +67,7 @@ class TelegramAPIServer:
"""
return self.base.format(token=token, method=method)
- def file_url(self, token: str, path: str) -> str:
+ def file_url(self, token: str, path: Union[str, Path]) -> str:
"""
Generate URL for downloading files
diff --git a/aiogram/enums/transaction_partner_type.py b/aiogram/enums/transaction_partner_type.py
index 79e7900e..ec84318a 100644
--- a/aiogram/enums/transaction_partner_type.py
+++ b/aiogram/enums/transaction_partner_type.py
@@ -13,3 +13,4 @@ class TransactionPartnerType(str, Enum):
USER = "user"
TELEGRAM_ADS = "telegram_ads"
TELEGRAM_API = "telegram_api"
+ AFFILIATE_PROGRAM = "affiliate_program"
diff --git a/aiogram/methods/__init__.py b/aiogram/methods/__init__.py
index 893f4f73..c40461fe 100644
--- a/aiogram/methods/__init__.py
+++ b/aiogram/methods/__init__.py
@@ -70,6 +70,8 @@ from .log_out import LogOut
from .pin_chat_message import PinChatMessage
from .promote_chat_member import PromoteChatMember
from .refund_star_payment import RefundStarPayment
+from .remove_chat_verification import RemoveChatVerification
+from .remove_user_verification import RemoveUserVerification
from .reopen_forum_topic import ReopenForumTopic
from .reopen_general_forum_topic import ReopenGeneralForumTopic
from .replace_sticker_in_set import ReplaceStickerInSet
@@ -130,6 +132,8 @@ from .unpin_all_forum_topic_messages import UnpinAllForumTopicMessages
from .unpin_all_general_forum_topic_messages import UnpinAllGeneralForumTopicMessages
from .unpin_chat_message import UnpinChatMessage
from .upload_sticker_file import UploadStickerFile
+from .verify_chat import VerifyChat
+from .verify_user import VerifyUser
__all__ = (
"AddStickerToSet",
@@ -203,6 +207,8 @@ __all__ = (
"PinChatMessage",
"PromoteChatMember",
"RefundStarPayment",
+ "RemoveChatVerification",
+ "RemoveUserVerification",
"ReopenForumTopic",
"ReopenGeneralForumTopic",
"ReplaceStickerInSet",
@@ -266,4 +272,6 @@ __all__ = (
"UnpinAllGeneralForumTopicMessages",
"UnpinChatMessage",
"UploadStickerFile",
+ "VerifyChat",
+ "VerifyUser",
)
diff --git a/aiogram/methods/base.py b/aiogram/methods/base.py
index b2d35bec..3279199a 100644
--- a/aiogram/methods/base.py
+++ b/aiogram/methods/base.py
@@ -90,6 +90,6 @@ class TelegramMethod(BotContextController, BaseModel, Generic[TelegramType], ABC
"This method is not mounted to a any bot instance, please call it explicilty "
"with bot instance `await bot(method)`\n"
"or mount method to a bot instance `method.as_(bot)` "
- "and then call it `await method()`"
+ "and then call it `await method`"
)
return self.emit(bot).__await__()
diff --git a/aiogram/methods/create_invoice_link.py b/aiogram/methods/create_invoice_link.py
index 0c17aac2..40321bde 100644
--- a/aiogram/methods/create_invoice_link.py
+++ b/aiogram/methods/create_invoice_link.py
@@ -27,11 +27,11 @@ class CreateInvoiceLink(TelegramMethod[str]):
prices: list[LabeledPrice]
"""Price breakdown, a JSON-serialized list of components (e.g. product price, tax, discount, delivery cost, delivery tax, bonus, etc.). Must contain exactly one item for payments in `Telegram Stars `_."""
business_connection_id: Optional[str] = None
- """Unique identifier of the business connection on behalf of which the link will be created"""
+ """Unique identifier of the business connection on behalf of which the link will be created. For payments in `Telegram Stars `_ only."""
provider_token: Optional[str] = None
"""Payment provider token, obtained via `@BotFather `_. Pass an empty string for payments in `Telegram Stars `_."""
subscription_period: Optional[int] = None
- """The number of seconds the subscription will be active for before the next payment. The currency must be set to 'XTR' (Telegram Stars) if the parameter is used. Currently, it must always be 2592000 (30 days) if specified."""
+ """The number of seconds the subscription will be active for before the next payment. The currency must be set to 'XTR' (Telegram Stars) if the parameter is used. Currently, it must always be 2592000 (30 days) if specified. Any number of subscriptions can be active for a given bot at the same time, including multiple concurrent subscriptions from the same user. Subscription price must no exceed 2500 Telegram Stars."""
max_tip_amount: Optional[int] = None
"""The maximum accepted amount for tips in the *smallest units* of the currency (integer, **not** float/double). For example, for a maximum tip of :code:`US$ 1.45` pass :code:`max_tip_amount = 145`. See the *exp* parameter in `currencies.json `_, it shows the number of digits past the decimal point for each currency (2 for the majority of currencies). Defaults to 0. Not supported for payments in `Telegram Stars `_."""
suggested_tip_amounts: Optional[list[int]] = None
diff --git a/aiogram/methods/remove_chat_verification.py b/aiogram/methods/remove_chat_verification.py
new file mode 100644
index 00000000..ff242c48
--- /dev/null
+++ b/aiogram/methods/remove_chat_verification.py
@@ -0,0 +1,32 @@
+from __future__ import annotations
+
+from typing import TYPE_CHECKING, Any, Union
+
+from .base import TelegramMethod
+
+
+class RemoveChatVerification(TelegramMethod[bool]):
+ """
+ Removes verification from a chat that is currently verified on behalf of the organization represented by the bot. Returns :code:`True` on success.
+
+ Source: https://core.telegram.org/bots/api#removechatverification
+ """
+
+ __returning__ = bool
+ __api_method__ = "removeChatVerification"
+
+ chat_id: Union[int, str]
+ """Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`)"""
+
+ if TYPE_CHECKING:
+ # DO NOT EDIT MANUALLY!!!
+ # This section was auto-generated via `butcher`
+
+ def __init__(
+ __pydantic__self__, *, chat_id: Union[int, str], **__pydantic_kwargs: Any
+ ) -> None:
+ # DO NOT EDIT MANUALLY!!!
+ # This method was auto-generated via `butcher`
+ # Is needed only for type checking and IDE support without any additional plugins
+
+ super().__init__(chat_id=chat_id, **__pydantic_kwargs)
diff --git a/aiogram/methods/remove_user_verification.py b/aiogram/methods/remove_user_verification.py
new file mode 100644
index 00000000..0cd4b4c8
--- /dev/null
+++ b/aiogram/methods/remove_user_verification.py
@@ -0,0 +1,30 @@
+from __future__ import annotations
+
+from typing import TYPE_CHECKING, Any
+
+from .base import TelegramMethod
+
+
+class RemoveUserVerification(TelegramMethod[bool]):
+ """
+ Removes verification from a user who is currently verified on behalf of the organization represented by the bot. Returns :code:`True` on success.
+
+ Source: https://core.telegram.org/bots/api#removeuserverification
+ """
+
+ __returning__ = bool
+ __api_method__ = "removeUserVerification"
+
+ user_id: int
+ """Unique identifier of the target user"""
+
+ if TYPE_CHECKING:
+ # DO NOT EDIT MANUALLY!!!
+ # This section was auto-generated via `butcher`
+
+ def __init__(__pydantic__self__, *, user_id: int, **__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, **__pydantic_kwargs)
diff --git a/aiogram/methods/send_gift.py b/aiogram/methods/send_gift.py
index a07e9f45..73b6ab60 100644
--- a/aiogram/methods/send_gift.py
+++ b/aiogram/methods/send_gift.py
@@ -20,6 +20,8 @@ class SendGift(TelegramMethod[bool]):
"""Unique identifier of the target user that will receive the gift"""
gift_id: str
"""Identifier of the gift"""
+ pay_for_upgrade: Optional[bool] = None
+ """Pass :code:`True` to pay for the gift upgrade from the bot's balance, thereby making the upgrade free for the receiver"""
text: Optional[str] = None
"""Text that will be shown along with the gift; 0-255 characters"""
text_parse_mode: Optional[str] = None
@@ -36,6 +38,7 @@ class SendGift(TelegramMethod[bool]):
*,
user_id: int,
gift_id: str,
+ pay_for_upgrade: Optional[bool] = None,
text: Optional[str] = None,
text_parse_mode: Optional[str] = None,
text_entities: Optional[list[MessageEntity]] = None,
@@ -48,6 +51,7 @@ class SendGift(TelegramMethod[bool]):
super().__init__(
user_id=user_id,
gift_id=gift_id,
+ pay_for_upgrade=pay_for_upgrade,
text=text,
text_parse_mode=text_parse_mode,
text_entities=text_entities,
diff --git a/aiogram/methods/set_sticker_set_thumbnail.py b/aiogram/methods/set_sticker_set_thumbnail.py
index ef83f701..64140ee4 100644
--- a/aiogram/methods/set_sticker_set_thumbnail.py
+++ b/aiogram/methods/set_sticker_set_thumbnail.py
@@ -21,9 +21,9 @@ class SetStickerSetThumbnail(TelegramMethod[bool]):
user_id: int
"""User identifier of the sticker set owner"""
format: str
- """Format of the thumbnail, must be one of 'static' for a **.WEBP** or **.PNG** image, 'animated' for a **.TGS** animation, or 'video' for a **WEBM** video"""
+ """Format of the thumbnail, must be one of 'static' for a **.WEBP** or **.PNG** image, 'animated' for a **.TGS** animation, or 'video' for a **.WEBM** video"""
thumbnail: Optional[Union[InputFile, str]] = None
- """A **.WEBP** or **.PNG** image with the thumbnail, must be up to 128 kilobytes in size and have a width and height of exactly 100px, or a **.TGS** animation with a thumbnail up to 32 kilobytes in size (see `https://core.telegram.org/stickers#animation-requirements `_`https://core.telegram.org/stickers#animation-requirements `_ for animated sticker technical requirements), or a **WEBM** video with the thumbnail up to 32 kilobytes in size; see `https://core.telegram.org/stickers#video-requirements `_`https://core.telegram.org/stickers#video-requirements `_ for video sticker technical requirements. Pass a *file_id* as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. :ref:`More information on Sending Files » `. Animated and video sticker set thumbnails can't be uploaded via HTTP URL. If omitted, then the thumbnail is dropped and the first sticker is used as the thumbnail."""
+ """A **.WEBP** or **.PNG** image with the thumbnail, must be up to 128 kilobytes in size and have a width and height of exactly 100px, or a **.TGS** animation with a thumbnail up to 32 kilobytes in size (see `https://core.telegram.org/stickers#animation-requirements `_`https://core.telegram.org/stickers#animation-requirements `_ for animated sticker technical requirements), or a **.WEBM** video with the thumbnail up to 32 kilobytes in size; see `https://core.telegram.org/stickers#video-requirements `_`https://core.telegram.org/stickers#video-requirements `_ for video sticker technical requirements. Pass a *file_id* as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. :ref:`More information on Sending Files » `. Animated and video sticker set thumbnails can't be uploaded via HTTP URL. If omitted, then the thumbnail is dropped and the first sticker is used as the thumbnail."""
if TYPE_CHECKING:
# DO NOT EDIT MANUALLY!!!
diff --git a/aiogram/methods/set_webhook.py b/aiogram/methods/set_webhook.py
index 01c74f9c..e7076839 100644
--- a/aiogram/methods/set_webhook.py
+++ b/aiogram/methods/set_webhook.py
@@ -8,7 +8,7 @@ from .base import TelegramMethod
class SetWebhook(TelegramMethod[bool]):
"""
- Use this method to specify a URL and receive incoming updates via an outgoing webhook. Whenever there is an update for the bot, we will send an HTTPS POST request to the specified URL, containing a JSON-serialized :class:`aiogram.types.update.Update`. In case of an unsuccessful request, we will give up after a reasonable amount of attempts. Returns :code:`True` on success.
+ Use this method to specify a URL and receive incoming updates via an outgoing webhook. Whenever there is an update for the bot, we will send an HTTPS POST request to the specified URL, containing a JSON-serialized :class:`aiogram.types.update.Update`. In case of an unsuccessful request (a request with response `HTTP status code `_ different from :code:`2XY`), we will repeat the request and give up after a reasonable amount of attempts. Returns :code:`True` on success.
If you'd like to make sure that the webhook was set by you, you can specify secret data in the parameter *secret_token*. If specified, the request will contain a header 'X-Telegram-Bot-Api-Secret-Token' with the secret token as content.
**Notes**
diff --git a/aiogram/methods/verify_chat.py b/aiogram/methods/verify_chat.py
new file mode 100644
index 00000000..9f1c36e4
--- /dev/null
+++ b/aiogram/methods/verify_chat.py
@@ -0,0 +1,40 @@
+from __future__ import annotations
+
+from typing import TYPE_CHECKING, Any, Optional, Union
+
+from .base import TelegramMethod
+
+
+class VerifyChat(TelegramMethod[bool]):
+ """
+ Verifies a chat on behalf of the organization which is represented by the bot. Returns :code:`True` on success.
+
+ Source: https://core.telegram.org/bots/api#verifychat
+ """
+
+ __returning__ = bool
+ __api_method__ = "verifyChat"
+
+ chat_id: Union[int, str]
+ """Unique identifier for the target chat or username of the target channel (in the format :code:`@channelusername`)"""
+ custom_description: Optional[str] = None
+ """Custom description for the verification; 0-70 characters. Must be empty if the organization isn't allowed to provide a custom verification description."""
+
+ if TYPE_CHECKING:
+ # DO NOT EDIT MANUALLY!!!
+ # This section was auto-generated via `butcher`
+
+ def __init__(
+ __pydantic__self__,
+ *,
+ chat_id: Union[int, str],
+ custom_description: Optional[str] = None,
+ **__pydantic_kwargs: Any,
+ ) -> None:
+ # DO NOT EDIT MANUALLY!!!
+ # This method was auto-generated via `butcher`
+ # Is needed only for type checking and IDE support without any additional plugins
+
+ super().__init__(
+ chat_id=chat_id, custom_description=custom_description, **__pydantic_kwargs
+ )
diff --git a/aiogram/methods/verify_user.py b/aiogram/methods/verify_user.py
new file mode 100644
index 00000000..3518dfaf
--- /dev/null
+++ b/aiogram/methods/verify_user.py
@@ -0,0 +1,40 @@
+from __future__ import annotations
+
+from typing import TYPE_CHECKING, Any, Optional
+
+from .base import TelegramMethod
+
+
+class VerifyUser(TelegramMethod[bool]):
+ """
+ Verifies a user on behalf of the organization which is represented by the bot. Returns :code:`True` on success.
+
+ Source: https://core.telegram.org/bots/api#verifyuser
+ """
+
+ __returning__ = bool
+ __api_method__ = "verifyUser"
+
+ user_id: int
+ """Unique identifier of the target user"""
+ custom_description: Optional[str] = None
+ """Custom description for the verification; 0-70 characters. Must be empty if the organization isn't allowed to provide a custom verification description."""
+
+ if TYPE_CHECKING:
+ # DO NOT EDIT MANUALLY!!!
+ # This section was auto-generated via `butcher`
+
+ def __init__(
+ __pydantic__self__,
+ *,
+ user_id: int,
+ custom_description: Optional[str] = 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, custom_description=custom_description, **__pydantic_kwargs
+ )
diff --git a/aiogram/types/__init__.py b/aiogram/types/__init__.py
index 18632627..8f695d23 100644
--- a/aiogram/types/__init__.py
+++ b/aiogram/types/__init__.py
@@ -1,5 +1,6 @@
from typing import List, Literal, Optional, Union
+from .affiliate_info import AffiliateInfo
from .animation import Animation
from .audio import Audio
from .background_fill import BackgroundFill
@@ -216,6 +217,7 @@ from .successful_payment import SuccessfulPayment
from .switch_inline_query_chosen_chat import SwitchInlineQueryChosenChat
from .text_quote import TextQuote
from .transaction_partner import TransactionPartner
+from .transaction_partner_affiliate_program import TransactionPartnerAffiliateProgram
from .transaction_partner_fragment import TransactionPartnerFragment
from .transaction_partner_other import TransactionPartnerOther
from .transaction_partner_telegram_ads import TransactionPartnerTelegramAds
@@ -241,6 +243,7 @@ from .webhook_info import WebhookInfo
from .write_access_allowed import WriteAccessAllowed
__all__ = (
+ "AffiliateInfo",
"Animation",
"Audio",
"BackgroundFill",
@@ -456,6 +459,7 @@ __all__ = (
"TelegramObject",
"TextQuote",
"TransactionPartner",
+ "TransactionPartnerAffiliateProgram",
"TransactionPartnerFragment",
"TransactionPartnerOther",
"TransactionPartnerTelegramAds",
diff --git a/aiogram/types/affiliate_info.py b/aiogram/types/affiliate_info.py
new file mode 100644
index 00000000..ac231abc
--- /dev/null
+++ b/aiogram/types/affiliate_info.py
@@ -0,0 +1,55 @@
+from __future__ import annotations
+
+from typing import TYPE_CHECKING, Any, Optional
+
+from .base import TelegramObject
+
+if TYPE_CHECKING:
+ from .chat import Chat
+ from .user import User
+
+
+class AffiliateInfo(TelegramObject):
+ """
+ Contains information about the affiliate that received a commission via this transaction.
+
+ Source: https://core.telegram.org/bots/api#affiliateinfo
+ """
+
+ commission_per_mille: int
+ """The number of Telegram Stars received by the affiliate for each 1000 Telegram Stars received by the bot from referred users"""
+ amount: int
+ """Integer amount of Telegram Stars received by the affiliate from the transaction, rounded to 0; can be negative for refunds"""
+ affiliate_user: Optional[User] = None
+ """*Optional*. The bot or the user that received an affiliate commission if it was received by a bot or a user"""
+ affiliate_chat: Optional[Chat] = None
+ """*Optional*. The chat that received an affiliate commission if it was received by a chat"""
+ nanostar_amount: Optional[int] = None
+ """*Optional*. The number of 1/1000000000 shares of Telegram Stars received by the affiliate; from -999999999 to 999999999; can be negative for refunds"""
+
+ if TYPE_CHECKING:
+ # DO NOT EDIT MANUALLY!!!
+ # This section was auto-generated via `butcher`
+
+ def __init__(
+ __pydantic__self__,
+ *,
+ commission_per_mille: int,
+ amount: int,
+ affiliate_user: Optional[User] = None,
+ affiliate_chat: Optional[Chat] = None,
+ nanostar_amount: Optional[int] = 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__(
+ commission_per_mille=commission_per_mille,
+ amount=amount,
+ affiliate_user=affiliate_user,
+ affiliate_chat=affiliate_chat,
+ nanostar_amount=nanostar_amount,
+ **__pydantic_kwargs,
+ )
diff --git a/aiogram/types/background_type_pattern.py b/aiogram/types/background_type_pattern.py
index 29c383c2..0c3ba3a3 100644
--- a/aiogram/types/background_type_pattern.py
+++ b/aiogram/types/background_type_pattern.py
@@ -13,7 +13,7 @@ if TYPE_CHECKING:
class BackgroundTypePattern(BackgroundType):
"""
- The background is a PNG or TGV (gzipped subset of SVG with MIME type 'application/x-tgwallpattern') pattern to be combined with the background fill chosen by the user.
+ The background is a .PNG or .TGV (gzipped subset of SVG with MIME type 'application/x-tgwallpattern') pattern to be combined with the background fill chosen by the user.
Source: https://core.telegram.org/bots/api#backgroundtypepattern
"""
diff --git a/aiogram/types/downloadable.py b/aiogram/types/downloadable.py
index be808293..080caf64 100644
--- a/aiogram/types/downloadable.py
+++ b/aiogram/types/downloadable.py
@@ -2,4 +2,5 @@ from typing import Protocol
class Downloadable(Protocol):
- file_id: str
+ @property
+ def file_id(self) -> str: ...
diff --git a/aiogram/types/gift.py b/aiogram/types/gift.py
index e25eb3ec..77be63ad 100644
--- a/aiogram/types/gift.py
+++ b/aiogram/types/gift.py
@@ -21,6 +21,8 @@ class Gift(TelegramObject):
"""The sticker that represents the gift"""
star_count: int
"""The number of Telegram Stars that must be paid to send the sticker"""
+ upgrade_star_count: Optional[int] = None
+ """*Optional*. The number of Telegram Stars that must be paid to upgrade the gift to a unique one"""
total_count: Optional[int] = None
"""*Optional*. The total number of the gifts of this type that can be sent; for limited gifts only"""
remaining_count: Optional[int] = None
@@ -36,6 +38,7 @@ class Gift(TelegramObject):
id: str,
sticker: Sticker,
star_count: int,
+ upgrade_star_count: Optional[int] = None,
total_count: Optional[int] = None,
remaining_count: Optional[int] = None,
**__pydantic_kwargs: Any,
@@ -48,6 +51,7 @@ class Gift(TelegramObject):
id=id,
sticker=sticker,
star_count=star_count,
+ upgrade_star_count=upgrade_star_count,
total_count=total_count,
remaining_count=remaining_count,
**__pydantic_kwargs,
diff --git a/aiogram/types/inline_query_result_article.py b/aiogram/types/inline_query_result_article.py
index c9987382..afd8ffdc 100644
--- a/aiogram/types/inline_query_result_article.py
+++ b/aiogram/types/inline_query_result_article.py
@@ -2,6 +2,8 @@ from __future__ import annotations
from typing import TYPE_CHECKING, Any, Literal, Optional, Union
+from pydantic import Field
+
from ..enums import InlineQueryResultType
from .inline_query_result import InlineQueryResult
@@ -39,8 +41,6 @@ class InlineQueryResultArticle(InlineQueryResult):
"""*Optional*. `Inline keyboard `_ attached to the message"""
url: Optional[str] = None
"""*Optional*. URL of the result"""
- hide_url: Optional[bool] = None
- """*Optional*. Pass :code:`True` if you don't want the URL to be shown in the message"""
description: Optional[str] = None
"""*Optional*. Short description of the result"""
thumbnail_url: Optional[str] = None
@@ -49,6 +49,11 @@ class InlineQueryResultArticle(InlineQueryResult):
"""*Optional*. Thumbnail width"""
thumbnail_height: Optional[int] = None
"""*Optional*. Thumbnail height"""
+ hide_url: Optional[bool] = Field(None, json_schema_extra={"deprecated": True})
+ """*Optional*. Pass :code:`True` if you don't want the URL to be shown in the message
+
+.. deprecated:: API:8.2
+ https://core.telegram.org/bots/api-changelog#january-1-2025"""
if TYPE_CHECKING:
# DO NOT EDIT MANUALLY!!!
@@ -69,11 +74,11 @@ class InlineQueryResultArticle(InlineQueryResult):
],
reply_markup: Optional[InlineKeyboardMarkup] = None,
url: Optional[str] = None,
- hide_url: Optional[bool] = None,
description: Optional[str] = None,
thumbnail_url: Optional[str] = None,
thumbnail_width: Optional[int] = None,
thumbnail_height: Optional[int] = None,
+ hide_url: Optional[bool] = None,
**__pydantic_kwargs: Any,
) -> None:
# DO NOT EDIT MANUALLY!!!
@@ -87,10 +92,10 @@ class InlineQueryResultArticle(InlineQueryResult):
input_message_content=input_message_content,
reply_markup=reply_markup,
url=url,
- hide_url=hide_url,
description=description,
thumbnail_url=thumbnail_url,
thumbnail_width=thumbnail_width,
thumbnail_height=thumbnail_height,
+ hide_url=hide_url,
**__pydantic_kwargs,
)
diff --git a/aiogram/types/inline_query_result_gif.py b/aiogram/types/inline_query_result_gif.py
index 2f56c652..cedc588c 100644
--- a/aiogram/types/inline_query_result_gif.py
+++ b/aiogram/types/inline_query_result_gif.py
@@ -28,7 +28,7 @@ class InlineQueryResultGif(InlineQueryResult):
id: str
"""Unique identifier for this result, 1-64 bytes"""
gif_url: str
- """A valid URL for the GIF file. File size must not exceed 1MB"""
+ """A valid URL for the GIF file"""
thumbnail_url: str
"""URL of the static (JPEG or GIF) or animated (MPEG4) thumbnail for the result"""
gif_width: Optional[int] = None
diff --git a/aiogram/types/inline_query_result_mpeg4_gif.py b/aiogram/types/inline_query_result_mpeg4_gif.py
index e1a39ae8..9fd1e716 100644
--- a/aiogram/types/inline_query_result_mpeg4_gif.py
+++ b/aiogram/types/inline_query_result_mpeg4_gif.py
@@ -28,7 +28,7 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult):
id: str
"""Unique identifier for this result, 1-64 bytes"""
mpeg4_url: str
- """A valid URL for the MPEG4 file. File size must not exceed 1MB"""
+ """A valid URL for the MPEG4 file"""
thumbnail_url: str
"""URL of the static (JPEG or GIF) or animated (MPEG4) thumbnail for the result"""
mpeg4_width: Optional[int] = None
diff --git a/aiogram/types/input_sticker.py b/aiogram/types/input_sticker.py
index 76fcc4b1..2971d712 100644
--- a/aiogram/types/input_sticker.py
+++ b/aiogram/types/input_sticker.py
@@ -19,7 +19,7 @@ class InputSticker(TelegramObject):
sticker: Union[InputFile, str]
"""The added sticker. Pass a *file_id* as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, upload a new one using multipart/form-data, or pass 'attach://' to upload a new one using multipart/form-data under name. Animated and video stickers can't be uploaded via HTTP URL. :ref:`More information on Sending Files » `"""
format: str
- """Format of the added sticker, must be one of 'static' for a **.WEBP** or **.PNG** image, 'animated' for a **.TGS** animation, 'video' for a **WEBM** video"""
+ """Format of the added sticker, must be one of 'static' for a **.WEBP** or **.PNG** image, 'animated' for a **.TGS** animation, 'video' for a **.WEBM** video"""
emoji_list: list[str]
"""List of 1-20 emoji associated with the sticker"""
mask_position: Optional[MaskPosition] = None
diff --git a/aiogram/types/star_transaction.py b/aiogram/types/star_transaction.py
index ab1bf836..1ef2856f 100644
--- a/aiogram/types/star_transaction.py
+++ b/aiogram/types/star_transaction.py
@@ -6,6 +6,9 @@ from .base import TelegramObject
from .custom import DateTime
if TYPE_CHECKING:
+ from .transaction_partner_affiliate_program import (
+ TransactionPartnerAffiliateProgram,
+ )
from .transaction_partner_fragment import TransactionPartnerFragment
from .transaction_partner_other import TransactionPartnerOther
from .transaction_partner_telegram_ads import TransactionPartnerTelegramAds
@@ -23,12 +26,15 @@ class StarTransaction(TelegramObject):
id: str
"""Unique identifier of the transaction. Coincides with the identifier of the original transaction for refund transactions. Coincides with *SuccessfulPayment.telegram_payment_charge_id* for successful incoming payments from users."""
amount: int
- """Number of Telegram Stars transferred by the transaction"""
+ """Integer amount of Telegram Stars transferred by the transaction"""
date: DateTime
"""Date the transaction was created in Unix time"""
+ nanostar_amount: Optional[int] = None
+ """*Optional*. The number of 1/1000000000 shares of Telegram Stars transferred by the transaction; from 0 to 999999999"""
source: Optional[
Union[
TransactionPartnerUser,
+ TransactionPartnerAffiliateProgram,
TransactionPartnerFragment,
TransactionPartnerTelegramAds,
TransactionPartnerTelegramApi,
@@ -39,6 +45,7 @@ class StarTransaction(TelegramObject):
receiver: Optional[
Union[
TransactionPartnerUser,
+ TransactionPartnerAffiliateProgram,
TransactionPartnerFragment,
TransactionPartnerTelegramAds,
TransactionPartnerTelegramApi,
@@ -57,9 +64,11 @@ class StarTransaction(TelegramObject):
id: str,
amount: int,
date: DateTime,
+ nanostar_amount: Optional[int] = None,
source: Optional[
Union[
TransactionPartnerUser,
+ TransactionPartnerAffiliateProgram,
TransactionPartnerFragment,
TransactionPartnerTelegramAds,
TransactionPartnerTelegramApi,
@@ -69,6 +78,7 @@ class StarTransaction(TelegramObject):
receiver: Optional[
Union[
TransactionPartnerUser,
+ TransactionPartnerAffiliateProgram,
TransactionPartnerFragment,
TransactionPartnerTelegramAds,
TransactionPartnerTelegramApi,
@@ -85,6 +95,7 @@ class StarTransaction(TelegramObject):
id=id,
amount=amount,
date=date,
+ nanostar_amount=nanostar_amount,
source=source,
receiver=receiver,
**__pydantic_kwargs,
diff --git a/aiogram/types/transaction_partner.py b/aiogram/types/transaction_partner.py
index 392d1cfe..fa2ca902 100644
--- a/aiogram/types/transaction_partner.py
+++ b/aiogram/types/transaction_partner.py
@@ -6,6 +6,7 @@ class TransactionPartner(TelegramObject):
This object describes the source of a transaction, or its recipient for outgoing transactions. Currently, it can be one of
- :class:`aiogram.types.transaction_partner_user.TransactionPartnerUser`
+ - :class:`aiogram.types.transaction_partner_affiliate_program.TransactionPartnerAffiliateProgram`
- :class:`aiogram.types.transaction_partner_fragment.TransactionPartnerFragment`
- :class:`aiogram.types.transaction_partner_telegram_ads.TransactionPartnerTelegramAds`
- :class:`aiogram.types.transaction_partner_telegram_api.TransactionPartnerTelegramApi`
diff --git a/aiogram/types/transaction_partner_affiliate_program.py b/aiogram/types/transaction_partner_affiliate_program.py
new file mode 100644
index 00000000..d78ecef1
--- /dev/null
+++ b/aiogram/types/transaction_partner_affiliate_program.py
@@ -0,0 +1,51 @@
+from __future__ import annotations
+
+from typing import TYPE_CHECKING, Any, Literal, Optional
+
+from ..enums import TransactionPartnerType
+from .transaction_partner import TransactionPartner
+
+if TYPE_CHECKING:
+ from .user import User
+
+
+class TransactionPartnerAffiliateProgram(TransactionPartner):
+ """
+ Describes the affiliate program that issued the affiliate commission received via this transaction.
+
+ Source: https://core.telegram.org/bots/api#transactionpartneraffiliateprogram
+ """
+
+ type: Literal[TransactionPartnerType.AFFILIATE_PROGRAM] = (
+ TransactionPartnerType.AFFILIATE_PROGRAM
+ )
+ """Type of the transaction partner, always 'affiliate_program'"""
+ commission_per_mille: int
+ """The number of Telegram Stars received by the bot for each 1000 Telegram Stars received by the affiliate program sponsor from referred users"""
+ sponsor_user: Optional[User] = None
+ """*Optional*. Information about the bot that sponsored the affiliate program"""
+
+ if TYPE_CHECKING:
+ # DO NOT EDIT MANUALLY!!!
+ # This section was auto-generated via `butcher`
+
+ def __init__(
+ __pydantic__self__,
+ *,
+ type: Literal[
+ TransactionPartnerType.AFFILIATE_PROGRAM
+ ] = TransactionPartnerType.AFFILIATE_PROGRAM,
+ commission_per_mille: int,
+ sponsor_user: Optional[User] = 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__(
+ type=type,
+ commission_per_mille=commission_per_mille,
+ sponsor_user=sponsor_user,
+ **__pydantic_kwargs,
+ )
diff --git a/aiogram/types/transaction_partner_user.py b/aiogram/types/transaction_partner_user.py
index fbb47864..16ccc652 100644
--- a/aiogram/types/transaction_partner_user.py
+++ b/aiogram/types/transaction_partner_user.py
@@ -6,6 +6,8 @@ from ..enums import TransactionPartnerType
from .transaction_partner import TransactionPartner
if TYPE_CHECKING:
+ from .affiliate_info import AffiliateInfo
+ from .gift import Gift
from .paid_media_photo import PaidMediaPhoto
from .paid_media_preview import PaidMediaPreview
from .paid_media_video import PaidMediaVideo
@@ -23,6 +25,8 @@ class TransactionPartnerUser(TransactionPartner):
"""Type of the transaction partner, always 'user'"""
user: User
"""Information about the user"""
+ affiliate: Optional[AffiliateInfo] = None
+ """*Optional*. Information about the affiliate that received a commission via this transaction"""
invoice_payload: Optional[str] = None
"""*Optional*. Bot-specified invoice payload"""
subscription_period: Optional[int] = None
@@ -31,7 +35,7 @@ class TransactionPartnerUser(TransactionPartner):
"""*Optional*. Information about the paid media bought by the user"""
paid_media_payload: Optional[str] = None
"""*Optional*. Bot-specified paid media payload"""
- gift: Optional[str] = None
+ gift: Optional[Gift] = None
"""*Optional*. The gift sent to the user by the bot"""
if TYPE_CHECKING:
@@ -43,13 +47,14 @@ class TransactionPartnerUser(TransactionPartner):
*,
type: Literal[TransactionPartnerType.USER] = TransactionPartnerType.USER,
user: User,
+ affiliate: Optional[AffiliateInfo] = None,
invoice_payload: Optional[str] = None,
subscription_period: Optional[int] = None,
paid_media: Optional[
list[Union[PaidMediaPreview, PaidMediaPhoto, PaidMediaVideo]]
] = None,
paid_media_payload: Optional[str] = None,
- gift: Optional[str] = None,
+ gift: Optional[Gift] = None,
**__pydantic_kwargs: Any,
) -> None:
# DO NOT EDIT MANUALLY!!!
@@ -59,6 +64,7 @@ class TransactionPartnerUser(TransactionPartner):
super().__init__(
type=type,
user=user,
+ affiliate=affiliate,
invoice_payload=invoice_payload,
subscription_period=subscription_period,
paid_media=paid_media,
diff --git a/aiogram/utils/deep_linking.py b/aiogram/utils/deep_linking.py
index 19cc64c6..fe2764f7 100644
--- a/aiogram/utils/deep_linking.py
+++ b/aiogram/utils/deep_linking.py
@@ -18,7 +18,7 @@ from aiogram.utils.payload import decode_payload, encode_payload
if TYPE_CHECKING:
from aiogram import Bot
-BAD_PATTERN = re.compile(r"[^A-z0-9-]")
+BAD_PATTERN = re.compile(r"[^a-zA-Z0-9-_]")
async def create_start_link(
diff --git a/docs/api/methods/index.rst b/docs/api/methods/index.rst
index 8030927b..b6aadc07 100644
--- a/docs/api/methods/index.rst
+++ b/docs/api/methods/index.rst
@@ -18,6 +18,8 @@ Stickers
get_available_gifts
get_custom_emoji_stickers
get_sticker_set
+ remove_chat_verification
+ remove_user_verification
replace_sticker_in_set
send_gift
send_sticker
@@ -29,6 +31,8 @@ Stickers
set_sticker_set_thumbnail
set_sticker_set_title
upload_sticker_file
+ verify_chat
+ verify_user
Available methods
=================
diff --git a/docs/api/methods/remove_chat_verification.rst b/docs/api/methods/remove_chat_verification.rst
new file mode 100644
index 00000000..068ea302
--- /dev/null
+++ b/docs/api/methods/remove_chat_verification.rst
@@ -0,0 +1,45 @@
+######################
+removeChatVerification
+######################
+
+Returns: :obj:`bool`
+
+.. automodule:: aiogram.methods.remove_chat_verification
+ :members:
+ :member-order: bysource
+ :undoc-members: True
+ :exclude-members: model_config,model_fields
+
+
+Usage
+=====
+
+As bot method
+-------------
+
+.. code-block::
+
+ result: bool = await bot.remove_chat_verification(...)
+
+
+Method as object
+----------------
+
+Imports:
+
+- :code:`from aiogram.methods.remove_chat_verification import RemoveChatVerification`
+- alias: :code:`from aiogram.methods import RemoveChatVerification`
+
+With specific bot
+~~~~~~~~~~~~~~~~~
+
+.. code-block:: python
+
+ result: bool = await bot(RemoveChatVerification(...))
+
+As reply into Webhook in handler
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: python
+
+ return RemoveChatVerification(...)
diff --git a/docs/api/methods/remove_user_verification.rst b/docs/api/methods/remove_user_verification.rst
new file mode 100644
index 00000000..a122abab
--- /dev/null
+++ b/docs/api/methods/remove_user_verification.rst
@@ -0,0 +1,45 @@
+######################
+removeUserVerification
+######################
+
+Returns: :obj:`bool`
+
+.. automodule:: aiogram.methods.remove_user_verification
+ :members:
+ :member-order: bysource
+ :undoc-members: True
+ :exclude-members: model_config,model_fields
+
+
+Usage
+=====
+
+As bot method
+-------------
+
+.. code-block::
+
+ result: bool = await bot.remove_user_verification(...)
+
+
+Method as object
+----------------
+
+Imports:
+
+- :code:`from aiogram.methods.remove_user_verification import RemoveUserVerification`
+- alias: :code:`from aiogram.methods import RemoveUserVerification`
+
+With specific bot
+~~~~~~~~~~~~~~~~~
+
+.. code-block:: python
+
+ result: bool = await bot(RemoveUserVerification(...))
+
+As reply into Webhook in handler
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: python
+
+ return RemoveUserVerification(...)
diff --git a/docs/api/methods/verify_chat.rst b/docs/api/methods/verify_chat.rst
new file mode 100644
index 00000000..e60a130a
--- /dev/null
+++ b/docs/api/methods/verify_chat.rst
@@ -0,0 +1,45 @@
+##########
+verifyChat
+##########
+
+Returns: :obj:`bool`
+
+.. automodule:: aiogram.methods.verify_chat
+ :members:
+ :member-order: bysource
+ :undoc-members: True
+ :exclude-members: model_config,model_fields
+
+
+Usage
+=====
+
+As bot method
+-------------
+
+.. code-block::
+
+ result: bool = await bot.verify_chat(...)
+
+
+Method as object
+----------------
+
+Imports:
+
+- :code:`from aiogram.methods.verify_chat import VerifyChat`
+- alias: :code:`from aiogram.methods import VerifyChat`
+
+With specific bot
+~~~~~~~~~~~~~~~~~
+
+.. code-block:: python
+
+ result: bool = await bot(VerifyChat(...))
+
+As reply into Webhook in handler
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: python
+
+ return VerifyChat(...)
diff --git a/docs/api/methods/verify_user.rst b/docs/api/methods/verify_user.rst
new file mode 100644
index 00000000..12aa6e3e
--- /dev/null
+++ b/docs/api/methods/verify_user.rst
@@ -0,0 +1,45 @@
+##########
+verifyUser
+##########
+
+Returns: :obj:`bool`
+
+.. automodule:: aiogram.methods.verify_user
+ :members:
+ :member-order: bysource
+ :undoc-members: True
+ :exclude-members: model_config,model_fields
+
+
+Usage
+=====
+
+As bot method
+-------------
+
+.. code-block::
+
+ result: bool = await bot.verify_user(...)
+
+
+Method as object
+----------------
+
+Imports:
+
+- :code:`from aiogram.methods.verify_user import VerifyUser`
+- alias: :code:`from aiogram.methods import VerifyUser`
+
+With specific bot
+~~~~~~~~~~~~~~~~~
+
+.. code-block:: python
+
+ result: bool = await bot(VerifyUser(...))
+
+As reply into Webhook in handler
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: python
+
+ return VerifyUser(...)
diff --git a/docs/api/types/affiliate_info.rst b/docs/api/types/affiliate_info.rst
new file mode 100644
index 00000000..0fe145e9
--- /dev/null
+++ b/docs/api/types/affiliate_info.rst
@@ -0,0 +1,10 @@
+#############
+AffiliateInfo
+#############
+
+
+.. automodule:: aiogram.types.affiliate_info
+ :members:
+ :member-order: bysource
+ :undoc-members: True
+ :exclude-members: model_config,model_fields
diff --git a/docs/api/types/index.rst b/docs/api/types/index.rst
index 0f8b97ad..446e0459 100644
--- a/docs/api/types/index.rst
+++ b/docs/api/types/index.rst
@@ -203,25 +203,13 @@ Inline mode
prepared_inline_message
sent_web_app_message
-Stickers
-========
-
-.. toctree::
- :maxdepth: 1
-
- gift
- gifts
- input_sticker
- mask_position
- sticker
- sticker_set
-
Payments
========
.. toctree::
:maxdepth: 1
+ affiliate_info
invoice
labeled_price
order_info
@@ -239,12 +227,26 @@ Payments
star_transactions
successful_payment
transaction_partner
+ transaction_partner_affiliate_program
transaction_partner_fragment
transaction_partner_other
transaction_partner_telegram_ads
transaction_partner_telegram_api
transaction_partner_user
+Stickers
+========
+
+.. toctree::
+ :maxdepth: 1
+
+ gift
+ gifts
+ input_sticker
+ mask_position
+ sticker
+ sticker_set
+
Telegram Passport
=================
diff --git a/docs/api/types/transaction_partner_affiliate_program.rst b/docs/api/types/transaction_partner_affiliate_program.rst
new file mode 100644
index 00000000..f20b2e62
--- /dev/null
+++ b/docs/api/types/transaction_partner_affiliate_program.rst
@@ -0,0 +1,10 @@
+##################################
+TransactionPartnerAffiliateProgram
+##################################
+
+
+.. automodule:: aiogram.types.transaction_partner_affiliate_program
+ :members:
+ :member-order: bysource
+ :undoc-members: True
+ :exclude-members: model_config,model_fields
diff --git a/docs/conf.py b/docs/conf.py
index 071f05f2..3fa07d02 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -69,3 +69,14 @@ texinfo_documents = [
towncrier_draft_autoversion_mode = "draft"
towncrier_draft_include_empty = False
towncrier_draft_working_directory = Path(__file__).parent.parent
+
+
+def skip_model_prefixed_members(app, what, name, obj, skip, options):
+ # Skip any member whose name starts with "model_"
+ if name.startswith("model_"):
+ return True
+ return skip
+
+
+def setup(app):
+ app.connect("autodoc-skip-member", skip_model_prefixed_members)
diff --git a/docs/locale/uk_UA/LC_MESSAGES/index.po b/docs/locale/uk_UA/LC_MESSAGES/index.po
index 496a6c50..fbfb3e14 100644
--- a/docs/locale/uk_UA/LC_MESSAGES/index.po
+++ b/docs/locale/uk_UA/LC_MESSAGES/index.po
@@ -173,7 +173,7 @@ msgstr ""
#: ../../../README.rst:71
msgid "If you have any questions, you can visit our community chats on Telegram:"
-msgstr "Якщо є якість додаткові запитання, ласкаво просимо до онлайн-спільнот:"
+msgstr "Якщо є додаткові запитання, ласкаво просимо до онлайн-спільнот:"
#: ../../../README.rst:73
msgid "🇺🇸 `@aiogram `_"
diff --git a/pyproject.toml b/pyproject.toml
index 0d916aa9..a5b7cd8d 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -42,7 +42,7 @@ classifiers = [
]
dependencies = [
"magic-filter>=1.0.12,<1.1",
- "aiohttp>=3.9.0,<3.11",
+ "aiohttp>=3.9.0,<3.12",
"pydantic>=2.4.1,<2.11",
"aiofiles>=23.2.1,<24.2",
"certifi>=2023.7.22",
@@ -60,7 +60,7 @@ fast = [
"aiodns>=3.0.0",
]
redis = [
- "redis[hiredis]>=5.0.1,<5.1.0",
+ "redis[hiredis]>=5.0.1,<5.3.0",
]
mongo = [
"motor>=3.3.2,<3.7.0",
diff --git a/tests/test_api/test_client/test_api_server.py b/tests/test_api/test_client/test_api_server.py
index 118ea630..36fd5140 100644
--- a/tests/test_api/test_client/test_api_server.py
+++ b/tests/test_api/test_client/test_api_server.py
@@ -1,5 +1,7 @@
from pathlib import Path
+import pytest
+
from aiogram.client.telegram import (
PRODUCTION,
BareFilesPathWrapper,
@@ -13,15 +15,17 @@ class TestAPIServer:
method_url = PRODUCTION.api_url(token="42:TEST", method="apiMethod")
assert method_url == "https://api.telegram.org/bot42:TEST/apiMethod"
- def test_file_url(self):
- file_url = PRODUCTION.file_url(token="42:TEST", path="path")
+ @pytest.mark.parametrize("path", ["path", Path("path")])
+ def test_file_url(self, path):
+ file_url = PRODUCTION.file_url(token="42:TEST", path=path)
assert file_url == "https://api.telegram.org/file/bot42:TEST/path"
- def test_from_base(self):
+ @pytest.mark.parametrize("path", ["path", Path("path")])
+ def test_from_base(self, path):
local_server = TelegramAPIServer.from_base("http://localhost:8081", is_local=True)
method_url = local_server.api_url("42:TEST", method="apiMethod")
- file_url = local_server.file_url(token="42:TEST", path="path")
+ file_url = local_server.file_url(token="42:TEST", path=path)
assert method_url == "http://localhost:8081/bot42:TEST/apiMethod"
assert file_url == "http://localhost:8081/file/bot42:TEST/path"
diff --git a/tests/test_api/test_client/test_bot.py b/tests/test_api/test_client/test_bot.py
index 34593864..11a11c34 100644
--- a/tests/test_api/test_client/test_bot.py
+++ b/tests/test_api/test_client/test_bot.py
@@ -1,5 +1,6 @@
import io
import os
+from pathlib import Path
from tempfile import mkstemp
from unittest.mock import AsyncMock, MagicMock, patch
@@ -112,7 +113,8 @@ class TestBot:
mocked_close.assert_not_awaited()
await session.close()
- async def test_download_file(self, aresponses: ResponsesMockServer):
+ @pytest.mark.parametrize("file_path", ["file.png", Path("file.png")])
+ async def test_download_file(self, aresponses: ResponsesMockServer, file_path):
aresponses.add(
method_pattern="get",
response=aresponses.Response(status=200, body=b"\f" * 10),
@@ -127,7 +129,7 @@ class TestBot:
async with Bot("42:TEST").context() as bot:
with patch("aiofiles.threadpool.sync_open", return_value=mock_file):
- await bot.download_file("TEST", "file.png")
+ await bot.download_file("TEST", file_path)
mock_file.write.assert_called_once_with(b"\f" * 10)
async def test_download_file_default_destination(
diff --git a/tests/test_api/test_client/test_session/test_aiohttp_session.py b/tests/test_api/test_client/test_session/test_aiohttp_session.py
index d382a7cf..bc0239df 100644
--- a/tests/test_api/test_client/test_session/test_aiohttp_session.py
+++ b/tests/test_api/test_client/test_session/test_aiohttp_session.py
@@ -41,7 +41,7 @@ class TestAiohttpSession:
async def test_create_proxy_session(self):
auth = aiohttp.BasicAuth("login", "password", "encoding")
- async with AiohttpSession(proxy=("socks5://proxy.url/", auth)) as session:
+ async with AiohttpSession(proxy=("socks5://proxy.url:1080/", auth)) as session:
assert session._connector_type == aiohttp_socks.ProxyConnector
assert isinstance(session._connector_init, dict)
@@ -51,7 +51,7 @@ class TestAiohttpSession:
assert isinstance(aiohttp_session.connector, aiohttp_socks.ProxyConnector)
async def test_create_proxy_session_proxy_url(self):
- async with AiohttpSession(proxy="socks4://proxy.url/") as session:
+ async with AiohttpSession(proxy="socks4://proxy.url:1080/") as session:
assert isinstance(session.proxy, str)
assert isinstance(session._connector_init, dict)
@@ -62,8 +62,8 @@ class TestAiohttpSession:
async def test_create_proxy_session_chained_proxies(self):
proxy_chain = [
- "socks4://proxy.url/",
- "socks5://proxy.url/",
+ "socks4://proxy.url:1080/",
+ "socks5://proxy.url:1080/",
"http://user:password@127.0.0.1:3128",
]
async with AiohttpSession(proxy=proxy_chain) as session:
@@ -90,7 +90,7 @@ class TestAiohttpSession:
assert session._should_reset_connector is False
assert session.proxy is None
- session.proxy = "socks5://auth:auth@proxy.url/"
+ session.proxy = "socks5://auth:auth@proxy.url:1080/"
assert session._should_reset_connector
await session.create_session()
assert session._should_reset_connector is False
diff --git a/tests/test_api/test_methods/test_remove_chat_verification.py b/tests/test_api/test_methods/test_remove_chat_verification.py
new file mode 100644
index 00000000..29186300
--- /dev/null
+++ b/tests/test_api/test_methods/test_remove_chat_verification.py
@@ -0,0 +1,12 @@
+from aiogram.methods import RemoveChatVerification, VerifyChat
+from aiogram.types import Poll
+from tests.mocked_bot import MockedBot
+
+
+class TestRemoveChatVerification:
+ async def test_bot_method(self, bot: MockedBot):
+ prepare_result = bot.add_result_for(RemoveChatVerification, ok=True, result=True)
+
+ response: bool = await bot.remove_chat_verification(chat_id=42)
+ request = bot.get_request()
+ assert response == prepare_result.result
diff --git a/tests/test_api/test_methods/test_remove_user_verification.py b/tests/test_api/test_methods/test_remove_user_verification.py
new file mode 100644
index 00000000..4d405c82
--- /dev/null
+++ b/tests/test_api/test_methods/test_remove_user_verification.py
@@ -0,0 +1,12 @@
+from aiogram.methods import RemoveUserVerification, VerifyChat
+from aiogram.types import Poll
+from tests.mocked_bot import MockedBot
+
+
+class TestRemoveUserVerification:
+ async def test_bot_method(self, bot: MockedBot):
+ prepare_result = bot.add_result_for(RemoveUserVerification, ok=True, result=True)
+
+ response: bool = await bot.remove_user_verification(user_id=42)
+ request = bot.get_request()
+ assert response == prepare_result.result
diff --git a/tests/test_api/test_methods/test_verify_chat.py b/tests/test_api/test_methods/test_verify_chat.py
new file mode 100644
index 00000000..1473b976
--- /dev/null
+++ b/tests/test_api/test_methods/test_verify_chat.py
@@ -0,0 +1,12 @@
+from aiogram.methods import VerifyChat
+from aiogram.types import Poll
+from tests.mocked_bot import MockedBot
+
+
+class TestVerifyChat:
+ async def test_bot_method(self, bot: MockedBot):
+ prepare_result = bot.add_result_for(VerifyChat, ok=True, result=True)
+
+ response: bool = await bot.verify_chat(chat_id=42)
+ request = bot.get_request()
+ assert response == prepare_result.result
diff --git a/tests/test_api/test_methods/test_verify_user.py b/tests/test_api/test_methods/test_verify_user.py
new file mode 100644
index 00000000..9bb502ca
--- /dev/null
+++ b/tests/test_api/test_methods/test_verify_user.py
@@ -0,0 +1,12 @@
+from aiogram.methods import VerifyChat, VerifyUser
+from aiogram.types import Poll
+from tests.mocked_bot import MockedBot
+
+
+class TestVerifyUser:
+ async def test_bot_method(self, bot: MockedBot):
+ prepare_result = bot.add_result_for(VerifyUser, ok=True, result=True)
+
+ response: bool = await bot.verify_user(user_id=42)
+ request = bot.get_request()
+ assert response == prepare_result.result
diff --git a/tests/test_utils/test_deep_linking.py b/tests/test_utils/test_deep_linking.py
index 85a6027b..c5f5259a 100644
--- a/tests/test_utils/test_deep_linking.py
+++ b/tests/test_utils/test_deep_linking.py
@@ -10,12 +10,14 @@ PAYLOADS = [
"aaBBccDDeeFF5544332211",
-12345678901234567890,
12345678901234567890,
+ "underscore_and-dash",
]
WRONG_PAYLOADS = [
"@BotFather",
"Some:special$characters#=",
"spaces spaces spaces",
1234567890123456789.0,
+ "has`backtick",
]