mirror of
https://github.com/aiogram/aiogram.git
synced 2026-04-08 16:37:47 +00:00
Telegram API 5.2 support (#572)
* feat: version number update * feat: add InputInvoiceMessageContent type * refactor: every param on a new line * feat: add `max_tip_amount` and `suggested_tip_amounts` to `sendInvoice` * feat: `start_parameter` of `sendInvoice` became optional * refactor: reorder params * feat: add `chat_type` to `InlineQuery` * feat: add `VoiceChatScheduled` * feat: add `voice_chat_scheduled` to `Message` * fix: sendChatAction documentation update * feat: add `record_voice` and `upload_voice` to `ChatActions` * feat: allow sending invoices to group, supergroup and channel
This commit is contained in:
parent
cce29ba532
commit
ea28e2a77a
12 changed files with 185 additions and 26 deletions
|
|
@ -6,7 +6,7 @@
|
|||
[](https://pypi.python.org/pypi/aiogram)
|
||||
[](https://pypi.python.org/pypi/aiogram)
|
||||
[](https://pypi.python.org/pypi/aiogram)
|
||||
[](https://core.telegram.org/bots/api)
|
||||
[](https://core.telegram.org/bots/api)
|
||||
[](http://docs.aiogram.dev/en/latest/?badge=latest)
|
||||
[](https://github.com/aiogram/aiogram/issues)
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ AIOGramBot
|
|||
:target: https://pypi.python.org/pypi/aiogram
|
||||
:alt: Supported python versions
|
||||
|
||||
.. image:: https://img.shields.io/badge/Telegram%20Bot%20API-5.1-blue.svg?style=flat-square&logo=telegram
|
||||
.. image:: https://img.shields.io/badge/Telegram%20Bot%20API-5.2-blue.svg?style=flat-square&logo=telegram
|
||||
:target: https://core.telegram.org/bots/api
|
||||
:alt: Telegram Bot API
|
||||
|
||||
|
|
|
|||
|
|
@ -43,5 +43,5 @@ __all__ = (
|
|||
'utils',
|
||||
)
|
||||
|
||||
__version__ = '2.12.2'
|
||||
__api_version__ = '5.1'
|
||||
__version__ = '2.13.0'
|
||||
__api_version__ = '5.2'
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ class Methods(Helper):
|
|||
"""
|
||||
Helper for Telegram API Methods listed on https://core.telegram.org/bots/api
|
||||
|
||||
List is updated to Bot API 5.1
|
||||
List is updated to Bot API 5.2
|
||||
"""
|
||||
mode = HelperMode.lowerCamelCase
|
||||
|
||||
|
|
|
|||
|
|
@ -1484,19 +1484,36 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin):
|
|||
async def send_chat_action(self, chat_id: typing.Union[base.Integer, base.String],
|
||||
action: base.String) -> base.Boolean:
|
||||
"""
|
||||
Use this method when you need to tell the user that something is happening on the bot's side.
|
||||
The status is set for 5 seconds or less
|
||||
(when a message arrives from your bot, Telegram clients clear its typing status).
|
||||
Use this method when you need to tell the user that something is
|
||||
happening on the bot's side. The status is set for 5 seconds or
|
||||
less (when a message arrives from your bot, Telegram clients
|
||||
clear its typing status). Returns True on success.
|
||||
|
||||
We only recommend using this method when a response from the bot will take
|
||||
a noticeable amount of time to arrive.
|
||||
Example: The ImageBot needs some time to process a request and
|
||||
upload the image. Instead of sending a text message along the
|
||||
lines of “Retrieving image, please wait…”, the bot may use
|
||||
sendChatAction with action = upload_photo. The user will see a
|
||||
“sending photo” status for the bot.
|
||||
|
||||
We only recommend using this method when a response from the bot
|
||||
will take a noticeable amount of time to arrive.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#sendchataction
|
||||
|
||||
:param chat_id: Unique identifier for the target chat or username of the target channel
|
||||
:param chat_id: Unique identifier for the target chat or
|
||||
username of the target channel (in the format
|
||||
@channelusername)
|
||||
:type chat_id: :obj:`typing.Union[base.Integer, base.String]`
|
||||
:param action: Type of action to broadcast
|
||||
|
||||
:param action: Type of action to broadcast. Choose one,
|
||||
depending on what the user is about to receive: `typing` for
|
||||
text messages, `upload_photo` for photos, `record_video` or
|
||||
`upload_video` for videos, `record_voice` or `upload_voice`
|
||||
for voice notes, `upload_document` for general files,
|
||||
`find_location` for location data, `record_video_note` or
|
||||
`upload_video_note` for video notes.
|
||||
:type action: :obj:`base.String`
|
||||
|
||||
:return: Returns True on success
|
||||
:rtype: :obj:`base.Boolean`
|
||||
"""
|
||||
|
|
@ -2780,10 +2797,19 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin):
|
|||
# === Payments ===
|
||||
# https://core.telegram.org/bots/api#payments
|
||||
|
||||
async def send_invoice(self, chat_id: base.Integer, title: base.String,
|
||||
description: base.String, payload: base.String,
|
||||
provider_token: base.String, start_parameter: base.String,
|
||||
currency: base.String, prices: typing.List[types.LabeledPrice],
|
||||
async def send_invoice(self,
|
||||
chat_id: typing.Union[base.Integer, base.String],
|
||||
title: base.String,
|
||||
description: base.String,
|
||||
payload: base.String,
|
||||
provider_token: base.String,
|
||||
currency: base.String,
|
||||
prices: typing.List[types.LabeledPrice],
|
||||
max_tip_amount: typing.Optional[base.Integer] = None,
|
||||
suggested_tip_amounts: typing.Optional[
|
||||
typing.List[base.Integer]
|
||||
] = None,
|
||||
start_parameter: typing.Optional[base.String] = None,
|
||||
provider_data: typing.Optional[typing.Dict] = None,
|
||||
photo_url: typing.Optional[base.String] = None,
|
||||
photo_size: typing.Optional[base.Integer] = None,
|
||||
|
|
@ -2799,14 +2825,17 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin):
|
|||
disable_notification: typing.Optional[base.Boolean] = None,
|
||||
reply_to_message_id: typing.Optional[base.Integer] = None,
|
||||
allow_sending_without_reply: typing.Optional[base.Boolean] = None,
|
||||
reply_markup: typing.Optional[types.InlineKeyboardMarkup] = None) -> types.Message:
|
||||
reply_markup: typing.Optional[types.InlineKeyboardMarkup] = None,
|
||||
) -> types.Message:
|
||||
"""
|
||||
Use this method to send invoices.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#sendinvoice
|
||||
|
||||
:param chat_id: Unique identifier for the target private chat
|
||||
:type chat_id: :obj:`base.Integer`
|
||||
:param chat_id: Unique identifier for the target chat or
|
||||
username of the target channel (in the format
|
||||
@channelusername)
|
||||
:type chat_id: :obj:`typing.Union[base.Integer, base.String]`
|
||||
|
||||
:param title: Product name, 1-32 characters
|
||||
:type title: :obj:`base.String`
|
||||
|
|
@ -2821,10 +2850,6 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin):
|
|||
:param provider_token: Payments provider token, obtained via Botfather
|
||||
:type provider_token: :obj:`base.String`
|
||||
|
||||
:param start_parameter: Unique deep-linking parameter that can be used to generate this
|
||||
invoice when used as a start parameter
|
||||
:type start_parameter: :obj:`base.String`
|
||||
|
||||
:param currency: Three-letter ISO 4217 currency code, see more on currencies
|
||||
:type currency: :obj:`base.String`
|
||||
|
||||
|
|
@ -2832,6 +2857,32 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin):
|
|||
(e.g. product price, tax, discount, delivery cost, delivery tax, bonus, etc.)
|
||||
:type prices: :obj:`typing.List[types.LabeledPrice]`
|
||||
|
||||
: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 US$ 1.45
|
||||
pass max_tip_amount = 145. See the exp parameter in
|
||||
currencies.json, it shows the number of digits past the
|
||||
decimal point for each currency (2 for the majority of
|
||||
currencies). Defaults to 0
|
||||
:type max_tip_amount: :obj:`typing.Optional[base.Integer]`
|
||||
|
||||
: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.
|
||||
:type suggested_tip_amounts: :obj:`typing.Optional[typing.List[base.Integer]]`
|
||||
|
||||
:param start_parameter: Unique deep-linking parameter. If left
|
||||
empty, forwarded copies of the sent message will have a Pay
|
||||
button, allowing multiple users to pay directly from the
|
||||
forwarded message, using the same invoice. If non-empty,
|
||||
forwarded copies of the sent message will have a URL button
|
||||
with a deep link to the bot (instead of a Pay button), with
|
||||
the value used as the start parameter
|
||||
:type start_parameter: :obj:`typing.Optional[base.String]`
|
||||
|
||||
:param provider_data: JSON-encoded data about the invoice, which will be shared with the payment provider
|
||||
:type provider_data: :obj:`typing.Optional[typing.Dict]`
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ from .input_file import InputFile
|
|||
from .input_media import InputMedia, InputMediaAnimation, InputMediaAudio, InputMediaDocument, InputMediaPhoto, \
|
||||
InputMediaVideo, MediaGroup
|
||||
from .input_message_content import InputContactMessageContent, InputLocationMessageContent, InputMessageContent, \
|
||||
InputTextMessageContent, InputVenueMessageContent
|
||||
InputTextMessageContent, InputVenueMessageContent, InputInvoiceMessageContent
|
||||
from .invoice import Invoice
|
||||
from .labeled_price import LabeledPrice
|
||||
from .location import Location
|
||||
|
|
@ -72,6 +72,7 @@ from .video_note import VideoNote
|
|||
from .voice import Voice
|
||||
from .voice_chat_ended import VoiceChatEnded
|
||||
from .voice_chat_participants_invited import VoiceChatParticipantsInvited
|
||||
from .voice_chat_scheduled import VoiceChatScheduled
|
||||
from .voice_chat_started import VoiceChatStarted
|
||||
from .webhook_info import WebhookInfo
|
||||
|
||||
|
|
@ -131,6 +132,7 @@ __all__ = (
|
|||
'InlineQueryResultVideo',
|
||||
'InlineQueryResultVoice',
|
||||
'InputContactMessageContent',
|
||||
'InputInvoiceMessageContent',
|
||||
'InputFile',
|
||||
'InputLocationMessageContent',
|
||||
'InputMedia',
|
||||
|
|
@ -191,6 +193,7 @@ __all__ = (
|
|||
'Voice',
|
||||
'VoiceChatEnded',
|
||||
'VoiceChatParticipantsInvited',
|
||||
'VoiceChatScheduled',
|
||||
'VoiceChatStarted',
|
||||
'WebhookInfo',
|
||||
'base',
|
||||
|
|
|
|||
|
|
@ -732,6 +732,8 @@ class ChatActions(helper.Helper):
|
|||
UPLOAD_VIDEO: str = helper.Item() # upload_video
|
||||
RECORD_AUDIO: str = helper.Item() # record_audio
|
||||
UPLOAD_AUDIO: str = helper.Item() # upload_audio
|
||||
RECORD_VOICE: str = helper.Item() # record_voice
|
||||
UPLOAD_VOICE: str = helper.Item() # upload_voice
|
||||
UPLOAD_DOCUMENT: str = helper.Item() # upload_document
|
||||
FIND_LOCATION: str = helper.Item() # find_location
|
||||
RECORD_VIDEO_NOTE: str = helper.Item() # record_video_note
|
||||
|
|
@ -817,6 +819,26 @@ class ChatActions(helper.Helper):
|
|||
"""
|
||||
await cls._do(cls.UPLOAD_AUDIO, sleep)
|
||||
|
||||
@classmethod
|
||||
async def record_voice(cls, sleep=None):
|
||||
"""
|
||||
Do record voice
|
||||
|
||||
:param sleep: sleep timeout
|
||||
:return:
|
||||
"""
|
||||
await cls._do(cls.RECORD_VOICE, sleep)
|
||||
|
||||
@classmethod
|
||||
async def upload_voice(cls, sleep=None):
|
||||
"""
|
||||
Do upload voice
|
||||
|
||||
:param sleep: sleep timeout
|
||||
:return:
|
||||
"""
|
||||
await cls._do(cls.UPLOAD_VOICE, sleep)
|
||||
|
||||
@classmethod
|
||||
async def upload_document(cls, sleep=None):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -17,9 +17,10 @@ class InlineQuery(base.TelegramObject):
|
|||
"""
|
||||
id: base.String = fields.Field()
|
||||
from_user: User = fields.Field(alias='from', base=User)
|
||||
location: Location = fields.Field(base=Location)
|
||||
query: base.String = fields.Field()
|
||||
offset: base.String = fields.Field()
|
||||
chat_type: base.String = fields.Field()
|
||||
location: Location = fields.Field(base=Location)
|
||||
|
||||
async def answer(self,
|
||||
results: typing.List[InlineQueryResult],
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ import typing
|
|||
from . import base
|
||||
from . import fields
|
||||
from .message_entity import MessageEntity
|
||||
from .labeled_price import LabeledPrice
|
||||
from ..utils.payload import generate_payload
|
||||
|
||||
|
||||
class InputMessageContent(base.TelegramObject):
|
||||
|
|
@ -44,6 +46,66 @@ class InputContactMessageContent(InputMessageContent):
|
|||
)
|
||||
|
||||
|
||||
class InputInvoiceMessageContent(InputMessageContent):
|
||||
"""
|
||||
Represents the content of an invoice message to be sent as the
|
||||
result of an inline query.
|
||||
|
||||
https://core.telegram.org/bots/api#inputinvoicemessagecontent
|
||||
"""
|
||||
|
||||
title: base.String = fields.Field()
|
||||
description: base.String = fields.Field()
|
||||
payload: base.String = fields.Field()
|
||||
provider_token: base.String = fields.Field()
|
||||
currency: base.String = fields.Field()
|
||||
prices: typing.List[LabeledPrice] = fields.ListField(base=LabeledPrice)
|
||||
max_tip_amount: typing.Optional[base.Integer] = fields.Field()
|
||||
suggested_tip_amounts: typing.Optional[
|
||||
typing.List[base.Integer]
|
||||
] = fields.ListField(base=base.Integer)
|
||||
provider_data: typing.Optional[base.String] = fields.Field()
|
||||
photo_url: typing.Optional[base.String] = fields.Field()
|
||||
photo_size: typing.Optional[base.Integer] = fields.Field()
|
||||
photo_width: typing.Optional[base.Integer] = fields.Field()
|
||||
photo_height: typing.Optional[base.Integer] = fields.Field()
|
||||
need_name: typing.Optional[base.Boolean] = fields.Field()
|
||||
need_phone_number: typing.Optional[base.Boolean] = fields.Field()
|
||||
need_email: typing.Optional[base.Boolean] = fields.Field()
|
||||
need_shipping_address: typing.Optional[base.Boolean] = fields.Field()
|
||||
send_phone_number_to_provider: typing.Optional[base.Boolean] = fields.Field()
|
||||
send_email_to_provider: typing.Optional[base.Boolean] = fields.Field()
|
||||
is_flexible: typing.Optional[base.Boolean] = fields.Field()
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
title: base.String,
|
||||
description: base.String,
|
||||
payload: base.String,
|
||||
provider_token: base.String,
|
||||
currency: base.String,
|
||||
prices: typing.List[LabeledPrice] = None,
|
||||
max_tip_amount: typing.Optional[base.Integer] = None,
|
||||
suggested_tip_amounts: typing.Optional[typing.List[base.Integer]] = None,
|
||||
provider_data: typing.Optional[base.String] = None,
|
||||
photo_url: typing.Optional[base.String] = None,
|
||||
photo_size: typing.Optional[base.Integer] = None,
|
||||
photo_width: typing.Optional[base.Integer] = None,
|
||||
photo_height: typing.Optional[base.Integer] = None,
|
||||
need_name: typing.Optional[base.Boolean] = None,
|
||||
need_phone_number: typing.Optional[base.Boolean] = None,
|
||||
need_email: typing.Optional[base.Boolean] = None,
|
||||
need_shipping_address: typing.Optional[base.Boolean] = None,
|
||||
send_phone_number_to_provider: typing.Optional[base.Boolean] = None,
|
||||
send_email_to_provider: typing.Optional[base.Boolean] = None,
|
||||
is_flexible: typing.Optional[base.Boolean] = None,
|
||||
):
|
||||
if prices is None:
|
||||
prices = []
|
||||
payload = generate_payload(**locals())
|
||||
super().__init__(**payload)
|
||||
|
||||
|
||||
class InputLocationMessageContent(InputMessageContent):
|
||||
"""
|
||||
Represents the content of a location message to be sent as the result of an inline query.
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ from .video_note import VideoNote
|
|||
from .voice import Voice
|
||||
from .voice_chat_ended import VoiceChatEnded
|
||||
from .voice_chat_participants_invited import VoiceChatParticipantsInvited
|
||||
from .voice_chat_scheduled import VoiceChatScheduled
|
||||
from .voice_chat_started import VoiceChatStarted
|
||||
from ..utils import helper
|
||||
from ..utils import markdown as md
|
||||
|
|
@ -98,6 +99,7 @@ class Message(base.TelegramObject):
|
|||
connected_website: base.String = fields.Field()
|
||||
passport_data: PassportData = fields.Field(base=PassportData)
|
||||
proximity_alert_triggered: ProximityAlertTriggered = fields.Field(base=ProximityAlertTriggered)
|
||||
voice_chat_scheduled: VoiceChatScheduled = fields.Field(base=VoiceChatScheduled)
|
||||
voice_chat_started: VoiceChatStarted = fields.Field(base=VoiceChatStarted)
|
||||
voice_chat_ended: VoiceChatEnded = fields.Field(base=VoiceChatEnded)
|
||||
voice_chat_participants_invited: VoiceChatParticipantsInvited = fields.Field(base=VoiceChatParticipantsInvited)
|
||||
|
|
@ -166,6 +168,8 @@ class Message(base.TelegramObject):
|
|||
return ContentType.PASSPORT_DATA
|
||||
if self.proximity_alert_triggered:
|
||||
return ContentType.PROXIMITY_ALERT_TRIGGERED
|
||||
if self.voice_chat_scheduled:
|
||||
return ContentType.VOICE_CHAT_SCHEDULED
|
||||
if self.voice_chat_started:
|
||||
return ContentType.VOICE_CHAT_STARTED
|
||||
if self.voice_chat_ended:
|
||||
|
|
@ -3033,6 +3037,7 @@ class ContentType(helper.Helper):
|
|||
GROUP_CHAT_CREATED = helper.Item() # group_chat_created
|
||||
PASSPORT_DATA = helper.Item() # passport_data
|
||||
PROXIMITY_ALERT_TRIGGERED = helper.Item() # proximity_alert_triggered
|
||||
VOICE_CHAT_SCHEDULED = helper.Item() # voice_chat_scheduled
|
||||
VOICE_CHAT_STARTED = helper.Item() # voice_chat_started
|
||||
VOICE_CHAT_ENDED = helper.Item() # voice_chat_ended
|
||||
VOICE_CHAT_PARTICIPANTS_INVITED = helper.Item() # voice_chat_participants_invited
|
||||
|
|
|
|||
15
aiogram/types/voice_chat_scheduled.py
Normal file
15
aiogram/types/voice_chat_scheduled.py
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
from datetime import datetime
|
||||
|
||||
from . import base
|
||||
from . import fields
|
||||
from .user import User
|
||||
|
||||
|
||||
class VoiceChatScheduled(base.TelegramObject):
|
||||
"""
|
||||
This object represents a service message about a voice chat scheduled in the chat.
|
||||
|
||||
https://core.telegram.org/bots/api#voicechatscheduled
|
||||
"""
|
||||
|
||||
start_date: datetime = fields.DateTimeField()
|
||||
|
|
@ -22,7 +22,7 @@ Welcome to aiogram's documentation!
|
|||
:target: https://pypi.python.org/pypi/aiogram
|
||||
:alt: Supported python versions
|
||||
|
||||
.. image:: https://img.shields.io/badge/Telegram%20Bot%20API-5.1-blue.svg?style=flat-square&logo=telegram
|
||||
.. image:: https://img.shields.io/badge/Telegram%20Bot%20API-5.2-blue.svg?style=flat-square&logo=telegram
|
||||
:target: https://core.telegram.org/bots/api
|
||||
:alt: Telegram Bot API
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue