Initial update. Update types and methods

This commit is contained in:
Alex Root Junior 2020-11-16 03:59:35 +02:00
parent 85265a34cd
commit a339514fb9
75 changed files with 1334 additions and 492 deletions

File diff suppressed because it is too large Load diff

View file

@ -4,6 +4,8 @@ from .answer_inline_query import AnswerInlineQuery
from .answer_pre_checkout_query import AnswerPreCheckoutQuery
from .answer_shipping_query import AnswerShippingQuery
from .base import Request, Response, TelegramMethod
from .close import Close
from .copy_message import CopyMessage
from .create_new_sticker_set import CreateNewStickerSet
from .delete_chat_photo import DeleteChatPhoto
from .delete_chat_sticker_set import DeleteChatStickerSet
@ -31,6 +33,7 @@ from .get_user_profile_photos import GetUserProfilePhotos
from .get_webhook_info import GetWebhookInfo
from .kick_chat_member import KickChatMember
from .leave_chat import LeaveChat
from .log_out import LogOut
from .pin_chat_message import PinChatMessage
from .promote_chat_member import PromoteChatMember
from .restrict_chat_member import RestrictChatMember
@ -67,6 +70,7 @@ from .set_webhook import SetWebhook
from .stop_message_live_location import StopMessageLiveLocation
from .stop_poll import StopPoll
from .unban_chat_member import UnbanChatMember
from .unpin_all_chat_messages import UnpinAllChatMessages
from .unpin_chat_message import UnpinChatMessage
from .upload_sticker_file import UploadStickerFile
@ -79,8 +83,11 @@ __all__ = (
"DeleteWebhook",
"GetWebhookInfo",
"GetMe",
"LogOut",
"Close",
"SendMessage",
"ForwardMessage",
"CopyMessage",
"SendPhoto",
"SendAudio",
"SendDocument",
@ -112,6 +119,7 @@ __all__ = (
"SetChatDescription",
"PinChatMessage",
"UnpinChatMessage",
"UnpinAllChatMessages",
"LeaveChat",
"GetChat",
"GetChatAdministrators",

View file

@ -126,7 +126,12 @@ def prepare_media_file(data: Dict[str, Any], files: Dict[str, InputFile]) -> Non
data["media"]["media"] = f"attach://{tag}"
def prepare_parse_mode(bot: Bot, root: Any, parse_mode_property: str = "parse_mode") -> None:
def prepare_parse_mode(
bot: Bot,
root: Any,
parse_mode_property: str = "parse_mode",
entities_property: str = "entities",
) -> None:
"""
Find and set parse_mode with highest priority.
@ -137,9 +142,14 @@ def prepare_parse_mode(bot: Bot, root: Any, parse_mode_property: str = "parse_mo
"""
if isinstance(root, list):
for item in root:
prepare_parse_mode(bot=bot, root=item, parse_mode_property=parse_mode_property)
prepare_parse_mode(
bot=bot,
root=item,
parse_mode_property=parse_mode_property,
entities_property=entities_property,
)
elif root.get(parse_mode_property, UNSET) is UNSET:
if bot.parse_mode:
if bot.parse_mode and not root.get(entities_property, None):
root[parse_mode_property] = bot.parse_mode
else:
root[parse_mode_property] = None

View file

@ -0,0 +1,26 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict
from .base import Request, TelegramMethod
if TYPE_CHECKING: # pragma: no cover
from ..client.bot import Bot
class Close(TelegramMethod[bool]):
"""
Use this method to close the bot instance before moving it from one local server to another.
You need to delete the webhook before calling this method to ensure that the bot isn't
launched again after server restart. The method will return error 429 in the first 10 minutes
after the bot is launched. Returns True on success. Requires no parameters.
Source: https://core.telegram.org/bots/api#close
"""
__returning__ = bool
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="close", data=data)

View file

@ -0,0 +1,67 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
from ..types import (
UNSET,
ForceReply,
InlineKeyboardMarkup,
MessageEntity,
MessageId,
ReplyKeyboardMarkup,
ReplyKeyboardRemove,
)
from .base import Request, TelegramMethod, prepare_parse_mode
if TYPE_CHECKING: # pragma: no cover
from ..client.bot import Bot
class CopyMessage(TelegramMethod[MessageId]):
"""
Use this method to copy messages of any kind. The method is analogous to the method
forwardMessages, but the copied message doesn't have a link to the original message. Returns
the MessageId of the sent message on success.
Source: https://core.telegram.org/bots/api#copymessage
"""
__returning__ = MessageId
chat_id: Union[int, str]
"""Unique identifier for the target chat or username of the target channel (in the format
@channelusername)"""
from_chat_id: Union[int, str]
"""Unique identifier for the chat where the original message was sent (or channel username in
the format @channelusername)"""
message_id: int
"""Message identifier in the chat specified in from_chat_id"""
caption: Optional[str] = None
"""New caption for media, 0-1024 characters after entities parsing. If not specified, the
original caption is kept"""
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the new caption. See formatting options for more details."""
caption_entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in the new caption, which can be specified instead of
parse_mode"""
disable_notification: Optional[bool] = None
"""Sends the message silently. Users will receive a notification with no sound."""
reply_to_message_id: Optional[int] = None
"""If the message is a reply, ID of the original message"""
allow_sending_without_reply: Optional[bool] = None
"""Pass True, if the message should be sent even if the specified replied-to message is not
found"""
reply_markup: Optional[
Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
] = None
"""Additional interface options. A JSON-serialized object for an inline keyboard, custom reply
keyboard, instructions to remove reply keyboard or to force a reply from the user."""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
prepare_parse_mode(
bot, data, parse_mode_property="parse_mode", entities_property="caption_entities"
)
return Request(method="copyMessage", data=data)

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict
from typing import TYPE_CHECKING, Any, Dict, Optional
from .base import Request, TelegramMethod
@ -11,13 +11,16 @@ if TYPE_CHECKING: # pragma: no cover
class DeleteWebhook(TelegramMethod[bool]):
"""
Use this method to remove webhook integration if you decide to switch back to getUpdates.
Returns True on success. Requires no parameters.
Returns True on success.
Source: https://core.telegram.org/bots/api#deletewebhook
"""
__returning__ = bool
drop_pending_updates: Optional[bool] = None
"""Pass True to drop all pending updates"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()

View file

@ -1,8 +1,8 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
from ..types import UNSET, InlineKeyboardMarkup, Message
from ..types import UNSET, InlineKeyboardMarkup, Message, MessageEntity
from .base import Request, TelegramMethod, prepare_parse_mode
if TYPE_CHECKING: # pragma: no cover
@ -11,8 +11,8 @@ if TYPE_CHECKING: # pragma: no cover
class EditMessageCaption(TelegramMethod[Union[Message, bool]]):
"""
Use this method to edit captions of messages. On success, if edited message is sent by the
bot, the edited Message is returned, otherwise True is returned.
Use this method to edit captions of messages. On success, if the edited message is not an
inline message, the edited Message is returned, otherwise True is returned.
Source: https://core.telegram.org/bots/api#editmessagecaption
"""
@ -30,11 +30,17 @@ class EditMessageCaption(TelegramMethod[Union[Message, bool]]):
"""New caption of the message, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the message caption. See formatting options for more details."""
caption_entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in the caption, which can be specified instead of
parse_mode"""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""A JSON-serialized object for an inline keyboard."""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
prepare_parse_mode(bot, data)
prepare_parse_mode(
bot, data, parse_mode_property="parse_mode", entities_property="caption_entities"
)
return Request(method="editMessageCaption", data=data)

View file

@ -13,7 +13,7 @@ class EditMessageLiveLocation(TelegramMethod[Union[Message, bool]]):
"""
Use this method to edit live location messages. A location can be edited until its live_period
expires or editing is explicitly disabled by a call to stopMessageLiveLocation. On success, if
the edited message was sent by the bot, the edited Message is returned, otherwise True is
the edited message is not an inline message, the edited Message is returned, otherwise True is
returned.
Source: https://core.telegram.org/bots/api#editmessagelivelocation
@ -32,6 +32,13 @@ class EditMessageLiveLocation(TelegramMethod[Union[Message, bool]]):
"""Required if inline_message_id is not specified. Identifier of the message to edit"""
inline_message_id: Optional[str] = None
"""Required if chat_id and message_id are not specified. Identifier of the inline message"""
horizontal_accuracy: Optional[float] = None
"""The radius of uncertainty for the location, measured in meters; 0-1500"""
heading: Optional[int] = None
"""Direction in which the user is moving, in degrees. Must be between 1 and 360 if specified."""
proximity_alert_radius: Optional[int] = None
"""Maximum distance for proximity alerts about approaching another chat member, in meters.
Must be between 1 and 100000 if specified."""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""A JSON-serialized object for a new inline keyboard."""

View file

@ -2,8 +2,8 @@ from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
from ..types import InlineKeyboardMarkup, InputFile, InputMedia, Message
from .base import Request, TelegramMethod, prepare_media_file, prepare_parse_mode
from ..types import InlineKeyboardMarkup, InputMedia, Message, InputFile
from .base import Request, TelegramMethod, prepare_parse_mode, prepare_media_file
if TYPE_CHECKING: # pragma: no cover
from ..client.bot import Bot
@ -12,11 +12,11 @@ if TYPE_CHECKING: # pragma: no cover
class EditMessageMedia(TelegramMethod[Union[Message, bool]]):
"""
Use this method to edit animation, audio, document, photo, or video messages. If a message is
a part of a message album, then it can be edited only to a photo or a video. Otherwise,
message type can be changed arbitrarily. When inline message is edited, new file can't be
uploaded. Use previously uploaded file via its file_id or specify a URL. On success, if the
edited message was sent by the bot, the edited Message is returned, otherwise True is
returned.
part of a message album, then it can be edited only to an audio for audio albums, only to a
document for document albums and to a photo or a video otherwise. When an inline message is
edited, a new file can't be uploaded. Use a previously uploaded file via its file_id or
specify a URL. On success, if the edited message was sent by the bot, the edited Message is
returned, otherwise True is returned.
Source: https://core.telegram.org/bots/api#editmessagemedia
"""

View file

@ -11,8 +11,8 @@ if TYPE_CHECKING: # pragma: no cover
class EditMessageReplyMarkup(TelegramMethod[Union[Message, bool]]):
"""
Use this method to edit only the reply markup of messages. On success, if edited message is
sent by the bot, the edited Message is returned, otherwise True is returned.
Use this method to edit only the reply markup of messages. On success, if the edited message
is not an inline message, the edited Message is returned, otherwise True is returned.
Source: https://core.telegram.org/bots/api#editmessagereplymarkup
"""

View file

@ -1,9 +1,9 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
from ..types import UNSET, InlineKeyboardMarkup, Message
from .base import Request, TelegramMethod
from ..types import UNSET, InlineKeyboardMarkup, Message, MessageEntity
from .base import Request, TelegramMethod, prepare_parse_mode
if TYPE_CHECKING: # pragma: no cover
from ..client.bot import Bot
@ -11,8 +11,8 @@ if TYPE_CHECKING: # pragma: no cover
class EditMessageText(TelegramMethod[Union[Message, bool]]):
"""
Use this method to edit text and game messages. On success, if edited message is sent by the
bot, the edited Message is returned, otherwise True is returned.
Use this method to edit text and game messages. On success, if the edited message is not an
inline message, the edited Message is returned, otherwise True is returned.
Source: https://core.telegram.org/bots/api#editmessagetext
"""
@ -30,6 +30,9 @@ class EditMessageText(TelegramMethod[Union[Message, bool]]):
"""Required if chat_id and message_id are not specified. Identifier of the inline message"""
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the message text. See formatting options for more details."""
entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in message text, which can be specified instead of
parse_mode"""
disable_web_page_preview: Optional[bool] = None
"""Disables link previews for links in this message"""
reply_markup: Optional[InlineKeyboardMarkup] = None
@ -38,4 +41,8 @@ class EditMessageText(TelegramMethod[Union[Message, bool]]):
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
prepare_parse_mode(
bot, data, parse_mode_property="parse_mode", entities_property="entities"
)
return Request(method="editMessageText", data=data)

View file

@ -0,0 +1,27 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict
from .base import Request, TelegramMethod
if TYPE_CHECKING: # pragma: no cover
from ..client.bot import Bot
class LogOut(TelegramMethod[bool]):
"""
Use this method to log out from the cloud Bot API server before launching the bot locally. You
must log out the bot before running it locally, otherwise there is no guarantee that the bot
will receive updates. After a successful call, you can immediately log in on a local server,
but will not be able to log in back to the cloud Bot API server for 10 minutes. Returns True
on success. Requires no parameters.
Source: https://core.telegram.org/bots/api#logout
"""
__returning__ = bool
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="logOut", data=data)

View file

@ -10,9 +10,10 @@ if TYPE_CHECKING: # pragma: no cover
class PinChatMessage(TelegramMethod[bool]):
"""
Use this method to pin a message in a group, a supergroup, or a channel. The bot must be an
administrator in the chat for this to work and must have the 'can_pin_messages' admin right in
the supergroup or 'can_edit_messages' admin right in the channel. Returns True on success.
Use this method to add a message to the list of pinned messages in a chat. If the chat is not
a private chat, the bot must be an administrator in the chat for this to work and must have
the 'can_pin_messages' admin right in a supergroup or 'can_edit_messages' admin right in a
channel. Returns True on success.
Source: https://core.telegram.org/bots/api#pinchatmessage
"""
@ -26,7 +27,7 @@ class PinChatMessage(TelegramMethod[bool]):
"""Identifier of a message to pin"""
disable_notification: Optional[bool] = None
"""Pass True, if it is not necessary to send a notification to all chat members about the new
pinned message. Notifications are always disabled in channels."""
pinned message. Notifications are always disabled in channels and private chats."""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()

View file

@ -24,6 +24,8 @@ class PromoteChatMember(TelegramMethod[bool]):
@channelusername)"""
user_id: int
"""Unique identifier of the target user"""
is_anonymous: Optional[bool] = None
"""Pass True, if the administrator's presence in the chat is hidden"""
can_change_info: Optional[bool] = None
"""Pass True, if the administrator can change chat title, photo and other settings"""
can_post_messages: Optional[bool] = None

View file

@ -27,7 +27,7 @@ class RestrictChatMember(TelegramMethod[bool]):
user_id: int
"""Unique identifier of the target user"""
permissions: ChatPermissions
"""New user permissions"""
"""A JSON-serialized object for new user permissions"""
until_date: Optional[Union[datetime.datetime, datetime.timedelta, int]] = None
"""Date when restrictions will be lifted for the user, unix time. If user is restricted for
more than 366 days or less than 30 seconds from the current time, they are considered to be

View file

@ -8,10 +8,11 @@ from ..types import (
InlineKeyboardMarkup,
InputFile,
Message,
MessageEntity,
ReplyKeyboardMarkup,
ReplyKeyboardRemove,
)
from .base import Request, TelegramMethod, prepare_file
from .base import Request, TelegramMethod, prepare_file, prepare_parse_mode
if TYPE_CHECKING: # pragma: no cover
from ..client.bot import Bot
@ -54,10 +55,16 @@ class SendAnimation(TelegramMethod[Message]):
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the animation caption. See formatting options for more
details."""
caption_entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in the caption, which can be specified instead of
parse_mode"""
disable_notification: Optional[bool] = None
"""Sends the message silently. Users will receive a notification with no sound."""
reply_to_message_id: Optional[int] = None
"""If the message is a reply, ID of the original message"""
allow_sending_without_reply: Optional[bool] = None
"""Pass True, if the message should be sent even if the specified replied-to message is not
found"""
reply_markup: Optional[
Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
] = None
@ -67,6 +74,10 @@ class SendAnimation(TelegramMethod[Message]):
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict(exclude={"animation", "thumb"})
prepare_parse_mode(
bot, data, parse_mode_property="parse_mode", entities_property="caption_entities"
)
files: Dict[str, InputFile] = {}
prepare_file(data=data, files=files, name="animation", value=self.animation)
prepare_file(data=data, files=files, name="thumb", value=self.thumb)

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
from ..types import (
UNSET,
@ -8,10 +8,11 @@ from ..types import (
InlineKeyboardMarkup,
InputFile,
Message,
MessageEntity,
ReplyKeyboardMarkup,
ReplyKeyboardRemove,
)
from .base import Request, TelegramMethod, prepare_file
from .base import Request, TelegramMethod, prepare_file, prepare_parse_mode
if TYPE_CHECKING: # pragma: no cover
from ..client.bot import Bot
@ -41,6 +42,9 @@ class SendAudio(TelegramMethod[Message]):
"""Audio caption, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the audio caption. See formatting options for more details."""
caption_entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in the caption, which can be specified instead of
parse_mode"""
duration: Optional[int] = None
"""Duration of the audio in seconds"""
performer: Optional[str] = None
@ -58,6 +62,9 @@ class SendAudio(TelegramMethod[Message]):
"""Sends the message silently. Users will receive a notification with no sound."""
reply_to_message_id: Optional[int] = None
"""If the message is a reply, ID of the original message"""
allow_sending_without_reply: Optional[bool] = None
"""Pass True, if the message should be sent even if the specified replied-to message is not
found"""
reply_markup: Optional[
Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
] = None
@ -67,6 +74,10 @@ class SendAudio(TelegramMethod[Message]):
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict(exclude={"audio", "thumb"})
prepare_parse_mode(
bot, data, parse_mode_property="parse_mode", entities_property="caption_entities"
)
files: Dict[str, InputFile] = {}
prepare_file(data=data, files=files, name="audio", value=self.audio)
prepare_file(data=data, files=files, name="thumb", value=self.thumb)

View file

@ -39,6 +39,9 @@ class SendContact(TelegramMethod[Message]):
"""Sends the message silently. Users will receive a notification with no sound."""
reply_to_message_id: Optional[int] = None
"""If the message is a reply, ID of the original message"""
allow_sending_without_reply: Optional[bool] = None
"""Pass True, if the message should be sent even if the specified replied-to message is not
found"""
reply_markup: Optional[
Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
] = None

View file

@ -29,12 +29,16 @@ class SendDice(TelegramMethod[Message]):
"""Unique identifier for the target chat or username of the target channel (in the format
@channelusername)"""
emoji: Optional[str] = None
"""Emoji on which the dice throw animation is based. Currently, must be one of '', '', or ''.
Dice can have values 1-6 for '' and '', and values 1-5 for ''. Defaults to ''"""
"""Emoji on which the dice throw animation is based. Currently, must be one of '', '', '', '',
or ''. Dice can have values 1-6 for '' and '', values 1-5 for '' and '', and values 1-64
for ''. Defaults to ''"""
disable_notification: Optional[bool] = None
"""Sends the message silently. Users will receive a notification with no sound."""
reply_to_message_id: Optional[int] = None
"""If the message is a reply, ID of the original message"""
allow_sending_without_reply: Optional[bool] = None
"""Pass True, if the message should be sent even if the specified replied-to message is not
found"""
reply_markup: Optional[
Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
] = None

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
from ..types import (
UNSET,
@ -8,10 +8,11 @@ from ..types import (
InlineKeyboardMarkup,
InputFile,
Message,
MessageEntity,
ReplyKeyboardMarkup,
ReplyKeyboardRemove,
)
from .base import Request, TelegramMethod, prepare_file
from .base import Request, TelegramMethod, prepare_file, prepare_parse_mode
if TYPE_CHECKING: # pragma: no cover
from ..client.bot import Bot
@ -47,10 +48,19 @@ class SendDocument(TelegramMethod[Message]):
after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the document caption. See formatting options for more details."""
caption_entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in the caption, which can be specified instead of
parse_mode"""
disable_content_type_detection: Optional[bool] = None
"""Disables automatic server-side content type detection for files uploaded using
multipart/form-data"""
disable_notification: Optional[bool] = None
"""Sends the message silently. Users will receive a notification with no sound."""
reply_to_message_id: Optional[int] = None
"""If the message is a reply, ID of the original message"""
allow_sending_without_reply: Optional[bool] = None
"""Pass True, if the message should be sent even if the specified replied-to message is not
found"""
reply_markup: Optional[
Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
] = None
@ -60,6 +70,10 @@ class SendDocument(TelegramMethod[Message]):
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict(exclude={"document", "thumb"})
prepare_parse_mode(
bot, data, parse_mode_property="parse_mode", entities_property="caption_entities"
)
files: Dict[str, InputFile] = {}
prepare_file(data=data, files=files, name="document", value=self.document)
prepare_file(data=data, files=files, name="thumb", value=self.thumb)

View file

@ -27,6 +27,9 @@ class SendGame(TelegramMethod[Message]):
"""Sends the message silently. Users will receive a notification with no sound."""
reply_to_message_id: Optional[int] = None
"""If the message is a reply, ID of the original message"""
allow_sending_without_reply: Optional[bool] = None
"""Pass True, if the message should be sent even if the specified replied-to message is not
found"""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""A JSON-serialized object for an inline keyboard. If empty, one 'Play game_title' button
will be shown. If not empty, the first button must launch the game."""

View file

@ -38,7 +38,7 @@ class SendInvoice(TelegramMethod[Message]):
"""Price breakdown, a JSON-serialized list of components (e.g. product price, tax, discount,
delivery cost, delivery tax, bonus, etc.)"""
provider_data: Optional[str] = None
"""JSON-encoded data about the invoice, which will be shared with the payment provider. A
"""A 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."""
photo_url: Optional[str] = None
"""URL of the product photo for the invoice. Can be a photo of the goods or a marketing image
@ -67,6 +67,9 @@ class SendInvoice(TelegramMethod[Message]):
"""Sends the message silently. Users will receive a notification with no sound."""
reply_to_message_id: Optional[int] = None
"""If the message is a reply, ID of the original message"""
allow_sending_without_reply: Optional[bool] = None
"""Pass True, if the message should be sent even if the specified replied-to message is not
found"""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""A JSON-serialized object for an inline keyboard. If empty, one 'Pay total price' button
will be shown. If not empty, the first button must be a Pay button."""

View file

@ -31,13 +31,24 @@ class SendLocation(TelegramMethod[Message]):
"""Latitude of the location"""
longitude: float
"""Longitude of the location"""
horizontal_accuracy: Optional[float] = None
"""The radius of uncertainty for the location, measured in meters; 0-1500"""
live_period: Optional[int] = None
"""Period in seconds for which the location will be updated (see Live Locations, should be
between 60 and 86400."""
heading: Optional[int] = None
"""For live locations, a direction in which the user is moving, in degrees. Must be between 1
and 360 if specified."""
proximity_alert_radius: Optional[int] = None
"""For live locations, a maximum distance for proximity alerts about approaching another chat
member, in meters. Must be between 1 and 100000 if specified."""
disable_notification: Optional[bool] = None
"""Sends the message silently. Users will receive a notification with no sound."""
reply_to_message_id: Optional[int] = None
"""If the message is a reply, ID of the original message"""
allow_sending_without_reply: Optional[bool] = None
"""Pass True, if the message should be sent even if the specified replied-to message is not
found"""
reply_markup: Optional[
Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
] = None

View file

@ -2,8 +2,8 @@ from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
from ..types import InputFile, InputMediaPhoto, InputMediaVideo, Message
from .base import Request, TelegramMethod, prepare_input_media, prepare_parse_mode
from ..types import InputMediaAudio, InputMediaDocument, InputMediaPhoto, InputMediaVideo
from .base import Request, TelegramMethod
if TYPE_CHECKING: # pragma: no cover
from ..client.bot import Bot
@ -11,8 +11,9 @@ if TYPE_CHECKING: # pragma: no cover
class SendMediaGroup(TelegramMethod[List[Message]]):
"""
Use this method to send a group of photos or videos as an album. On success, an array of the
sent Messages is returned.
Use this method to send a group of photos, videos, documents or audios as an album. Documents
and audio files can be only grouped in an album with messages of the same type. On success, an
array of Messages that were sent is returned.
Source: https://core.telegram.org/bots/api#sendmediagroup
"""
@ -22,12 +23,15 @@ class SendMediaGroup(TelegramMethod[List[Message]]):
chat_id: Union[int, str]
"""Unique identifier for the target chat or username of the target channel (in the format
@channelusername)"""
media: List[Union[InputMediaPhoto, InputMediaVideo]]
"""A JSON-serialized array describing photos and videos to be sent, must include 2-10 items"""
media: List[Union[InputMediaAudio, InputMediaDocument, InputMediaPhoto, InputMediaVideo]]
"""A JSON-serialized array describing messages to be sent, must include 2-10 items"""
disable_notification: Optional[bool] = None
"""Sends the messages silently. Users will receive a notification with no sound."""
"""Sends messages silently. Users will receive a notification with no sound."""
reply_to_message_id: Optional[int] = None
"""If the messages are a reply, ID of the original message"""
allow_sending_without_reply: Optional[bool] = None
"""Pass True, if the message should be sent even if the specified replied-to message is not
found"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()

View file

@ -1,12 +1,13 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
from ..types import (
UNSET,
ForceReply,
InlineKeyboardMarkup,
Message,
MessageEntity,
ReplyKeyboardMarkup,
ReplyKeyboardRemove,
)
@ -32,12 +33,18 @@ class SendMessage(TelegramMethod[Message]):
"""Text of the message to be sent, 1-4096 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the message text. See formatting options for more details."""
entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in message text, which can be specified instead of
parse_mode"""
disable_web_page_preview: Optional[bool] = None
"""Disables link previews for links in this message"""
disable_notification: Optional[bool] = None
"""Sends the message silently. Users will receive a notification with no sound."""
reply_to_message_id: Optional[int] = None
"""If the message is a reply, ID of the original message"""
allow_sending_without_reply: Optional[bool] = None
"""Pass True, if the message should be sent even if the specified replied-to message is not
found"""
reply_markup: Optional[
Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
] = None
@ -46,6 +53,9 @@ class SendMessage(TelegramMethod[Message]):
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
prepare_parse_mode(bot, data)
prepare_parse_mode(
bot, data, parse_mode_property="parse_mode", entities_property="entities"
)
return Request(method="sendMessage", data=data)

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
from ..types import (
UNSET,
@ -8,10 +8,11 @@ from ..types import (
InlineKeyboardMarkup,
InputFile,
Message,
MessageEntity,
ReplyKeyboardMarkup,
ReplyKeyboardRemove,
)
from .base import Request, TelegramMethod, prepare_file
from .base import Request, TelegramMethod, prepare_file, prepare_parse_mode
if TYPE_CHECKING: # pragma: no cover
from ..client.bot import Bot
@ -38,10 +39,16 @@ class SendPhoto(TelegramMethod[Message]):
entities parsing"""
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the photo caption. See formatting options for more details."""
caption_entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in the caption, which can be specified instead of
parse_mode"""
disable_notification: Optional[bool] = None
"""Sends the message silently. Users will receive a notification with no sound."""
reply_to_message_id: Optional[int] = None
"""If the message is a reply, ID of the original message"""
allow_sending_without_reply: Optional[bool] = None
"""Pass True, if the message should be sent even if the specified replied-to message is not
found"""
reply_markup: Optional[
Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
] = None
@ -51,6 +58,10 @@ class SendPhoto(TelegramMethod[Message]):
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict(exclude={"photo"})
prepare_parse_mode(
bot, data, parse_mode_property="parse_mode", entities_property="caption_entities"
)
files: Dict[str, InputFile] = {}
prepare_file(data=data, files=files, name="photo", value=self.photo)

View file

@ -8,6 +8,7 @@ from ..types import (
ForceReply,
InlineKeyboardMarkup,
Message,
MessageEntity,
ReplyKeyboardMarkup,
ReplyKeyboardRemove,
)
@ -30,7 +31,7 @@ class SendPoll(TelegramMethod[Message]):
"""Unique identifier for the target chat or username of the target channel (in the format
@channelusername)"""
question: str
"""Poll question, 1-255 characters"""
"""Poll question, 1-300 characters"""
options: List[str]
"""A JSON-serialized list of answer options, 2-10 strings 1-100 characters each"""
is_anonymous: Optional[bool] = None
@ -47,6 +48,9 @@ class SendPoll(TelegramMethod[Message]):
quiz-style poll, 0-200 characters with at most 2 line feeds after entities parsing"""
explanation_parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the explanation. See formatting options for more details."""
explanation_entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in the poll explanation, which can be specified
instead of parse_mode"""
open_period: Optional[int] = None
"""Amount of time in seconds the poll will be active after creation, 5-600. Can't be used
together with close_date."""
@ -59,6 +63,9 @@ class SendPoll(TelegramMethod[Message]):
"""Sends the message silently. Users will receive a notification with no sound."""
reply_to_message_id: Optional[int] = None
"""If the message is a reply, ID of the original message"""
allow_sending_without_reply: Optional[bool] = None
"""Pass True, if the message should be sent even if the specified replied-to message is not
found"""
reply_markup: Optional[
Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
] = None
@ -67,6 +74,12 @@ class SendPoll(TelegramMethod[Message]):
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
prepare_parse_mode(bot, data, parse_mode_property="explanation_parse_mode")
prepare_parse_mode(
bot,
data,
parse_mode_property="explanation_parse_mode",
entities_property="explanation_entities",
)
return Request(method="sendPoll", data=data)

View file

@ -37,6 +37,9 @@ class SendSticker(TelegramMethod[Message]):
"""Sends the message silently. Users will receive a notification with no sound."""
reply_to_message_id: Optional[int] = None
"""If the message is a reply, ID of the original message"""
allow_sending_without_reply: Optional[bool] = None
"""Pass True, if the message should be sent even if the specified replied-to message is not
found"""
reply_markup: Optional[
Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
] = None

View file

@ -40,10 +40,17 @@ class SendVenue(TelegramMethod[Message]):
foursquare_type: Optional[str] = None
"""Foursquare type of the venue, if known. (For example, 'arts_entertainment/default',
'arts_entertainment/aquarium' or 'food/icecream'.)"""
google_place_id: Optional[str] = None
"""Google Places identifier of the venue"""
google_place_type: Optional[str] = None
"""Google Places type of the venue. (See supported types.)"""
disable_notification: Optional[bool] = None
"""Sends the message silently. Users will receive a notification with no sound."""
reply_to_message_id: Optional[int] = None
"""If the message is a reply, ID of the original message"""
allow_sending_without_reply: Optional[bool] = None
"""Pass True, if the message should be sent even if the specified replied-to message is not
found"""
reply_markup: Optional[
Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
] = None

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
from ..types import (
UNSET,
@ -8,10 +8,11 @@ from ..types import (
InlineKeyboardMarkup,
InputFile,
Message,
MessageEntity,
ReplyKeyboardMarkup,
ReplyKeyboardRemove,
)
from .base import Request, TelegramMethod, prepare_file
from .base import Request, TelegramMethod, prepare_file, prepare_parse_mode
if TYPE_CHECKING: # pragma: no cover
from ..client.bot import Bot
@ -53,12 +54,18 @@ class SendVideo(TelegramMethod[Message]):
entities parsing"""
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the video caption. See formatting options for more details."""
caption_entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in the caption, which can be specified instead of
parse_mode"""
supports_streaming: Optional[bool] = None
"""Pass True, if the uploaded video is suitable for streaming"""
disable_notification: Optional[bool] = None
"""Sends the message silently. Users will receive a notification with no sound."""
reply_to_message_id: Optional[int] = None
"""If the message is a reply, ID of the original message"""
allow_sending_without_reply: Optional[bool] = None
"""Pass True, if the message should be sent even if the specified replied-to message is not
found"""
reply_markup: Optional[
Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
] = None
@ -68,6 +75,10 @@ class SendVideo(TelegramMethod[Message]):
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict(exclude={"video", "thumb"})
prepare_parse_mode(
bot, data, parse_mode_property="parse_mode", entities_property="caption_entities"
)
files: Dict[str, InputFile] = {}
prepare_file(data=data, files=files, name="video", value=self.video)
prepare_file(data=data, files=files, name="thumb", value=self.thumb)

View file

@ -48,6 +48,9 @@ class SendVideoNote(TelegramMethod[Message]):
"""Sends the message silently. Users will receive a notification with no sound."""
reply_to_message_id: Optional[int] = None
"""If the message is a reply, ID of the original message"""
allow_sending_without_reply: Optional[bool] = None
"""Pass True, if the message should be sent even if the specified replied-to message is not
found"""
reply_markup: Optional[
Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
] = None

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
from ..types import (
UNSET,
@ -8,10 +8,11 @@ from ..types import (
InlineKeyboardMarkup,
InputFile,
Message,
MessageEntity,
ReplyKeyboardMarkup,
ReplyKeyboardRemove,
)
from .base import Request, TelegramMethod, prepare_file
from .base import Request, TelegramMethod, prepare_file, prepare_parse_mode
if TYPE_CHECKING: # pragma: no cover
from ..client.bot import Bot
@ -42,12 +43,18 @@ class SendVoice(TelegramMethod[Message]):
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the voice message caption. See formatting options for more
details."""
caption_entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in the caption, which can be specified instead of
parse_mode"""
duration: Optional[int] = None
"""Duration of the voice message in seconds"""
disable_notification: Optional[bool] = None
"""Sends the message silently. Users will receive a notification with no sound."""
reply_to_message_id: Optional[int] = None
"""If the message is a reply, ID of the original message"""
allow_sending_without_reply: Optional[bool] = None
"""Pass True, if the message should be sent even if the specified replied-to message is not
found"""
reply_markup: Optional[
Union[InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply]
] = None
@ -57,6 +64,10 @@ class SendVoice(TelegramMethod[Message]):
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict(exclude={"voice"})
prepare_parse_mode(
bot, data, parse_mode_property="parse_mode", entities_property="caption_entities"
)
files: Dict[str, InputFile] = {}
prepare_file(data=data, files=files, name="voice", value=self.voice)

View file

@ -37,6 +37,9 @@ class SetWebhook(TelegramMethod[bool]):
certificate: Optional[InputFile] = None
"""Upload your public key certificate so that the root certificate in use can be checked. See
our self-signed guide for details."""
ip_address: Optional[str] = None
"""The fixed IP address which will be used to send webhook requests instead of the IP address
resolved through DNS"""
max_connections: Optional[int] = None
"""Maximum allowed number of simultaneous HTTPS connections to the webhook for update
delivery, 1-100. Defaults to 40. Use lower values to limit the load on your bot's server,
@ -47,6 +50,8 @@ class SetWebhook(TelegramMethod[bool]):
these types. See Update for a complete list of available update types. Specify an empty
list to receive all updates regardless of type (default). If not specified, the previous
setting will be used."""
drop_pending_updates: Optional[bool] = None
"""Pass True to drop all pending updates"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict(exclude={"certificate"})

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Union
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
from .base import Request, TelegramMethod
@ -12,7 +12,10 @@ class UnbanChatMember(TelegramMethod[bool]):
"""
Use this method to unban a previously kicked user in a supergroup or channel. The user will
not return to the group or channel automatically, but will be able to join via link, etc. The
bot must be an administrator for this to work. Returns True on success.
bot must be an administrator for this to work. By default, this method guarantees that after
the call the user is not a member of the chat, but will be able to join it. So if the user is
a member of the chat they will also be removed from the chat. If you don't want this, use the
parameter only_if_banned. Returns True on success.
Source: https://core.telegram.org/bots/api#unbanchatmember
"""
@ -24,6 +27,8 @@ class UnbanChatMember(TelegramMethod[bool]):
the format @username)"""
user_id: int
"""Unique identifier of the target user"""
only_if_banned: Optional[bool] = None
"""Do nothing if the user is not banned"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()

View file

@ -0,0 +1,30 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Union
from .base import Request, TelegramMethod
if TYPE_CHECKING: # pragma: no cover
from ..client.bot import Bot
class UnpinAllChatMessages(TelegramMethod[bool]):
"""
Use this method to clear the list of pinned messages in a chat. If the chat is not a private
chat, the bot must be an administrator in the chat for this to work and must have the
'can_pin_messages' admin right in a supergroup or 'can_edit_messages' admin right in a
channel. Returns True on success.
Source: https://core.telegram.org/bots/api#unpinallchatmessages
"""
__returning__ = bool
chat_id: Union[int, str]
"""Unique identifier for the target chat or username of the target channel (in the format
@channelusername)"""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()
return Request(method="unpinAllChatMessages", data=data)

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Dict, Union
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
from .base import Request, TelegramMethod
@ -10,9 +10,10 @@ if TYPE_CHECKING: # pragma: no cover
class UnpinChatMessage(TelegramMethod[bool]):
"""
Use this method to unpin a message in a group, a supergroup, or a channel. The bot must be an
administrator in the chat for this to work and must have the 'can_pin_messages' admin right in
the supergroup or 'can_edit_messages' admin right in the channel. Returns True on success.
Use this method to remove a message from the list of pinned messages in a chat. If the chat is
not a private chat, the bot must be an administrator in the chat for this to work and must
have the 'can_pin_messages' admin right in a supergroup or 'can_edit_messages' admin right in
a channel. Returns True on success.
Source: https://core.telegram.org/bots/api#unpinchatmessage
"""
@ -22,6 +23,9 @@ class UnpinChatMessage(TelegramMethod[bool]):
chat_id: Union[int, str]
"""Unique identifier for the target chat or username of the target channel (in the format
@channelusername)"""
message_id: Optional[int] = None
"""Identifier of a message to unpin. If not specified, the most recent pinned message (by
sending date) will be unpinned."""
def build_request(self, bot: Bot) -> Request:
data: Dict[str, Any] = self.dict()

View file

@ -5,12 +5,13 @@ from .bot_command import BotCommand
from .callback_game import CallbackGame
from .callback_query import CallbackQuery
from .chat import Chat
from .chat_location import ChatLocation
from .chat_member import ChatMember
from .chat_permissions import ChatPermissions
from .chat_photo import ChatPhoto
from .chosen_inline_result import ChosenInlineResult
from .contact import Contact
from .dice import Dice, DiceEmoji
from .dice import Dice
from .document import Document
from .downloadable import Downloadable
from .encrypted_credentials import EncryptedCredentials
@ -64,6 +65,7 @@ from .login_url import LoginUrl
from .mask_position import MaskPosition
from .message import ContentType, Message
from .message_entity import MessageEntity
from .message_id import MessageId
from .order_info import OrderInfo
from .passport_data import PassportData
from .passport_element_error import PassportElementError
@ -82,6 +84,7 @@ from .poll import Poll
from .poll_answer import PollAnswer
from .poll_option import PollOption
from .pre_checkout_query import PreCheckoutQuery
from .proximity_alert_triggered import ProximityAlertTriggered
from .reply_keyboard_markup import ReplyKeyboardMarkup
from .reply_keyboard_remove import ReplyKeyboardRemove
from .response_parameters import ResponseParameters
@ -113,22 +116,23 @@ __all__ = (
"Chat",
"Message",
"ContentType",
"MessageId",
"MessageEntity",
"PhotoSize",
"Animation",
"Audio",
"Document",
"Video",
"Animation",
"Voice",
"VideoNote",
"Voice",
"Contact",
"Location",
"Venue",
"Dice",
"PollOption",
"PollAnswer",
"Poll",
"Dice",
"DiceEmoji",
"Location",
"Venue",
"ProximityAlertTriggered",
"UserProfilePhotos",
"File",
"ReplyKeyboardMarkup",
@ -143,6 +147,7 @@ __all__ = (
"ChatPhoto",
"ChatMember",
"ChatPermissions",
"ChatLocation",
"BotCommand",
"ResponseParameters",
"InputMedia",

View file

@ -26,6 +26,8 @@ class Audio(TelegramObject):
"""Performer of the audio as defined by sender or by audio tags"""
title: Optional[str] = None
"""Title of the audio as defined by sender or by audio tags"""
file_name: Optional[str] = None
"""Original filename as defined by sender"""
mime_type: Optional[str] = None
"""MIME type of the file as defined by sender"""
file_size: Optional[int] = None

View file

@ -5,6 +5,7 @@ from typing import TYPE_CHECKING, Optional
from .base import TelegramObject
if TYPE_CHECKING: # pragma: no cover
from .chat_location import ChatLocation
from .chat_permissions import ChatPermissions
from .chat_photo import ChatPhoto
from .message import Message
@ -34,6 +35,8 @@ class Chat(TelegramObject):
"""Last name of the other party in a private chat"""
photo: Optional[ChatPhoto] = None
"""Chat photo. Returned only in getChat."""
bio: Optional[str] = None
"""Bio of the other party in a private chat. Returned only in getChat."""
description: Optional[str] = None
"""Description, for groups, supergroups and channel chats. Returned only in getChat."""
invite_link: Optional[str] = None
@ -41,7 +44,7 @@ class Chat(TelegramObject):
generates their own invite links, so the bot must first generate the link using
exportChatInviteLink. Returned only in getChat."""
pinned_message: Optional[Message] = None
"""Pinned message, for groups, supergroups and channels. Returned only in getChat."""
"""The most recent pinned message (by sending date). Returned only in getChat."""
permissions: Optional[ChatPermissions] = None
"""Default chat member permissions, for groups and supergroups. Returned only in getChat."""
slow_mode_delay: Optional[int] = None
@ -51,3 +54,12 @@ class Chat(TelegramObject):
"""For supergroups, name of group sticker set. Returned only in getChat."""
can_set_sticker_set: Optional[bool] = None
"""True, if the bot can change the group sticker set. Returned only in getChat."""
linked_chat_id: Optional[int] = None
"""Unique identifier for the linked chat, i.e. the discussion group identifier for a channel
and vice versa; for supergroups and channel chats. This identifier may be greater than 32
bits and some programming languages may have difficulty/silent defects in interpreting it.
But it is smaller than 52 bits, so a signed 64 bit integer or double-precision float type
are safe for storing this identifier. Returned only in getChat."""
location: Optional[ChatLocation] = None
"""For supergroups, the location to which the supergroup is connected. Returned only in
getChat."""

View file

@ -0,0 +1,21 @@
from __future__ import annotations
from typing import TYPE_CHECKING
from .base import TelegramObject
if TYPE_CHECKING: # pragma: no cover
from .location import Location
class ChatLocation(TelegramObject):
"""
Represents a location to which a chat is connected.
Source: https://core.telegram.org/bots/api#chatlocation
"""
location: Location
"""The location to which the supergroup is connected. Can't be a live location."""
address: str
"""Location address; 1-64 characters, as defined by the chat owner"""

View file

@ -24,8 +24,8 @@ class ChatMember(TelegramObject):
'left' or 'kicked'"""
custom_title: Optional[str] = None
"""Owner and administrators only. Custom title for this user"""
until_date: Optional[Union[datetime.datetime, datetime.timedelta, int]] = None
"""Restricted and kicked only. Date when restrictions will be lifted for this user; unix time"""
is_anonymous: Optional[bool] = None
"""Owner and administrators only. True, if the user's presence in the chat is hidden"""
can_be_edited: Optional[bool] = None
"""Administrators only. True, if the bot is allowed to edit administrator privileges of that
user"""
@ -66,6 +66,8 @@ class ChatMember(TelegramObject):
inline bots"""
can_add_web_page_previews: Optional[bool] = None
"""Restricted only. True, if the user is allowed to add web page previews to their messages"""
until_date: Optional[Union[datetime.datetime, datetime.timedelta, int]] = None
"""Restricted and kicked only. Date when restrictions will be lifted for this user; unix time"""
@property
def is_chat_admin(self) -> bool:

View file

@ -13,7 +13,8 @@ class Dice(TelegramObject):
emoji: str
"""Emoji on which the dice throw animation is based"""
value: int
"""Value of the dice, 1-6 for '' and '' base emoji, 1-5 for '' base emoji"""
"""Value of the dice, 1-6 for '' and '' base emoji, 1-5 for '' and '' base emoji, 1-64 for ''
base emoji"""
class DiceEmoji:

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Optional
from typing import TYPE_CHECKING, List, Optional
from pydantic import Field
@ -10,6 +10,7 @@ from .inline_query_result import InlineQueryResult
if TYPE_CHECKING: # pragma: no cover
from .inline_keyboard_markup import InlineKeyboardMarkup
from .input_message_content import InputMessageContent
from .message_entity import MessageEntity
class InlineQueryResultAudio(InlineQueryResult):
@ -35,6 +36,9 @@ class InlineQueryResultAudio(InlineQueryResult):
"""Caption, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the audio caption. See formatting options for more details."""
caption_entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in the caption, which can be specified instead of
parse_mode"""
performer: Optional[str] = None
"""Performer"""
audio_duration: Optional[int] = None

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Optional
from typing import TYPE_CHECKING, List, Optional
from pydantic import Field
@ -10,6 +10,7 @@ from .inline_query_result import InlineQueryResult
if TYPE_CHECKING: # pragma: no cover
from .inline_keyboard_markup import InlineKeyboardMarkup
from .input_message_content import InputMessageContent
from .message_entity import MessageEntity
class InlineQueryResultCachedAudio(InlineQueryResult):
@ -33,6 +34,9 @@ class InlineQueryResultCachedAudio(InlineQueryResult):
"""Caption, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the audio caption. See formatting options for more details."""
caption_entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in the caption, which can be specified instead of
parse_mode"""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""Inline keyboard attached to the message"""
input_message_content: Optional[InputMessageContent] = None

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Optional
from typing import TYPE_CHECKING, List, Optional
from pydantic import Field
@ -10,6 +10,7 @@ from .inline_query_result import InlineQueryResult
if TYPE_CHECKING: # pragma: no cover
from .inline_keyboard_markup import InlineKeyboardMarkup
from .input_message_content import InputMessageContent
from .message_entity import MessageEntity
class InlineQueryResultCachedDocument(InlineQueryResult):
@ -37,6 +38,9 @@ class InlineQueryResultCachedDocument(InlineQueryResult):
"""Caption of the document to be sent, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the document caption. See formatting options for more details."""
caption_entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in the caption, which can be specified instead of
parse_mode"""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""Inline keyboard attached to the message"""
input_message_content: Optional[InputMessageContent] = None

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Optional
from typing import TYPE_CHECKING, List, Optional
from pydantic import Field
@ -10,6 +10,7 @@ from .inline_query_result import InlineQueryResult
if TYPE_CHECKING: # pragma: no cover
from .inline_keyboard_markup import InlineKeyboardMarkup
from .input_message_content import InputMessageContent
from .message_entity import MessageEntity
class InlineQueryResultCachedGif(InlineQueryResult):
@ -33,6 +34,9 @@ class InlineQueryResultCachedGif(InlineQueryResult):
"""Caption of the GIF file to be sent, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the caption. See formatting options for more details."""
caption_entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in the caption, which can be specified instead of
parse_mode"""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""Inline keyboard attached to the message"""
input_message_content: Optional[InputMessageContent] = None

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Optional
from typing import TYPE_CHECKING, List, Optional
from pydantic import Field
@ -10,6 +10,7 @@ from .inline_query_result import InlineQueryResult
if TYPE_CHECKING: # pragma: no cover
from .inline_keyboard_markup import InlineKeyboardMarkup
from .input_message_content import InputMessageContent
from .message_entity import MessageEntity
class InlineQueryResultCachedMpeg4Gif(InlineQueryResult):
@ -34,6 +35,9 @@ class InlineQueryResultCachedMpeg4Gif(InlineQueryResult):
"""Caption of the MPEG-4 file to be sent, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the caption. See formatting options for more details."""
caption_entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in the caption, which can be specified instead of
parse_mode"""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""Inline keyboard attached to the message"""
input_message_content: Optional[InputMessageContent] = None

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Optional
from typing import TYPE_CHECKING, List, Optional
from pydantic import Field
@ -10,6 +10,7 @@ from .inline_query_result import InlineQueryResult
if TYPE_CHECKING: # pragma: no cover
from .inline_keyboard_markup import InlineKeyboardMarkup
from .input_message_content import InputMessageContent
from .message_entity import MessageEntity
class InlineQueryResultCachedPhoto(InlineQueryResult):
@ -35,6 +36,9 @@ class InlineQueryResultCachedPhoto(InlineQueryResult):
"""Caption of the photo to be sent, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the photo caption. See formatting options for more details."""
caption_entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in the caption, which can be specified instead of
parse_mode"""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""Inline keyboard attached to the message"""
input_message_content: Optional[InputMessageContent] = None

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Optional
from typing import TYPE_CHECKING, List, Optional
from pydantic import Field
@ -10,6 +10,7 @@ from .inline_query_result import InlineQueryResult
if TYPE_CHECKING: # pragma: no cover
from .inline_keyboard_markup import InlineKeyboardMarkup
from .input_message_content import InputMessageContent
from .message_entity import MessageEntity
class InlineQueryResultCachedVideo(InlineQueryResult):
@ -35,6 +36,9 @@ class InlineQueryResultCachedVideo(InlineQueryResult):
"""Caption of the video to be sent, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the video caption. See formatting options for more details."""
caption_entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in the caption, which can be specified instead of
parse_mode"""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""Inline keyboard attached to the message"""
input_message_content: Optional[InputMessageContent] = None

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Optional
from typing import TYPE_CHECKING, List, Optional
from pydantic import Field
@ -10,6 +10,7 @@ from .inline_query_result import InlineQueryResult
if TYPE_CHECKING: # pragma: no cover
from .inline_keyboard_markup import InlineKeyboardMarkup
from .input_message_content import InputMessageContent
from .message_entity import MessageEntity
class InlineQueryResultCachedVoice(InlineQueryResult):
@ -36,6 +37,9 @@ class InlineQueryResultCachedVoice(InlineQueryResult):
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the voice message caption. See formatting options for more
details."""
caption_entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in the caption, which can be specified instead of
parse_mode"""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""Inline keyboard attached to the message"""
input_message_content: Optional[InputMessageContent] = None

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Optional
from typing import TYPE_CHECKING, List, Optional
from pydantic import Field
@ -10,6 +10,7 @@ from .inline_query_result import InlineQueryResult
if TYPE_CHECKING: # pragma: no cover
from .inline_keyboard_markup import InlineKeyboardMarkup
from .input_message_content import InputMessageContent
from .message_entity import MessageEntity
class InlineQueryResultDocument(InlineQueryResult):
@ -38,6 +39,9 @@ class InlineQueryResultDocument(InlineQueryResult):
"""Caption of the document to be sent, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the document caption. See formatting options for more details."""
caption_entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in the caption, which can be specified instead of
parse_mode"""
description: Optional[str] = None
"""Short description of the result"""
reply_markup: Optional[InlineKeyboardMarkup] = None

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Optional
from typing import TYPE_CHECKING, List, Optional
from pydantic import Field
@ -10,6 +10,7 @@ from .inline_query_result import InlineQueryResult
if TYPE_CHECKING: # pragma: no cover
from .inline_keyboard_markup import InlineKeyboardMarkup
from .input_message_content import InputMessageContent
from .message_entity import MessageEntity
class InlineQueryResultGif(InlineQueryResult):
@ -44,6 +45,9 @@ class InlineQueryResultGif(InlineQueryResult):
"""Caption of the GIF file to be sent, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the caption. See formatting options for more details."""
caption_entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in the caption, which can be specified instead of
parse_mode"""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""Inline keyboard attached to the message"""
input_message_content: Optional[InputMessageContent] = None

View file

@ -32,8 +32,16 @@ class InlineQueryResultLocation(InlineQueryResult):
"""Location longitude in degrees"""
title: str
"""Location title"""
horizontal_accuracy: Optional[float] = None
"""The radius of uncertainty for the location, measured in meters; 0-1500"""
live_period: Optional[int] = None
"""Period in seconds for which the location can be updated, should be between 60 and 86400."""
heading: Optional[int] = None
"""For live locations, a direction in which the user is moving, in degrees. Must be between 1
and 360 if specified."""
proximity_alert_radius: Optional[int] = None
"""For live locations, a maximum distance for proximity alerts about approaching another chat
member, in meters. Must be between 1 and 100000 if specified."""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""Inline keyboard attached to the message"""
input_message_content: Optional[InputMessageContent] = None

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Optional
from typing import TYPE_CHECKING, List, Optional
from pydantic import Field
@ -10,6 +10,7 @@ from .inline_query_result import InlineQueryResult
if TYPE_CHECKING: # pragma: no cover
from .inline_keyboard_markup import InlineKeyboardMarkup
from .input_message_content import InputMessageContent
from .message_entity import MessageEntity
class InlineQueryResultMpeg4Gif(InlineQueryResult):
@ -45,6 +46,9 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult):
"""Caption of the MPEG-4 file to be sent, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the caption. See formatting options for more details."""
caption_entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in the caption, which can be specified instead of
parse_mode"""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""Inline keyboard attached to the message"""
input_message_content: Optional[InputMessageContent] = None

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Optional
from typing import TYPE_CHECKING, List, Optional
from pydantic import Field
@ -10,6 +10,7 @@ from .inline_query_result import InlineQueryResult
if TYPE_CHECKING: # pragma: no cover
from .inline_keyboard_markup import InlineKeyboardMarkup
from .input_message_content import InputMessageContent
from .message_entity import MessageEntity
class InlineQueryResultPhoto(InlineQueryResult):
@ -41,6 +42,9 @@ class InlineQueryResultPhoto(InlineQueryResult):
"""Caption of the photo to be sent, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the photo caption. See formatting options for more details."""
caption_entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in the caption, which can be specified instead of
parse_mode"""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""Inline keyboard attached to the message"""
input_message_content: Optional[InputMessageContent] = None

View file

@ -38,6 +38,10 @@ class InlineQueryResultVenue(InlineQueryResult):
foursquare_type: Optional[str] = None
"""Foursquare type of the venue, if known. (For example, 'arts_entertainment/default',
'arts_entertainment/aquarium' or 'food/icecream'.)"""
google_place_id: Optional[str] = None
"""Google Places identifier of the venue"""
google_place_type: Optional[str] = None
"""Google Places type of the venue. (See supported types.)"""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""Inline keyboard attached to the message"""
input_message_content: Optional[InputMessageContent] = None

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Optional
from typing import TYPE_CHECKING, List, Optional
from pydantic import Field
@ -10,6 +10,7 @@ from .inline_query_result import InlineQueryResult
if TYPE_CHECKING: # pragma: no cover
from .inline_keyboard_markup import InlineKeyboardMarkup
from .input_message_content import InputMessageContent
from .message_entity import MessageEntity
class InlineQueryResultVideo(InlineQueryResult):

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Optional
from typing import TYPE_CHECKING, List, Optional
from pydantic import Field
@ -10,6 +10,7 @@ from .inline_query_result import InlineQueryResult
if TYPE_CHECKING: # pragma: no cover
from .inline_keyboard_markup import InlineKeyboardMarkup
from .input_message_content import InputMessageContent
from .message_entity import MessageEntity
class InlineQueryResultVoice(InlineQueryResult):
@ -37,6 +38,9 @@ class InlineQueryResultVoice(InlineQueryResult):
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the voice message caption. See formatting options for more
details."""
caption_entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in the caption, which can be specified instead of
parse_mode"""
voice_duration: Optional[int] = None
"""Recording duration in seconds"""
reply_markup: Optional[InlineKeyboardMarkup] = None

View file

@ -16,5 +16,13 @@ class InputLocationMessageContent(InputMessageContent):
"""Latitude of the location in degrees"""
longitude: float
"""Longitude of the location in degrees"""
horizontal_accuracy: Optional[float] = None
"""The radius of uncertainty for the location, measured in meters; 0-1500"""
live_period: Optional[int] = None
"""Period in seconds for which the location can be updated, should be between 60 and 86400."""
heading: Optional[int] = None
"""For live locations, a direction in which the user is moving, in degrees. Must be between 1
and 360 if specified."""
proximity_alert_radius: Optional[int] = None
"""For live locations, a maximum distance for proximity alerts about approaching another chat
member, in meters. Must be between 1 and 100000 if specified."""

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Optional, Union
from typing import TYPE_CHECKING, List, Optional, Union
from pydantic import Field
@ -9,6 +9,7 @@ from .input_media import InputMedia
if TYPE_CHECKING: # pragma: no cover
from .input_file import InputFile
from .message_entity import MessageEntity
class InputMediaAnimation(InputMedia):
@ -37,6 +38,9 @@ class InputMediaAnimation(InputMedia):
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the animation caption. See formatting options for more
details."""
caption_entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in the caption, which can be specified instead of
parse_mode"""
width: Optional[int] = None
"""Animation width"""
height: Optional[int] = None

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Optional, Union
from typing import TYPE_CHECKING, List, Optional, Union
from pydantic import Field
@ -9,6 +9,7 @@ from .input_media import InputMedia
if TYPE_CHECKING: # pragma: no cover
from .input_file import InputFile
from .message_entity import MessageEntity
class InputMediaAudio(InputMedia):
@ -36,6 +37,9 @@ class InputMediaAudio(InputMedia):
"""Caption of the audio to be sent, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the audio caption. See formatting options for more details."""
caption_entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in the caption, which can be specified instead of
parse_mode"""
duration: Optional[int] = None
"""Duration of the audio in seconds"""
performer: Optional[str] = None

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Optional, Union
from typing import TYPE_CHECKING, List, Optional, Union
from pydantic import Field
@ -9,6 +9,7 @@ from .input_media import InputMedia
if TYPE_CHECKING: # pragma: no cover
from .input_file import InputFile
from .message_entity import MessageEntity
class InputMediaDocument(InputMedia):
@ -36,3 +37,9 @@ class InputMediaDocument(InputMedia):
"""Caption of the document to be sent, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the document caption. See formatting options for more details."""
caption_entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in the caption, which can be specified instead of
parse_mode"""
disable_content_type_detection: Optional[bool] = None
"""Disables automatic server-side content type detection for files uploaded using
multipart/form-data. Always true, if the document is sent as part of an album."""

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Optional, Union
from typing import TYPE_CHECKING, List, Optional, Union
from pydantic import Field
@ -9,6 +9,7 @@ from .input_media import InputMedia
if TYPE_CHECKING: # pragma: no cover
from .input_file import InputFile
from .message_entity import MessageEntity
class InputMediaPhoto(InputMedia):
@ -29,3 +30,6 @@ class InputMediaPhoto(InputMedia):
"""Caption of the photo to be sent, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the photo caption. See formatting options for more details."""
caption_entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in the caption, which can be specified instead of
parse_mode"""

View file

@ -1,6 +1,6 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Optional, Union
from typing import TYPE_CHECKING, List, Optional, Union
from pydantic import Field
@ -9,6 +9,7 @@ from .input_media import InputMedia
if TYPE_CHECKING: # pragma: no cover
from .input_file import InputFile
from .message_entity import MessageEntity
class InputMediaVideo(InputMedia):
@ -36,6 +37,9 @@ class InputMediaVideo(InputMedia):
"""Caption of the video to be sent, 0-1024 characters after entities parsing"""
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the video caption. See formatting options for more details."""
caption_entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in the caption, which can be specified instead of
parse_mode"""
width: Optional[int] = None
"""Video width"""
height: Optional[int] = None

View file

@ -1,9 +1,9 @@
from __future__ import annotations
from .base import MutableTelegramObject
from .base import TelegramObject
class InputMessageContent(MutableTelegramObject):
class InputMessageContent(TelegramObject):
"""
This object represents the content of a message to be sent as a result of an inline query.
Telegram clients currently support the following 4 types:

View file

@ -1,10 +1,13 @@
from __future__ import annotations
from typing import Optional
from typing import TYPE_CHECKING, List, Optional
from .base import UNSET
from .input_message_content import InputMessageContent
if TYPE_CHECKING: # pragma: no cover
from .message_entity import MessageEntity
class InputTextMessageContent(InputMessageContent):
"""
@ -17,5 +20,8 @@ class InputTextMessageContent(InputMessageContent):
"""Text of the message to be sent, 1-4096 characters"""
parse_mode: Optional[str] = UNSET
"""Mode for parsing entities in the message text. See formatting options for more details."""
entities: Optional[List[MessageEntity]] = None
"""List of special entities that appear in message text, which can be specified instead of
parse_mode"""
disable_web_page_preview: Optional[bool] = None
"""Disables link previews for links in the sent message"""

View file

@ -25,3 +25,7 @@ class InputVenueMessageContent(InputMessageContent):
foursquare_type: Optional[str] = None
"""Foursquare type of the venue, if known. (For example, 'arts_entertainment/default',
'arts_entertainment/aquarium' or 'food/icecream'.)"""
google_place_id: Optional[str] = None
"""Google Places identifier of the venue"""
google_place_type: Optional[str] = None
"""Google Places type of the venue. (See supported types.)"""

View file

@ -1,5 +1,7 @@
from __future__ import annotations
from typing import Optional
from .base import TelegramObject
@ -14,3 +16,13 @@ class Location(TelegramObject):
"""Longitude as defined by sender"""
latitude: float
"""Latitude as defined by sender"""
horizontal_accuracy: Optional[float] = None
"""The radius of uncertainty for the location, measured in meters; 0-1500"""
live_period: Optional[int] = None
"""Time relative to the message sending date, during which the location can be updated, in
seconds. For active live locations only."""
heading: Optional[int] = None
"""The direction in which user is moving, in degrees; 1-360. For active live locations only."""
proximity_alert_radius: Optional[int] = None
"""Maximum distance for proximity alerts about approaching another chat member, in meters. For
sent live locations only."""

View file

@ -30,6 +30,7 @@ if TYPE_CHECKING: # pragma: no cover
from .poll import Poll
from .reply_keyboard_markup import ReplyKeyboardMarkup
from .reply_keyboard_remove import ReplyKeyboardRemove
from .proximity_alert_triggered import ProximityAlertTriggered
from .sticker import Sticker
from .successful_payment import SuccessfulPayment
from .user import User
@ -74,10 +75,15 @@ class Message(TelegramObject):
"""Conversation the message belongs to"""
from_user: Optional[User] = Field(None, alias="from")
"""Sender, empty for messages sent to channels"""
sender_chat: Optional[Chat] = None
"""Sender of the message, sent on behalf of a chat. The channel itself for channel messages.
The supergroup itself for messages from anonymous group administrators. The linked channel
for messages automatically forwarded to the discussion group"""
forward_from: Optional[User] = None
"""For forwarded messages, sender of the original message"""
forward_from_chat: Optional[Chat] = None
"""For messages forwarded from channels, information about the original channel"""
"""For messages forwarded from channels or from anonymous administrators, information about
the original sender chat"""
forward_from_message_id: Optional[int] = None
"""For messages forwarded from channels, identifier of the original message in the channel"""
forward_signature: Optional[str] = None
@ -97,7 +103,8 @@ class Message(TelegramObject):
media_group_id: Optional[str] = None
"""The unique identifier of a media message group this message belongs to"""
author_signature: Optional[str] = None
"""Signature of the post author for messages in channels"""
"""Signature of the post author for messages in channels, or the custom title of an anonymous
group administrator"""
text: Optional[str] = None
"""For text messages, the actual UTF-8 text of the message, 0-4096 characters"""
entities: Optional[List[MessageEntity]] = None
@ -183,6 +190,9 @@ class Message(TelegramObject):
"""The domain name of the website on which the user has logged in."""
passport_data: Optional[PassportData] = None
"""Telegram Passport data"""
proximity_alert_triggered: Optional[ProximityAlertTriggered] = None
"""Service message. A user in the chat triggered another user's proximity alert while sharing
Live Location."""
reply_markup: Optional[InlineKeyboardMarkup] = None
"""Inline keyboard attached to the message. login_url buttons are represented as ordinary url
buttons."""

View file

@ -0,0 +1,14 @@
from __future__ import annotations
from .base import TelegramObject
class MessageId(TelegramObject):
"""
This object represents a unique message identifier.
Source: https://core.telegram.org/bots/api#messageid
"""
message_id: int
"""Unique message identifier"""

View file

@ -0,0 +1,24 @@
from __future__ import annotations
from typing import TYPE_CHECKING
from .base import TelegramObject
if TYPE_CHECKING: # pragma: no cover
from .user import User
class ProximityAlertTriggered(TelegramObject):
"""
This object represents the content of a service message, sent whenever a user in the chat
triggers a proximity alert set by another user.
Source: https://core.telegram.org/bots/api#proximityalerttriggered
"""
traveler: User
"""User that triggered the alert"""
watcher: User
"""User that set the alert"""
distance: int
"""The distance between the users"""

View file

@ -16,7 +16,7 @@ class Venue(TelegramObject):
"""
location: Location
"""Venue location"""
"""Venue location. Can't be a live location"""
title: str
"""Name of the venue"""
address: str
@ -26,3 +26,7 @@ class Venue(TelegramObject):
foursquare_type: Optional[str] = None
"""Foursquare type of the venue. (For example, 'arts_entertainment/default',
'arts_entertainment/aquarium' or 'food/icecream'.)"""
google_place_id: Optional[str] = None
"""Google Places identifier of the venue"""
google_place_type: Optional[str] = None
"""Google Places type of the venue. (See supported types.)"""

View file

@ -28,6 +28,8 @@ class Video(TelegramObject):
"""Duration of the video in seconds as defined by sender"""
thumb: Optional[PhotoSize] = None
"""Video thumbnail"""
file_name: Optional[str] = None
"""Original filename as defined by sender"""
mime_type: Optional[str] = None
"""Mime type of a file as defined by sender"""
file_size: Optional[int] = None

View file

@ -18,6 +18,8 @@ class WebhookInfo(TelegramObject):
"""True, if a custom certificate was provided for webhook certificate checks"""
pending_update_count: int
"""Number of updates awaiting delivery"""
ip_address: Optional[str] = None
"""Currently used webhook IP address"""
last_error_date: Optional[int] = None
"""Unix time for the most recent error that happened when trying to deliver an update via
webhook"""

View file

@ -255,7 +255,7 @@ class Dispatcher(Router):
await asyncio.gather(*coro_list)
finally:
for bot in bots: # Close sessions
await bot.close()
await bot.session.close()
loggers.dispatcher.info("Polling stopped")
await self.emit_shutdown(**workflow_data)