diff --git a/README.rst b/README.rst index 1cf2765d..09072c81 100644 --- a/README.rst +++ b/README.rst @@ -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-4.9-blue.svg?style=flat-square&logo=telegram +.. image:: https://img.shields.io/badge/Telegram%20Bot%20API-5.0-blue.svg?style=flat-square&logo=telegram :target: https://core.telegram.org/bots/api :alt: Telegram Bot API diff --git a/aiogram/__init__.py b/aiogram/__init__.py index e9ba5b53..03d29bf7 100644 --- a/aiogram/__init__.py +++ b/aiogram/__init__.py @@ -43,5 +43,5 @@ __all__ = ( 'utils', ) -__version__ = '2.10.1' -__api_version__ = '4.9' +__version__ = '2.11' +__api_version__ = '5.0' diff --git a/aiogram/bot/api.py b/aiogram/bot/api.py index cb258cdf..03c7e209 100644 --- a/aiogram/bot/api.py +++ b/aiogram/bot/api.py @@ -1,20 +1,57 @@ import logging import os +from dataclasses import dataclass from http import HTTPStatus import aiohttp from .. import types -from ..utils import exceptions -from ..utils import json +from ..utils import exceptions, json from ..utils.helper import Helper, HelperMode, Item # Main aiogram logger log = logging.getLogger('aiogram') -# API Url's -API_URL = "https://api.telegram.org/bot{token}/{method}" -FILE_URL = "https://api.telegram.org/file/bot{token}/{path}" + +@dataclass(frozen=True) +class TelegramAPIServer: + """ + Base config for API Endpoints + """ + + base: str + file: str + + def api_url(self, token: str, method: str) -> str: + """ + Generate URL for API methods + + :param token: Bot token + :param method: API method name (case insensitive) + :return: URL + """ + return self.base.format(token=token, method=method) + + def file_url(self, token: str, path: str) -> str: + """ + Generate URL for downloading files + + :param token: Bot token + :param path: file path + :return: URL + """ + return self.file.format(token=token, path=path) + + @classmethod + def from_base(cls, base: str) -> 'TelegramAPIServer': + base = base.rstrip("/") + return cls( + base=f"{base}/bot{{token}}/{{method}}", + file=f"{base}/file/bot{{token}}/{{method}}", + ) + + +TELEGRAM_PRODUCTION = TelegramAPIServer.from_base("https://api.telegram.org") def check_token(token: str) -> bool: @@ -92,11 +129,10 @@ def check_result(method_name: str, content_type: str, status_code: int, body: st raise exceptions.TelegramAPIError(f"{description} [{status_code}]") -async def make_request(session, token, method, data=None, files=None, **kwargs): - # log.debug(f"Make request: '{method}' with data: {data} and files {files}") +async def make_request(session, server, token, method, data=None, files=None, **kwargs): log.debug('Make request: "%s" with data: "%r" and files "%r"', method, data, files) - url = Methods.api_url(token=token, method=method) + url = server.api_url(token=token, method=method) req = compose_data(data, files) try: @@ -153,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 4.9 + List is updated to Bot API 5.0 """ mode = HelperMode.lowerCamelCase @@ -165,8 +201,11 @@ class Methods(Helper): # Available methods GET_ME = Item() # getMe + LOG_OUT = Item() # logOut + CLOSE = Item() # close SEND_MESSAGE = Item() # sendMessage FORWARD_MESSAGE = Item() # forwardMessage + COPY_MESSAGE = Item() # copyMessage SEND_PHOTO = Item() # sendPhoto SEND_AUDIO = Item() # sendAudio SEND_DOCUMENT = Item() # sendDocument @@ -198,6 +237,7 @@ class Methods(Helper): SET_CHAT_DESCRIPTION = Item() # setChatDescription PIN_CHAT_MESSAGE = Item() # pinChatMessage UNPIN_CHAT_MESSAGE = Item() # unpinChatMessage + UNPIN_ALL_CHAT_MESSAGES = Item() # unpinAllChatMessages LEAVE_CHAT = Item() # leaveChat GET_CHAT = Item() # getChat GET_CHAT_ADMINISTRATORS = Item() # getChatAdministrators @@ -242,25 +282,3 @@ class Methods(Helper): SEND_GAME = Item() # sendGame SET_GAME_SCORE = Item() # setGameScore GET_GAME_HIGH_SCORES = Item() # getGameHighScores - - @staticmethod - def api_url(token, method): - """ - Generate API URL with included token and method name - - :param token: - :param method: - :return: - """ - return API_URL.format(token=token, method=method) - - @staticmethod - def file_url(token, path): - """ - Generate File URL with included token and file path - - :param token: - :param path: - :return: - """ - return FILE_URL.format(token=token, path=path) diff --git a/aiogram/bot/base.py b/aiogram/bot/base.py index f45546c3..07e44c1c 100644 --- a/aiogram/bot/base.py +++ b/aiogram/bot/base.py @@ -12,9 +12,11 @@ import certifi from aiohttp.helpers import sentinel from . import api +from .api import TelegramAPIServer, TELEGRAM_PRODUCTION from ..types import ParseMode, base from ..utils import json from ..utils.auth_widget import check_integrity +from ..utils.deprecated import deprecated class BaseBot: @@ -33,7 +35,8 @@ class BaseBot: proxy_auth: Optional[aiohttp.BasicAuth] = None, validate_token: Optional[base.Boolean] = True, parse_mode: typing.Optional[base.String] = None, - timeout: typing.Optional[typing.Union[base.Integer, base.Float, aiohttp.ClientTimeout]] = None + timeout: typing.Optional[typing.Union[base.Integer, base.Float, aiohttp.ClientTimeout]] = None, + server: TelegramAPIServer = TELEGRAM_PRODUCTION ): """ Instructions how to get Bot token is found here: https://core.telegram.org/bots#3-how-do-i-create-a-bot @@ -54,6 +57,8 @@ class BaseBot: :type parse_mode: :obj:`str` :param timeout: Request timeout :type timeout: :obj:`typing.Optional[typing.Union[base.Integer, base.Float, aiohttp.ClientTimeout]]` + :param server: Telegram Bot API Server endpoint. + :type server: :obj:`TelegramAPIServer` :raise: when token is invalid throw an :obj:`aiogram.utils.exceptions.ValidationError` """ self._main_loop = loop @@ -64,6 +69,7 @@ class BaseBot: self._token = None self.__token = token self.id = int(token.split(sep=':')[0]) + self.server = server self.proxy = proxy self.proxy_auth = proxy_auth @@ -173,6 +179,8 @@ class BaseBot: finally: self._ctx_token.reset(token) + @deprecated("This method's behavior will be changed in aiogram v3.0. " + "More info: https://core.telegram.org/bots/api#close", stacklevel=3) async def close(self): """ Close all client sessions @@ -197,7 +205,7 @@ class BaseBot: :rtype: Union[List, Dict] :raise: :obj:`aiogram.exceptions.TelegramApiError` """ - return await api.make_request(self.session, self.__token, method, data, files, + return await api.make_request(self.session, self.server, self.__token, method, data, files, proxy=self.proxy, proxy_auth=self.proxy_auth, timeout=self.timeout, **kwargs) async def download_file(self, file_path: base.String, @@ -237,7 +245,7 @@ class BaseBot: return dest def get_file_url(self, file_path): - return api.Methods.file_url(token=self.__token, path=file_path) + return self.server.file_url(token=self.__token, path=file_path) async def send_file(self, file_type, method, file, payload) -> Union[Dict, base.Boolean]: """ diff --git a/aiogram/bot/bot.py b/aiogram/bot/bot.py index c5678a37..0ac13702 100644 --- a/aiogram/bot/bot.py +++ b/aiogram/bot/bot.py @@ -7,6 +7,8 @@ import warnings from .base import BaseBot, api from .. import types from ..types import base +from ..utils.deprecated import deprecated +from ..utils.exceptions import ValidationError from ..utils.mixins import DataMixin, ContextInstanceMixin from ..utils.payload import generate_payload, prepare_arg, prepare_attachment, prepare_file @@ -64,9 +66,9 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): # === Getting updates === # https://core.telegram.org/bots/api#getting-updates - async def get_updates(self, offset: typing.Union[base.Integer, None] = None, - limit: typing.Union[base.Integer, None] = None, - timeout: typing.Union[base.Integer, None] = None, + async def get_updates(self, offset: typing.Optional[base.Integer] = None, + limit: typing.Optional[base.Integer] = None, + timeout: typing.Optional[base.Integer] = None, allowed_updates: typing.Union[typing.List[base.String], None] = None) -> typing.List[types.Update]: """ @@ -79,11 +81,11 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): Source: https://core.telegram.org/bots/api#getupdates :param offset: Identifier of the first update to be returned - :type offset: :obj:`typing.Union[base.Integer, None]` + :type offset: :obj:`typing.Optional[base.Integer]` :param limit: Limits the number of updates to be retrieved - :type limit: :obj:`typing.Union[base.Integer, None]` + :type limit: :obj:`typing.Optional[base.Integer]` :param timeout: Timeout in seconds for long polling - :type timeout: :obj:`typing.Union[base.Integer, None]` + :type timeout: :obj:`typing.Optional[base.Integer]` :param allowed_updates: List the types of updates you want your bot to receive :type allowed_updates: :obj:`typing.Union[typing.List[base.String], None]` :return: An Array of Update objects is returned @@ -95,27 +97,61 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): result = await self.request(api.Methods.GET_UPDATES, payload) return [types.Update(**update) for update in result] - async def set_webhook(self, url: base.String, - certificate: typing.Union[base.InputFile, None] = None, - max_connections: typing.Union[base.Integer, None] = None, - allowed_updates: typing.Union[typing.List[base.String], None] = None) -> base.Boolean: + async def set_webhook(self, + url: base.String, + certificate: typing.Optional[base.InputFile] = None, + ip_address: typing.Optional[base.String] = None, + max_connections: typing.Optional[base.Integer] = None, + allowed_updates: typing.Optional[typing.List[base.String]] = None, + drop_pending_updates: typing.Optional[base.Boolean] = None, + ) -> base.Boolean: """ - Use this method to specify a url and receive incoming updates via an outgoing webhook. - Whenever there is an update for the bot, we will send an HTTPS POST request to the specified url, - containing a JSON-serialized Update. In case of an unsuccessful request, - we will give up after a reasonable amount of attempts. + Use this method to specify a url and receive incoming updates via an outgoing + webhook. Whenever there is an update for the bot, we will send an HTTPS POST + request to the specified url, containing a JSON-serialized Update. In case + of an unsuccessful request, we will give up after a reasonable amount of + attempts. Returns True on success. + + If you'd like to make sure that the Webhook request comes from Telegram, + we recommend using a secret path in the URL, e.g. + `https://www.example.com/`. + Since nobody else knows your bot's token, you can be pretty sure it's us. Source: https://core.telegram.org/bots/api#setwebhook - :param url: HTTPS url to send updates to. Use an empty string to remove webhook integration + :param url: HTTPS url to send updates to. Use an empty string to remove + webhook integration :type url: :obj:`base.String` - :param certificate: Upload your public key certificate so that the root certificate in use can be checked - :type certificate: :obj:`typing.Union[base.InputFile, None]` - :param max_connections: Maximum allowed number of simultaneous HTTPS connections to the webhook - for update delivery, 1-100. - :type max_connections: :obj:`typing.Union[base.Integer, None]` - :param allowed_updates: List the types of updates you want your bot to receive - :type allowed_updates: :obj:`typing.Union[typing.List[base.String], None]` + + :param certificate: Upload your public key certificate so that the root + certificate in use can be checked. See our self-signed guide for details: + https://core.telegram.org/bots/self-signed + :type certificate: :obj:`typing.Optional[base.InputFile]` + + :param ip_address: The fixed IP address which will be used to send webhook + requests instead of the IP address resolved through DNS + :type ip_address: :obj:`typing.Optional[base.String]` + + :param max_connections: 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, and higher + values to increase your bot's throughput. + :type max_connections: :obj:`typing.Optional[base.Integer]` + + :param allowed_updates: A list of the update types you want your bot to + receive. For example, specify [“message”, “edited_channel_post”, + “callback_query”] to only receive updates of 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. + Please note that this parameter doesn't affect updates created before the + call to the setWebhook, so unwanted updates may be received for a short + period of time. + :type allowed_updates: :obj:`typing.Optional[typing.List[base.String]]` + + :param drop_pending_updates: Pass True to drop all pending updates + :type drop_pending_updates: :obj:`typing.Optional[base.Boolean]` + :return: Returns true :rtype: :obj:`base.Boolean` """ @@ -128,13 +164,18 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): result = await self.request(api.Methods.SET_WEBHOOK, payload, files) return result - async def delete_webhook(self) -> base.Boolean: + async def delete_webhook(self, + drop_pending_updates: typing.Optional[base.Boolean] = None, + ) -> base.Boolean: """ - Use this method to remove webhook integration if you decide to switch back to getUpdates. - Returns True on success. Requires no parameters. + Use this method to remove webhook integration if you decide to switch back + to getUpdates. Returns True on success. Source: https://core.telegram.org/bots/api#deletewebhook + :param drop_pending_updates: Pass True to drop all pending updates + :type drop_pending_updates: :obj:`typing.Optional[base.Boolean]` + :return: Returns True on success :rtype: :obj:`base.Boolean` """ @@ -176,15 +217,57 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): result = await self.request(api.Methods.GET_ME, payload) return types.User(**result) - async def send_message(self, chat_id: typing.Union[base.Integer, base.String], text: base.String, - parse_mode: typing.Union[base.String, None] = None, - disable_web_page_preview: typing.Union[base.Boolean, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, - reply_to_message_id: typing.Union[base.Integer, None] = None, + async def log_out(self) -> base.Boolean: + """ + 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 will not be able to log in again using the + same token for 10 minutes. Returns True on success. Requires no parameters. + + Source: https://core.telegram.org/bots/api#logout + + :return: Returns True on success + :rtype: :obj:`base.Boolean` + """ + payload = generate_payload(**locals()) + + result = await self.request(api.Methods.LOG_OUT, payload) + return result + + @deprecated("This method will be renamed to `close` in aiogram v3.0") + async def close_bot(self) -> base.Boolean: + """ + 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 + + :return: Returns True on success + :rtype: :obj:`base.Boolean` + """ + payload = generate_payload(**locals()) + + result = await self.request(api.Methods.CLOSE, payload) + return result + + async def send_message(self, + chat_id: typing.Union[base.Integer, base.String], + text: base.String, + parse_mode: typing.Optional[base.String] = None, + entities: typing.Optional[typing.List[types.MessageEntity]] = None, + disable_web_page_preview: typing.Optional[base.Boolean] = None, + 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.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, - types.ForceReply, None] = None) -> types.Message: + types.ForceReply, None] = None, + ) -> types.Message: """ Use this method to send text messages. @@ -192,21 +275,36 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :param chat_id: Unique identifier for the target chat or username of the target channel :type chat_id: :obj:`typing.Union[base.Integer, base.String]` + :param text: Text of the message to be sent :type text: :obj:`base.String` + :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. - :type parse_mode: :obj:`typing.Union[base.String, None]` + :type parse_mode: :obj:`typing.Optional[base.String]` + + :param entities: List of special entities that appear in message text, + which can be specified instead of parse_mode + :type entities: :obj:`typing.Optional[typing.List[types.MessageEntity]]` + :param disable_web_page_preview: Disables link previews for links in this message - :type disable_web_page_preview: :obj:`typing.Union[base.Boolean, None]` + :type disable_web_page_preview: :obj:`typing.Optional[base.Boolean]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + :param reply_to_message_id: If the message is a reply, ID of the original message - :type reply_to_message_id: :obj:`typing.Union[base.Integer, None]` + :type reply_to_message_id: :obj:`typing.Optional[base.Integer]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + :return: On success, the sent Message is returned :rtype: :obj:`types.Message` """ @@ -221,7 +319,7 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): async def forward_message(self, chat_id: typing.Union[base.Integer, base.String], from_chat_id: typing.Union[base.Integer, base.String], message_id: base.Integer, - disable_notification: typing.Union[base.Boolean, None] = None) -> types.Message: + disable_notification: typing.Optional[base.Boolean] = None) -> types.Message: """ Use this method to forward messages of any kind. @@ -232,7 +330,7 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :param from_chat_id: Unique identifier for the chat where the original message was sent :type from_chat_id: :obj:`typing.Union[base.Integer, base.String]` :param disable_notification: Sends the message silently. Users will receive a notification with no sound - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` :param message_id: Message identifier in the chat specified in from_chat_id :type message_id: :obj:`base.Integer` :return: On success, the sent Message is returned @@ -243,16 +341,97 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): result = await self.request(api.Methods.FORWARD_MESSAGE, payload) return types.Message(**result) - async def send_photo(self, chat_id: typing.Union[base.Integer, base.String], + async def copy_message(self, + chat_id: typing.Union[base.Integer, base.String], + from_chat_id: typing.Union[base.Integer, base.String], + message_id: base.Integer, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[types.MessageEntity]] = None, + 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.Union[types.InlineKeyboardMarkup, + types.ReplyKeyboardMarkup, + types.ReplyKeyboardRemove, + types.ForceReply, None] = None, + ) -> types.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 + + :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 from_chat_id: Unique identifier for the chat where the original + message was sent (or channel username in the format @channelusername) + :type from_chat_id: :obj:`typing.Union[base.Integer, base.String]` + + :param message_id: Message identifier in the chat specified in from_chat_id + :type message_id: :obj:`base.Integer` + + :param caption: New caption for media, 0-1024 characters after entities + parsing. If not specified, the original caption is kept + :type caption: :obj:`typing.Optional[base.String]` + + :param parse_mode: Mode for parsing entities in the new caption. See + formatting options for more details: + https://core.telegram.org/bots/api#formatting-options + :type parse_mode: :obj:`typing.Optional[base.String]` + + :param caption_entities: List of special entities that appear in the new + caption, which can be specified instead of parse_mode + :type caption_entities: :obj:`typing.Optional[typing.List[types.MessageEntity]]` + + :param disable_notification: Sends the message silently. Users will receive + a notification with no sound + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param reply_to_message_id: If the message is a reply, ID of the original + message + :type reply_to_message_id: :obj:`typing.Optional[base.Integer]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + + :param reply_markup: 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. + :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, + types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, + None]` + + :return: On success, the sent Message is returned + :rtype: :obj:`types.Message` + """ + reply_markup = prepare_arg(reply_markup) + payload = generate_payload(**locals()) + + if self.parse_mode: + payload.setdefault('parse_mode', self.parse_mode) + + result = await self.request(api.Methods.COPY_MESSAGE, payload) + return types.MessageId(**result) + + async def send_photo(self, + chat_id: typing.Union[base.Integer, base.String], photo: typing.Union[base.InputFile, base.String], - caption: typing.Union[base.String, None] = None, - parse_mode: typing.Union[base.String, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, - reply_to_message_id: typing.Union[base.Integer, None] = None, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[types.MessageEntity]] = None, + 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.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, - types.ForceReply, None] = None) -> types.Message: + types.ForceReply, None] = None, + ) -> types.Message: """ Use this method to send photos. @@ -260,21 +439,36 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :param chat_id: Unique identifier for the target chat or username of the target channel :type chat_id: :obj:`typing.Union[base.Integer, base.String]` + :param photo: Photo to send :type photo: :obj:`typing.Union[base.InputFile, base.String]` + :param caption: Photo caption (may also be used when resending photos by file_id), 0-1024 characters - :type caption: :obj:`typing.Union[base.String, None]` + :type caption: :obj:`typing.Optional[base.String]` + :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. - :type parse_mode: :obj:`typing.Union[base.String, None]` + :type parse_mode: :obj:`typing.Optional[base.String]` + + :param caption_entities: List of special entities that appear in message text, + which can be specified instead of parse_mode + :type caption_entities: :obj:`typing.Optional[typing.List[types.MessageEntity]]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + :param reply_to_message_id: If the message is a reply, ID of the original message - :type reply_to_message_id: :obj:`typing.Union[base.Integer, None]` + :type reply_to_message_id: :obj:`typing.Optional[base.Integer]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + :return: On success, the sent Message is returned :rtype: :obj:`types.Message` """ @@ -289,20 +483,24 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): result = await self.request(api.Methods.SEND_PHOTO, payload, files) return types.Message(**result) - async def send_audio(self, chat_id: typing.Union[base.Integer, base.String], + async def send_audio(self, + chat_id: typing.Union[base.Integer, base.String], audio: typing.Union[base.InputFile, base.String], - caption: typing.Union[base.String, None] = None, - parse_mode: typing.Union[base.String, None] = None, - duration: typing.Union[base.Integer, None] = None, - performer: typing.Union[base.String, None] = None, - title: typing.Union[base.String, None] = None, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[types.MessageEntity]] = None, + duration: typing.Optional[base.Integer] = None, + performer: typing.Optional[base.String] = None, + title: typing.Optional[base.String] = None, thumb: typing.Union[base.InputFile, base.String, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, - reply_to_message_id: typing.Union[base.Integer, None] = None, + 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.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, - types.ForceReply, None] = None) -> types.Message: + types.ForceReply, None] = None, + ) -> types.Message: """ Use this method to send audio files, if you want Telegram clients to display them in the music player. Your audio must be in the .mp3 format. @@ -313,29 +511,48 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :param chat_id: Unique identifier for the target chat or username of the target channel :type chat_id: :obj:`typing.Union[base.Integer, base.String]` + :param audio: Audio file to send :type audio: :obj:`typing.Union[base.InputFile, base.String]` + :param caption: Audio caption, 0-1024 characters - :type caption: :obj:`typing.Union[base.String, None]` + :type caption: :obj:`typing.Optional[base.String]` + :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. - :type parse_mode: :obj:`typing.Union[base.String, None]` + :type parse_mode: :obj:`typing.Optional[base.String]` + + :param caption_entities: List of special entities that appear in message text, + which can be specified instead of parse_mode + :type caption_entities: :obj:`typing.Optional[typing.List[types.MessageEntity]]` + :param duration: Duration of the audio in seconds - :type duration: :obj:`typing.Union[base.Integer, None]` + :type duration: :obj:`typing.Optional[base.Integer]` + :param performer: Performer - :type performer: :obj:`typing.Union[base.String, None]` + :type performer: :obj:`typing.Optional[base.String]` + :param title: Track name - :type title: :obj:`typing.Union[base.String, None]` + :type title: :obj:`typing.Optional[base.String]` + :param thumb: Thumbnail of the file sent :type thumb: :obj:`typing.Union[base.InputFile, base.String, None]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + :param reply_to_message_id: If the message is a reply, ID of the original message - :type reply_to_message_id: :obj:`typing.Union[base.Integer, None]` + :type reply_to_message_id: :obj:`typing.Optional[base.Integer]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + :return: On success, the sent Message is returned :rtype: :obj:`types.Message` """ @@ -351,43 +568,75 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): result = await self.request(api.Methods.SEND_AUDIO, payload, files) return types.Message(**result) - async def send_document(self, chat_id: typing.Union[base.Integer, base.String], + async def send_document(self, + chat_id: typing.Union[base.Integer, base.String], document: typing.Union[base.InputFile, base.String], thumb: typing.Union[base.InputFile, base.String, None] = None, - caption: typing.Union[base.String, None] = None, - parse_mode: typing.Union[base.String, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, - reply_to_message_id: typing.Union[base.Integer, None] = None, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[types.MessageEntity]] = None, + disable_content_type_detection: typing.Optional[base.Boolean] = None, + 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.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, - types.ForceReply, None] = None) -> types.Message: + types.ForceReply, + None] = None, + ) -> types.Message: """ - Use this method to send general files. - - Bots can currently send files of any type of up to 50 MB in size, this limit may be changed in the future. + Use this method to send general files. On success, the sent Message is + returned. Bots can currently send files of any type of up to 50 MB in size, + this limit may be changed in the future. Source: https://core.telegram.org/bots/api#senddocument - :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 :type chat_id: :obj:`typing.Union[base.Integer, base.String]` + :param document: File to send :type document: :obj:`typing.Union[base.InputFile, base.String]` + :param thumb: Thumbnail of the file sent :type thumb: :obj:`typing.Union[base.InputFile, base.String, None]` - :param caption: Document caption (may also be used when resending documents by file_id), 0-1024 characters - :type caption: :obj:`typing.Union[base.String, None]` - :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show bold, italic, - fixed-width text or inline URLs in your bot's message. - :type parse_mode: :obj:`typing.Union[base.String, None]` - :param disable_notification: Sends the message silently. Users will receive a notification with no sound - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` - :param reply_to_message_id: If the message is a reply, ID of the original message - :type reply_to_message_id: :obj:`typing.Union[base.Integer, None]` - :param reply_markup: 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 - :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, - types.ReplyKeyboardRemove, types.ForceReply], None]` + + :param caption: Document caption (may also be used when resending documents + by file_id), 0-1024 characters + :type caption: :obj:`typing.Optional[base.String]` + + :param disable_content_type_detection: Disables automatic server-side content + type detection for files uploaded using multipart/form-data + :type disable_content_type_detection: :obj:`typing.Optional[base.Boolean]` + + :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show + bold, italic, fixed-width text or inline URLs in your bot's message. + :type parse_mode: :obj:`typing.Optional[base.String]` + + :param caption_entities: List of special entities that appear in message text, + which can be specified instead of parse_mode + :type caption_entities: :obj:`typing.Optional[typing.List[types.MessageEntity]]` + + :param disable_notification: Sends the message silently. Users will receive a + notification with no sound + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param reply_to_message_id: If the message is a reply, ID of the original + message + :type reply_to_message_id: :obj:`typing.Optional[base.Integer]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + + :param reply_markup: 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 + :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, + types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply], + None]` + :return: On success, the sent Message is returned :rtype: :obj:`types.Message` """ @@ -405,15 +654,17 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): async def send_video(self, chat_id: typing.Union[base.Integer, base.String], video: typing.Union[base.InputFile, base.String], - duration: typing.Union[base.Integer, None] = None, - width: typing.Union[base.Integer, None] = None, - height: typing.Union[base.Integer, None] = None, + duration: typing.Optional[base.Integer] = None, + width: typing.Optional[base.Integer] = None, + height: typing.Optional[base.Integer] = None, thumb: typing.Union[base.InputFile, base.String, None] = None, - caption: typing.Union[base.String, None] = None, - parse_mode: typing.Union[base.String, None] = None, - supports_streaming: typing.Union[base.Boolean, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, - reply_to_message_id: typing.Union[base.Integer, None] = None, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[types.MessageEntity]] = None, + supports_streaming: typing.Optional[base.Boolean] = None, + 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.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, @@ -426,31 +677,51 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :param chat_id: Unique identifier for the target chat or username of the target channel :type chat_id: :obj:`typing.Union[base.Integer, base.String]` + :param video: Video to send :type video: :obj:`typing.Union[base.InputFile, base.String]` + :param duration: Duration of sent video in seconds - :type duration: :obj:`typing.Union[base.Integer, None]` + :type duration: :obj:`typing.Optional[base.Integer]` + :param width: Video width - :type width: :obj:`typing.Union[base.Integer, None]` + :type width: :obj:`typing.Optional[base.Integer]` + :param height: Video height - :type height: :obj:`typing.Union[base.Integer, None]` + :type height: :obj:`typing.Optional[base.Integer]` + :param thumb: Thumbnail of the file sent :type thumb: :obj:`typing.Union[base.InputFile, base.String, None]` + :param caption: Video caption (may also be used when resending videos by file_id), 0-1024 characters - :type caption: :obj:`typing.Union[base.String, None]` + :type caption: :obj:`typing.Optional[base.String]` + :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. - :type parse_mode: :obj:`typing.Union[base.String, None]` + :type parse_mode: :obj:`typing.Optional[base.String]` + + :param caption_entities: List of special entities that appear in message text, + which can be specified instead of parse_mode + :type caption_entities: :obj:`typing.Optional[typing.List[types.MessageEntity]]` + :param supports_streaming: Pass True, if the uploaded video is suitable for streaming - :type supports_streaming: :obj:`typing.Union[base.Boolean, None]` + :type supports_streaming: :obj:`typing.Optional[base.Boolean]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + :param reply_to_message_id: If the message is a reply, ID of the original message - :type reply_to_message_id: :obj:`typing.Union[base.Integer, None]` + :type reply_to_message_id: :obj:`typing.Optional[base.Integer]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + :return: On success, the sent Message is returned :rtype: :obj:`types.Message` """ @@ -469,18 +740,20 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): async def send_animation(self, chat_id: typing.Union[base.Integer, base.String], animation: typing.Union[base.InputFile, base.String], - duration: typing.Union[base.Integer, None] = None, - width: typing.Union[base.Integer, None] = None, - height: typing.Union[base.Integer, None] = None, + duration: typing.Optional[base.Integer] = None, + width: typing.Optional[base.Integer] = None, + height: typing.Optional[base.Integer] = None, thumb: typing.Union[typing.Union[base.InputFile, base.String], None] = None, - caption: typing.Union[base.String, None] = None, - parse_mode: typing.Union[base.String, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, - reply_to_message_id: typing.Union[base.Integer, None] = None, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[types.MessageEntity]] = None, + 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.Union[typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, - types.ForceReply], None] = None + types.ForceReply], None] = None, ) -> types.Message: """ Use this method to send animation files (GIF or H.264/MPEG-4 AVC video without sound). @@ -493,32 +766,51 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :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 animation: Animation to send. Pass a file_id as String to send an animation that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get an animation from the Internet, or upload a new animation using multipart/form-data :type animation: :obj:`typing.Union[base.InputFile, base.String]` + :param duration: Duration of sent animation in seconds - :type duration: :obj:`typing.Union[base.Integer, None]` + :type duration: :obj:`typing.Optional[base.Integer]` + :param width: Animation width - :type width: :obj:`typing.Union[base.Integer, None]` + :type width: :obj:`typing.Optional[base.Integer]` + :param height: Animation height - :type height: :obj:`typing.Union[base.Integer, None]` + :type height: :obj:`typing.Optional[base.Integer]` + :param thumb: Thumbnail of the file sent. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail‘s width and height should not exceed 320. :type thumb: :obj:`typing.Union[typing.Union[base.InputFile, base.String], None]` + :param caption: Animation caption (may also be used when resending animation by file_id), 0-1024 characters - :type caption: :obj:`typing.Union[base.String, None]` + :type caption: :obj:`typing.Optional[base.String]` + :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption - :type parse_mode: :obj:`typing.Union[base.String, None]` + :type parse_mode: :obj:`typing.Optional[base.String]` + + :param caption_entities: List of special entities that appear in message text, + which can be specified instead of parse_mode + :type caption_entities: :obj:`typing.Optional[typing.List[types.MessageEntity]]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + :param reply_to_message_id: If the message is a reply, ID of the original message - :type reply_to_message_id: :obj:`typing.Union[base.Integer, None]` + :type reply_to_message_id: :obj:`typing.Optional[base.Integer]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply], None]` + :return: On success, the sent Message is returned :rtype: :obj:`types.Message` """ @@ -534,17 +826,21 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): result = await self.request(api.Methods.SEND_ANIMATION, payload, files) return types.Message(**result) - async def send_voice(self, chat_id: typing.Union[base.Integer, base.String], + async def send_voice(self, + chat_id: typing.Union[base.Integer, base.String], voice: typing.Union[base.InputFile, base.String], - caption: typing.Union[base.String, None] = None, - parse_mode: typing.Union[base.String, None] = None, - duration: typing.Union[base.Integer, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, - reply_to_message_id: typing.Union[base.Integer, None] = None, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[types.MessageEntity]] = None, + duration: typing.Optional[base.Integer] = None, + 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.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, - types.ForceReply, None] = None) -> types.Message: + types.ForceReply, None] = None, + ) -> types.Message: """ Use this method to send audio files, if you want Telegram clients to display the file as a playable voice message. @@ -556,23 +852,39 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :param chat_id: Unique identifier for the target chat or username of the target channel :type chat_id: :obj:`typing.Union[base.Integer, base.String]` + :param voice: Audio file to send :type voice: :obj:`typing.Union[base.InputFile, base.String]` + :param caption: Voice message caption, 0-1024 characters - :type caption: :obj:`typing.Union[base.String, None]` + :type caption: :obj:`typing.Optional[base.String]` + :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. - :type parse_mode: :obj:`typing.Union[base.String, None]` + :type parse_mode: :obj:`typing.Optional[base.String]` + + :param caption_entities: List of special entities that appear in message text, + which can be specified instead of parse_mode + :type caption_entities: :obj:`typing.Optional[typing.List[types.MessageEntity]]` + :param duration: Duration of the voice message in seconds - :type duration: :obj:`typing.Union[base.Integer, None]` + :type duration: :obj:`typing.Optional[base.Integer]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + :param reply_to_message_id: If the message is a reply, ID of the original message - :type reply_to_message_id: :obj:`typing.Union[base.Integer, None]` + :type reply_to_message_id: :obj:`typing.Optional[base.Integer]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + :return: On success, the sent Message is returned :rtype: :obj:`types.Message` """ @@ -589,11 +901,12 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): async def send_video_note(self, chat_id: typing.Union[base.Integer, base.String], video_note: typing.Union[base.InputFile, base.String], - duration: typing.Union[base.Integer, None] = None, - length: typing.Union[base.Integer, None] = None, + duration: typing.Optional[base.Integer] = None, + length: typing.Optional[base.Integer] = None, thumb: typing.Union[base.InputFile, base.String, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, - reply_to_message_id: typing.Union[base.Integer, None] = None, + 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.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, @@ -606,22 +919,34 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :param chat_id: Unique identifier for the target chat or username of the target channel :type chat_id: :obj:`typing.Union[base.Integer, base.String]` + :param video_note: Video note to send :type video_note: :obj:`typing.Union[base.InputFile, base.String]` + :param duration: Duration of sent video in seconds - :type duration: :obj:`typing.Union[base.Integer, None]` + :type duration: :obj:`typing.Optional[base.Integer]` + :param length: Video width and height - :type length: :obj:`typing.Union[base.Integer, None]` + :type length: :obj:`typing.Optional[base.Integer]` + :param thumb: Thumbnail of the file sent :type thumb: :obj:`typing.Union[base.InputFile, base.String, None]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + :param reply_to_message_id: If the message is a reply, ID of the original message - :type reply_to_message_id: :obj:`typing.Union[base.Integer, None]` + :type reply_to_message_id: :obj:`typing.Optional[base.Integer]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + :return: On success, the sent Message is returned :rtype: :obj:`types.Message` """ @@ -634,24 +959,41 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): result = await self.request(api.Methods.SEND_VIDEO_NOTE, payload, files) return types.Message(**result) - async def send_media_group(self, chat_id: typing.Union[base.Integer, base.String], + async def send_media_group(self, + chat_id: typing.Union[base.Integer, base.String], media: typing.Union[types.MediaGroup, typing.List], - disable_notification: typing.Union[base.Boolean, None] = None, - reply_to_message_id: typing.Union[base.Integer, - None] = None) -> typing.List[types.Message]: + 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, + ) -> typing.List[types.Message]: """ - Use this method to send a group of photos or videos as an album. + Use this method to send a group of photos, videos, documents or audios as + an album. Documents and audio files can be only group 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 - :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 media: A JSON-serialized array describing photos and videos to be sent + + :param media: A JSON-serialized array describing messages to be sent, must + include 2-10 items :type media: :obj:`typing.Union[types.MediaGroup, typing.List]` - :param disable_notification: Sends the message silently. Users will receive a notification with no sound - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` - :param reply_to_message_id: If the message is a reply, ID of the original message - :type reply_to_message_id: :obj:`typing.Union[base.Integer, None]` + + :param disable_notification: Sends messages silently. Users will receive a + notification with no sound. + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param reply_to_message_id: If the messages are a reply, ID of the original + message + :type reply_to_message_id: :obj:`typing.Optional[base.Integer]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :return: On success, an array of the sent Messages is returned :rtype: typing.List[types.Message] """ @@ -659,6 +1001,10 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): if isinstance(media, list): media = types.MediaGroup(media) + # check MediaGroup quantity + if 2 > len(media.media) > 10: + raise ValidationError("Media group must include 2-10 items") + files = dict(media.get_files()) media = prepare_arg(media) @@ -669,9 +1015,13 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): async def send_location(self, chat_id: typing.Union[base.Integer, base.String], latitude: base.Float, longitude: base.Float, - live_period: typing.Union[base.Integer, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, - reply_to_message_id: typing.Union[base.Integer, None] = None, + horizontal_accuracy: typing.Optional[base.Float] = None, + live_period: typing.Optional[base.Integer] = None, + heading: typing.Optional[base.Integer] = None, + proximity_alert_radius: typing.Optional[base.Integer] = None, + 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.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, @@ -683,20 +1033,44 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :param chat_id: Unique identifier for the target chat or username of the target channel :type chat_id: :obj:`typing.Union[base.Integer, base.String]` + :param latitude: Latitude of the location :type latitude: :obj:`base.Float` + :param longitude: Longitude of the location :type longitude: :obj:`base.Float` + + :param horizontal_accuracy: The radius of uncertainty for the location, + measured in meters; 0-1500 + :type horizontal_accuracy: :obj:`typing.Optional[base.Float]` + :param live_period: Period in seconds for which the location will be updated - :type live_period: :obj:`typing.Union[base.Integer, None]` + :type live_period: :obj:`typing.Optional[base.Integer]` + + :param heading: For live locations, a direction in which the user is moving, + in degrees. Must be between 1 and 360 if specified. + :type heading: :obj:`typing.Optional[base.Integer]` + + :param proximity_alert_radius: For live locations, a maximum distance for + proximity alerts about approaching another chat member, in meters. Must + be between 1 and 100000 if specified. + :type proximity_alert_radius: :obj:`typing.Optional[base.Integer]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + :param reply_to_message_id: If the message is a reply, ID of the original message - :type reply_to_message_id: :obj:`typing.Union[base.Integer, None]` + :type reply_to_message_id: :obj:`typing.Optional[base.Integer]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + :return: On success, the sent Message is returned :rtype: :obj:`types.Message` """ @@ -706,12 +1080,17 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): result = await self.request(api.Methods.SEND_LOCATION, payload) return types.Message(**result) - async def edit_message_live_location(self, latitude: base.Float, longitude: base.Float, + async def edit_message_live_location(self, + latitude: base.Float, + longitude: base.Float, chat_id: typing.Union[base.Integer, base.String, None] = None, - message_id: typing.Union[base.Integer, None] = None, - inline_message_id: typing.Union[base.String, None] = None, - reply_markup: typing.Union[types.InlineKeyboardMarkup, - None] = None) -> types.Message or base.Boolean: + message_id: typing.Optional[base.Integer] = None, + inline_message_id: typing.Optional[base.String] = None, + horizontal_accuracy: typing.Optional[base.Float] = None, + heading: typing.Optional[base.Integer] = None, + proximity_alert_radius: typing.Optional[base.Integer] = None, + reply_markup: typing.Optional[types.InlineKeyboardMarkup] = None, + ) -> types.Message or base.Boolean: """ Use this method to edit live location messages sent by the bot or via the bot (for inline bots). A location can be edited until its live_period expires or editing is explicitly disabled by a call @@ -721,16 +1100,35 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :param chat_id: Required if inline_message_id is not specified :type chat_id: :obj:`typing.Union[base.Integer, base.String, None]` + :param message_id: Required if inline_message_id is not specified. Identifier of the sent message - :type message_id: :obj:`typing.Union[base.Integer, None]` + :type message_id: :obj:`typing.Optional[base.Integer]` + :param inline_message_id: Required if chat_id and message_id are not specified. Identifier of the inline message - :type inline_message_id: :obj:`typing.Union[base.String, None]` + :type inline_message_id: :obj:`typing.Optional[base.String]` + :param latitude: Latitude of new location :type latitude: :obj:`base.Float` + :param longitude: Longitude of new location :type longitude: :obj:`base.Float` + + :param horizontal_accuracy: The radius of uncertainty for the location, + measured in meters; 0-1500 + :type horizontal_accuracy: :obj:`typing.Optional[base.Float]` + + :param heading: Direction in which the user is moving, in degrees. Must be + between 1 and 360 if specified. + :type heading: :obj:`typing.Optional[base.Integer]` + + :param proximity_alert_radius: For live locations, a maximum distance for + proximity alerts about approaching another chat member, in meters. Must + be between 1 and 100000 if specified. + :type proximity_alert_radius: :obj:`typing.Optional[base.Integer]` + :param reply_markup: A JSON-serialized object for a new inline keyboard - :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, None]` + :type reply_markup: :obj:`typing.Optional[types.InlineKeyboardMarkup]` + :return: On success, if the edited message was sent by the bot, the edited Message is returned, otherwise True is returned. :rtype: :obj:`typing.Union[types.Message, base.Boolean]` @@ -745,8 +1143,8 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): async def stop_message_live_location(self, chat_id: typing.Union[base.Integer, base.String, None] = None, - message_id: typing.Union[base.Integer, None] = None, - inline_message_id: typing.Union[base.String, None] = None, + message_id: typing.Optional[base.Integer] = None, + inline_message_id: typing.Optional[base.String] = None, reply_markup: typing.Union[types.InlineKeyboardMarkup, None] = None) -> types.Message or base.Boolean: """ @@ -758,11 +1156,11 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :param chat_id: Required if inline_message_id is not specified :type chat_id: :obj:`typing.Union[base.Integer, base.String, None]` :param message_id: Required if inline_message_id is not specified. Identifier of the sent message - :type message_id: :obj:`typing.Union[base.Integer, None]` + :type message_id: :obj:`typing.Optional[base.Integer]` :param inline_message_id: Required if chat_id and message_id are not specified. Identifier of the inline message - :type inline_message_id: :obj:`typing.Union[base.String, None]` + :type inline_message_id: :obj:`typing.Optional[base.String]` :param reply_markup: A JSON-serialized object for a new inline keyboard - :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, None]` + :type reply_markup: :obj:`typing.Optional[types.InlineKeyboardMarkup]` :return: On success, if the message was sent by the bot, the sent Message is returned, otherwise True is returned. :rtype: :obj:`typing.Union[types.Message, base.Boolean]` @@ -775,44 +1173,77 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): return result return types.Message(**result) - async def send_venue(self, chat_id: typing.Union[base.Integer, base.String], - latitude: base.Float, longitude: base.Float, - title: base.String, address: base.String, - foursquare_id: typing.Union[base.String, None] = None, - foursquare_type: typing.Union[base.String, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, - reply_to_message_id: typing.Union[base.Integer, None] = None, + async def send_venue(self, + chat_id: typing.Union[base.Integer, base.String], + latitude: base.Float, + longitude: base.Float, + title: base.String, + address: base.String, + foursquare_id: typing.Optional[base.String] = None, + foursquare_type: typing.Optional[base.String] = None, + google_place_id: typing.Optional[base.String] = None, + google_place_type: typing.Optional[base.String] = None, + 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.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, - types.ForceReply, None] = None) -> types.Message: + types.ForceReply, None] = None, + ) -> types.Message: """ Use this method to send information about a venue. Source: https://core.telegram.org/bots/api#sendvenue - :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 latitude: Latitude of the venue :type latitude: :obj:`base.Float` + :param longitude: Longitude of the venue :type longitude: :obj:`base.Float` + :param title: Name of the venue :type title: :obj:`base.String` + :param address: Address of the venue :type address: :obj:`base.String` + :param foursquare_id: Foursquare identifier of the venue - :type foursquare_id: :obj:`typing.Union[base.String, None]` + :type foursquare_id: :obj:`typing.Optional[base.String]` + :param foursquare_type: Foursquare type of the venue, if known - :type foursquare_type: :obj:`typing.Union[base.String, None]` - :param disable_notification: Sends the message silently. Users will receive a notification with no sound - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` - :param reply_to_message_id: If the message is a reply, ID of the original message - :type reply_to_message_id: :obj:`typing.Union[base.Integer, None]` - :param reply_markup: 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 + :type foursquare_type: :obj:`typing.Optional[base.String]` + + :param google_place_id: Google Places identifier of the venue + :type google_place_id: :obj:`typing.Optional[base.String]` + + :param google_place_type: Google Places type of the venue. See supported + types: https://developers.google.com/places/web-service/supported_types + :type google_place_type: :obj:`typing.Optional[base.String]` + + :param disable_notification: Sends the message silently. Users will receive + a notification with no sound + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param reply_to_message_id: If the message is a reply, ID of the original + message + :type reply_to_message_id: :obj:`typing.Optional[base.Integer]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, - types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, + None]` + :return: On success, the sent Message is returned :rtype: :obj:`types.Message` """ @@ -824,10 +1255,11 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): async def send_contact(self, chat_id: typing.Union[base.Integer, base.String], phone_number: base.String, first_name: base.String, - last_name: typing.Union[base.String, None] = None, - vcard: typing.Union[base.String, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, - reply_to_message_id: typing.Union[base.Integer, None] = None, + last_name: typing.Optional[base.String] = None, + vcard: typing.Optional[base.String] = None, + 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.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, @@ -839,22 +1271,34 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :param chat_id: Unique identifier for the target chat or username of the target channel :type chat_id: :obj:`typing.Union[base.Integer, base.String]` + :param phone_number: Contact's phone number :type phone_number: :obj:`base.String` + :param first_name: Contact's first name :type first_name: :obj:`base.String` + :param last_name: Contact's last name - :type last_name: :obj:`typing.Union[base.String, None]` + :type last_name: :obj:`typing.Optional[base.String]` + :param vcard: vcard - :type vcard: :obj:`typing.Union[base.String, None]` + :type vcard: :obj:`typing.Optional[base.String]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + :param reply_to_message_id: If the message is a reply, ID of the original message - :type reply_to_message_id: :obj:`typing.Union[base.Integer, None]` + :type reply_to_message_id: :obj:`typing.Optional[base.Integer]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + :return: On success, the sent Message is returned :rtype: :obj:`types.Message` """ @@ -864,7 +1308,8 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): result = await self.request(api.Methods.SEND_CONTACT, payload) return types.Message(**result) - async def send_poll(self, chat_id: typing.Union[base.Integer, base.String], + async def send_poll(self, + chat_id: typing.Union[base.Integer, base.String], question: base.String, options: typing.List[base.String], is_anonymous: typing.Optional[base.Boolean] = None, @@ -873,56 +1318,97 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): correct_option_id: typing.Optional[base.Integer] = None, explanation: typing.Optional[base.String] = None, explanation_parse_mode: typing.Optional[base.String] = None, - open_period: typing.Union[base.Integer, None] = None, + explanation_entities: typing.Optional[typing.List[types.MessageEntity]] = None, + open_period: typing.Optional[base.Integer] = None, close_date: typing.Union[ - base.Integer, datetime.datetime, datetime.timedelta, None] = None, + base.Integer, + datetime.datetime, + datetime.timedelta, + None] = None, is_closed: typing.Optional[base.Boolean] = None, 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.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, - types.ForceReply, None] = None) -> types.Message: + types.ForceReply, None] = None, + ) -> types.Message: """ - Use this method to send a native poll. A native poll can't be sent to a private chat. - On success, the sent Message is returned. + Use this method to send a native poll. On success, the sent Message is + returned. Source: https://core.telegram.org/bots/api#sendpoll - :param chat_id: Unique identifier for the target chat - or username of the target channel (in the format @channelusername). - A native poll can't be sent to a private chat. + :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 question: Poll question, 1-255 characters + + :param question: Poll question, 1-300 characters :type question: :obj:`base.String` - :param options: List of answer options, 2-10 strings 1-100 characters each + + :param options: A list of answer options, 2-10 strings 1-100 characters each :type options: :obj:`typing.List[base.String]` + :param is_anonymous: True, if the poll needs to be anonymous, defaults to True :type is_anonymous: :obj:`typing.Optional[base.Boolean]` + :param type: Poll type, “quiz” or “regular”, defaults to “regular” :type type: :obj:`typing.Optional[base.String]` - :param allows_multiple_answers: True, if the poll allows multiple answers, ignored for polls in quiz mode, defaults to False + + :param allows_multiple_answers: True, if the poll allows multiple answers, + ignored for polls in quiz mode, defaults to False :type allows_multiple_answers: :obj:`typing.Optional[base.Boolean]` - :param correct_option_id: 0-based identifier of the correct answer option, required for polls in quiz mode + + :param correct_option_id: 0-based identifier of the correct answer option, + required for polls in quiz mode :type correct_option_id: :obj:`typing.Optional[base.Integer]` - :param explanation: Text that is shown when a user chooses an incorrect answer or taps on the lamp icon in a quiz-style poll, 0-200 characters with at most 2 line feeds after entities parsing + + :param explanation: Text that is shown when a user chooses an incorrect + answer or taps on the lamp icon in a quiz-style poll, 0-200 characters + with at most 2 line feeds after entities parsing :type explanation: :obj:`typing.Optional[base.String]` - :param explanation_parse_mode: Mode for parsing entities in the explanation. See formatting options for more details. + + :param explanation_parse_mode: Mode for parsing entities in the explanation. + See formatting options for more details. :type explanation_parse_mode: :obj:`typing.Optional[base.String]` - :param open_period: Amount of time in seconds the poll will be active after creation, 5-600. Can't be used together with close_date. - :type open_period: :obj:`typing.Union[base.Integer, None]` - :param close_date: Point in time (Unix timestamp) when the poll will be automatically closed. Must be at least 5 and no more than 600 seconds in the future. Can't be used together with open_period. - :type close_date: :obj:`typing.Union[base.Integer, datetime.datetime, datetime.timedelta, None]` + + :param explanation_entities: List of special entities that appear in message + text, which can be specified instead of parse_mode + :type explanation_entities: :obj:`typing.Optional[typing.List[types.MessageEntity]]` + + :param open_period: Amount of time in seconds the poll will be active after + creation, 5-600. Can't be used together with close_date. + :type open_period: :obj:`typing.Optional[base.Integer]` + + :param close_date: Point in time (Unix timestamp) when the poll will be + automatically closed. Must be at least 5 and no more than 600 seconds in + the future. Can't be used together with open_period. + :type close_date: :obj:`typing.Union[base.Integer, datetime.datetime, + datetime.timedelta, None]` + :param is_closed: Pass True, if the poll needs to be immediately closed :type is_closed: :obj:`typing.Optional[base.Boolean]` - :param disable_notification: Sends the message silently. Users will receive a notification with no sound. + + :param disable_notification: Sends the message silently. Users will receive + a notification with no sound. :type disable_notification: :obj:`typing.Optional[Boolean]` - :param reply_to_message_id: If the message is a reply, ID of the original message + + :param reply_to_message_id: If the message is a reply, ID of the original + message :type reply_to_message_id: :obj:`typing.Optional[Integer]` - :param reply_markup: 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 + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, - types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, + None]` + :return: On success, the sent Message is returned :rtype: :obj:`types.Message` """ @@ -936,34 +1422,50 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): result = await self.request(api.Methods.SEND_POLL, payload) return types.Message(**result) - async def send_dice(self, chat_id: typing.Union[base.Integer, base.String], - disable_notification: typing.Union[base.Boolean, None] = None, - emoji: typing.Union[base.String, None] = None, - reply_to_message_id: typing.Union[base.Integer, None] = None, + async def send_dice(self, + chat_id: typing.Union[base.Integer, base.String], + disable_notification: typing.Optional[base.Boolean] = None, + emoji: typing.Optional[base.String] = None, + reply_to_message_id: typing.Optional[base.Integer] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, - types.ForceReply, None] = None) -> types.Message: + types.ForceReply, None] = None, + ) -> types.Message: """ - Use this method to send a dice, which will have a random value from 1 to 6. + Use this method to send an animated emoji that will display a random value. On success, the sent Message is returned. - (Yes, we're aware of the “proper” singular of die. - But it's awkward, and we decided to help it change. One dice at a time!) Source: https://core.telegram.org/bots/api#senddice - :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 emoji: Emoji on which the dice throw animation is based. Currently, must be one of “🎲” or “🎯”. Defauts to “🎲” - :type emoji: :obj:`typing.Union[base.String, None]` - :param disable_notification: Sends the message silently. Users will receive a notification with no sound - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + + :param emoji: 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 “🎲” + :type emoji: :obj:`typing.Optional[base.String]` + + :param disable_notification: Sends the message silently. Users will receive + a notification with no sound + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + :param reply_to_message_id: If the message is a reply, ID of the original message - :type reply_to_message_id: :obj:`typing.Union[base.Integer, None]` - :param reply_markup: 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 + :type reply_to_message_id: :obj:`typing.Optional[base.Integer]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + :return: On success, the sent Message is returned :rtype: :obj:`types.Message` """ @@ -998,8 +1500,8 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): result = await self.request(api.Methods.SEND_CHAT_ACTION, payload) return result - async def get_user_profile_photos(self, user_id: base.Integer, offset: typing.Union[base.Integer, None] = None, - limit: typing.Union[base.Integer, None] = None) -> types.UserProfilePhotos: + async def get_user_profile_photos(self, user_id: base.Integer, offset: typing.Optional[base.Integer] = None, + limit: typing.Optional[base.Integer] = None) -> types.UserProfilePhotos: """ Use this method to get a list of profile pictures for a user. Returns a UserProfilePhotos object. @@ -1008,9 +1510,9 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :param user_id: Unique identifier of the target user :type user_id: :obj:`base.Integer` :param offset: Sequential number of the first photo to be returned. By default, all photos are returned - :type offset: :obj:`typing.Union[base.Integer, None]` + :type offset: :obj:`typing.Optional[base.Integer]` :param limit: Limits the number of photos to be retrieved. Values between 1—100 are accepted. Defaults to 100 - :type limit: :obj:`typing.Union[base.Integer, None]` + :type limit: :obj:`typing.Optional[base.Integer]` :return: Returns a UserProfilePhotos object :rtype: :obj:`types.UserProfilePhotos` """ @@ -1060,7 +1562,7 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :param user_id: Unique identifier of the target user :type user_id: :obj:`base.Integer` :param until_date: Date when the user will be unbanned, unix time - :type until_date: :obj:`typing.Union[base.Integer, None]` + :type until_date: :obj:`typing.Optional[base.Integer]` :return: Returns True on success :rtype: :obj:`base.Boolean` """ @@ -1070,20 +1572,32 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): result = await self.request(api.Methods.KICK_CHAT_MEMBER, payload) return result - async def unban_chat_member(self, chat_id: typing.Union[base.Integer, base.String], - user_id: base.Integer) -> base.Boolean: + async def unban_chat_member(self, + chat_id: typing.Union[base.Integer, base.String], + user_id: base.Integer, + only_if_banned: typing.Optional[base.Boolean] = None, + ) -> base.Boolean: """ - 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. + 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. 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 - :param chat_id: Unique identifier for the target group or username of the target supergroup or channel + :param chat_id: Unique identifier for the target group or username of the + target supergroup or channel (in the format @username) :type chat_id: :obj:`typing.Union[base.Integer, base.String]` + :param user_id: Unique identifier of the target user :type user_id: :obj:`base.Integer` + + :param only_if_banned: Do nothing if the user is not banned + :type only_if_banned: :obj:`typing.Optional[base.Boolean]` + :return: Returns True on success :rtype: :obj:`base.Boolean` """ @@ -1098,10 +1612,10 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): # permissions argument need to be required after removing other `can_*` arguments until_date: typing.Union[ base.Integer, datetime.datetime, datetime.timedelta, None] = None, - can_send_messages: typing.Union[base.Boolean, None] = None, - can_send_media_messages: typing.Union[base.Boolean, None] = None, - can_send_other_messages: typing.Union[base.Boolean, None] = None, - can_add_web_page_previews: typing.Union[base.Boolean, None] = None) -> base.Boolean: + can_send_messages: typing.Optional[base.Boolean] = None, + can_send_media_messages: typing.Optional[base.Boolean] = None, + can_send_other_messages: typing.Optional[base.Boolean] = None, + can_add_web_page_previews: typing.Optional[base.Boolean] = None) -> base.Boolean: """ Use this method to restrict a user in a supergroup. The bot must be an administrator in the supergroup for this to work and must have the appropriate admin rights. @@ -1116,18 +1630,18 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :param permissions: New user permissions :type permissions: :obj:`ChatPermissions` :param until_date: Date when restrictions will be lifted for the user, unix time - :type until_date: :obj:`typing.Union[base.Integer, None]` + :type until_date: :obj:`typing.Optional[base.Integer]` :param can_send_messages: Pass True, if the user can send text messages, contacts, locations and venues - :type can_send_messages: :obj:`typing.Union[base.Boolean, None]` + :type can_send_messages: :obj:`typing.Optional[base.Boolean]` :param can_send_media_messages: Pass True, if the user can send audios, documents, photos, videos, video notes and voice notes, implies can_send_messages - :type can_send_media_messages: :obj:`typing.Union[base.Boolean, None]` + :type can_send_media_messages: :obj:`typing.Optional[base.Boolean]` :param can_send_other_messages: Pass True, if the user can send animations, games, stickers and use inline bots, implies can_send_media_messages - :type can_send_other_messages: :obj:`typing.Union[base.Boolean, None]` + :type can_send_other_messages: :obj:`typing.Optional[base.Boolean]` :param can_add_web_page_previews: Pass True, if the user may add web page previews to their messages, implies can_send_media_messages - :type can_add_web_page_previews: :obj:`typing.Union[base.Boolean, None]` + :type can_add_web_page_previews: :obj:`typing.Optional[base.Boolean]` :return: Returns True on success :rtype: :obj:`base.Boolean` """ @@ -1148,16 +1662,19 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): result = await self.request(api.Methods.RESTRICT_CHAT_MEMBER, payload) return result - async def promote_chat_member(self, chat_id: typing.Union[base.Integer, base.String], + async def promote_chat_member(self, + chat_id: typing.Union[base.Integer, base.String], user_id: base.Integer, - can_change_info: typing.Union[base.Boolean, None] = None, - can_post_messages: typing.Union[base.Boolean, None] = None, - can_edit_messages: typing.Union[base.Boolean, None] = None, - can_delete_messages: typing.Union[base.Boolean, None] = None, - can_invite_users: typing.Union[base.Boolean, None] = None, - can_restrict_members: typing.Union[base.Boolean, None] = None, - can_pin_messages: typing.Union[base.Boolean, None] = None, - can_promote_members: typing.Union[base.Boolean, None] = None) -> base.Boolean: + is_anonymous: typing.Optional[base.Boolean] = None, + can_change_info: typing.Optional[base.Boolean] = None, + can_post_messages: typing.Optional[base.Boolean] = None, + can_edit_messages: typing.Optional[base.Boolean] = None, + can_delete_messages: typing.Optional[base.Boolean] = None, + can_invite_users: typing.Optional[base.Boolean] = None, + can_restrict_members: typing.Optional[base.Boolean] = None, + can_pin_messages: typing.Optional[base.Boolean] = None, + can_promote_members: typing.Optional[base.Boolean] = None, + ) -> base.Boolean: """ Use this method to promote or demote a user in a supergroup or a channel. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. @@ -1167,26 +1684,39 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :param chat_id: Unique identifier for the target chat or username of the target channel :type chat_id: :obj:`typing.Union[base.Integer, base.String]` + :param user_id: Unique identifier of the target user :type user_id: :obj:`base.Integer` + + :param is_anonymous: Pass True, if the administrator's presence in the chat is hidden + :type is_anonymous: :obj:`typing.Optional[base.Boolean]` + :param can_change_info: Pass True, if the administrator can change chat title, photo and other settings - :type can_change_info: :obj:`typing.Union[base.Boolean, None]` + :type can_change_info: :obj:`typing.Optional[base.Boolean]` + :param can_post_messages: Pass True, if the administrator can create channel posts, channels only - :type can_post_messages: :obj:`typing.Union[base.Boolean, None]` + :type can_post_messages: :obj:`typing.Optional[base.Boolean]` + :param can_edit_messages: Pass True, if the administrator can edit messages of other users, channels only - :type can_edit_messages: :obj:`typing.Union[base.Boolean, None]` + :type can_edit_messages: :obj:`typing.Optional[base.Boolean]` + :param can_delete_messages: Pass True, if the administrator can delete messages of other users - :type can_delete_messages: :obj:`typing.Union[base.Boolean, None]` + :type can_delete_messages: :obj:`typing.Optional[base.Boolean]` + :param can_invite_users: Pass True, if the administrator can invite new users to the chat - :type can_invite_users: :obj:`typing.Union[base.Boolean, None]` + :type can_invite_users: :obj:`typing.Optional[base.Boolean]` + :param can_restrict_members: Pass True, if the administrator can restrict, ban or unban chat members - :type can_restrict_members: :obj:`typing.Union[base.Boolean, None]` + :type can_restrict_members: :obj:`typing.Optional[base.Boolean]` + :param can_pin_messages: Pass True, if the administrator can pin messages, supergroups only - :type can_pin_messages: :obj:`typing.Union[base.Boolean, None]` + :type can_pin_messages: :obj:`typing.Optional[base.Boolean]` + :param can_promote_members: Pass True, if the administrator can add new administrators with a subset of his own privileges or demote administrators that he has promoted, directly or indirectly (promoted by administrators that were appointed by him) - :type can_promote_members: :obj:`typing.Union[base.Boolean, None]` + :type can_promote_members: :obj:`typing.Optional[base.Boolean]` + :return: Returns True on success :rtype: :obj:`base.Boolean` """ @@ -1320,7 +1850,7 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): return result async def set_chat_description(self, chat_id: typing.Union[base.Integer, base.String], - description: typing.Union[base.String, None] = None) -> base.Boolean: + description: typing.Optional[base.String] = None) -> base.Boolean: """ Use this method to change the description of a supergroup or a channel. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. @@ -1330,7 +1860,7 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :param chat_id: Unique identifier for the target chat or username of the target channel :type chat_id: :obj:`typing.Union[base.Integer, base.String]` :param description: New chat description, 0-255 characters - :type description: :obj:`typing.Union[base.String, None]` + :type description: :obj:`typing.Optional[base.String]` :return: Returns True on success :rtype: :obj:`base.Boolean` """ @@ -1339,21 +1869,31 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): result = await self.request(api.Methods.SET_CHAT_DESCRIPTION, payload) return result - async def pin_chat_message(self, chat_id: typing.Union[base.Integer, base.String], message_id: base.Integer, - disable_notification: typing.Union[base.Boolean, None] = None) -> base.Boolean: + async def pin_chat_message(self, + chat_id: typing.Union[base.Integer, base.String], + message_id: base.Integer, + disable_notification: typing.Optional[base.Boolean] = None, + ) -> base.Boolean: """ - Use this method to pin a message in a supergroup. - The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. + 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 - :param chat_id: Unique identifier for the target chat or username of the target supergroup + :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 message_id: Identifier of a message to pin :type message_id: :obj:`base.Integer` - :param disable_notification: Pass True, if it is not necessary to send a notification to - all group members about the new pinned message - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + + :param disable_notification: Pass True, if it is not necessary to send a + notification to all group members about the new pinned message + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + :return: Returns True on success :rtype: :obj:`base.Boolean` """ @@ -1362,15 +1902,27 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): result = await self.request(api.Methods.PIN_CHAT_MESSAGE, payload) return result - async def unpin_chat_message(self, chat_id: typing.Union[base.Integer, base.String]) -> base.Boolean: + async def unpin_chat_message(self, + chat_id: typing.Union[base.Integer, base.String], + message_id: typing.Optional[base.Integer] = None, + ) -> base.Boolean: """ - Use this method to unpin a message in a supergroup chat. - The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. + 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 - :param chat_id: Unique identifier for the target chat or username of the target supergroup + :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 message_id: Identifier of a message to unpin. If not specified, the + most recent pinned message (by sending date) will be unpinned. + :type message_id: :obj:`typing.Optional[base.Integer]` + :return: Returns True on success :rtype: :obj:`base.Boolean` """ @@ -1379,6 +1931,29 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): result = await self.request(api.Methods.UNPIN_CHAT_MESSAGE, payload) return result + async def unpin_all_chat_messages(self, + chat_id: typing.Union[base.Integer, base.String], + ) -> base.Boolean: + """ + 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 + + :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]` + + :return: Returns True on success + :rtype: :obj:`base.Boolean` + """ + payload = generate_payload(**locals()) + + result = await self.request(api.Methods.UNPIN_ALL_CHAT_MESSAGES, payload) + return result + async def leave_chat(self, chat_id: typing.Union[base.Integer, base.String]) -> base.Boolean: """ Use this method for your bot to leave a group, supergroup or channel. @@ -1511,10 +2086,10 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): return result async def answer_callback_query(self, callback_query_id: base.String, - text: typing.Union[base.String, None] = None, - show_alert: typing.Union[base.Boolean, None] = None, - url: typing.Union[base.String, None] = None, - cache_time: typing.Union[base.Integer, None] = None) -> base.Boolean: + text: typing.Optional[base.String] = None, + show_alert: typing.Optional[base.Boolean] = None, + url: typing.Optional[base.String] = None, + cache_time: typing.Optional[base.Integer] = None) -> base.Boolean: """ Use this method to send answers to callback queries sent from inline keyboards. The answer will be displayed to the user as a notification at the top of the chat screen or as an alert. @@ -1528,15 +2103,15 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :param callback_query_id: Unique identifier for the query to be answered :type callback_query_id: :obj:`base.String` :param text: Text of the notification. If not specified, nothing will be shown to the user, 0-1024 characters - :type text: :obj:`typing.Union[base.String, None]` + :type text: :obj:`typing.Optional[base.String]` :param show_alert: If true, an alert will be shown by the client instead of a notification at the top of the chat screen. Defaults to false. - :type show_alert: :obj:`typing.Union[base.Boolean, None]` + :type show_alert: :obj:`typing.Optional[base.Boolean]` :param url: URL that will be opened by the user's client - :type url: :obj:`typing.Union[base.String, None]` + :type url: :obj:`typing.Optional[base.String]` :param cache_time: The maximum amount of time in seconds that the result of the callback query may be cached client-side. - :type cache_time: :obj:`typing.Union[base.Integer, None]` + :type cache_time: :obj:`typing.Optional[base.Integer]` :return: On success, True is returned :rtype: :obj:`base.Boolean` """ @@ -1576,14 +2151,17 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): result = await self.request(api.Methods.GET_MY_COMMANDS, payload) return [types.BotCommand(**bot_command_data) for bot_command_data in result] - async def edit_message_text(self, text: base.String, + async def edit_message_text(self, + text: base.String, chat_id: typing.Union[base.Integer, base.String, None] = None, - message_id: typing.Union[base.Integer, None] = None, - inline_message_id: typing.Union[base.String, None] = None, - parse_mode: typing.Union[base.String, None] = None, - disable_web_page_preview: typing.Union[base.Boolean, None] = None, + message_id: typing.Optional[base.Integer] = None, + inline_message_id: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + entities: typing.Optional[typing.List[types.MessageEntity]] = None, + disable_web_page_preview: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[types.InlineKeyboardMarkup, - None] = None) -> types.Message or base.Boolean: + None] = None, + ) -> types.Message or base.Boolean: """ Use this method to edit text and game messages sent by the bot or via the bot (for inline bots). @@ -1592,19 +2170,30 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :param chat_id: Required if inline_message_id is not specified Unique identifier for the target chat or username of the target channel :type chat_id: :obj:`typing.Union[base.Integer, base.String, None]` + :param message_id: Required if inline_message_id is not specified. Identifier of the sent message - :type message_id: :obj:`typing.Union[base.Integer, None]` + :type message_id: :obj:`typing.Optional[base.Integer]` + :param inline_message_id: Required if chat_id and message_id are not specified. Identifier of the inline message - :type inline_message_id: :obj:`typing.Union[base.String, None]` + :type inline_message_id: :obj:`typing.Optional[base.String]` + :param text: New text of the message :type text: :obj:`base.String` + :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. - :type parse_mode: :obj:`typing.Union[base.String, None]` + :type parse_mode: :obj:`typing.Optional[base.String]` + + :param entities: List of special entities that appear in message text, + which can be specified instead of parse_mode + :type entities: :obj:`typing.Optional[typing.List[types.MessageEntity]]` + :param disable_web_page_preview: Disables link previews for links in this message - :type disable_web_page_preview: :obj:`typing.Union[base.Boolean, None]` + :type disable_web_page_preview: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: A JSON-serialized object for an inline keyboard - :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, None]` + :type reply_markup: :obj:`typing.Optional[types.InlineKeyboardMarkup]` + :return: On success, if edited message is sent by the bot, the edited Message is returned, otherwise True is returned. :rtype: :obj:`typing.Union[types.Message, base.Boolean]` @@ -1620,10 +2209,11 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): return types.Message(**result) async def edit_message_caption(self, chat_id: typing.Union[base.Integer, base.String, None] = None, - message_id: typing.Union[base.Integer, None] = None, - inline_message_id: typing.Union[base.String, None] = None, - caption: typing.Union[base.String, None] = None, - parse_mode: typing.Union[base.String, None] = None, + message_id: typing.Optional[base.Integer] = None, + inline_message_id: typing.Optional[base.String] = None, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[types.MessageEntity]] = None, reply_markup: typing.Union[types.InlineKeyboardMarkup, None] = None) -> types.Message or base.Boolean: """ @@ -1634,17 +2224,27 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :param chat_id: Required if inline_message_id is not specified Unique identifier for the target chat or username of the target channel :type chat_id: :obj:`typing.Union[base.Integer, base.String, None]` + :param message_id: Required if inline_message_id is not specified. Identifier of the sent message - :type message_id: :obj:`typing.Union[base.Integer, None]` + :type message_id: :obj:`typing.Optional[base.Integer]` + :param inline_message_id: Required if chat_id and message_id are not specified. Identifier of the inline message - :type inline_message_id: :obj:`typing.Union[base.String, None]` + :type inline_message_id: :obj:`typing.Optional[base.String]` + :param caption: New caption of the message - :type caption: :obj:`typing.Union[base.String, None]` + :type caption: :obj:`typing.Optional[base.String]` + :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. - :type parse_mode: :obj:`typing.Union[base.String, None]` + :type parse_mode: :obj:`typing.Optional[base.String]` + + :param caption_entities: List of special entities that appear in message text, + which can be specified instead of parse_mode + :type caption_entities: :obj:`typing.Optional[typing.List[types.MessageEntity]]` + :param reply_markup: A JSON-serialized object for an inline keyboard - :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, None]` + :type reply_markup: :obj:`typing.Optional[types.InlineKeyboardMarkup]` + :return: On success, if edited message is sent by the bot, the edited Message is returned, otherwise True is returned. :rtype: :obj:`typing.Union[types.Message, base.Boolean]` @@ -1662,9 +2262,9 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): async def edit_message_media(self, media: types.InputMedia, chat_id: typing.Union[typing.Union[base.Integer, base.String], None] = None, - message_id: typing.Union[base.Integer, None] = None, - inline_message_id: typing.Union[base.String, None] = None, - reply_markup: typing.Union[types.InlineKeyboardMarkup, None] = None, + message_id: typing.Optional[base.Integer] = None, + inline_message_id: typing.Optional[base.String] = None, + reply_markup: typing.Optional[types.InlineKeyboardMarkup] = None, ) -> typing.Union[types.Message, base.Boolean]: """ Use this method to edit audio, document, photo, or video messages. @@ -1681,13 +2281,13 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :param chat_id: Required if inline_message_id is not specified :type chat_id: :obj:`typing.Union[typing.Union[base.Integer, base.String], None]` :param message_id: Required if inline_message_id is not specified. Identifier of the sent message - :type message_id: :obj:`typing.Union[base.Integer, None]` + :type message_id: :obj:`typing.Optional[base.Integer]` :param inline_message_id: Required if chat_id and message_id are not specified. Identifier of the inline message - :type inline_message_id: :obj:`typing.Union[base.String, None]` + :type inline_message_id: :obj:`typing.Optional[base.String]` :param media: A JSON-serialized object for a new media content of the message :type media: :obj:`types.InputMedia` :param reply_markup: A JSON-serialized object for a new inline keyboard - :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, None]` + :type reply_markup: :obj:`typing.Optional[types.InlineKeyboardMarkup]` :return: On success, if the edited message was sent by the bot, the edited Message is returned, otherwise True is returned :rtype: :obj:`typing.Union[types.Message, base.Boolean]` @@ -1707,8 +2307,8 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): async def edit_message_reply_markup(self, chat_id: typing.Union[base.Integer, base.String, None] = None, - message_id: typing.Union[base.Integer, None] = None, - inline_message_id: typing.Union[base.String, None] = None, + message_id: typing.Optional[base.Integer] = None, + inline_message_id: typing.Optional[base.String] = None, reply_markup: typing.Union[types.InlineKeyboardMarkup, None] = None) -> types.Message or base.Boolean: """ @@ -1720,11 +2320,11 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): Unique identifier for the target chat or username of the target channel :type chat_id: :obj:`typing.Union[base.Integer, base.String, None]` :param message_id: Required if inline_message_id is not specified. Identifier of the sent message - :type message_id: :obj:`typing.Union[base.Integer, None]` + :type message_id: :obj:`typing.Optional[base.Integer]` :param inline_message_id: Required if chat_id and message_id are not specified. Identifier of the inline message - :type inline_message_id: :obj:`typing.Union[base.String, None]` + :type inline_message_id: :obj:`typing.Optional[base.String]` :param reply_markup: A JSON-serialized object for an inline keyboard - :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, None]` + :type reply_markup: :obj:`typing.Optional[types.InlineKeyboardMarkup]` :return: On success, if edited message is sent by the bot, the edited Message is returned, otherwise True is returned. :rtype: :obj:`typing.Union[types.Message, base.Boolean]` @@ -1739,7 +2339,7 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): async def stop_poll(self, chat_id: typing.Union[base.String, base.Integer], message_id: base.Integer, - reply_markup: typing.Union[types.InlineKeyboardMarkup, None] = None) -> types.Poll: + reply_markup: typing.Optional[types.InlineKeyboardMarkup] = None) -> types.Poll: """ Use this method to stop a poll which was sent by the bot. On success, the stopped Poll with the final results is returned. @@ -1749,7 +2349,7 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :param message_id: Identifier of the original message with the poll :type message_id: :obj:`base.Integer` :param reply_markup: A JSON-serialized object for a new message inline keyboard. - :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, None]` + :type reply_markup: :obj:`typing.Optional[types.InlineKeyboardMarkup]` :return: On success, the stopped Poll with the final results is returned. :rtype: :obj:`types.Poll` """ @@ -1788,8 +2388,9 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): async def send_sticker(self, chat_id: typing.Union[base.Integer, base.String], sticker: typing.Union[base.InputFile, base.String], - disable_notification: typing.Union[base.Boolean, None] = None, - reply_to_message_id: typing.Union[base.Integer, None] = None, + 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.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, @@ -1801,16 +2402,25 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :param chat_id: Unique identifier for the target chat or username of the target channel :type chat_id: :obj:`typing.Union[base.Integer, base.String]` + :param sticker: Sticker to send :type sticker: :obj:`typing.Union[base.InputFile, base.String]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + :param reply_to_message_id: If the message is a reply, ID of the original message - :type reply_to_message_id: :obj:`typing.Union[base.Integer, None]` + :type reply_to_message_id: :obj:`typing.Optional[base.Integer]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + :return: On success, the sent Message is returned :rtype: :obj:`types.Message` """ @@ -1869,8 +2479,8 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): emojis: base.String, png_sticker: typing.Union[base.InputFile, base.String] = None, tgs_sticker: base.InputFile = None, - contains_masks: typing.Union[base.Boolean, None] = None, - mask_position: typing.Union[types.MaskPosition, None] = None) -> base.Boolean: + contains_masks: typing.Optional[base.Boolean] = None, + mask_position: typing.Optional[types.MaskPosition] = None) -> base.Boolean: """ Use this method to create a new sticker set owned by a user. The bot will be able to edit the sticker set thus created. @@ -1899,9 +2509,9 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :param emojis: One or more emoji corresponding to the sticker :type emojis: :obj:`base.String` :param contains_masks: Pass True, if a set of mask stickers should be created - :type contains_masks: :obj:`typing.Union[base.Boolean, None]` + :type contains_masks: :obj:`typing.Optional[base.Boolean]` :param mask_position: A JSON-serialized object for position where the mask should be placed on faces - :type mask_position: :obj:`typing.Union[types.MaskPosition, None]` + :type mask_position: :obj:`typing.Optional[types.MaskPosition]` :return: Returns True on success :rtype: :obj:`base.Boolean` """ @@ -1921,7 +2531,7 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): emojis: base.String, png_sticker: typing.Union[base.InputFile, base.String] = None, tgs_sticker: base.InputFile = None, - mask_position: typing.Union[types.MaskPosition, None] = None) -> base.Boolean: + mask_position: typing.Optional[types.MaskPosition] = None) -> base.Boolean: """ Use this method to add a new sticker to a set created by the bot. You must use exactly one of the fields png_sticker or tgs_sticker. @@ -1947,7 +2557,7 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :param emojis: One or more emoji corresponding to the sticker :type emojis: :obj:`base.String` :param mask_position: A JSON-serialized object for position where the mask should be placed on faces - :type mask_position: :obj:`typing.Union[types.MaskPosition, None]` + :type mask_position: :obj:`typing.Optional[types.MaskPosition]` :return: Returns True on success :rtype: :obj:`base.Boolean` """ @@ -2030,11 +2640,11 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): async def answer_inline_query(self, inline_query_id: base.String, results: typing.List[types.InlineQueryResult], - cache_time: typing.Union[base.Integer, None] = None, - is_personal: typing.Union[base.Boolean, None] = None, - next_offset: typing.Union[base.String, None] = None, - switch_pm_text: typing.Union[base.String, None] = None, - switch_pm_parameter: typing.Union[base.String, None] = None) -> base.Boolean: + cache_time: typing.Optional[base.Integer] = None, + is_personal: typing.Optional[base.Boolean] = None, + next_offset: typing.Optional[base.String] = None, + switch_pm_text: typing.Optional[base.String] = None, + switch_pm_parameter: typing.Optional[base.String] = None) -> base.Boolean: """ Use this method to send answers to an inline query. No more than 50 results per query are allowed. @@ -2047,22 +2657,22 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :type results: :obj:`typing.List[types.InlineQueryResult]` :param cache_time: The maximum amount of time in seconds that the result of the inline query may be cached on the server. Defaults to 300. - :type cache_time: :obj:`typing.Union[base.Integer, None]` + :type cache_time: :obj:`typing.Optional[base.Integer]` :param is_personal: Pass True, if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any user who sends the same query - :type is_personal: :obj:`typing.Union[base.Boolean, None]` + :type is_personal: :obj:`typing.Optional[base.Boolean]` :param next_offset: Pass the offset that a client should send in the next query with the same text to receive more results. Pass an empty string if there are no more results or if you don‘t support pagination. Offset length can’t exceed 64 bytes. - :type next_offset: :obj:`typing.Union[base.String, None]` + :type next_offset: :obj:`typing.Optional[base.String]` :param switch_pm_text: If passed, clients will display a button with specified text that switches the user to a private chat with the bot and sends the bot a start message with the parameter switch_pm_parameter - :type switch_pm_text: :obj:`typing.Union[base.String, None]` + :type switch_pm_text: :obj:`typing.Optional[base.String]` :param switch_pm_parameter: Deep-linking parameter for the /start message sent to the bot when user presses the switch button. 1-64 characters, only A-Z, a-z, 0-9, _ and - are allowed. - :type switch_pm_parameter: :obj:`typing.Union[base.String, None]` + :type switch_pm_parameter: :obj:`typing.Optional[base.String]` :return: On success, True is returned :rtype: :obj:`base.Boolean` """ @@ -2079,21 +2689,22 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): description: base.String, payload: base.String, provider_token: base.String, start_parameter: base.String, currency: base.String, prices: typing.List[types.LabeledPrice], - provider_data: typing.Union[typing.Dict, None] = None, - photo_url: typing.Union[base.String, None] = None, - photo_size: typing.Union[base.Integer, None] = None, - photo_width: typing.Union[base.Integer, None] = None, - photo_height: typing.Union[base.Integer, None] = None, - need_name: typing.Union[base.Boolean, None] = None, - need_phone_number: typing.Union[base.Boolean, None] = None, - need_email: typing.Union[base.Boolean, None] = None, - need_shipping_address: typing.Union[base.Boolean, None] = None, - send_phone_number_to_provider: typing.Union[base.Boolean, None] = None, - send_email_to_provider: typing.Union[base.Boolean, None] = None, - is_flexible: typing.Union[base.Boolean, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, - reply_to_message_id: typing.Union[base.Integer, None] = None, - reply_markup: typing.Union[types.InlineKeyboardMarkup, None] = None) -> types.Message: + provider_data: typing.Optional[typing.Dict] = 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, + 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: """ Use this method to send invoices. @@ -2101,54 +2712,81 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :param chat_id: Unique identifier for the target private chat :type chat_id: :obj:`base.Integer` + :param title: Product name, 1-32 characters :type title: :obj:`base.String` + :param description: Product description, 1-255 characters :type description: :obj:`base.String` + :param payload: Bot-defined invoice payload, 1-128 bytes This will not be displayed to the user, use for your internal processes. :type payload: :obj:`base.String` + :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` + :param prices: Price breakdown, a list of components (e.g. product price, tax, discount, delivery cost, delivery tax, bonus, etc.) :type prices: :obj:`typing.List[types.LabeledPrice]` + :param provider_data: JSON-encoded data about the invoice, which will be shared with the payment provider - :type provider_data: :obj:`typing.Union[typing.Dict, None]` + :type provider_data: :obj:`typing.Optional[typing.Dict]` + :param photo_url: URL of the product photo for the invoice - :type photo_url: :obj:`typing.Union[base.String, None]` + :type photo_url: :obj:`typing.Optional[base.String]` + :param photo_size: Photo size - :type photo_size: :obj:`typing.Union[base.Integer, None]` + :type photo_size: :obj:`typing.Optional[base.Integer]` + :param photo_width: Photo width - :type photo_width: :obj:`typing.Union[base.Integer, None]` + :type photo_width: :obj:`typing.Optional[base.Integer]` + :param photo_height: Photo height - :type photo_height: :obj:`typing.Union[base.Integer, None]` + :type photo_height: :obj:`typing.Optional[base.Integer]` + :param need_name: Pass True, if you require the user's full name to complete the order - :type need_name: :obj:`typing.Union[base.Boolean, None]` + :type need_name: :obj:`typing.Optional[base.Boolean]` + :param need_phone_number: Pass True, if you require the user's phone number to complete the order - :type need_phone_number: :obj:`typing.Union[base.Boolean, None]` + :type need_phone_number: :obj:`typing.Optional[base.Boolean]` + :param need_email: Pass True, if you require the user's email to complete the order - :type need_email: :obj:`typing.Union[base.Boolean, None]` + :type need_email: :obj:`typing.Optional[base.Boolean]` + :param need_shipping_address: Pass True, if you require the user's shipping address to complete the order - :type need_shipping_address: :obj:`typing.Union[base.Boolean, None]` + :type need_shipping_address: :obj:`typing.Optional[base.Boolean]` + :param send_phone_number_to_provider: Pass True, if user's phone number should be sent to provider - :type send_phone_number_to_provider: :obj:`typing.Union[base.Boolean, None]` + :type send_phone_number_to_provider: :obj:`typing.Optional[base.Boolean]` + :param send_email_to_provider: Pass True, if user's email address should be sent to provider - :type send_email_to_provider: :obj:`typing.Union[base.Boolean, None]` + :type send_email_to_provider: :obj:`typing.Optional[base.Boolean]` + :param is_flexible: Pass True, if the final price depends on the shipping method - :type is_flexible: :obj:`typing.Union[base.Boolean, None]` + :type is_flexible: :obj:`typing.Optional[base.Boolean]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + :param reply_to_message_id: If the message is a reply, ID of the original message - :type reply_to_message_id: :obj:`typing.Union[base.Integer, None]` + :type reply_to_message_id: :obj:`typing.Optional[base.Integer]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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. - :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, None]` + :type reply_markup: :obj:`typing.Optional[types.InlineKeyboardMarkup]` + :return: On success, the sent Message is returned :rtype: :obj:`types.Message` """ @@ -2161,7 +2799,7 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): async def answer_shipping_query(self, shipping_query_id: base.String, ok: base.Boolean, shipping_options: typing.Union[typing.List[types.ShippingOption], None] = None, - error_message: typing.Union[base.String, None] = None) -> base.Boolean: + error_message: typing.Optional[base.String] = None) -> base.Boolean: """ If you sent an invoice requesting a shipping address and the parameter is_flexible was specified, the Bot API will send an Update with a shipping_query field to the bot. @@ -2179,7 +2817,7 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): Error message in human readable form that explains why it is impossible to complete the order (e.g. "Sorry, delivery to your desired address is unavailable'). Telegram will display this message to the user. - :type error_message: :obj:`typing.Union[base.String, None]` + :type error_message: :obj:`typing.Optional[base.String]` :return: On success, True is returned :rtype: :obj:`base.Boolean` """ @@ -2194,7 +2832,7 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): return result async def answer_pre_checkout_query(self, pre_checkout_query_id: base.String, ok: base.Boolean, - error_message: typing.Union[base.String, None] = None) -> base.Boolean: + error_message: typing.Optional[base.String] = None) -> base.Boolean: """ Once the user has confirmed their payment and shipping details, the Bot API sends the final confirmation in the form of an Update with the field pre_checkout_query. @@ -2212,7 +2850,7 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): (e.g. "Sorry, somebody just bought the last of our amazing black T-shirts while you were busy filling out your payment details. Please choose a different color or garment!"). Telegram will display this message to the user. - :type error_message: :obj:`typing.Union[base.String, None]` + :type error_message: :obj:`typing.Optional[base.String]` :return: On success, True is returned :rtype: :obj:`base.Boolean` """ @@ -2256,10 +2894,14 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): # === Games === # https://core.telegram.org/bots/api#games - async def send_game(self, chat_id: base.Integer, game_short_name: base.String, - disable_notification: typing.Union[base.Boolean, None] = None, - reply_to_message_id: typing.Union[base.Integer, None] = None, - reply_markup: typing.Union[types.InlineKeyboardMarkup, None] = None) -> types.Message: + async def send_game(self, + chat_id: base.Integer, + game_short_name: base.String, + 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: """ Use this method to send a game. @@ -2267,16 +2909,25 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :param chat_id: Unique identifier for the target chat :type chat_id: :obj:`base.Integer` - :param game_short_name: Short name of the game, serves as the unique identifier for the game. \ + + :param game_short_name: Short name of the game, serves as the unique identifier for the game. Set up your games via Botfather. :type game_short_name: :obj:`base.String` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + :param reply_to_message_id: If the message is a reply, ID of the original message - :type reply_to_message_id: :obj:`typing.Union[base.Integer, None]` + :type reply_to_message_id: :obj:`typing.Optional[base.Integer]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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. - :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, None]` + :type reply_markup: :obj:`typing.Optional[types.InlineKeyboardMarkup]` + :return: On success, the sent Message is returned :rtype: :obj:`types.Message` """ @@ -2287,10 +2938,10 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): return types.Message(**result) async def set_game_score(self, user_id: base.Integer, score: base.Integer, - force: typing.Union[base.Boolean, None] = None, - disable_edit_message: typing.Union[base.Boolean, None] = None, - chat_id: typing.Union[base.Integer, None] = None, - message_id: typing.Union[base.Integer, None] = None, + force: typing.Optional[base.Boolean] = None, + disable_edit_message: typing.Optional[base.Boolean] = None, + chat_id: typing.Optional[base.Integer] = None, + message_id: typing.Optional[base.Integer] = None, inline_message_id: typing.Union[base.String, None] = None) -> types.Message or base.Boolean: """ @@ -2304,16 +2955,16 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :type score: :obj:`base.Integer` :param force: Pass True, if the high score is allowed to decrease This can be useful when fixing mistakes or banning cheaters - :type force: :obj:`typing.Union[base.Boolean, None]` + :type force: :obj:`typing.Optional[base.Boolean]` :param disable_edit_message: Pass True, if the game message should not be automatically edited to include the current scoreboard - :type disable_edit_message: :obj:`typing.Union[base.Boolean, None]` + :type disable_edit_message: :obj:`typing.Optional[base.Boolean]` :param chat_id: Required if inline_message_id is not specified. Unique identifier for the target chat - :type chat_id: :obj:`typing.Union[base.Integer, None]` + :type chat_id: :obj:`typing.Optional[base.Integer]` :param message_id: Required if inline_message_id is not specified. Identifier of the sent message - :type message_id: :obj:`typing.Union[base.Integer, None]` + :type message_id: :obj:`typing.Optional[base.Integer]` :param inline_message_id: Required if chat_id and message_id are not specified. Identifier of the inline message - :type inline_message_id: :obj:`typing.Union[base.String, None]` + :type inline_message_id: :obj:`typing.Optional[base.String]` :return: On success, if the message was sent by the bot, returns the edited Message, otherwise returns True Returns an error, if the new score is not greater than the user's current score in the chat and force is False. @@ -2327,8 +2978,8 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): return types.Message(**result) async def get_game_high_scores(self, user_id: base.Integer, - chat_id: typing.Union[base.Integer, None] = None, - message_id: typing.Union[base.Integer, None] = None, + chat_id: typing.Optional[base.Integer] = None, + message_id: typing.Optional[base.Integer] = None, inline_message_id: typing.Union[base.String, None] = None) -> typing.List[types.GameHighScore]: """ @@ -2343,11 +2994,11 @@ class Bot(BaseBot, DataMixin, ContextInstanceMixin): :param user_id: Target user id :type user_id: :obj:`base.Integer` :param chat_id: Required if inline_message_id is not specified. Unique identifier for the target chat - :type chat_id: :obj:`typing.Union[base.Integer, None]` + :type chat_id: :obj:`typing.Optional[base.Integer]` :param message_id: Required if inline_message_id is not specified. Identifier of the sent message - :type message_id: :obj:`typing.Union[base.Integer, None]` + :type message_id: :obj:`typing.Optional[base.Integer]` :param inline_message_id: Required if chat_id and message_id are not specified. Identifier of the inline message - :type inline_message_id: :obj:`typing.Union[base.String, None]` + :type inline_message_id: :obj:`typing.Optional[base.String]` :return: Will return the score of the specified user and several of his neighbors in a game On success, returns an Array of GameHighScore objects. This method will currently return scores for the target user, diff --git a/aiogram/contrib/fsm_storage/mongo.py b/aiogram/contrib/fsm_storage/mongo.py index a7601cc4..f810a3eb 100644 --- a/aiogram/contrib/fsm_storage/mongo.py +++ b/aiogram/contrib/fsm_storage/mongo.py @@ -5,9 +5,9 @@ This module has mongo storage for finite-state machine from typing import Union, Dict, Optional, List, Tuple, AnyStr -import pymongo try: + import pymongo import motor from motor.motor_asyncio import AsyncIOMotorClient, AsyncIOMotorDatabase except ModuleNotFoundError as e: @@ -26,6 +26,7 @@ COLLECTIONS = (STATE, DATA, BUCKET) class MongoStorage(BaseStorage): """ Mongo-based storage for FSM. + Usage: .. code-block:: python3 @@ -39,7 +40,6 @@ class MongoStorage(BaseStorage): await dp.storage.close() await dp.storage.wait_closed() - """ def __init__(self, host='localhost', port=27017, db_name='aiogram_fsm', uri=None, diff --git a/aiogram/contrib/fsm_storage/rethinkdb.py b/aiogram/contrib/fsm_storage/rethinkdb.py index a9d822d5..5bb9062a 100644 --- a/aiogram/contrib/fsm_storage/rethinkdb.py +++ b/aiogram/contrib/fsm_storage/rethinkdb.py @@ -19,16 +19,17 @@ class RethinkDBStorage(BaseStorage): Usage: - ..code-block:: python3 + .. code-block:: python3 storage = RethinkDBStorage(db='aiogram', table='aiogram', user='aiogram', password='aiogram_secret') dispatcher = Dispatcher(bot, storage=storage) And need to close connection when shutdown - ..code-clock:: python3 + .. code-block:: python3 await storage.close() + await storage.wait_closed() """ @@ -54,7 +55,7 @@ class RethinkDBStorage(BaseStorage): self._ssl = ssl or {} self._loop = loop - self._conn: typing.Union[Connection, None] = None + self._conn: typing.Optional[Connection] = None async def connect(self) -> Connection: """ diff --git a/aiogram/dispatcher/storage.py b/aiogram/dispatcher/storage.py index a2992322..9a4eac76 100644 --- a/aiogram/dispatcher/storage.py +++ b/aiogram/dispatcher/storage.py @@ -300,7 +300,7 @@ class FSMContext: async def update_data(self, data: typing.Dict = None, **kwargs): await self.storage.update_data(chat=self.chat, user=self.user, data=data, **kwargs) - async def set_state(self, state: typing.Union[typing.AnyStr, None] = None): + async def set_state(self, state: typing.Optional[typing.AnyStr] = None): await self.storage.set_state(chat=self.chat, user=self.user, state=self._resolve_state(state)) async def set_data(self, data: typing.Dict = None): diff --git a/aiogram/dispatcher/webhook.py b/aiogram/dispatcher/webhook.py index 5199d591..b6280ed1 100644 --- a/aiogram/dispatcher/webhook.py +++ b/aiogram/dispatcher/webhook.py @@ -939,8 +939,8 @@ class SendMediaGroup(BaseResponse, ReplyToMixin, DisableNotificationMixin): def __init__(self, chat_id: Union[Integer, String], media: Union[types.MediaGroup, List] = None, - disable_notification: typing.Union[Boolean, None] = None, - reply_to_message_id: typing.Union[Integer, None] = None): + disable_notification: typing.Optional[Boolean] = None, + reply_to_message_id: typing.Optional[Integer] = None): """ Use this method to send a group of photos or videos as an album. @@ -951,9 +951,9 @@ class SendMediaGroup(BaseResponse, ReplyToMixin, DisableNotificationMixin): :param media: A JSON-serialized array describing photos and videos to be sent :type media: :obj:`typing.Union[types.MediaGroup, typing.List]` :param disable_notification: Sends the message silently. Users will receive a notification with no sound. - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` :param reply_to_message_id: If the message is a reply, ID of the original message - :type reply_to_message_id: :obj:`typing.Union[base.Integer, None]` + :type reply_to_message_id: :obj:`typing.Optional[base.Integer]` :return: On success, an array of the sent Messages is returned. :rtype: typing.List[types.Message] """ diff --git a/aiogram/types/__init__.py b/aiogram/types/__init__.py index d46f24da..26201130 100644 --- a/aiogram/types/__init__.py +++ b/aiogram/types/__init__.py @@ -7,6 +7,7 @@ from .bot_command import BotCommand from .callback_game import CallbackGame from .callback_query import CallbackQuery from .chat import Chat, ChatActions, ChatType +from .chat_location import ChatLocation from .chat_member import ChatMember, ChatMemberStatus from .chat_permissions import ChatPermissions from .chat_photo import ChatPhoto @@ -40,6 +41,7 @@ from .login_url import LoginUrl from .mask_position import MaskPosition from .message import ContentType, ContentTypes, Message, ParseMode from .message_entity import MessageEntity, MessageEntityType +from .message_id import MessageId from .order_info import OrderInfo from .passport_data import PassportData from .passport_element_error import PassportElementError, PassportElementErrorDataField, PassportElementErrorFile, \ @@ -49,6 +51,7 @@ from .passport_file import PassportFile from .photo_size import PhotoSize from .poll import PollOption, Poll, PollAnswer, PollType from .pre_checkout_query import PreCheckoutQuery +from .proximity_alert_triggered import ProximityAlertTriggered from .reply_keyboard import KeyboardButton, ReplyKeyboardMarkup, ReplyKeyboardRemove, KeyboardButtonPollType from .response_parameters import ResponseParameters from .shipping_address import ShippingAddress @@ -76,6 +79,7 @@ __all__ = ( 'CallbackQuery', 'Chat', 'ChatActions', + 'ChatLocation', 'ChatMember', 'ChatMemberStatus', 'ChatPermissions', @@ -141,6 +145,7 @@ __all__ = ( 'Message', 'MessageEntity', 'MessageEntityType', + 'MessageId', 'OrderInfo', 'ParseMode', 'PassportData', @@ -158,6 +163,7 @@ __all__ = ( 'PollOption', 'PollType', 'PreCheckoutQuery', + 'ProximityAlertTriggered', 'ReplyKeyboardMarkup', 'ReplyKeyboardRemove', 'ResponseParameters', diff --git a/aiogram/types/audio.py b/aiogram/types/audio.py index 6859668f..1657c9cc 100644 --- a/aiogram/types/audio.py +++ b/aiogram/types/audio.py @@ -15,6 +15,7 @@ class Audio(base.TelegramObject, mixins.Downloadable): duration: base.Integer = fields.Field() performer: base.String = fields.Field() title: base.String = fields.Field() + file_name: base.String = fields.Field() mime_type: base.String = fields.Field() file_size: base.Integer = fields.Field() thumb: PhotoSize = fields.Field(base=PhotoSize) diff --git a/aiogram/types/callback_query.py b/aiogram/types/callback_query.py index e847bff8..5eeb2f0c 100644 --- a/aiogram/types/callback_query.py +++ b/aiogram/types/callback_query.py @@ -28,10 +28,10 @@ class CallbackQuery(base.TelegramObject): data: base.String = fields.Field() game_short_name: base.String = fields.Field() - async def answer(self, text: typing.Union[base.String, None] = None, - show_alert: typing.Union[base.Boolean, None] = None, - url: typing.Union[base.String, None] = None, - cache_time: typing.Union[base.Integer, None] = None): + async def answer(self, text: typing.Optional[base.String] = None, + show_alert: typing.Optional[base.Boolean] = None, + url: typing.Optional[base.String] = None, + cache_time: typing.Optional[base.Integer] = None): """ Use this method to send answers to callback queries sent from inline keyboards. The answer will be displayed to the user as a notification at the top of the chat screen or as an alert. @@ -43,15 +43,15 @@ class CallbackQuery(base.TelegramObject): Source: https://core.telegram.org/bots/api#answercallbackquery :param text: Text of the notification. If not specified, nothing will be shown to the user, 0-200 characters - :type text: :obj:`typing.Union[base.String, None]` + :type text: :obj:`typing.Optional[base.String]` :param show_alert: If true, an alert will be shown by the client instead of a notification at the top of the chat screen. Defaults to false. - :type show_alert: :obj:`typing.Union[base.Boolean, None]` + :type show_alert: :obj:`typing.Optional[base.Boolean]` :param url: URL that will be opened by the user's client. - :type url: :obj:`typing.Union[base.String, None]` + :type url: :obj:`typing.Optional[base.String]` :param cache_time: The maximum amount of time in seconds that the result of the callback query may be cached client-side. - :type cache_time: :obj:`typing.Union[base.Integer, None]` + :type cache_time: :obj:`typing.Optional[base.Integer]` :return: On success, True is returned. :rtype: :obj:`base.Boolean`""" return await self.bot.answer_callback_query(callback_query_id=self.id, diff --git a/aiogram/types/chat.py b/aiogram/types/chat.py index 28cc5ed0..0021eb23 100644 --- a/aiogram/types/chat.py +++ b/aiogram/types/chat.py @@ -4,13 +4,14 @@ import asyncio import datetime import typing -from ..utils import helper, markdown from . import base, fields +from .chat_location import ChatLocation from .chat_member import ChatMember from .chat_permissions import ChatPermissions from .chat_photo import ChatPhoto from .input_file import InputFile -from ..utils.deprecated import deprecated +from ..utils import helper, markdown +from ..utils.deprecated import deprecated, DeprecatedReadOnlyClassVar class Chat(base.TelegramObject): @@ -27,6 +28,7 @@ class Chat(base.TelegramObject): last_name: base.String = fields.Field() all_members_are_administrators: base.Boolean = fields.Field() photo: ChatPhoto = fields.Field(base=ChatPhoto) + bio: base.String = fields.Field() description: base.String = fields.Field() invite_link: base.String = fields.Field() pinned_message: 'Message' = fields.Field(base='Message') @@ -34,6 +36,8 @@ class Chat(base.TelegramObject): slow_mode_delay: base.Integer = fields.Field() sticker_set_name: base.String = fields.Field() can_set_sticker_set: base.Boolean = fields.Field() + linked_chat_id: base.Integer = fields.Field() + location: ChatLocation = fields.Field() def __hash__(self): return self.id @@ -48,7 +52,7 @@ class Chat(base.TelegramObject): return self.title @property - def mention(self) -> typing.Union[base.String, None]: + def mention(self) -> typing.Optional[base.String]: """ Get mention if a Chat has a username, or get full name if this is a Private Chat, otherwise None is returned """ @@ -175,14 +179,15 @@ class Chat(base.TelegramObject): Source: https://core.telegram.org/bots/api#setchatdescription :param description: New chat description, 0-255 characters - :type description: :obj:`typing.Union[base.String, None]` + :type description: :obj:`typing.Optional[base.String]` :return: Returns True on success. :rtype: :obj:`base.Boolean` """ return await self.bot.set_chat_description(self.id, description) async def kick(self, user_id: base.Integer, - until_date: typing.Union[base.Integer, datetime.datetime, datetime.timedelta, None] = None) -> base.Boolean: + until_date: typing.Union[ + base.Integer, datetime.datetime, datetime.timedelta, None] = None) -> base.Boolean: """ Use this method to kick a user from a group, a supergroup or a channel. In the case of supergroups and channels, the user will not be able to return to the group @@ -199,35 +204,49 @@ class Chat(base.TelegramObject): :param user_id: Unique identifier of the target user :type user_id: :obj:`base.Integer` :param until_date: Date when the user will be unbanned, unix time. - :type until_date: :obj:`typing.Union[base.Integer, None]` + :type until_date: :obj:`typing.Optional[base.Integer]` :return: Returns True on success. :rtype: :obj:`base.Boolean` """ return await self.bot.kick_chat_member(self.id, user_id=user_id, until_date=until_date) - async def unban(self, user_id: base.Integer) -> base.Boolean: + async def unban(self, + user_id: base.Integer, + only_if_banned: typing.Optional[base.Boolean] = None, + ) -> base.Boolean: """ - 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. + 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. 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 :param user_id: Unique identifier of the target user :type user_id: :obj:`base.Integer` + + :param only_if_banned: Do nothing if the user is not banned + :type only_if_banned: :obj:`typing.Optional[base.Boolean]` + :return: Returns True on success. :rtype: :obj:`base.Boolean` """ - return await self.bot.unban_chat_member(self.id, user_id=user_id) + return await self.bot.unban_chat_member( + chat_id=self.id, + user_id=user_id, + only_if_banned=only_if_banned, + ) async def restrict(self, user_id: base.Integer, permissions: typing.Optional[ChatPermissions] = None, until_date: typing.Union[base.Integer, datetime.datetime, datetime.timedelta, None] = None, - can_send_messages: typing.Union[base.Boolean, None] = None, - can_send_media_messages: typing.Union[base.Boolean, None] = None, - can_send_other_messages: typing.Union[base.Boolean, None] = None, - can_add_web_page_previews: typing.Union[base.Boolean, None] = None) -> base.Boolean: + can_send_messages: typing.Optional[base.Boolean] = None, + can_send_media_messages: typing.Optional[base.Boolean] = None, + can_send_other_messages: typing.Optional[base.Boolean] = None, + can_add_web_page_previews: typing.Optional[base.Boolean] = None) -> base.Boolean: """ Use this method to restrict a user in a supergroup. The bot must be an administrator in the supergroup for this to work and must have the appropriate admin rights. @@ -240,18 +259,18 @@ class Chat(base.TelegramObject): :param permissions: New user permissions :type permissions: :obj:`ChatPermissions` :param until_date: Date when restrictions will be lifted for the user, unix time. - :type until_date: :obj:`typing.Union[base.Integer, None]` + :type until_date: :obj:`typing.Optional[base.Integer]` :param can_send_messages: Pass True, if the user can send text messages, contacts, locations and venues - :type can_send_messages: :obj:`typing.Union[base.Boolean, None]` + :type can_send_messages: :obj:`typing.Optional[base.Boolean]` :param can_send_media_messages: Pass True, if the user can send audios, documents, photos, videos, video notes and voice notes, implies can_send_messages - :type can_send_media_messages: :obj:`typing.Union[base.Boolean, None]` + :type can_send_media_messages: :obj:`typing.Optional[base.Boolean]` :param can_send_other_messages: Pass True, if the user can send animations, games, stickers and use inline bots, implies can_send_media_messages - :type can_send_other_messages: :obj:`typing.Union[base.Boolean, None]` + :type can_send_other_messages: :obj:`typing.Optional[base.Boolean]` :param can_add_web_page_previews: Pass True, if the user may add web page previews to their messages, implies can_send_media_messages - :type can_add_web_page_previews: :obj:`typing.Union[base.Boolean, None]` + :type can_add_web_page_previews: :obj:`typing.Optional[base.Boolean]` :return: Returns True on success. :rtype: :obj:`base.Boolean` """ @@ -264,14 +283,14 @@ class Chat(base.TelegramObject): can_add_web_page_previews=can_add_web_page_previews) async def promote(self, user_id: base.Integer, - can_change_info: typing.Union[base.Boolean, None] = None, - can_post_messages: typing.Union[base.Boolean, None] = None, - can_edit_messages: typing.Union[base.Boolean, None] = None, - can_delete_messages: typing.Union[base.Boolean, None] = None, - can_invite_users: typing.Union[base.Boolean, None] = None, - can_restrict_members: typing.Union[base.Boolean, None] = None, - can_pin_messages: typing.Union[base.Boolean, None] = None, - can_promote_members: typing.Union[base.Boolean, None] = None) -> base.Boolean: + can_change_info: typing.Optional[base.Boolean] = None, + can_post_messages: typing.Optional[base.Boolean] = None, + can_edit_messages: typing.Optional[base.Boolean] = None, + can_delete_messages: typing.Optional[base.Boolean] = None, + can_invite_users: typing.Optional[base.Boolean] = None, + can_restrict_members: typing.Optional[base.Boolean] = None, + can_pin_messages: typing.Optional[base.Boolean] = None, + can_promote_members: typing.Optional[base.Boolean] = None) -> base.Boolean: """ Use this method to promote or demote a user in a supergroup or a channel. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. @@ -282,23 +301,23 @@ class Chat(base.TelegramObject): :param user_id: Unique identifier of the target user :type user_id: :obj:`base.Integer` :param can_change_info: Pass True, if the administrator can change chat title, photo and other settings - :type can_change_info: :obj:`typing.Union[base.Boolean, None]` + :type can_change_info: :obj:`typing.Optional[base.Boolean]` :param can_post_messages: Pass True, if the administrator can create channel posts, channels only - :type can_post_messages: :obj:`typing.Union[base.Boolean, None]` + :type can_post_messages: :obj:`typing.Optional[base.Boolean]` :param can_edit_messages: Pass True, if the administrator can edit messages of other users, channels only - :type can_edit_messages: :obj:`typing.Union[base.Boolean, None]` + :type can_edit_messages: :obj:`typing.Optional[base.Boolean]` :param can_delete_messages: Pass True, if the administrator can delete messages of other users - :type can_delete_messages: :obj:`typing.Union[base.Boolean, None]` + :type can_delete_messages: :obj:`typing.Optional[base.Boolean]` :param can_invite_users: Pass True, if the administrator can invite new users to the chat - :type can_invite_users: :obj:`typing.Union[base.Boolean, None]` + :type can_invite_users: :obj:`typing.Optional[base.Boolean]` :param can_restrict_members: Pass True, if the administrator can restrict, ban or unban chat members - :type can_restrict_members: :obj:`typing.Union[base.Boolean, None]` + :type can_restrict_members: :obj:`typing.Optional[base.Boolean]` :param can_pin_messages: Pass True, if the administrator can pin messages, supergroups only - :type can_pin_messages: :obj:`typing.Union[base.Boolean, None]` + :type can_pin_messages: :obj:`typing.Optional[base.Boolean]` :param can_promote_members: Pass True, if the administrator can add new administrators with a subset of his own privileges or demote administrators that he has promoted, directly or indirectly (promoted by administrators that were appointed by him) - :type can_promote_members: :obj:`typing.Union[base.Boolean, None]` + :type can_promote_members: :obj:`typing.Optional[base.Boolean]` :return: Returns True on success. :rtype: :obj:`base.Boolean` """ @@ -338,36 +357,73 @@ class Chat(base.TelegramObject): :param custom_title: New custom title for the administrator; 0-16 characters, emoji are not allowed :return: True on success. """ - return await self.bot.set_chat_administrator_custom_title(chat_id=self.id, user_id=user_id, custom_title=custom_title) + return await self.bot.set_chat_administrator_custom_title(chat_id=self.id, user_id=user_id, + custom_title=custom_title) - async def pin_message(self, message_id: base.Integer, disable_notification: base.Boolean = False) -> base.Boolean: + async def pin_message(self, + message_id: base.Integer, + disable_notification: typing.Optional[base.Boolean] = False, + ) -> base.Boolean: """ - Use this method to pin a message in a supergroup. - The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. + 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 :param message_id: Identifier of a message to pin :type message_id: :obj:`base.Integer` - :param disable_notification: Pass True, if it is not necessary to send a notification to - all group members about the new pinned message - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` - :return: Returns True on success. + + :param disable_notification: Pass True, if it is not necessary to send a + notification to all group members about the new pinned message + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :return: Returns True on success :rtype: :obj:`base.Boolean` """ return await self.bot.pin_chat_message(self.id, message_id, disable_notification) - async def unpin_message(self) -> base.Boolean: + async def unpin_message(self, + message_id: typing.Optional[base.Integer] = None, + ) -> base.Boolean: """ - Use this method to unpin a message in a supergroup chat. - The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. + 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 - :return: Returns True on success. + :param message_id: Identifier of a message to unpin. If not specified, the + most recent pinned message (by sending date) will be unpinned. + :type message_id: :obj:`typing.Optional[base.Integer]` + + :return: Returns True on success :rtype: :obj:`base.Boolean` """ - return await self.bot.unpin_chat_message(self.id) + return await self.bot.unpin_chat_message( + chat_id=self.id, + message_id=message_id, + ) + + async def unpin_all_messages(self): + """ + 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 + + :return: Returns True on success + :rtype: :obj:`base.Boolean` + """ + return await self.bot.unpin_all_chat_messages( + chat_id=self.id, + ) async def leave(self) -> base.Boolean: """ @@ -494,6 +550,7 @@ class ChatType(helper.Helper): :key: PRIVATE :key: GROUP :key: SUPER_GROUP + :key: SUPERGROUP :key: CHANNEL """ @@ -501,9 +558,14 @@ class ChatType(helper.Helper): PRIVATE = helper.Item() # private GROUP = helper.Item() # group - SUPER_GROUP = helper.Item() # supergroup + SUPERGROUP = helper.Item() # supergroup CHANNEL = helper.Item() # channel + SUPER_GROUP: DeprecatedReadOnlyClassVar[ChatType, helper.Item] \ + = DeprecatedReadOnlyClassVar( + "SUPER_GROUP chat type is deprecated, use SUPERGROUP instead.", + new_value_getter=lambda cls: cls.SUPERGROUP) + @staticmethod def _check(obj, chat_types) -> bool: if hasattr(obj, 'chat'): @@ -543,7 +605,7 @@ class ChatType(helper.Helper): :param obj: :return: """ - return cls._check(obj, [cls.SUPER_GROUP]) + return cls._check(obj, [cls.SUPER_GROUP, cls.SUPERGROUP]) @classmethod @deprecated("This filter was moved to ChatTypeFilter, and will be removed in aiogram v3.0") @@ -554,7 +616,7 @@ class ChatType(helper.Helper): :param obj: :return: """ - return cls._check(obj, [cls.GROUP, cls.SUPER_GROUP]) + return cls._check(obj, [cls.GROUP, cls.SUPER_GROUP, cls.SUPERGROUP]) @classmethod @deprecated("This filter was moved to ChatTypeFilter, and will be removed in aiogram v3.0") diff --git a/aiogram/types/chat_location.py b/aiogram/types/chat_location.py new file mode 100644 index 00000000..0438c544 --- /dev/null +++ b/aiogram/types/chat_location.py @@ -0,0 +1,16 @@ +from . import base +from . import fields +from .location import Location + + +class ChatLocation(base.TelegramObject): + """ + Represents a location to which a chat is connected. + + https://core.telegram.org/bots/api#chatlocation + """ + location: Location = fields.Field() + address: base.String = fields.Field() + + def __init__(self, location: Location, address: base.String): + super().__init__(location=location, address=address) diff --git a/aiogram/types/chat_member.py b/aiogram/types/chat_member.py index 274c8a26..4aa52b80 100644 --- a/aiogram/types/chat_member.py +++ b/aiogram/types/chat_member.py @@ -1,6 +1,4 @@ import datetime -import warnings -from typing import Optional from . import base from . import fields @@ -17,6 +15,7 @@ class ChatMember(base.TelegramObject): user: User = fields.Field(base=User) status: base.String = fields.Field() custom_title: base.String = fields.Field() + is_anonymous: base.Boolean = fields.Field() until_date: datetime.datetime = fields.DateTimeField() can_be_edited: base.Boolean = fields.Field() can_change_info: base.Boolean = fields.Field() diff --git a/aiogram/types/dice.py b/aiogram/types/dice.py index 7b3f1727..70c50e09 100644 --- a/aiogram/types/dice.py +++ b/aiogram/types/dice.py @@ -17,3 +17,5 @@ class DiceEmoji: DICE = '🎲' DART = '🎯' BASKETBALL = '🏀' + FOOTBALL = '⚽' + SLOT_MACHINE = '🎰' diff --git a/aiogram/types/inline_query.py b/aiogram/types/inline_query.py index 379394a0..436c11b0 100644 --- a/aiogram/types/inline_query.py +++ b/aiogram/types/inline_query.py @@ -23,11 +23,11 @@ class InlineQuery(base.TelegramObject): async def answer(self, results: typing.List[InlineQueryResult], - cache_time: typing.Union[base.Integer, None] = None, - is_personal: typing.Union[base.Boolean, None] = None, - next_offset: typing.Union[base.String, None] = None, - switch_pm_text: typing.Union[base.String, None] = None, - switch_pm_parameter: typing.Union[base.String, None] = None): + cache_time: typing.Optional[base.Integer] = None, + is_personal: typing.Optional[base.Boolean] = None, + next_offset: typing.Optional[base.String] = None, + switch_pm_text: typing.Optional[base.String] = None, + switch_pm_parameter: typing.Optional[base.String] = None): """ Use this method to send answers to an inline query. No more than 50 results per query are allowed. @@ -38,22 +38,22 @@ class InlineQuery(base.TelegramObject): :type results: :obj:`typing.List[types.InlineQueryResult]` :param cache_time: The maximum amount of time in seconds that the result of the inline query may be cached on the server. Defaults to 300. - :type cache_time: :obj:`typing.Union[base.Integer, None]` + :type cache_time: :obj:`typing.Optional[base.Integer]` :param is_personal: Pass True, if results may be cached on the server side only for the user that sent the query. By default, results may be returned to any user who sends the same query - :type is_personal: :obj:`typing.Union[base.Boolean, None]` + :type is_personal: :obj:`typing.Optional[base.Boolean]` :param next_offset: Pass the offset that a client should send in the next query with the same text to receive more results. Pass an empty string if there are no more results or if you don‘t support pagination. Offset length can’t exceed 64 bytes. - :type next_offset: :obj:`typing.Union[base.String, None]` + :type next_offset: :obj:`typing.Optional[base.String]` :param switch_pm_text: If passed, clients will display a button with specified text that switches the user to a private chat with the bot and sends the bot a start message with the parameter switch_pm_parameter - :type switch_pm_text: :obj:`typing.Union[base.String, None]` + :type switch_pm_text: :obj:`typing.Optional[base.String]` :param switch_pm_parameter: Deep-linking parameter for the /start message sent to the bot when user presses the switch button. 1-64 characters, only A-Z, a-z, 0-9, _ and - are allowed. - :type switch_pm_parameter: :obj:`typing.Union[base.String, None]` + :type switch_pm_parameter: :obj:`typing.Optional[base.String]` :return: On success, True is returned :rtype: :obj:`base.Boolean` """ diff --git a/aiogram/types/inline_query_result.py b/aiogram/types/inline_query_result.py index fccaa2a1..da09db9d 100644 --- a/aiogram/types/inline_query_result.py +++ b/aiogram/types/inline_query_result.py @@ -4,6 +4,7 @@ from . import base from . import fields from .inline_keyboard import InlineKeyboardMarkup from .input_message_content import InputMessageContent +from .message_entity import MessageEntity class InlineQueryResult(base.TelegramObject): @@ -83,23 +84,29 @@ class InlineQueryResultPhoto(InlineQueryResult): caption: base.String = fields.Field() input_message_content: InputMessageContent = fields.Field(base=InputMessageContent) - def __init__(self, *, - id: base.String, - photo_url: base.String, - thumb_url: base.String, - photo_width: typing.Optional[base.Integer] = None, - photo_height: typing.Optional[base.Integer] = None, - title: typing.Optional[base.String] = None, - description: typing.Optional[base.String] = None, - caption: typing.Optional[base.String] = None, - parse_mode: typing.Optional[base.String] = None, - reply_markup: typing.Optional[InlineKeyboardMarkup] = None, - input_message_content: typing.Optional[InputMessageContent] = None): - super(InlineQueryResultPhoto, self).__init__(id=id, photo_url=photo_url, thumb_url=thumb_url, - photo_width=photo_width, photo_height=photo_height, title=title, - description=description, caption=caption, - parse_mode=parse_mode, reply_markup=reply_markup, - input_message_content=input_message_content) + def __init__( + self, + *, + id: base.String, + photo_url: base.String, + thumb_url: base.String, + photo_width: typing.Optional[base.Integer] = None, + photo_height: typing.Optional[base.Integer] = None, + title: typing.Optional[base.String] = None, + description: typing.Optional[base.String] = None, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + reply_markup: typing.Optional[InlineKeyboardMarkup] = None, + input_message_content: typing.Optional[InputMessageContent] = None, + ): + super().__init__( + id=id, photo_url=photo_url, thumb_url=thumb_url, + photo_width=photo_width, photo_height=photo_height, title=title, + description=description, caption=caption, + parse_mode=parse_mode, caption_entities=caption_entities, + reply_markup=reply_markup, input_message_content=input_message_content, + ) class InlineQueryResultGif(InlineQueryResult): @@ -123,23 +130,29 @@ class InlineQueryResultGif(InlineQueryResult): caption: base.String = fields.Field() input_message_content: InputMessageContent = fields.Field(base=InputMessageContent) - def __init__(self, *, - id: base.String, - gif_url: base.String, - gif_width: typing.Optional[base.Integer] = None, - gif_height: typing.Optional[base.Integer] = None, - gif_duration: typing.Optional[base.Integer] = None, - thumb_url: typing.Optional[base.String] = None, - title: typing.Optional[base.String] = None, - caption: typing.Optional[base.String] = None, - parse_mode: typing.Optional[base.String] = None, - reply_markup: typing.Optional[InlineKeyboardMarkup] = None, - input_message_content: typing.Optional[InputMessageContent] = None): - super(InlineQueryResultGif, self).__init__(id=id, gif_url=gif_url, gif_width=gif_width, - gif_height=gif_height, gif_duration=gif_duration, - thumb_url=thumb_url, title=title, caption=caption, - parse_mode=parse_mode, reply_markup=reply_markup, - input_message_content=input_message_content) + def __init__( + self, + *, + id: base.String, + gif_url: base.String, + gif_width: typing.Optional[base.Integer] = None, + gif_height: typing.Optional[base.Integer] = None, + gif_duration: typing.Optional[base.Integer] = None, + thumb_url: typing.Optional[base.String] = None, + title: typing.Optional[base.String] = None, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + reply_markup: typing.Optional[InlineKeyboardMarkup] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + input_message_content: typing.Optional[InputMessageContent] = None, + ): + super().__init__( + id=id, gif_url=gif_url, gif_width=gif_width, gif_height=gif_height, + gif_duration=gif_duration, thumb_url=thumb_url, title=title, + caption=caption, parse_mode=parse_mode, reply_markup=reply_markup, + caption_entities=caption_entities, + input_message_content=input_message_content, + ) class InlineQueryResultMpeg4Gif(InlineQueryResult): @@ -163,23 +176,30 @@ class InlineQueryResultMpeg4Gif(InlineQueryResult): caption: base.String = fields.Field() input_message_content: InputMessageContent = fields.Field(base=InputMessageContent) - def __init__(self, *, - id: base.String, - mpeg4_url: base.String, - thumb_url: base.String, - mpeg4_width: typing.Optional[base.Integer] = None, - mpeg4_height: typing.Optional[base.Integer] = None, - mpeg4_duration: typing.Optional[base.Integer] = None, - title: typing.Optional[base.String] = None, - caption: typing.Optional[base.String] = None, - parse_mode: typing.Optional[base.String] = None, - reply_markup: typing.Optional[InlineKeyboardMarkup] = None, - input_message_content: typing.Optional[InputMessageContent] = None): - super(InlineQueryResultMpeg4Gif, self).__init__(id=id, mpeg4_url=mpeg4_url, mpeg4_width=mpeg4_width, - mpeg4_height=mpeg4_height, mpeg4_duration=mpeg4_duration, - thumb_url=thumb_url, title=title, caption=caption, - parse_mode=parse_mode, reply_markup=reply_markup, - input_message_content=input_message_content) + def __init__( + self, + *, + id: base.String, + mpeg4_url: base.String, + thumb_url: base.String, + mpeg4_width: typing.Optional[base.Integer] = None, + mpeg4_height: typing.Optional[base.Integer] = None, + mpeg4_duration: typing.Optional[base.Integer] = None, + title: typing.Optional[base.String] = None, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + reply_markup: typing.Optional[InlineKeyboardMarkup] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + input_message_content: typing.Optional[InputMessageContent] = None, + ): + super().__init__( + id=id, mpeg4_url=mpeg4_url, mpeg4_width=mpeg4_width, + mpeg4_height=mpeg4_height, mpeg4_duration=mpeg4_duration, + thumb_url=thumb_url, title=title, caption=caption, + parse_mode=parse_mode, reply_markup=reply_markup, + caption_entities=caption_entities, + input_message_content=input_message_content, + ) class InlineQueryResultVideo(InlineQueryResult): @@ -207,26 +227,32 @@ class InlineQueryResultVideo(InlineQueryResult): description: base.String = fields.Field() input_message_content: InputMessageContent = fields.Field(base=InputMessageContent) - def __init__(self, *, - id: base.String, - video_url: base.String, - mime_type: base.String, - thumb_url: base.String, - title: base.String, - caption: typing.Optional[base.String] = None, - parse_mode: typing.Optional[base.String] = None, - video_width: typing.Optional[base.Integer] = None, - video_height: typing.Optional[base.Integer] = None, - video_duration: typing.Optional[base.Integer] = None, - description: typing.Optional[base.String] = None, - reply_markup: typing.Optional[InlineKeyboardMarkup] = None, - input_message_content: typing.Optional[InputMessageContent] = None): - super(InlineQueryResultVideo, self).__init__(id=id, video_url=video_url, mime_type=mime_type, - thumb_url=thumb_url, title=title, caption=caption, - video_width=video_width, video_height=video_height, - video_duration=video_duration, description=description, - parse_mode=parse_mode, reply_markup=reply_markup, - input_message_content=input_message_content) + def __init__( + self, + *, + id: base.String, + video_url: base.String, + mime_type: base.String, + thumb_url: base.String, + title: base.String, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + video_width: typing.Optional[base.Integer] = None, + video_height: typing.Optional[base.Integer] = None, + video_duration: typing.Optional[base.Integer] = None, + description: typing.Optional[base.String] = None, + reply_markup: typing.Optional[InlineKeyboardMarkup] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + input_message_content: typing.Optional[InputMessageContent] = None, + ): + super().__init__( + id=id, video_url=video_url, mime_type=mime_type, thumb_url=thumb_url, + title=title, caption=caption, video_width=video_width, + video_height=video_height, video_duration=video_duration, + description=description, parse_mode=parse_mode, + reply_markup=reply_markup, caption_entities=caption_entities, + input_message_content=input_message_content, + ) class InlineQueryResultAudio(InlineQueryResult): @@ -248,21 +274,27 @@ class InlineQueryResultAudio(InlineQueryResult): audio_duration: base.Integer = fields.Field() input_message_content: InputMessageContent = fields.Field(base=InputMessageContent) - def __init__(self, *, - id: base.String, - audio_url: base.String, - title: base.String, - caption: typing.Optional[base.String] = None, - parse_mode: typing.Optional[base.String] = None, - performer: typing.Optional[base.String] = None, - audio_duration: typing.Optional[base.Integer] = None, - reply_markup: typing.Optional[InlineKeyboardMarkup] = None, - input_message_content: typing.Optional[InputMessageContent] = None): - super(InlineQueryResultAudio, self).__init__(id=id, audio_url=audio_url, title=title, - caption=caption, parse_mode=parse_mode, - performer=performer, audio_duration=audio_duration, - reply_markup=reply_markup, - input_message_content=input_message_content) + def __init__( + self, + *, + id: base.String, + audio_url: base.String, + title: base.String, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + performer: typing.Optional[base.String] = None, + audio_duration: typing.Optional[base.Integer] = None, + reply_markup: typing.Optional[InlineKeyboardMarkup] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + input_message_content: typing.Optional[InputMessageContent] = None, + ): + super().__init__( + id=id, audio_url=audio_url, title=title, + caption=caption, parse_mode=parse_mode, + performer=performer, audio_duration=audio_duration, + reply_markup=reply_markup, caption_entities=caption_entities, + input_message_content=input_message_content, + ) class InlineQueryResultVoice(InlineQueryResult): @@ -285,19 +317,25 @@ class InlineQueryResultVoice(InlineQueryResult): voice_duration: base.Integer = fields.Field() input_message_content: InputMessageContent = fields.Field(base=InputMessageContent) - def __init__(self, *, - id: base.String, - voice_url: base.String, - title: base.String, - caption: typing.Optional[base.String] = None, - parse_mode: typing.Optional[base.String] = None, - voice_duration: typing.Optional[base.Integer] = None, - reply_markup: typing.Optional[InlineKeyboardMarkup] = None, - input_message_content: typing.Optional[InputMessageContent] = None): - super(InlineQueryResultVoice, self).__init__(id=id, voice_url=voice_url, title=title, - caption=caption, voice_duration=voice_duration, - parse_mode=parse_mode, reply_markup=reply_markup, - input_message_content=input_message_content) + def __init__( + self, + *, + id: base.String, + voice_url: base.String, + title: base.String, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + voice_duration: typing.Optional[base.Integer] = None, + reply_markup: typing.Optional[InlineKeyboardMarkup] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + input_message_content: typing.Optional[InputMessageContent] = None, + ): + super().__init__( + id=id, voice_url=voice_url, title=title, caption=caption, + voice_duration=voice_duration, parse_mode=parse_mode, + reply_markup=reply_markup, caption_entities=caption_entities, + input_message_content=input_message_content, + ) class InlineQueryResultDocument(InlineQueryResult): @@ -323,25 +361,31 @@ class InlineQueryResultDocument(InlineQueryResult): thumb_width: base.Integer = fields.Field() thumb_height: base.Integer = fields.Field() - def __init__(self, *, - id: base.String, - title: base.String, - caption: typing.Optional[base.String] = None, - parse_mode: typing.Optional[base.String] = None, - document_url: typing.Optional[base.String] = None, - mime_type: typing.Optional[base.String] = None, - description: typing.Optional[base.String] = None, - reply_markup: typing.Optional[InlineKeyboardMarkup] = None, - input_message_content: typing.Optional[InputMessageContent] = None, - thumb_url: typing.Optional[base.String] = None, - thumb_width: typing.Optional[base.Integer] = None, - thumb_height: typing.Optional[base.Integer] = None): - super(InlineQueryResultDocument, self).__init__(id=id, title=title, caption=caption, - document_url=document_url, mime_type=mime_type, - description=description, reply_markup=reply_markup, - input_message_content=input_message_content, - thumb_url=thumb_url, thumb_width=thumb_width, - thumb_height=thumb_height, parse_mode=parse_mode) + def __init__( + self, + *, + id: base.String, + title: base.String, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + document_url: typing.Optional[base.String] = None, + mime_type: typing.Optional[base.String] = None, + description: typing.Optional[base.String] = None, + reply_markup: typing.Optional[InlineKeyboardMarkup] = None, + input_message_content: typing.Optional[InputMessageContent] = None, + thumb_url: typing.Optional[base.String] = None, + thumb_width: typing.Optional[base.Integer] = None, + thumb_height: typing.Optional[base.Integer] = None, + ): + super().__init__( + id=id, title=title, caption=caption, parse_mode=parse_mode, + caption_entities=caption_entities, document_url=document_url, + mime_type=mime_type, description=description, reply_markup=reply_markup, + input_message_content=input_message_content, + thumb_url=thumb_url, thumb_width=thumb_width, + thumb_height=thumb_height, + ) class InlineQueryResultLocation(InlineQueryResult): @@ -352,16 +396,16 @@ class InlineQueryResultLocation(InlineQueryResult): Alternatively, you can use input_message_content to send a message with the specified content instead of the location. - Note: This will only work in Telegram versions released after 9 April, 2016. - Older clients will ignore them. - https://core.telegram.org/bots/api#inlinequeryresultlocation """ type: base.String = fields.Field(alias='type', default='location') latitude: base.Float = fields.Field() longitude: base.Float = fields.Field() title: base.String = fields.Field() + horizontal_accuracy: typing.Optional[base.Float] = fields.Field() live_period: base.Integer = fields.Field() + heading: typing.Optional[base.Integer] = fields.Field() + proximity_alert_radius: typing.Optional[base.Integer] = fields.Field() input_message_content: InputMessageContent = fields.Field(base=InputMessageContent) thumb_url: base.String = fields.Field() thumb_width: base.Integer = fields.Field() @@ -372,18 +416,31 @@ class InlineQueryResultLocation(InlineQueryResult): latitude: base.Float, longitude: base.Float, title: base.String, + horizontal_accuracy: typing.Optional[base.Float] = None, live_period: typing.Optional[base.Integer] = None, + heading: typing.Optional[base.Integer] = None, + proximity_alert_radius: typing.Optional[base.Integer] = None, reply_markup: typing.Optional[InlineKeyboardMarkup] = None, input_message_content: typing.Optional[InputMessageContent] = None, thumb_url: typing.Optional[base.String] = None, thumb_width: typing.Optional[base.Integer] = None, - thumb_height: typing.Optional[base.Integer] = None): - super(InlineQueryResultLocation, self).__init__(id=id, latitude=latitude, longitude=longitude, - title=title, live_period=live_period, - reply_markup=reply_markup, - input_message_content=input_message_content, - thumb_url=thumb_url, thumb_width=thumb_width, - thumb_height=thumb_height) + thumb_height: typing.Optional[base.Integer] = None, + ): + super().__init__( + id=id, + latitude=latitude, + longitude=longitude, + title=title, + horizontal_accuracy=horizontal_accuracy, + live_period=live_period, + heading=heading, + proximity_alert_radius=proximity_alert_radius, + reply_markup=reply_markup, + input_message_content=input_message_content, + thumb_url=thumb_url, + thumb_width=thumb_width, + thumb_height=thumb_height + ) class InlineQueryResultVenue(InlineQueryResult): @@ -404,31 +461,40 @@ class InlineQueryResultVenue(InlineQueryResult): title: base.String = fields.Field() address: base.String = fields.Field() foursquare_id: base.String = fields.Field() + foursquare_type: base.String = fields.Field() + google_place_id: base.String = fields.Field() + google_place_type: base.String = fields.Field() input_message_content: InputMessageContent = fields.Field(base=InputMessageContent) thumb_url: base.String = fields.Field() thumb_width: base.Integer = fields.Field() thumb_height: base.Integer = fields.Field() - foursquare_type: base.String = fields.Field() - def __init__(self, *, - id: base.String, - latitude: base.Float, - longitude: base.Float, - title: base.String, - address: base.String, - foursquare_id: typing.Optional[base.String] = None, - reply_markup: typing.Optional[InlineKeyboardMarkup] = None, - input_message_content: typing.Optional[InputMessageContent] = None, - thumb_url: typing.Optional[base.String] = None, - thumb_width: typing.Optional[base.Integer] = None, - thumb_height: typing.Optional[base.Integer] = None, - foursquare_type: typing.Optional[base.String] = None): - super(InlineQueryResultVenue, self).__init__(id=id, latitude=latitude, longitude=longitude, - title=title, address=address, foursquare_id=foursquare_id, - reply_markup=reply_markup, - input_message_content=input_message_content, thumb_url=thumb_url, - thumb_width=thumb_width, thumb_height=thumb_height, - foursquare_type=foursquare_type) + def __init__( + self, + *, + id: base.String, + latitude: base.Float, + longitude: base.Float, + title: base.String, + address: base.String, + foursquare_id: typing.Optional[base.String] = None, + foursquare_type: typing.Optional[base.String] = None, + google_place_id: typing.Optional[base.String] = None, + google_place_type: typing.Optional[base.String] = None, + reply_markup: typing.Optional[InlineKeyboardMarkup] = None, + input_message_content: typing.Optional[InputMessageContent] = None, + thumb_url: typing.Optional[base.String] = None, + thumb_width: typing.Optional[base.Integer] = None, + thumb_height: typing.Optional[base.Integer] = None, + ): + super().__init__( + id=id, latitude=latitude, longitude=longitude, title=title, + address=address, foursquare_id=foursquare_id, + foursquare_type=foursquare_type, google_place_id=google_place_id, + google_place_type=google_place_type, reply_markup=reply_markup, + input_message_content=input_message_content, thumb_url=thumb_url, + thumb_width=thumb_width, thumb_height=thumb_height, + ) class InlineQueryResultContact(InlineQueryResult): @@ -510,19 +576,24 @@ class InlineQueryResultCachedPhoto(InlineQueryResult): caption: base.String = fields.Field() input_message_content: InputMessageContent = fields.Field(base=InputMessageContent) - def __init__(self, *, - id: base.String, - photo_file_id: base.String, - title: typing.Optional[base.String] = None, - description: typing.Optional[base.String] = None, - caption: typing.Optional[base.String] = None, - parse_mode: typing.Optional[base.String] = None, - reply_markup: typing.Optional[InlineKeyboardMarkup] = None, - input_message_content: typing.Optional[InputMessageContent] = None): - super(InlineQueryResultCachedPhoto, self).__init__(id=id, photo_file_id=photo_file_id, title=title, - description=description, caption=caption, - parse_mode=parse_mode, reply_markup=reply_markup, - input_message_content=input_message_content) + def __init__( + self, + *, + id: base.String, + photo_file_id: base.String, + title: typing.Optional[base.String] = None, + description: typing.Optional[base.String] = None, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + reply_markup: typing.Optional[InlineKeyboardMarkup] = None, + input_message_content: typing.Optional[InputMessageContent] = None, + ): + super().__init__( + id=id, photo_file_id=photo_file_id, title=title, description=description, + caption=caption, parse_mode=parse_mode, caption_entities=caption_entities, + reply_markup=reply_markup, input_message_content=input_message_content, + ) class InlineQueryResultCachedGif(InlineQueryResult): @@ -541,18 +612,23 @@ class InlineQueryResultCachedGif(InlineQueryResult): caption: base.String = fields.Field() input_message_content: InputMessageContent = fields.Field(base=InputMessageContent) - def __init__(self, *, - id: base.String, - gif_file_id: base.String, - title: typing.Optional[base.String] = None, - caption: typing.Optional[base.String] = None, - parse_mode: typing.Optional[base.String] = None, - reply_markup: typing.Optional[InlineKeyboardMarkup] = None, - input_message_content: typing.Optional[InputMessageContent] = None): - super(InlineQueryResultCachedGif, self).__init__(id=id, gif_file_id=gif_file_id, - title=title, caption=caption, - parse_mode=parse_mode, reply_markup=reply_markup, - input_message_content=input_message_content) + def __init__( + self, + *, + id: base.String, + gif_file_id: base.String, + title: typing.Optional[base.String] = None, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + reply_markup: typing.Optional[InlineKeyboardMarkup] = None, + input_message_content: typing.Optional[InputMessageContent] = None, + ): + super().__init__( + id=id, gif_file_id=gif_file_id, title=title, caption=caption, + parse_mode=parse_mode, caption_entities=caption_entities, + reply_markup=reply_markup, input_message_content=input_message_content, + ) class InlineQueryResultCachedMpeg4Gif(InlineQueryResult): @@ -571,18 +647,23 @@ class InlineQueryResultCachedMpeg4Gif(InlineQueryResult): caption: base.String = fields.Field() input_message_content: InputMessageContent = fields.Field(base=InputMessageContent) - def __init__(self, *, - id: base.String, - mpeg4_file_id: base.String, - title: typing.Optional[base.String] = None, - caption: typing.Optional[base.String] = None, - parse_mode: typing.Optional[base.String] = None, - reply_markup: typing.Optional[InlineKeyboardMarkup] = None, - input_message_content: typing.Optional[InputMessageContent] = None): - super(InlineQueryResultCachedMpeg4Gif, self).__init__(id=id, mpeg4_file_id=mpeg4_file_id, - title=title, caption=caption, - parse_mode=parse_mode, reply_markup=reply_markup, - input_message_content=input_message_content) + def __init__( + self, + *, + id: base.String, + mpeg4_file_id: base.String, + title: typing.Optional[base.String] = None, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + reply_markup: typing.Optional[InlineKeyboardMarkup] = None, + input_message_content: typing.Optional[InputMessageContent] = None, + ): + super().__init__( + id=id, mpeg4_file_id=mpeg4_file_id, title=title, caption=caption, + parse_mode=parse_mode, caption_entities=caption_entities, + reply_markup=reply_markup, input_message_content=input_message_content, + ) class InlineQueryResultCachedSticker(InlineQueryResult): @@ -631,20 +712,25 @@ class InlineQueryResultCachedDocument(InlineQueryResult): caption: base.String = fields.Field() input_message_content: InputMessageContent = fields.Field(base=InputMessageContent) - def __init__(self, *, - id: base.String, - title: base.String, - document_file_id: base.String, - description: typing.Optional[base.String] = None, - caption: typing.Optional[base.String] = None, - parse_mode: typing.Optional[base.String] = None, - reply_markup: typing.Optional[InlineKeyboardMarkup] = None, - input_message_content: typing.Optional[InputMessageContent] = None): - super(InlineQueryResultCachedDocument, self).__init__(id=id, title=title, - document_file_id=document_file_id, - description=description, caption=caption, - parse_mode=parse_mode, reply_markup=reply_markup, - input_message_content=input_message_content) + def __init__( + self, + *, + id: base.String, + title: base.String, + document_file_id: base.String, + description: typing.Optional[base.String] = None, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + reply_markup: typing.Optional[InlineKeyboardMarkup] = None, + input_message_content: typing.Optional[InputMessageContent] = None, + ): + super().__init__( + id=id, title=title, document_file_id=document_file_id, + description=description, caption=caption, parse_mode=parse_mode, + caption_entities=caption_entities, reply_markup=reply_markup, + input_message_content=input_message_content, + ) class InlineQueryResultCachedVideo(InlineQueryResult): @@ -664,19 +750,24 @@ class InlineQueryResultCachedVideo(InlineQueryResult): caption: base.String = fields.Field() input_message_content: InputMessageContent = fields.Field(base=InputMessageContent) - def __init__(self, *, - id: base.String, - video_file_id: base.String, - title: base.String, - description: typing.Optional[base.String] = None, - caption: typing.Optional[base.String] = None, - parse_mode: typing.Optional[base.String] = None, - reply_markup: typing.Optional[InlineKeyboardMarkup] = None, - input_message_content: typing.Optional[InputMessageContent] = None): - super(InlineQueryResultCachedVideo, self).__init__(id=id, video_file_id=video_file_id, title=title, - description=description, caption=caption, - parse_mode=parse_mode, reply_markup=reply_markup, - input_message_content=input_message_content) + def __init__( + self, + *, + id: base.String, + video_file_id: base.String, + title: base.String, + description: typing.Optional[base.String] = None, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + reply_markup: typing.Optional[InlineKeyboardMarkup] = None, + input_message_content: typing.Optional[InputMessageContent] = None, + ): + super().__init__( + id=id, video_file_id=video_file_id, title=title, description=description, + caption=caption, parse_mode=parse_mode, caption_entities=caption_entities, + reply_markup=reply_markup, input_message_content=input_message_content, + ) class InlineQueryResultCachedVoice(InlineQueryResult): @@ -697,18 +788,23 @@ class InlineQueryResultCachedVoice(InlineQueryResult): caption: base.String = fields.Field() input_message_content: InputMessageContent = fields.Field(base=InputMessageContent) - def __init__(self, *, - id: base.String, - voice_file_id: base.String, - title: base.String, - caption: typing.Optional[base.String] = None, - parse_mode: typing.Optional[base.String] = None, - reply_markup: typing.Optional[InlineKeyboardMarkup] = None, - input_message_content: typing.Optional[InputMessageContent] = None): - super(InlineQueryResultCachedVoice, self).__init__(id=id, voice_file_id=voice_file_id, - title=title, caption=caption, - parse_mode=parse_mode, reply_markup=reply_markup, - input_message_content=input_message_content) + def __init__( + self, + *, + id: base.String, + voice_file_id: base.String, + title: base.String, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + reply_markup: typing.Optional[InlineKeyboardMarkup] = None, + input_message_content: typing.Optional[InputMessageContent] = None, + ): + super().__init__( + id=id, voice_file_id=voice_file_id, title=title, caption=caption, + parse_mode=parse_mode, caption_entities=caption_entities, + reply_markup=reply_markup, input_message_content=input_message_content, + ) class InlineQueryResultCachedAudio(InlineQueryResult): @@ -729,14 +825,19 @@ class InlineQueryResultCachedAudio(InlineQueryResult): caption: base.String = fields.Field() input_message_content: InputMessageContent = fields.Field(base=InputMessageContent) - def __init__(self, *, - id: base.String, - audio_file_id: base.String, - caption: typing.Optional[base.String] = None, - parse_mode: typing.Optional[base.String] = None, - reply_markup: typing.Optional[InlineKeyboardMarkup] = None, - input_message_content: typing.Optional[InputMessageContent] = None): - super(InlineQueryResultCachedAudio, self).__init__(id=id, audio_file_id=audio_file_id, - caption=caption, parse_mode=parse_mode, - reply_markup=reply_markup, - input_message_content=input_message_content) + def __init__( + self, + *, + id: base.String, + audio_file_id: base.String, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + reply_markup: typing.Optional[InlineKeyboardMarkup] = None, + input_message_content: typing.Optional[InputMessageContent] = None, + ): + super().__init__( + id=id, audio_file_id=audio_file_id, caption=caption, + parse_mode=parse_mode, caption_entities=caption_entities, + reply_markup=reply_markup, input_message_content=input_message_content, + ) diff --git a/aiogram/types/input_file.py b/aiogram/types/input_file.py index 3c397395..3a78c499 100644 --- a/aiogram/types/input_file.py +++ b/aiogram/types/input_file.py @@ -4,6 +4,8 @@ import io import logging import os import secrets +from pathlib import Path +from typing import Union import aiohttp @@ -25,7 +27,7 @@ class InputFile(base.TelegramObject): https://core.telegram.org/bots/api#inputfile """ - def __init__(self, path_or_bytesio, filename=None, conf=None): + def __init__(self, path_or_bytesio: Union[str, io.IOBase, Path], filename=None, conf=None): """ :param path_or_bytesio: @@ -45,6 +47,12 @@ class InputFile(base.TelegramObject): elif isinstance(path_or_bytesio, _WebPipe): self._path = None self._file = path_or_bytesio + + elif isinstance(path_or_bytesio, Path): + self._file = path_or_bytesio.open("rb") + self._path = path_or_bytesio.resolve() + if filename is None: + filename = path_or_bytesio.name else: raise TypeError('Not supported file type.') diff --git a/aiogram/types/input_media.py b/aiogram/types/input_media.py index 25422df1..943a534c 100644 --- a/aiogram/types/input_media.py +++ b/aiogram/types/input_media.py @@ -5,6 +5,7 @@ import typing from . import base from . import fields from .input_file import InputFile +from .message_entity import MessageEntity ATTACHMENT_PREFIX = 'attach://' @@ -106,28 +107,48 @@ class InputMediaAnimation(InputMedia): height: base.Integer = fields.Field() duration: base.Integer = fields.Field() - def __init__(self, media: base.InputFile, - thumb: typing.Union[base.InputFile, base.String] = None, - caption: base.String = None, - width: base.Integer = None, height: base.Integer = None, duration: base.Integer = None, - parse_mode: base.String = None, **kwargs): - super(InputMediaAnimation, self).__init__(type='animation', media=media, thumb=thumb, caption=caption, - width=width, height=height, duration=duration, - parse_mode=parse_mode, conf=kwargs) + def __init__( + self, + media: base.InputFile, + thumb: typing.Union[base.InputFile, base.String] = None, + caption: base.String = None, + width: base.Integer = None, + height: base.Integer = None, + duration: base.Integer = None, + parse_mode: base.String = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + **kwargs, + ): + super().__init__( + type='animation', media=media, thumb=thumb, caption=caption, width=width, + height=height, duration=duration, parse_mode=parse_mode, + caption_entities=caption_entities, conf=kwargs, + ) class InputMediaDocument(InputMedia): """ - Represents a photo to be sent. + Represents a general file to be sent. https://core.telegram.org/bots/api#inputmediadocument """ - def __init__(self, media: base.InputFile, thumb: typing.Union[base.InputFile, base.String] = None, - caption: base.String = None, parse_mode: base.String = None, **kwargs): - super(InputMediaDocument, self).__init__(type='document', media=media, thumb=thumb, - caption=caption, parse_mode=parse_mode, - conf=kwargs) + def __init__( + self, + media: base.InputFile, + thumb: typing.Union[base.InputFile, base.String, None] = None, + caption: base.String = None, + parse_mode: base.String = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + disable_content_type_detection: typing.Optional[base.Boolean] = None, + **kwargs, + ): + super().__init__( + type='document', media=media, thumb=thumb, caption=caption, + parse_mode=parse_mode, caption_entities=caption_entities, + disable_content_type_detection=disable_content_type_detection, + conf=kwargs, + ) class InputMediaAudio(InputMedia): @@ -141,17 +162,23 @@ class InputMediaAudio(InputMedia): performer: base.String = fields.Field() title: base.String = fields.Field() - def __init__(self, media: base.InputFile, - thumb: typing.Union[base.InputFile, base.String] = None, - caption: base.String = None, - duration: base.Integer = None, - performer: base.String = None, - title: base.String = None, - parse_mode: base.String = None, **kwargs): - super(InputMediaAudio, self).__init__(type='audio', media=media, thumb=thumb, - caption=caption, duration=duration, - performer=performer, title=title, - parse_mode=parse_mode, conf=kwargs) + def __init__( + self, + media: base.InputFile, + thumb: typing.Union[base.InputFile, base.String] = None, + caption: base.String = None, + duration: base.Integer = None, + performer: base.String = None, + title: base.String = None, + parse_mode: base.String = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + **kwargs, + ): + super().__init__( + type='audio', media=media, thumb=thumb, caption=caption, + duration=duration, performer=performer, title=title, + parse_mode=parse_mode, caption_entities=caption_entities, conf=kwargs, + ) class InputMediaPhoto(InputMedia): @@ -161,11 +188,18 @@ class InputMediaPhoto(InputMedia): https://core.telegram.org/bots/api#inputmediaphoto """ - def __init__(self, media: base.InputFile, thumb: typing.Union[base.InputFile, base.String] = None, - caption: base.String = None, parse_mode: base.String = None, **kwargs): - super(InputMediaPhoto, self).__init__(type='photo', media=media, thumb=thumb, - caption=caption, parse_mode=parse_mode, - conf=kwargs) + def __init__( + self, + media: base.InputFile, + caption: base.String = None, + parse_mode: base.String = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + **kwargs, + ): + super().__init__( + type='photo', media=media, caption=caption, parse_mode=parse_mode, + caption_entities=caption_entities, conf=kwargs, + ) class InputMediaVideo(InputMedia): @@ -179,16 +213,25 @@ class InputMediaVideo(InputMedia): duration: base.Integer = fields.Field() supports_streaming: base.Boolean = fields.Field() - def __init__(self, media: base.InputFile, - thumb: typing.Union[base.InputFile, base.String] = None, - caption: base.String = None, - width: base.Integer = None, height: base.Integer = None, duration: base.Integer = None, - parse_mode: base.String = None, - supports_streaming: base.Boolean = None, **kwargs): - super(InputMediaVideo, self).__init__(type='video', media=media, thumb=thumb, caption=caption, - width=width, height=height, duration=duration, - parse_mode=parse_mode, - supports_streaming=supports_streaming, conf=kwargs) + def __init__( + self, + media: base.InputFile, + thumb: typing.Union[base.InputFile, base.String] = None, + caption: base.String = None, + width: base.Integer = None, + height: base.Integer = None, + duration: base.Integer = None, + parse_mode: base.String = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + supports_streaming: base.Boolean = None, + **kwargs, + ): + super().__init__( + type='video', media=media, thumb=thumb, caption=caption, + width=width, height=height, duration=duration, + parse_mode=parse_mode, caption_entities=caption_entities, + supports_streaming=supports_streaming, conf=kwargs + ) class MediaGroup(base.TelegramObject): diff --git a/aiogram/types/input_message_content.py b/aiogram/types/input_message_content.py index 736a4454..522d44c5 100644 --- a/aiogram/types/input_message_content.py +++ b/aiogram/types/input_message_content.py @@ -2,6 +2,7 @@ import typing from . import base from . import fields +from .message_entity import MessageEntity class InputMessageContent(base.TelegramObject): @@ -40,17 +41,31 @@ class InputLocationMessageContent(InputMessageContent): """ Represents the content of a location message to be sent as the result of an inline query. - Note: This will only work in Telegram versions released after 9 April, 2016. - Older clients will ignore them. - https://core.telegram.org/bots/api#inputlocationmessagecontent """ latitude: base.Float = fields.Field() longitude: base.Float = fields.Field() + horizontal_accuracy: typing.Optional[base.Float] = fields.Field() + live_period: typing.Optional[base.Integer] = fields.Field() + heading: typing.Optional[base.Integer] = fields.Field() + proximity_alert_radius: typing.Optional[base.Integer] = fields.Field() - def __init__(self, latitude: base.Float, - longitude: base.Float): - super(InputLocationMessageContent, self).__init__(latitude=latitude, longitude=longitude) + def __init__(self, + latitude: base.Float, + longitude: base.Float, + horizontal_accuracy: typing.Optional[base.Float] = None, + live_period: typing.Optional[base.Integer] = None, + heading: typing.Optional[base.Integer] = None, + proximity_alert_radius: typing.Optional[base.Integer] = None, + ): + super().__init__( + latitude=latitude, + longitude=longitude, + horizontal_accuracy=horizontal_accuracy, + live_period=live_period, + heading=heading, + proximity_alert_radius=proximity_alert_radius, + ) class InputTextMessageContent(InputMessageContent): @@ -69,14 +84,21 @@ class InputTextMessageContent(InputMessageContent): except RuntimeError: pass - def __init__(self, message_text: typing.Optional[base.String] = None, - parse_mode: typing.Optional[base.String] = None, - disable_web_page_preview: typing.Optional[base.Boolean] = None): + def __init__( + self, + message_text: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + disable_web_page_preview: typing.Optional[base.Boolean] = None, + ): if parse_mode is None: parse_mode = self.safe_get_parse_mode() - super(InputTextMessageContent, self).__init__(message_text=message_text, parse_mode=parse_mode, - disable_web_page_preview=disable_web_page_preview) + super().__init__( + message_text=message_text, parse_mode=parse_mode, + caption_entities=caption_entities, + disable_web_page_preview=disable_web_page_preview, + ) class InputVenueMessageContent(InputMessageContent): @@ -93,11 +115,24 @@ class InputVenueMessageContent(InputMessageContent): title: base.String = fields.Field() address: base.String = fields.Field() foursquare_id: base.String = fields.Field() + foursquare_type: base.String = fields.Field() + google_place_id: base.String = fields.Field() + google_place_type: base.String = fields.Field() - def __init__(self, latitude: typing.Optional[base.Float] = None, - longitude: typing.Optional[base.Float] = None, - title: typing.Optional[base.String] = None, - address: typing.Optional[base.String] = None, - foursquare_id: typing.Optional[base.String] = None): - super(InputVenueMessageContent, self).__init__(latitude=latitude, longitude=longitude, title=title, - address=address, foursquare_id=foursquare_id) + def __init__( + self, + latitude: typing.Optional[base.Float] = None, + longitude: typing.Optional[base.Float] = None, + title: typing.Optional[base.String] = None, + address: typing.Optional[base.String] = None, + foursquare_id: typing.Optional[base.String] = None, + foursquare_type: typing.Optional[base.String] = None, + google_place_id: typing.Optional[base.String] = None, + google_place_type: typing.Optional[base.String] = None, + ): + super().__init__( + latitude=latitude, longitude=longitude, title=title, + address=address, foursquare_id=foursquare_id, + foursquare_type=foursquare_type, google_place_id=google_place_id, + google_place_type=google_place_type, + ) diff --git a/aiogram/types/location.py b/aiogram/types/location.py index ea2f81c4..5f159e33 100644 --- a/aiogram/types/location.py +++ b/aiogram/types/location.py @@ -1,3 +1,5 @@ +import typing + from . import base from . import fields @@ -10,3 +12,7 @@ class Location(base.TelegramObject): """ longitude: base.Float = fields.Field() latitude: base.Float = fields.Field() + horizontal_accuracy: typing.Optional[base.Float] = fields.Field() + live_period: typing.Optional[base.Integer] = fields.Field() + heading: typing.Optional[base.Integer] = fields.Field() + proximity_alert_radius: typing.Optional[base.Integer] = fields.Field() diff --git a/aiogram/types/message.py b/aiogram/types/message.py index 9d2ad505..900b731c 100644 --- a/aiogram/types/message.py +++ b/aiogram/types/message.py @@ -6,6 +6,7 @@ import typing from ..utils import helper from ..utils import markdown as md +from ..utils.deprecated import deprecated from ..utils.text_decorations import html_decoration, markdown_decoration from . import base, fields from .animation import Animation @@ -21,9 +22,11 @@ from .input_media import InputMedia, MediaGroup from .invoice import Invoice from .location import Location from .message_entity import MessageEntity +from .message_id import MessageId from .passport_data import PassportData from .photo_size import PhotoSize from .poll import Poll +from .proximity_alert_triggered import ProximityAlertTriggered from .reply_keyboard import ReplyKeyboardMarkup, ReplyKeyboardRemove from .sticker import Sticker from .successful_payment import SuccessfulPayment @@ -43,6 +46,7 @@ class Message(base.TelegramObject): message_id: base.Integer = fields.Field() from_user: User = fields.Field(alias="from", base=User) + sender_chat: Chat = fields.Field(base=Chat) date: datetime.datetime = fields.DateTimeField() chat: Chat = fields.Field(base=Chat) forward_from: User = fields.Field(base=User) @@ -89,6 +93,7 @@ class Message(base.TelegramObject): successful_payment: SuccessfulPayment = fields.Field(base=SuccessfulPayment) connected_website: base.String = fields.Field() passport_data: PassportData = fields.Field(base=PassportData) + proximity_alert_triggered: ProximityAlertTriggered = fields.Field(base=ProximityAlertTriggered) reply_markup: InlineKeyboardMarkup = fields.Field(base=InlineKeyboardMarkup) @property @@ -150,6 +155,8 @@ class Message(base.TelegramObject): return ContentType.GROUP_CHAT_CREATED if self.passport_data: return ContentType.PASSPORT_DATA + if self.proximity_alert_triggered: + return ContentType.PROXIMITY_ALERT_TRIGGERED return ContentType.UNKNOWN @@ -280,9 +287,11 @@ class Message(base.TelegramObject): async def answer( self, text: base.String, - parse_mode: typing.Union[base.String, None] = None, - disable_web_page_preview: typing.Union[base.Boolean, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, + parse_mode: typing.Optional[base.String] = None, + entities: typing.Optional[typing.List[MessageEntity]] = None, + disable_web_page_preview: typing.Optional[base.Boolean] = None, + disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, @@ -297,19 +306,33 @@ class Message(base.TelegramObject): :param text: Text of the message to be sent :type text: :obj:`base.String` + :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. - :type parse_mode: :obj:`typing.Union[base.String, None]` + :type parse_mode: :obj:`typing.Optional[base.String]` + + :param entities: List of special entities that appear in message text, + which can be specified instead of parse_mode + :type entities: :obj:`typing.Optional[typing.List[MessageEntity]]` + :param disable_web_page_preview: Disables link previews for links in this message - :type disable_web_page_preview: :obj:`typing.Union[base.Boolean, None]` + :type disable_web_page_preview: :obj:`typing.Optional[base.Boolean]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + :param reply: fill 'reply_to_message_id' :type reply: :obj:`base.Boolean` + :return: On success, the sent Message is returned :rtype: :obj:`types.Message` """ @@ -317,18 +340,22 @@ class Message(base.TelegramObject): chat_id=self.chat.id, text=text, parse_mode=parse_mode, + entities=entities, disable_web_page_preview=disable_web_page_preview, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, ) async def answer_photo( self, photo: typing.Union[base.InputFile, base.String], - caption: typing.Union[base.String, None] = None, - parse_mode: typing.Union[base.String, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, @@ -345,19 +372,33 @@ class Message(base.TelegramObject): :param photo: Photo to send :type photo: :obj:`typing.Union[base.InputFile, base.String]` + :param caption: Photo caption (may also be used when resending photos by file_id), 0-1024 characters - :type caption: :obj:`typing.Union[base.String, None]` + :type caption: :obj:`typing.Optional[base.String]` + :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. - :type parse_mode: :obj:`typing.Union[base.String, None]` + :type parse_mode: :obj:`typing.Optional[base.String]` + + :param caption_entities: List of special entities that appear in message text, + which can be specified instead of parse_mode + :type caption_entities: :obj:`typing.Optional[typing.List[MessageEntity]]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + :param reply: fill 'reply_to_message_id' :type reply: :obj:`base.Boolean` + :return: On success, the sent Message is returned :rtype: :obj:`types.Message` """ @@ -366,21 +407,25 @@ class Message(base.TelegramObject): photo=photo, caption=caption, parse_mode=parse_mode, + caption_entities=caption_entities, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, ) async def answer_audio( self, audio: typing.Union[base.InputFile, base.String], - caption: typing.Union[base.String, None] = None, - parse_mode: typing.Union[base.String, None] = None, - duration: typing.Union[base.Integer, None] = None, - performer: typing.Union[base.String, None] = None, - title: typing.Union[base.String, None] = None, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + duration: typing.Optional[base.Integer] = None, + performer: typing.Optional[base.String] = None, + title: typing.Optional[base.String] = None, thumb: typing.Union[typing.Union[base.InputFile, base.String], None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, + disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, @@ -400,27 +445,46 @@ class Message(base.TelegramObject): :param audio: Audio file to send. :type audio: :obj:`typing.Union[base.InputFile, base.String]` + :param caption: Audio caption, 0-200 characters - :type caption: :obj:`typing.Union[base.String, None]` + :type caption: :obj:`typing.Optional[base.String]` + :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. - :type parse_mode: :obj:`typing.Union[base.String, None]` + :type parse_mode: :obj:`typing.Optional[base.String]` + + :param caption_entities: List of special entities that appear in message text, + which can be specified instead of parse_mode + :type caption_entities: :obj:`typing.Optional[typing.List[MessageEntity]]` + :param duration: Duration of the audio in seconds - :type duration: :obj:`typing.Union[base.Integer, None]` + :type duration: :obj:`typing.Optional[base.Integer]` + :param performer: Performer - :type performer: :obj:`typing.Union[base.String, None]` + :type performer: :obj:`typing.Optional[base.String]` + :param title: Track name - :type title: :obj:`typing.Union[base.String, None]` + :type title: :obj:`typing.Optional[base.String]` + :param thumb: Thumbnail of the file sent. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail‘s width and height should not exceed 320. :type thumb: :obj:`typing.Union[typing.Union[base.InputFile, base.String], None]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound. - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + :param reply: fill 'reply_to_message_id' + :type reply: :obj:`base.Boolean` + :return: On success, the sent Message is returned. :rtype: :obj:`types.Message` """ @@ -429,25 +493,29 @@ class Message(base.TelegramObject): audio=audio, caption=caption, parse_mode=parse_mode, + caption_entities=caption_entities, duration=duration, performer=performer, title=title, thumb=thumb, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, ) async def answer_animation( self, animation: typing.Union[base.InputFile, base.String], - duration: typing.Union[base.Integer, None] = None, - width: typing.Union[base.Integer, None] = None, - height: typing.Union[base.Integer, None] = None, + duration: typing.Optional[base.Integer] = None, + width: typing.Optional[base.Integer] = None, + height: typing.Optional[base.Integer] = None, thumb: typing.Union[typing.Union[base.InputFile, base.String], None] = None, - caption: typing.Union[base.String, None] = None, - parse_mode: typing.Union[base.String, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, @@ -469,27 +537,46 @@ class Message(base.TelegramObject): on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get an animation from the Internet, or upload a new animation using multipart/form-data :type animation: :obj:`typing.Union[base.InputFile, base.String]` + :param duration: Duration of sent animation in seconds - :type duration: :obj:`typing.Union[base.Integer, None]` + :type duration: :obj:`typing.Optional[base.Integer]` + :param width: Animation width - :type width: :obj:`typing.Union[base.Integer, None]` + :type width: :obj:`typing.Optional[base.Integer]` + :param height: Animation height - :type height: :obj:`typing.Union[base.Integer, None]` + :type height: :obj:`typing.Optional[base.Integer]` + :param thumb: Thumbnail of the file sent. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail‘s width and height should not exceed 320. :type thumb: :obj:`typing.Union[typing.Union[base.InputFile, base.String], None]` + :param caption: Animation caption (may also be used when resending animation by file_id), 0-1024 characters - :type caption: :obj:`typing.Union[base.String, None]` + :type caption: :obj:`typing.Optional[base.String]` + :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption - :type parse_mode: :obj:`typing.Union[base.String, None]` + :type parse_mode: :obj:`typing.Optional[base.String]` + + :param caption_entities: List of special entities that appear in message text, + which can be specified instead of parse_mode + :type caption_entities: :obj:`typing.Optional[typing.List[MessageEntity]]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply], None]` + :param reply: fill 'reply_to_message_id' + :type reply: :obj:`base.Boolean` + :return: On success, the sent Message is returned :rtype: :obj:`types.Message` """ @@ -502,8 +589,10 @@ class Message(base.TelegramObject): thumb=thumb, caption=caption, parse_mode=parse_mode, + caption_entities=caption_entities, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, ) @@ -511,9 +600,12 @@ class Message(base.TelegramObject): self, document: typing.Union[base.InputFile, base.String], thumb: typing.Union[typing.Union[base.InputFile, base.String], None] = None, - caption: typing.Union[base.String, None] = None, - parse_mode: typing.Union[base.String, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + disable_content_type_detection: typing.Optional[base.Boolean] = None, + disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, @@ -524,30 +616,53 @@ class Message(base.TelegramObject): reply: base.Boolean = False, ) -> Message: """ - Use this method to send general files. - - Bots can currently send files of any type of up to 50 MB in size, this limit may be changed in the future. + Use this method to send general files. On success, the sent Message is + returned. Bots can currently send files of any type of up to 50 MB in size, + this limit may be changed in the future. Source: https://core.telegram.org/bots/api#senddocument - :param document: File to send. + :param document: File to send :type document: :obj:`typing.Union[base.InputFile, base.String]` - :param thumb: Thumbnail of the file sent. The thumbnail should be in JPEG format and less than 200 kB in size. - A thumbnail‘s width and height should not exceed 320. - :type thumb: :obj:`typing.Union[typing.Union[base.InputFile, base.String], None]` - :param caption: Document caption (may also be used when resending documents by file_id), 0-200 characters - :type caption: :obj:`typing.Union[base.String, None]` - :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show bold, italic, - fixed-width text or inline URLs in the media caption - :type parse_mode: :obj:`typing.Union[base.String, None]` - :param disable_notification: Sends the message silently. Users will receive a notification with no sound. - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` - :param reply_markup: 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 + + :param thumb: Thumbnail of the file sent + :type thumb: :obj:`typing.Union[base.InputFile, base.String, None]` + + :param caption: Document caption (may also be used when resending documents + by file_id), 0-1024 characters + :type caption: :obj:`typing.Optional[base.String]` + + :param disable_content_type_detection: Disables automatic server-side content + type detection for files uploaded using multipart/form-data + :type disable_content_type_detection: :obj:`typing.Optional[base.Boolean]` + + :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show + bold, italic, fixed-width text or inline URLs in your bot's message. + :type parse_mode: :obj:`typing.Optional[base.String]` + + :param caption_entities: List of special entities that appear in message text, + which can be specified instead of parse_mode + :type caption_entities: :obj:`typing.Optional[typing.List[MessageEntity]]` + + :param disable_notification: Sends the message silently. Users will receive a + notification with no sound + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, - types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply], None]` - :param reply: fill 'reply_to_message_id' - :return: On success, the sent Message is returned. + types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply], + None]` + + :param reply: True if the message is a reply + :type reply: :obj:`typing.Optional[base.Boolean]` + + :return: On success, the sent Message is returned :rtype: :obj:`types.Message` """ return await self.bot.send_document( @@ -556,21 +671,26 @@ class Message(base.TelegramObject): document=document, caption=caption, parse_mode=parse_mode, + caption_entities=caption_entities, + disable_content_type_detection=disable_content_type_detection, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, ) async def answer_video( self, video: typing.Union[base.InputFile, base.String], - duration: typing.Union[base.Integer, None] = None, - width: typing.Union[base.Integer, None] = None, - height: typing.Union[base.Integer, None] = None, - thumb: typing.Union[typing.Union[base.InputFile, base.String], None] = None, - caption: typing.Union[base.String, None] = None, - parse_mode: typing.Union[base.String, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, + duration: typing.Optional[base.Integer] = None, + width: typing.Optional[base.Integer] = None, + height: typing.Optional[base.Integer] = None, + thumb: typing.Union[base.InputFile, base.String, None] = None, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, @@ -588,27 +708,46 @@ class Message(base.TelegramObject): :param video: Video to send. :type video: :obj:`typing.Union[base.InputFile, base.String]` + :param duration: Duration of sent video in seconds - :type duration: :obj:`typing.Union[base.Integer, None]` + :type duration: :obj:`typing.Optional[base.Integer]` + :param width: Video width - :type width: :obj:`typing.Union[base.Integer, None]` + :type width: :obj:`typing.Optional[base.Integer]` + :param height: Video height - :type height: :obj:`typing.Union[base.Integer, None]` + :type height: :obj:`typing.Optional[base.Integer]` + :param thumb: Thumbnail of the file sent. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail‘s width and height should not exceed 320. - :type thumb: :obj:`typing.Union[typing.Union[base.InputFile, base.String], None]` + :type thumb: :obj:`typing.Union[base.InputFile, base.String, None]` + :param caption: Video caption (may also be used when resending videos by file_id), 0-200 characters - :type caption: :obj:`typing.Union[base.String, None]` + :type caption: :obj:`typing.Optional[base.String]` + :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption - :type parse_mode: :obj:`typing.Union[base.String, None]` + :type parse_mode: :obj:`typing.Optional[base.String]` + + :param caption_entities: List of special entities that appear in message text, + which can be specified instead of parse_mode + :type caption_entities: :obj:`typing.Optional[typing.List[MessageEntity]]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound. - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + :param reply: fill 'reply_to_message_id' + :type reply: :obj:`base.Boolean` + :return: On success, the sent Message is returned. :rtype: :obj:`types.Message` """ @@ -621,18 +760,22 @@ class Message(base.TelegramObject): thumb=thumb, caption=caption, parse_mode=parse_mode, + caption_entities=caption_entities, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, ) async def answer_voice( self, voice: typing.Union[base.InputFile, base.String], - caption: typing.Union[base.String, None] = None, - parse_mode: typing.Union[base.String, None] = None, - duration: typing.Union[base.Integer, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + duration: typing.Optional[base.Integer] = None, + disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, @@ -653,20 +796,36 @@ class Message(base.TelegramObject): :param voice: Audio file to send. :type voice: :obj:`typing.Union[base.InputFile, base.String]` + :param caption: Voice message caption, 0-200 characters - :type caption: :obj:`typing.Union[base.String, None]` + :type caption: :obj:`typing.Optional[base.String]` + :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption - :type parse_mode: :obj:`typing.Union[base.String, None]` + :type parse_mode: :obj:`typing.Optional[base.String]` + + :param caption_entities: List of special entities that appear in message text, + which can be specified instead of parse_mode + :type caption_entities: :obj:`typing.Optional[typing.List[MessageEntity]]` + :param duration: Duration of the voice message in seconds - :type duration: :obj:`typing.Union[base.Integer, None]` + :type duration: :obj:`typing.Optional[base.Integer]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound. - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + :param reply: fill 'reply_to_message_id' + :type reply: :obj:`base.Boolean` + :return: On success, the sent Message is returned. :rtype: :obj:`types.Message` """ @@ -675,19 +834,22 @@ class Message(base.TelegramObject): voice=voice, caption=caption, parse_mode=parse_mode, + caption_entities=caption_entities, duration=duration, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, ) async def answer_video_note( self, video_note: typing.Union[base.InputFile, base.String], - duration: typing.Union[base.Integer, None] = None, - length: typing.Union[base.Integer, None] = None, + duration: typing.Optional[base.Integer] = None, + length: typing.Optional[base.Integer] = None, thumb: typing.Union[typing.Union[base.InputFile, base.String], None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, + disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, @@ -705,20 +867,32 @@ class Message(base.TelegramObject): :param video_note: Video note to send. :type video_note: :obj:`typing.Union[base.InputFile, base.String]` + :param duration: Duration of sent video in seconds - :type duration: :obj:`typing.Union[base.Integer, None]` + :type duration: :obj:`typing.Optional[base.Integer]` + :param length: Video width and height - :type length: :obj:`typing.Union[base.Integer, None]` + :type length: :obj:`typing.Optional[base.Integer]` + :param thumb: Thumbnail of the file sent. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail‘s width and height should not exceed 320. :type thumb: :obj:`typing.Union[typing.Union[base.InputFile, base.String], None]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound. - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + :param reply: fill 'reply_to_message_id' + :type reply: :obj:`base.Boolean` + :return: On success, the sent Message is returned. :rtype: :obj:`types.Message` """ @@ -730,25 +904,39 @@ class Message(base.TelegramObject): thumb=thumb, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, ) async def answer_media_group( self, media: typing.Union[MediaGroup, typing.List], - disable_notification: typing.Union[base.Boolean, None] = None, + disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply: base.Boolean = False, ) -> typing.List[Message]: """ - Use this method to send a group of photos or videos as an album. + Use this method to send a group of photos, videos, documents or audios as + an album. Documents and audio files can be only group 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 :param media: A JSON-serialized array describing photos and videos to be sent :type media: :obj:`typing.Union[types.MediaGroup, typing.List]` - :param disable_notification: Sends the message silently. Users will receive a notification with no sound. - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + + :param disable_notification: Sends the message silently. Users will receive + a notification with no sound. + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply: fill 'reply_to_message_id' + :type reply: :obj:`base.Boolean` + :return: On success, an array of the sent Messages is returned. :rtype: typing.List[types.Message] """ @@ -757,14 +945,16 @@ class Message(base.TelegramObject): media=media, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, ) async def answer_location( self, latitude: base.Float, longitude: base.Float, - live_period: typing.Union[base.Integer, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, + live_period: typing.Optional[base.Integer] = None, + disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, @@ -781,17 +971,28 @@ class Message(base.TelegramObject): :param latitude: Latitude of the location :type latitude: :obj:`base.Float` + :param longitude: Longitude of the location :type longitude: :obj:`base.Float` + :param live_period: Period in seconds for which the location will be updated - :type live_period: :obj:`typing.Union[base.Integer, None]` + :type live_period: :obj:`typing.Optional[base.Integer]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound. - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + :param reply: fill 'reply_to_message_id' + :type reply: :obj:`base.Boolean` + :return: On success, the sent Message is returned. :rtype: :obj:`types.Message` """ @@ -802,6 +1003,7 @@ class Message(base.TelegramObject): live_period=live_period, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, ) @@ -811,8 +1013,12 @@ class Message(base.TelegramObject): longitude: base.Float, title: base.String, address: base.String, - foursquare_id: typing.Union[base.String, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, + foursquare_id: typing.Optional[base.String] = None, + foursquare_type: typing.Optional[base.String] = None, + google_place_id: typing.Optional[base.String] = None, + google_place_type: typing.Optional[base.String] = None, + disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, @@ -827,23 +1033,53 @@ class Message(base.TelegramObject): Source: https://core.telegram.org/bots/api#sendvenue + :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 latitude: Latitude of the venue :type latitude: :obj:`base.Float` + :param longitude: Longitude of the venue :type longitude: :obj:`base.Float` + :param title: Name of the venue :type title: :obj:`base.String` + :param address: Address of the venue :type address: :obj:`base.String` + :param foursquare_id: Foursquare identifier of the venue - :type foursquare_id: :obj:`typing.Union[base.String, None]` - :param disable_notification: Sends the message silently. Users will receive a notification with no sound. - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` - :param reply_markup: 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 + :type foursquare_id: :obj:`typing.Optional[base.String]` + + :param foursquare_type: Foursquare type of the venue, if known + :type foursquare_type: :obj:`typing.Optional[base.String]` + + :param google_place_id: Google Places identifier of the venue + :type google_place_id: :obj:`typing.Optional[base.String]` + + :param google_place_type: Google Places type of the venue. See supported + types: https://developers.google.com/places/web-service/supported_types + :type google_place_type: :obj:`typing.Optional[base.String]` + + :param disable_notification: Sends the message silently. Users will receive + a notification with no sound + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, - types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, + None]` + :param reply: fill 'reply_to_message_id' + :type reply: :obj:`base.Boolean` + :return: On success, the sent Message is returned. :rtype: :obj:`types.Message` """ @@ -854,8 +1090,12 @@ class Message(base.TelegramObject): title=title, address=address, foursquare_id=foursquare_id, + foursquare_type=foursquare_type, + google_place_id=google_place_id, + google_place_type=google_place_type, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, ) @@ -863,8 +1103,9 @@ class Message(base.TelegramObject): self, phone_number: base.String, first_name: base.String, - last_name: typing.Union[base.String, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, + last_name: typing.Optional[base.String] = None, + disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, @@ -881,17 +1122,28 @@ class Message(base.TelegramObject): :param phone_number: Contact's phone number :type phone_number: :obj:`base.String` + :param first_name: Contact's first name :type first_name: :obj:`base.String` + :param last_name: Contact's last name - :type last_name: :obj:`typing.Union[base.String, None]` + :type last_name: :obj:`typing.Optional[base.String]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound. - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + :param reply: fill 'reply_to_message_id' + :type reply: :obj:`base.Boolean` + :return: On success, the sent Message is returned. :rtype: :obj:`types.Message` """ @@ -902,13 +1154,15 @@ class Message(base.TelegramObject): last_name=last_name, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, ) async def answer_sticker( self, sticker: typing.Union[base.InputFile, base.String], - disable_notification: typing.Union[base.Boolean, None] = None, + disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, @@ -925,13 +1179,22 @@ class Message(base.TelegramObject): :param sticker: Sticker to send. :type sticker: :obj:`typing.Union[base.InputFile, base.String]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound. - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + :param reply: fill 'reply_to_message_id' + :type reply: :obj:`base.Boolean` + :return: On success, the sent Message is returned. :rtype: :obj:`types.Message` """ @@ -940,6 +1203,7 @@ class Message(base.TelegramObject): sticker=sticker, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, ) @@ -953,10 +1217,12 @@ class Message(base.TelegramObject): correct_option_id: typing.Optional[base.Integer] = None, explanation: typing.Optional[base.String] = None, explanation_parse_mode: typing.Optional[base.String] = None, - open_period: typing.Union[base.Integer, None] = None, + explanation_entities: typing.Optional[typing.List[MessageEntity]] = None, + open_period: typing.Optional[base.Integer] = None, close_date: typing.Union[base.Integer, datetime.datetime, datetime.timedelta, None] = None, is_closed: typing.Optional[base.Boolean] = None, disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, @@ -967,40 +1233,75 @@ class Message(base.TelegramObject): reply: base.Boolean = False, ) -> Message: """ - Use this method to send a native poll. A native poll can't be sent to a private chat. - On success, the sent Message is returned. + Use this method to send a native poll. On success, the sent Message is + returned. Source: https://core.telegram.org/bots/api#sendpoll :param question: Poll question, 1-255 characters :type question: :obj:`base.String` + :param options: List of answer options, 2-10 strings 1-100 characters each :type options: :obj:`typing.List[base.String]` + :param is_anonymous: True, if the poll needs to be anonymous, defaults to True :type is_anonymous: :obj:`typing.Optional[base.Boolean]` + :param type: Poll type, “quiz” or “regular”, defaults to “regular” :type type: :obj:`typing.Optional[base.String]` - :param allows_multiple_answers: True, if the poll allows multiple answers, ignored for polls in quiz mode, defaults to False + + :param allows_multiple_answers: True, if the poll allows multiple answers, + ignored for polls in quiz mode, defaults to False :type allows_multiple_answers: :obj:`typing.Optional[base.Boolean]` - :param correct_option_id: 0-based identifier of the correct answer option, required for polls in quiz mode + + :param correct_option_id: 0-based identifier of the correct answer option, + required for polls in quiz mode :type correct_option_id: :obj:`typing.Optional[base.Integer]` - :param explanation: Text that is shown when a user chooses an incorrect answer or taps on the lamp icon in a quiz-style poll, 0-200 characters with at most 2 line feeds after entities parsing + + :param explanation: Text that is shown when a user chooses an incorrect + answer or taps on the lamp icon in a quiz-style poll, 0-200 characters + with at most 2 line feeds after entities parsing :type explanation: :obj:`typing.Optional[base.String]` - :param explanation_parse_mode: Mode for parsing entities in the explanation. See formatting options for more details. + + :param explanation_parse_mode: Mode for parsing entities in the explanation. + See formatting options for more details. :type explanation_parse_mode: :obj:`typing.Optional[base.String]` - :param open_period: Amount of time in seconds the poll will be active after creation, 5-600. Can't be used together with close_date. - :type open_period: :obj:`typing.Union[base.Integer, None]` - :param close_date: Point in time (Unix timestamp) when the poll will be automatically closed. Must be at least 5 and no more than 600 seconds in the future. Can't be used together with open_period. - :type close_date: :obj:`typing.Union[base.Integer, datetime.datetime, datetime.timedelta, None]` + + :param explanation_entities: List of special entities that appear in message + text, which can be specified instead of parse_mode + :type explanation_entities: :obj:`typing.Optional[typing.List[MessageEntity]]` + + :param open_period: Amount of time in seconds the poll will be active after + creation, 5-600. Can't be used together with close_date. + :type open_period: :obj:`typing.Optional[base.Integer]` + + :param close_date: Point in time (Unix timestamp) when the poll will be + automatically closed. Must be at least 5 and no more than 600 seconds in + the future. Can't be used together with open_period. + :type close_date: :obj:`typing.Union[base.Integer, datetime.datetime, + datetime.timedelta, None]` + :param is_closed: Pass True, if the poll needs to be immediately closed :type is_closed: :obj:`typing.Optional[base.Boolean]` - :param disable_notification: Sends the message silently. Users will receive a notification with no sound. + + :param disable_notification: Sends the message silently. Users will receive + a notification with no sound. :type disable_notification: :obj:`typing.Optional[Boolean]` - :param reply_markup: 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 + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, - types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, + None]` + :param reply: fill 'reply_to_message_id' + :type reply: :obj:`base.Boolean` + :return: On success, the sent Message is returned :rtype: :obj:`types.Message` """ @@ -1014,18 +1315,21 @@ class Message(base.TelegramObject): correct_option_id=correct_option_id, explanation=explanation, explanation_parse_mode=explanation_parse_mode, + explanation_entities=explanation_entities, open_period=open_period, close_date=close_date, is_closed=is_closed, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, ) async def answer_dice( self, - emoji: typing.Union[base.String, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, + emoji: typing.Optional[base.String] = None, + disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, @@ -1036,22 +1340,39 @@ class Message(base.TelegramObject): reply: base.Boolean = False, ) -> Message: """ - Use this method to send a dice, which will have a random value from 1 to 6. + Use this method to send an animated emoji that will display a random value. On success, the sent Message is returned. - (Yes, we're aware of the “proper” singular of die. - But it's awkward, and we decided to help it change. One dice at a time!) Source: https://core.telegram.org/bots/api#senddice - :param emoji: Emoji on which the dice throw animation is based. Currently, must be one of “🎲” or “🎯”. Defauts to “🎲” - :type emoji: :obj:`typing.Union[base.String, None]` - :param disable_notification: Sends the message silently. Users will receive a notification with no sound. - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` - :param reply_markup: 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 + :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 emoji: 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 “🎲” + :type emoji: :obj:`typing.Optional[base.String]` + + :param disable_notification: Sends the message silently. Users will receive + a notification with no sound + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, - types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, + None]` + :param reply: fill 'reply_to_message_id' + :type reply: :obj:`base.Boolean` + :return: On success, the sent Message is returned. :rtype: :obj:`types.Message` """ @@ -1060,15 +1381,18 @@ class Message(base.TelegramObject): emoji=emoji, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, ) async def reply( self, text: base.String, - parse_mode: typing.Union[base.String, None] = None, - disable_web_page_preview: typing.Union[base.Boolean, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, + parse_mode: typing.Optional[base.String] = None, + entities: typing.Optional[typing.List[MessageEntity]] = None, + disable_web_page_preview: typing.Optional[base.Boolean] = None, + disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, @@ -1083,19 +1407,33 @@ class Message(base.TelegramObject): :param text: Text of the message to be sent :type text: :obj:`base.String` + :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. - :type parse_mode: :obj:`typing.Union[base.String, None]` + :type parse_mode: :obj:`typing.Optional[base.String]` + + :param entities: List of special entities that appear in message text, + which can be specified instead of parse_mode + :type entities: :obj:`typing.Optional[typing.List[MessageEntity]]` + :param disable_web_page_preview: Disables link previews for links in this message - :type disable_web_page_preview: :obj:`typing.Union[base.Boolean, None]` + :type disable_web_page_preview: :obj:`typing.Optional[base.Boolean]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + :param reply: fill 'reply_to_message_id' :type reply: :obj:`base.Boolean` + :return: On success, the sent Message is returned :rtype: :obj:`types.Message` """ @@ -1103,18 +1441,22 @@ class Message(base.TelegramObject): chat_id=self.chat.id, text=text, parse_mode=parse_mode, + entities=entities, disable_web_page_preview=disable_web_page_preview, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, ) async def reply_photo( self, photo: typing.Union[base.InputFile, base.String], - caption: typing.Union[base.String, None] = None, - parse_mode: typing.Union[base.String, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, @@ -1131,19 +1473,33 @@ class Message(base.TelegramObject): :param photo: Photo to send :type photo: :obj:`typing.Union[base.InputFile, base.String]` + :param caption: Photo caption (may also be used when resending photos by file_id), 0-1024 characters - :type caption: :obj:`typing.Union[base.String, None]` + :type caption: :obj:`typing.Optional[base.String]` + :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. - :type parse_mode: :obj:`typing.Union[base.String, None]` + :type parse_mode: :obj:`typing.Optional[base.String]` + + :param caption_entities: List of special entities that appear in message text, + which can be specified instead of parse_mode + :type caption_entities: :obj:`typing.Optional[typing.List[MessageEntity]]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + :param reply: fill 'reply_to_message_id' :type reply: :obj:`base.Boolean` + :return: On success, the sent Message is returned :rtype: :obj:`types.Message` """ @@ -1152,21 +1508,25 @@ class Message(base.TelegramObject): photo=photo, caption=caption, parse_mode=parse_mode, + caption_entities=caption_entities, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, ) async def reply_audio( self, audio: typing.Union[base.InputFile, base.String], - caption: typing.Union[base.String, None] = None, - parse_mode: typing.Union[base.String, None] = None, - duration: typing.Union[base.Integer, None] = None, - performer: typing.Union[base.String, None] = None, - title: typing.Union[base.String, None] = None, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + duration: typing.Optional[base.Integer] = None, + performer: typing.Optional[base.String] = None, + title: typing.Optional[base.String] = None, thumb: typing.Union[typing.Union[base.InputFile, base.String], None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, + disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, @@ -1186,27 +1546,46 @@ class Message(base.TelegramObject): :param audio: Audio file to send. :type audio: :obj:`typing.Union[base.InputFile, base.String]` + :param caption: Audio caption, 0-200 characters - :type caption: :obj:`typing.Union[base.String, None]` + :type caption: :obj:`typing.Optional[base.String]` + :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. - :type parse_mode: :obj:`typing.Union[base.String, None]` + :type parse_mode: :obj:`typing.Optional[base.String]` + + :param caption_entities: List of special entities that appear in message text, + which can be specified instead of parse_mode + :type caption_entities: :obj:`typing.Optional[typing.List[MessageEntity]]` + :param duration: Duration of the audio in seconds - :type duration: :obj:`typing.Union[base.Integer, None]` + :type duration: :obj:`typing.Optional[base.Integer]` + :param performer: Performer - :type performer: :obj:`typing.Union[base.String, None]` + :type performer: :obj:`typing.Optional[base.String]` + :param title: Track name - :type title: :obj:`typing.Union[base.String, None]` + :type title: :obj:`typing.Optional[base.String]` + :param thumb: Thumbnail of the file sent. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail‘s width and height should not exceed 320. :type thumb: :obj:`typing.Union[typing.Union[base.InputFile, base.String], None]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound. - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + :param reply: fill 'reply_to_message_id' + :type reply: :obj:`base.Boolean` + :return: On success, the sent Message is returned. :rtype: :obj:`types.Message` """ @@ -1215,25 +1594,29 @@ class Message(base.TelegramObject): audio=audio, caption=caption, parse_mode=parse_mode, + caption_entities=caption_entities, duration=duration, performer=performer, title=title, thumb=thumb, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, ) async def reply_animation( self, animation: typing.Union[base.InputFile, base.String], - duration: typing.Union[base.Integer, None] = None, - width: typing.Union[base.Integer, None] = None, - height: typing.Union[base.Integer, None] = None, + duration: typing.Optional[base.Integer] = None, + width: typing.Optional[base.Integer] = None, + height: typing.Optional[base.Integer] = None, thumb: typing.Union[typing.Union[base.InputFile, base.String], None] = None, - caption: typing.Union[base.String, None] = None, - parse_mode: typing.Union[base.String, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, @@ -1255,27 +1638,46 @@ class Message(base.TelegramObject): on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get an animation from the Internet, or upload a new animation using multipart/form-data :type animation: :obj:`typing.Union[base.InputFile, base.String]` + :param duration: Duration of sent animation in seconds - :type duration: :obj:`typing.Union[base.Integer, None]` + :type duration: :obj:`typing.Optional[base.Integer]` + :param width: Animation width - :type width: :obj:`typing.Union[base.Integer, None]` + :type width: :obj:`typing.Optional[base.Integer]` + :param height: Animation height - :type height: :obj:`typing.Union[base.Integer, None]` + :type height: :obj:`typing.Optional[base.Integer]` + :param thumb: Thumbnail of the file sent. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail‘s width and height should not exceed 320. :type thumb: :obj:`typing.Union[typing.Union[base.InputFile, base.String], None]` + :param caption: Animation caption (may also be used when resending animation by file_id), 0-1024 characters - :type caption: :obj:`typing.Union[base.String, None]` + :type caption: :obj:`typing.Optional[base.String]` + :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption - :type parse_mode: :obj:`typing.Union[base.String, None]` + :type parse_mode: :obj:`typing.Optional[base.String]` + + :param caption_entities: List of special entities that appear in message text, + which can be specified instead of parse_mode + :type caption_entities: :obj:`typing.Optional[typing.List[MessageEntity]]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply], None]` + :param reply: fill 'reply_to_message_id' + :type reply: :obj:`base.Boolean` + :return: On success, the sent Message is returned :rtype: :obj:`types.Message` """ @@ -1288,8 +1690,10 @@ class Message(base.TelegramObject): thumb=thumb, caption=caption, parse_mode=parse_mode, + caption_entities=caption_entities, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, ) @@ -1297,9 +1701,12 @@ class Message(base.TelegramObject): self, document: typing.Union[base.InputFile, base.String], thumb: typing.Union[typing.Union[base.InputFile, base.String], None] = None, - caption: typing.Union[base.String, None] = None, - parse_mode: typing.Union[base.String, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + disable_content_type_detection: typing.Optional[base.Boolean] = None, + disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, @@ -1310,30 +1717,53 @@ class Message(base.TelegramObject): reply: base.Boolean = True, ) -> Message: """ - Use this method to send general files. - - Bots can currently send files of any type of up to 50 MB in size, this limit may be changed in the future. + Use this method to send general files. On success, the sent Message is + returned. Bots can currently send files of any type of up to 50 MB in size, + this limit may be changed in the future. Source: https://core.telegram.org/bots/api#senddocument - :param document: File to send. + :param document: File to send :type document: :obj:`typing.Union[base.InputFile, base.String]` - :param thumb: Thumbnail of the file sent. The thumbnail should be in JPEG format and less than 200 kB in size. - A thumbnail‘s width and height should not exceed 320. - :type thumb: :obj:`typing.Union[typing.Union[base.InputFile, base.String], None]` - :param caption: Document caption (may also be used when resending documents by file_id), 0-200 characters - :type caption: :obj:`typing.Union[base.String, None]` - :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show bold, italic, - fixed-width text or inline URLs in the media caption - :type parse_mode: :obj:`typing.Union[base.String, None]` - :param disable_notification: Sends the message silently. Users will receive a notification with no sound. - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` - :param reply_markup: 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 + + :param thumb: Thumbnail of the file sent + :type thumb: :obj:`typing.Union[base.InputFile, base.String, None]` + + :param caption: Document caption (may also be used when resending documents + by file_id), 0-1024 characters + :type caption: :obj:`typing.Optional[base.String]` + + :param disable_content_type_detection: Disables automatic server-side content + type detection for files uploaded using multipart/form-data + :type disable_content_type_detection: :obj:`typing.Optional[base.Boolean]` + + :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show + bold, italic, fixed-width text or inline URLs in your bot's message. + :type parse_mode: :obj:`typing.Optional[base.String]` + + :param caption_entities: List of special entities that appear in message text, + which can be specified instead of parse_mode + :type caption_entities: :obj:`typing.Optional[typing.List[MessageEntity]]` + + :param disable_notification: Sends the message silently. Users will receive a + notification with no sound + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, - types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply], None]` - :param reply: fill 'reply_to_message_id' - :return: On success, the sent Message is returned. + types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply], + None]` + + :param reply: True if the message is a reply + :type reply: :obj:`typing.Optional[base.Boolean]` + + :return: On success, the sent Message is returned :rtype: :obj:`types.Message` """ return await self.bot.send_document( @@ -1342,21 +1772,26 @@ class Message(base.TelegramObject): thumb=thumb, caption=caption, parse_mode=parse_mode, + caption_entities=caption_entities, + disable_content_type_detection=disable_content_type_detection, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, ) async def reply_video( self, video: typing.Union[base.InputFile, base.String], - duration: typing.Union[base.Integer, None] = None, - width: typing.Union[base.Integer, None] = None, - height: typing.Union[base.Integer, None] = None, - thumb: typing.Union[typing.Union[base.InputFile, base.String], None] = None, - caption: typing.Union[base.String, None] = None, - parse_mode: typing.Union[base.String, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, + duration: typing.Optional[base.Integer] = None, + width: typing.Optional[base.Integer] = None, + height: typing.Optional[base.Integer] = None, + thumb: typing.Union[base.InputFile, base.String, None] = None, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, @@ -1374,27 +1809,46 @@ class Message(base.TelegramObject): :param video: Video to send. :type video: :obj:`typing.Union[base.InputFile, base.String]` + :param duration: Duration of sent video in seconds - :type duration: :obj:`typing.Union[base.Integer, None]` + :type duration: :obj:`typing.Optional[base.Integer]` + :param width: Video width - :type width: :obj:`typing.Union[base.Integer, None]` + :type width: :obj:`typing.Optional[base.Integer]` + :param height: Video height - :type height: :obj:`typing.Union[base.Integer, None]` + :type height: :obj:`typing.Optional[base.Integer]` + :param thumb: Thumbnail of the file sent. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail‘s width and height should not exceed 320. - :type thumb: :obj:`typing.Union[typing.Union[base.InputFile, base.String], None]` + :type thumb: :obj:`typing.Union[base.InputFile, base.String, None]` + :param caption: Video caption (may also be used when resending videos by file_id), 0-200 characters - :type caption: :obj:`typing.Union[base.String, None]` + :type caption: :obj:`typing.Optional[base.String]` + :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption - :type parse_mode: :obj:`typing.Union[base.String, None]` + :type parse_mode: :obj:`typing.Optional[base.String]` + + :param caption_entities: List of special entities that appear in message text, + which can be specified instead of parse_mode + :type caption_entities: :obj:`typing.Optional[typing.List[MessageEntity]]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound. - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + :param reply: fill 'reply_to_message_id' + :type reply: :obj:`base.Boolean` + :return: On success, the sent Message is returned. :rtype: :obj:`types.Message` """ @@ -1407,18 +1861,22 @@ class Message(base.TelegramObject): thumb=thumb, caption=caption, parse_mode=parse_mode, + caption_entities=caption_entities, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, ) async def reply_voice( self, voice: typing.Union[base.InputFile, base.String], - caption: typing.Union[base.String, None] = None, - parse_mode: typing.Union[base.String, None] = None, - duration: typing.Union[base.Integer, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + duration: typing.Optional[base.Integer] = None, + disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, @@ -1439,20 +1897,36 @@ class Message(base.TelegramObject): :param voice: Audio file to send. :type voice: :obj:`typing.Union[base.InputFile, base.String]` + :param caption: Voice message caption, 0-200 characters - :type caption: :obj:`typing.Union[base.String, None]` + :type caption: :obj:`typing.Optional[base.String]` + :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in the media caption - :type parse_mode: :obj:`typing.Union[base.String, None]` + :type parse_mode: :obj:`typing.Optional[base.String]` + + :param caption_entities: List of special entities that appear in message text, + which can be specified instead of parse_mode + :type caption_entities: :obj:`typing.Optional[typing.List[MessageEntity]]` + :param duration: Duration of the voice message in seconds - :type duration: :obj:`typing.Union[base.Integer, None]` + :type duration: :obj:`typing.Optional[base.Integer]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound. - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + :param reply: fill 'reply_to_message_id' + :type reply: :obj:`base.Boolean` + :return: On success, the sent Message is returned. :rtype: :obj:`types.Message` """ @@ -1461,19 +1935,22 @@ class Message(base.TelegramObject): voice=voice, caption=caption, parse_mode=parse_mode, + caption_entities=caption_entities, duration=duration, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, ) async def reply_video_note( self, video_note: typing.Union[base.InputFile, base.String], - duration: typing.Union[base.Integer, None] = None, - length: typing.Union[base.Integer, None] = None, + duration: typing.Optional[base.Integer] = None, + length: typing.Optional[base.Integer] = None, thumb: typing.Union[typing.Union[base.InputFile, base.String], None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, + disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, @@ -1491,20 +1968,32 @@ class Message(base.TelegramObject): :param video_note: Video note to send. :type video_note: :obj:`typing.Union[base.InputFile, base.String]` + :param duration: Duration of sent video in seconds - :type duration: :obj:`typing.Union[base.Integer, None]` + :type duration: :obj:`typing.Optional[base.Integer]` + :param length: Video width and height - :type length: :obj:`typing.Union[base.Integer, None]` + :type length: :obj:`typing.Optional[base.Integer]` + :param thumb: Thumbnail of the file sent. The thumbnail should be in JPEG format and less than 200 kB in size. A thumbnail‘s width and height should not exceed 320. :type thumb: :obj:`typing.Union[typing.Union[base.InputFile, base.String], None]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound. - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, - types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None] + ` :param reply: fill 'reply_to_message_id' + :type reply: :obj:`base.Boolean` + :return: On success, the sent Message is returned. :rtype: :obj:`types.Message` """ @@ -1516,25 +2005,39 @@ class Message(base.TelegramObject): thumb=thumb, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, ) async def reply_media_group( self, media: typing.Union[MediaGroup, typing.List], - disable_notification: typing.Union[base.Boolean, None] = None, + disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply: base.Boolean = True, ) -> typing.List[Message]: """ - Use this method to send a group of photos or videos as an album. + Use this method to send a group of photos, videos, documents or audios as + an album. Documents and audio files can be only group 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 :param media: A JSON-serialized array describing photos and videos to be sent :type media: :obj:`typing.Union[types.MediaGroup, typing.List]` - :param disable_notification: Sends the message silently. Users will receive a notification with no sound. - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + + :param disable_notification: Sends the message silently. Users will receive + a notification with no sound. + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply: fill 'reply_to_message_id' + :type reply: :obj:`base.Boolean` + :return: On success, an array of the sent Messages is returned. :rtype: typing.List[types.Message] """ @@ -1543,14 +2046,15 @@ class Message(base.TelegramObject): media=media, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, ) async def reply_location( self, latitude: base.Float, longitude: base.Float, - live_period: typing.Union[base.Integer, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, + live_period: typing.Optional[base.Integer] = None, + disable_notification: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, @@ -1570,14 +2074,15 @@ class Message(base.TelegramObject): :param longitude: Longitude of the location :type longitude: :obj:`base.Float` :param live_period: Period in seconds for which the location will be updated - :type live_period: :obj:`typing.Union[base.Integer, None]` + :type live_period: :obj:`typing.Optional[base.Integer]` :param disable_notification: Sends the message silently. Users will receive a notification with no sound. - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` :param reply: fill 'reply_to_message_id' + :type reply: :obj:`base.Boolean` :return: On success, the sent Message is returned. :rtype: :obj:`types.Message` """ @@ -1597,8 +2102,12 @@ class Message(base.TelegramObject): longitude: base.Float, title: base.String, address: base.String, - foursquare_id: typing.Union[base.String, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, + foursquare_id: typing.Optional[base.String] = None, + foursquare_type: typing.Optional[base.String] = None, + google_place_id: typing.Optional[base.String] = None, + google_place_type: typing.Optional[base.String] = None, + disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, @@ -1613,23 +2122,53 @@ class Message(base.TelegramObject): Source: https://core.telegram.org/bots/api#sendvenue + :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 latitude: Latitude of the venue :type latitude: :obj:`base.Float` + :param longitude: Longitude of the venue :type longitude: :obj:`base.Float` + :param title: Name of the venue :type title: :obj:`base.String` + :param address: Address of the venue :type address: :obj:`base.String` + :param foursquare_id: Foursquare identifier of the venue - :type foursquare_id: :obj:`typing.Union[base.String, None]` - :param disable_notification: Sends the message silently. Users will receive a notification with no sound. - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` - :param reply_markup: 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 + :type foursquare_id: :obj:`typing.Optional[base.String]` + + :param foursquare_type: Foursquare type of the venue, if known + :type foursquare_type: :obj:`typing.Optional[base.String]` + + :param google_place_id: Google Places identifier of the venue + :type google_place_id: :obj:`typing.Optional[base.String]` + + :param google_place_type: Google Places type of the venue. See supported + types: https://developers.google.com/places/web-service/supported_types + :type google_place_type: :obj:`typing.Optional[base.String]` + + :param disable_notification: Sends the message silently. Users will receive + a notification with no sound + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, - types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, + None]` + :param reply: fill 'reply_to_message_id' + :type reply: :obj:`base.Boolean` + :return: On success, the sent Message is returned. :rtype: :obj:`types.Message` """ @@ -1640,8 +2179,12 @@ class Message(base.TelegramObject): title=title, address=address, foursquare_id=foursquare_id, + foursquare_type=foursquare_type, + google_place_id=google_place_id, + google_place_type=google_place_type, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, ) @@ -1649,8 +2192,9 @@ class Message(base.TelegramObject): self, phone_number: base.String, first_name: base.String, - last_name: typing.Union[base.String, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, + last_name: typing.Optional[base.String] = None, + disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, @@ -1667,17 +2211,28 @@ class Message(base.TelegramObject): :param phone_number: Contact's phone number :type phone_number: :obj:`base.String` + :param first_name: Contact's first name :type first_name: :obj:`base.String` + :param last_name: Contact's last name - :type last_name: :obj:`typing.Union[base.String, None]` + :type last_name: :obj:`typing.Optional[base.String]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound. - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + :param reply: fill 'reply_to_message_id' + :type reply: :obj:`base.Boolean` + :return: On success, the sent Message is returned. :rtype: :obj:`types.Message` """ @@ -1688,6 +2243,7 @@ class Message(base.TelegramObject): last_name=last_name, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, ) @@ -1701,10 +2257,12 @@ class Message(base.TelegramObject): correct_option_id: typing.Optional[base.Integer] = None, explanation: typing.Optional[base.String] = None, explanation_parse_mode: typing.Optional[base.String] = None, - open_period: typing.Union[base.Integer, None] = None, + explanation_entities: typing.Optional[typing.List[MessageEntity]] = None, + open_period: typing.Optional[base.Integer] = None, close_date: typing.Union[base.Integer, datetime.datetime, datetime.timedelta, None] = None, is_closed: typing.Optional[base.Boolean] = None, disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, @@ -1715,40 +2273,75 @@ class Message(base.TelegramObject): reply: base.Boolean = True, ) -> Message: """ - Use this method to send a native poll. A native poll can't be sent to a private chat. - On success, the sent Message is returned. + Use this method to send a native poll. On success, the sent Message is + returned. Source: https://core.telegram.org/bots/api#sendpoll :param question: Poll question, 1-255 characters :type question: :obj:`base.String` + :param options: List of answer options, 2-10 strings 1-100 characters each :type options: :obj:`typing.List[base.String]` + :param is_anonymous: True, if the poll needs to be anonymous, defaults to True :type is_anonymous: :obj:`typing.Optional[base.Boolean]` + :param type: Poll type, “quiz” or “regular”, defaults to “regular” :type type: :obj:`typing.Optional[base.String]` - :param allows_multiple_answers: True, if the poll allows multiple answers, ignored for polls in quiz mode, defaults to False + + :param allows_multiple_answers: True, if the poll allows multiple answers, + ignored for polls in quiz mode, defaults to False :type allows_multiple_answers: :obj:`typing.Optional[base.Boolean]` - :param correct_option_id: 0-based identifier of the correct answer option, required for polls in quiz mode + + :param correct_option_id: 0-based identifier of the correct answer option, + required for polls in quiz mode :type correct_option_id: :obj:`typing.Optional[base.Integer]` - :param explanation: Text that is shown when a user chooses an incorrect answer or taps on the lamp icon in a quiz-style poll, 0-200 characters with at most 2 line feeds after entities parsing + + :param explanation: Text that is shown when a user chooses an incorrect + answer or taps on the lamp icon in a quiz-style poll, 0-200 characters + with at most 2 line feeds after entities parsing :type explanation: :obj:`typing.Optional[base.String]` - :param explanation_parse_mode: Mode for parsing entities in the explanation. See formatting options for more details. + + :param explanation_parse_mode: Mode for parsing entities in the explanation. + See formatting options for more details. :type explanation_parse_mode: :obj:`typing.Optional[base.String]` - :param open_period: Amount of time in seconds the poll will be active after creation, 5-600. Can't be used together with close_date. - :type open_period: :obj:`typing.Union[base.Integer, None]` - :param close_date: Point in time (Unix timestamp) when the poll will be automatically closed. Must be at least 5 and no more than 600 seconds in the future. Can't be used together with open_period. - :type close_date: :obj:`typing.Union[base.Integer, datetime.datetime, datetime.timedelta, None]` + + :param explanation_entities: List of special entities that appear in message + text, which can be specified instead of parse_mode + :type explanation_entities: :obj:`typing.Optional[typing.List[MessageEntity]]` + + :param open_period: Amount of time in seconds the poll will be active after + creation, 5-600. Can't be used together with close_date. + :type open_period: :obj:`typing.Optional[base.Integer]` + + :param close_date: Point in time (Unix timestamp) when the poll will be + automatically closed. Must be at least 5 and no more than 600 seconds in + the future. Can't be used together with open_period. + :type close_date: :obj:`typing.Union[base.Integer, datetime.datetime, + datetime.timedelta, None]` + :param is_closed: Pass True, if the poll needs to be immediately closed :type is_closed: :obj:`typing.Optional[base.Boolean]` - :param disable_notification: Sends the message silently. Users will receive a notification with no sound. + + :param disable_notification: Sends the message silently. Users will receive + a notification with no sound. :type disable_notification: :obj:`typing.Optional[Boolean]` - :param reply_markup: 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 + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, - types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, + None]` + :param reply: fill 'reply_to_message_id' + :type reply: :obj:`base.Boolean` + :return: On success, the sent Message is returned :rtype: :obj:`types.Message` """ @@ -1762,18 +2355,21 @@ class Message(base.TelegramObject): correct_option_id=correct_option_id, explanation=explanation, explanation_parse_mode=explanation_parse_mode, + explanation_entities=explanation_entities, open_period=open_period, close_date=close_date, is_closed=is_closed, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, ) async def reply_sticker( self, sticker: typing.Union[base.InputFile, base.String], - disable_notification: typing.Union[base.Boolean, None] = None, + disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, @@ -1790,13 +2386,22 @@ class Message(base.TelegramObject): :param sticker: Sticker to send. :type sticker: :obj:`typing.Union[base.InputFile, base.String]` + :param disable_notification: Sends the message silently. Users will receive a notification with no sound. - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + :param reply: fill 'reply_to_message_id' + :type reply: :obj:`base.Boolean` + :return: On success, the sent Message is returned. :rtype: :obj:`types.Message` """ @@ -1805,13 +2410,15 @@ class Message(base.TelegramObject): sticker=sticker, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, ) async def reply_dice( self, - emoji: typing.Union[base.String, None] = None, - disable_notification: typing.Union[base.Boolean, None] = None, + emoji: typing.Optional[base.String] = None, + disable_notification: typing.Optional[base.Boolean] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, @@ -1822,22 +2429,39 @@ class Message(base.TelegramObject): reply: base.Boolean = True, ) -> Message: """ - Use this method to send a dice, which will have a random value from 1 to 6. + Use this method to send an animated emoji that will display a random value. On success, the sent Message is returned. - (Yes, we're aware of the “proper” singular of die. - But it's awkward, and we decided to help it change. One dice at a time!) Source: https://core.telegram.org/bots/api#senddice - :param emoji: Emoji on which the dice throw animation is based. Currently, must be one of “🎲” or “🎯”. Defauts to “🎲” - :type emoji: :obj:`typing.Union[base.String, None]` - :param disable_notification: Sends the message silently. Users will receive a notification with no sound. - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` - :param reply_markup: 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 + :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 emoji: 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 “🎲” + :type emoji: :obj:`typing.Optional[base.String]` + + :param disable_notification: Sends the message silently. Users will receive + a notification with no sound + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + + :param allow_sending_without_reply: Pass True, if the message should be sent + even if the specified replied-to message is not found + :type allow_sending_without_reply: :obj:`typing.Optional[base.Boolean]` + + :param reply_markup: 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 :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, - types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, None]` + types.ReplyKeyboardMarkup, types.ReplyKeyboardRemove, types.ForceReply, + None]` + :param reply: fill 'reply_to_message_id' + :type reply: :obj:`base.Boolean` + :return: On success, the sent Message is returned. :rtype: :obj:`types.Message` """ @@ -1846,13 +2470,14 @@ class Message(base.TelegramObject): emoji=emoji, disable_notification=disable_notification, reply_to_message_id=self.message_id if reply else None, + allow_sending_without_reply=allow_sending_without_reply, reply_markup=reply_markup, ) async def forward( self, chat_id: typing.Union[base.Integer, base.String], - disable_notification: typing.Union[base.Boolean, None] = None, + disable_notification: typing.Optional[base.Boolean] = None, ) -> Message: """ Forward this message @@ -1862,7 +2487,7 @@ class Message(base.TelegramObject): :param chat_id: Unique identifier for the target chat or username of the target channel :type chat_id: :obj:`typing.Union[base.Integer, base.String]` :param disable_notification: Sends the message silently. Users will receive a notification with no sound - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :type disable_notification: :obj:`typing.Optional[base.Boolean]` :return: On success, the sent Message is returned :rtype: :obj:`types.Message` """ @@ -1873,9 +2498,10 @@ class Message(base.TelegramObject): async def edit_text( self, text: base.String, - parse_mode: typing.Union[base.String, None] = None, - disable_web_page_preview: typing.Union[base.Boolean, None] = None, - reply_markup: typing.Union[InlineKeyboardMarkup, None] = None, + parse_mode: typing.Optional[base.String] = None, + entities: typing.Optional[typing.List[MessageEntity]] = None, + disable_web_page_preview: typing.Optional[base.Boolean] = None, + reply_markup: typing.Optional[InlineKeyboardMarkup] = None, ) -> typing.Union[Message, base.Boolean]: """ Use this method to edit text and game messages sent by the bot or via the bot (for inline bots). @@ -1884,13 +2510,21 @@ class Message(base.TelegramObject): :param text: New text of the message :type text: :obj:`base.String` + :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show bold, italic, fixed-width text or inline URLs in your bot's message. - :type parse_mode: :obj:`typing.Union[base.String, None]` + :type parse_mode: :obj:`typing.Optional[base.String]` + + :param entities: List of special entities that appear in message text, + which can be specified instead of parse_mode + :type entities: :obj:`typing.Optional[typing.List[MessageEntity]]` + :param disable_web_page_preview: Disables link previews for links in this message - :type disable_web_page_preview: :obj:`typing.Union[base.Boolean, None]` + :type disable_web_page_preview: :obj:`typing.Optional[base.Boolean]` + :param reply_markup: A JSON-serialized object for an inline keyboard. - :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, None]` + :type reply_markup: :obj:`typing.Optional[types.InlineKeyboardMarkup]` + :return: On success, if edited message is sent by the bot, the edited Message is returned, otherwise True is returned. :rtype: :obj:`typing.Union[types.Message, base.Boolean]` @@ -1900,6 +2534,7 @@ class Message(base.TelegramObject): chat_id=self.chat.id, message_id=self.message_id, parse_mode=parse_mode, + entities=entities, disable_web_page_preview=disable_web_page_preview, reply_markup=reply_markup, ) @@ -1907,23 +2542,32 @@ class Message(base.TelegramObject): async def edit_caption( self, caption: base.String, - parse_mode: typing.Union[base.String, None] = None, - reply_markup: typing.Union[InlineKeyboardMarkup, None] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + reply_markup: typing.Optional[InlineKeyboardMarkup] = None, ) -> typing.Union[Message, base.Boolean]: """ - Use this method to edit captions of messages sent by the bot or via the bot (for inline bots). + Use this method to edit captions of messages sent by the bot or via the bot + (for inline bots). Source: https://core.telegram.org/bots/api#editmessagecaption :param caption: New caption of the message - :type caption: :obj:`typing.Union[base.String, None]` - :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show bold, italic, - fixed-width text or inline URLs in your bot's message. - :type parse_mode: :obj:`typing.Union[base.String, None]` + :type caption: :obj:`typing.Optional[base.String]` + + :param parse_mode: Send Markdown or HTML, if you want Telegram apps to show + bold, italic, fixed-width text or inline URLs in your bot's message. + :type parse_mode: :obj:`typing.Optional[base.String]` + + :param caption_entities: List of special entities that appear in message text, + which can be specified instead of parse_mode + :type caption_entities: :obj:`typing.Optional[typing.List[MessageEntity]]` + :param reply_markup: A JSON-serialized object for an inline keyboard - :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, None]` - :return: On success, if edited message is sent by the bot, the edited Message is returned, - otherwise True is returned. + :type reply_markup: :obj:`typing.Optional[types.InlineKeyboardMarkup]` + + :return: On success, if edited message is sent by the bot, the edited Message + is returned, otherwise True is returned. :rtype: :obj:`typing.Union[types.Message, base.Boolean]` """ return await self.bot.edit_message_caption( @@ -1931,13 +2575,14 @@ class Message(base.TelegramObject): message_id=self.message_id, caption=caption, parse_mode=parse_mode, + caption_entities=caption_entities, reply_markup=reply_markup, ) async def edit_media( self, media: InputMedia, - reply_markup: typing.Union[InlineKeyboardMarkup, None] = None, + reply_markup: typing.Optional[InlineKeyboardMarkup] = None, ) -> typing.Union[Message, base.Boolean]: """ Use this method to edit audio, document, photo, or video messages. @@ -1954,7 +2599,7 @@ class Message(base.TelegramObject): :param media: A JSON-serialized object for a new media content of the message :type media: :obj:`types.InputMedia` :param reply_markup: A JSON-serialized object for a new inline keyboard - :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, None]` + :type reply_markup: :obj:`typing.Optional[types.InlineKeyboardMarkup]` :return: On success, if the edited message was sent by the bot, the edited Message is returned, otherwise True is returned :rtype: :obj:`typing.Union[types.Message, base.Boolean]` @@ -1967,7 +2612,7 @@ class Message(base.TelegramObject): ) async def edit_reply_markup( - self, reply_markup: typing.Union[InlineKeyboardMarkup, None] = None + self, reply_markup: typing.Optional[InlineKeyboardMarkup] = None ) -> typing.Union[Message, base.Boolean]: """ Use this method to edit only the reply markup of messages sent by the bot or via the bot (for inline bots). @@ -1975,7 +2620,7 @@ class Message(base.TelegramObject): Source: https://core.telegram.org/bots/api#editmessagereplymarkup :param reply_markup: A JSON-serialized object for an inline keyboard - :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, None]` + :type reply_markup: :obj:`typing.Optional[types.InlineKeyboardMarkup]` :return: On success, if edited message is sent by the bot, the edited Message is returned, otherwise True is returned. :rtype: :obj:`typing.Union[types.Message, base.Boolean]` @@ -2000,7 +2645,7 @@ class Message(base.TelegramObject): self, latitude: base.Float, longitude: base.Float, - reply_markup: typing.Union[InlineKeyboardMarkup, None] = None, + reply_markup: typing.Optional[InlineKeyboardMarkup] = None, ) -> typing.Union[Message, base.Boolean]: """ Use this method to edit live location messages sent by the bot or via the bot (for inline bots). @@ -2014,7 +2659,7 @@ class Message(base.TelegramObject): :param longitude: Longitude of new location :type longitude: :obj:`base.Float` :param reply_markup: A JSON-serialized object for a new inline keyboard. - :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, None]` + :type reply_markup: :obj:`typing.Optional[types.InlineKeyboardMarkup]` :return: On success, if the edited message was sent by the bot, the edited Message is returned, otherwise True is returned. :rtype: :obj:`typing.Union[types.Message, base.Boolean]` @@ -2028,7 +2673,7 @@ class Message(base.TelegramObject): ) async def stop_live_location( - self, reply_markup: typing.Union[InlineKeyboardMarkup, None] = None + self, reply_markup: typing.Optional[InlineKeyboardMarkup] = None ) -> typing.Union[Message, base.Boolean]: """ Use this method to stop updating a live location message sent by the bot or via the bot @@ -2037,7 +2682,7 @@ class Message(base.TelegramObject): Source: https://core.telegram.org/bots/api#stopmessagelivelocation :param reply_markup: A JSON-serialized object for a new inline keyboard. - :type reply_markup: :obj:`typing.Union[types.InlineKeyboardMarkup, None]` + :type reply_markup: :obj:`typing.Optional[types.InlineKeyboardMarkup]` :return: On success, if the message was sent by the bot, the sent Message is returned, otherwise True is returned. :rtype: :obj:`typing.Union[types.Message, base.Boolean]` @@ -2064,27 +2709,55 @@ class Message(base.TelegramObject): return await self.bot.delete_message(self.chat.id, self.message_id) async def pin( - self, disable_notification: typing.Union[base.Boolean, None] = None + self, disable_notification: typing.Optional[base.Boolean] = None, ) -> base.Boolean: """ - Use this method to pin a message in a supergroup. - The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. + 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 - :param disable_notification: Pass True, if it is not necessary to send a notification to - all group members about the new pinned message - :type disable_notification: :obj:`typing.Union[base.Boolean, None]` + :param disable_notification: Pass True, if it is not necessary to send a + notification to all group members about the new pinned message + :type disable_notification: :obj:`typing.Optional[base.Boolean]` + :return: Returns True on success :rtype: :obj:`base.Boolean` """ return await self.chat.pin_message(self.message_id, disable_notification) + async def unpin(self) -> base.Boolean: + """ + 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 + + :return: Returns True on success + :rtype: :obj:`base.Boolean` + """ + return await self.chat.unpin_message( + message_id=self.message_id, + ) + + @deprecated( + "This method deprecated since Bot API 4.5. Use method `copy_to` instead. \n" + "Read more: https://core.telegram.org/bots/api#copymessage", + stacklevel=3 + ) async def send_copy( self: Message, chat_id: typing.Union[str, int], disable_notification: typing.Optional[bool] = None, + disable_web_page_preview: typing.Optional[bool] = None, reply_to_message_id: typing.Optional[int] = None, + allow_sending_without_reply: typing.Optional[base.Boolean] = None, reply_markup: typing.Union[ InlineKeyboardMarkup, ReplyKeyboardMarkup, None ] = None, @@ -2094,12 +2767,15 @@ class Message(base.TelegramObject): :param chat_id: :param disable_notification: + :param disable_web_page_preview: for text messages only :param reply_to_message_id: + :param allow_sending_without_reply: :param reply_markup: :return: """ kwargs = { "chat_id": chat_id, + "allow_sending_without_reply": allow_sending_without_reply, "reply_markup": reply_markup or self.reply_markup, "parse_mode": ParseMode.HTML, "disable_notification": disable_notification, @@ -2108,6 +2784,7 @@ class Message(base.TelegramObject): text = self.html_text if (self.text or self.caption) else None if self.text: + kwargs["disable_web_page_preview"] = disable_web_page_preview return await self.bot.send_message(text=text, **kwargs) elif self.audio: return await self.bot.send_audio( @@ -2181,6 +2858,33 @@ class Message(base.TelegramObject): else: raise TypeError("This type of message can't be copied.") + async def copy_to( + self, + chat_id: typing.Union[base.Integer, base.String], + caption: typing.Optional[base.String] = None, + parse_mode: typing.Optional[base.String] = None, + caption_entities: typing.Optional[typing.List[MessageEntity]] = None, + 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.Union[InlineKeyboardMarkup, + ReplyKeyboardMarkup, + ReplyKeyboardRemove, + ForceReply, None] = None, + ) -> MessageId: + return await self.bot.copy_message( + chat_id=chat_id, + from_chat_id=self.chat.id, + message_id=self.message_id, + caption=caption, + parse_mode=parse_mode, + caption_entities=caption_entities, + disable_notification=disable_notification, + reply_to_message_id=reply_to_message_id, + allow_sending_without_reply=allow_sending_without_reply, + reply_markup=reply_markup + ) + def __int__(self): return self.message_id @@ -2244,6 +2948,7 @@ class ContentType(helper.Helper): DELETE_CHAT_PHOTO = helper.Item() # delete_chat_photo GROUP_CHAT_CREATED = helper.Item() # group_chat_created PASSPORT_DATA = helper.Item() # passport_data + PROXIMITY_ALERT_TRIGGERED = helper.Item() # proximity_alert_triggered UNKNOWN = helper.Item() # unknown ANY = helper.Item() # any diff --git a/aiogram/types/message_id.py b/aiogram/types/message_id.py new file mode 100644 index 00000000..0157f5e7 --- /dev/null +++ b/aiogram/types/message_id.py @@ -0,0 +1,10 @@ +from . import base, fields + + +class MessageId(base.TelegramObject): + """ + This object represents a unique message identifier. + + https://core.telegram.org/bots/api#messageid + """ + message_id: base.String = fields.Field() diff --git a/aiogram/types/proximity_alert_triggered.py b/aiogram/types/proximity_alert_triggered.py new file mode 100644 index 00000000..240854d8 --- /dev/null +++ b/aiogram/types/proximity_alert_triggered.py @@ -0,0 +1,15 @@ +from . import base +from . import fields +from .user import User + + +class ProximityAlertTriggered(base.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. + + https://core.telegram.org/bots/api#proximityalerttriggered + """ + traveler: User = fields.Field() + watcher: User = fields.Field() + distance: base.Integer = fields.Field() diff --git a/aiogram/types/venue.py b/aiogram/types/venue.py index f7b2a277..b851650b 100644 --- a/aiogram/types/venue.py +++ b/aiogram/types/venue.py @@ -14,3 +14,5 @@ class Venue(base.TelegramObject): address: base.String = fields.Field() foursquare_id: base.String = fields.Field() foursquare_type: base.String = fields.Field() + google_place_id: base.String = fields.Field() + google_place_type: base.String = fields.Field() diff --git a/aiogram/types/video.py b/aiogram/types/video.py index 97dbb90f..d4958761 100644 --- a/aiogram/types/video.py +++ b/aiogram/types/video.py @@ -16,5 +16,6 @@ class Video(base.TelegramObject, mixins.Downloadable): height: base.Integer = fields.Field() duration: base.Integer = fields.Field() thumb: PhotoSize = fields.Field(base=PhotoSize) + file_name: base.String = fields.Field() mime_type: base.String = fields.Field() file_size: base.Integer = fields.Field() diff --git a/aiogram/types/webhook_info.py b/aiogram/types/webhook_info.py index 995d3aaa..dc1a7cd9 100644 --- a/aiogram/types/webhook_info.py +++ b/aiogram/types/webhook_info.py @@ -13,6 +13,7 @@ class WebhookInfo(base.TelegramObject): url: base.String = fields.Field() has_custom_certificate: base.Boolean = fields.Field() pending_update_count: base.Integer = fields.Field() + ip_address: base.String = fields.Field() last_error_date: base.Integer = fields.Field() last_error_message: base.String = fields.Field() max_connections: base.Integer = fields.Field() diff --git a/aiogram/utils/exceptions.py b/aiogram/utils/exceptions.py index a289be25..cc1885dd 100644 --- a/aiogram/utils/exceptions.py +++ b/aiogram/utils/exceptions.py @@ -12,6 +12,7 @@ - MessageTextIsEmpty - MessageCantBeEdited - MessageCantBeDeleted + - MessageCantBeForwarded - MessageToEditNotFound - MessageToReplyNotFound - ToMuchMessages @@ -38,6 +39,7 @@ - URLHostIsEmpty - StartParamInvalid - ButtonDataInvalid + - FileIsTooBig - WrongFileIdentifier - GroupDeactivated - BadWebhook @@ -194,7 +196,7 @@ class MessageToReplyNotFound(MessageError): """ Will be raised when you try to reply to very old or deleted or unknown message. """ - match = 'message to reply not found' + match = 'Reply message not found' class MessageIdentifierNotSpecified(MessageError): @@ -213,6 +215,10 @@ class MessageCantBeDeleted(MessageError): match = 'message can\'t be deleted' +class MessageCantBeForwarded(MessageError): + match = 'message can\'t be forwarded' + + class MessageToEditNotFound(MessageError): match = 'message to edit not found' @@ -347,6 +353,10 @@ class ButtonDataInvalid(BadRequest): text = 'Button data invalid' +class FileIsTooBig(BadRequest): + match = 'File is too big' + + class WrongFileIdentifier(BadRequest): match = 'wrong file identifier/HTTP URL specified' @@ -505,7 +515,7 @@ class Unauthorized(TelegramAPIError, _MatchErrorMixin): class BotKicked(Unauthorized): - match = 'bot was kicked from a chat' + match = 'bot was kicked from' class BotBlocked(Unauthorized): diff --git a/aiogram/utils/executor.py b/aiogram/utils/executor.py index fe4837e3..1b5b0b0b 100644 --- a/aiogram/utils/executor.py +++ b/aiogram/utils/executor.py @@ -354,7 +354,7 @@ class Executor: self.dispatcher.stop_polling() await self.dispatcher.storage.close() await self.dispatcher.storage.wait_closed() - await self.dispatcher.bot.close() + await self.dispatcher.bot.session.close() async def _startup_polling(self): await self._welcome() diff --git a/dev_requirements.txt b/dev_requirements.txt index c0c2a39d..0252e7e1 100644 --- a/dev_requirements.txt +++ b/dev_requirements.txt @@ -16,3 +16,4 @@ sphinxcontrib-programoutput>=0.14 aiohttp-socks>=0.3.4 rethinkdb>=2.4.1 coverage==4.5.3 +motor>=2.2.0 diff --git a/docs/source/dispatcher/filters.rst b/docs/source/dispatcher/filters.rst index f53a4c95..b8f4962e 100644 --- a/docs/source/dispatcher/filters.rst +++ b/docs/source/dispatcher/filters.rst @@ -10,7 +10,7 @@ Filter factory greatly simplifies the reuse of filters when registering handlers Filters factory =============== -.. autoclass:: aiogram.dispatcher.filters.factory.FiltersFactory +.. autoclass:: aiogram.dispatcher.filters.FiltersFactory :members: :show-inheritance: @@ -21,28 +21,28 @@ Builtin filters Command ------- -.. autoclass:: aiogram.dispatcher.filters.builtin.Command +.. autoclass:: aiogram.dispatcher.filters.Command :members: :show-inheritance: CommandStart ------------ -.. autoclass:: aiogram.dispatcher.filters.builtin.CommandStart +.. autoclass:: aiogram.dispatcher.filters.CommandStart :members: :show-inheritance: CommandHelp ----------- -.. autoclass:: aiogram.dispatcher.filters.builtin.CommandHelp +.. autoclass:: aiogram.dispatcher.filters.CommandHelp :members: :show-inheritance: CommandSettings --------------- -.. autoclass:: aiogram.dispatcher.filters.builtin.CommandSettings +.. autoclass:: aiogram.dispatcher.filters.CommandSettings :members: :show-inheritance: @@ -50,7 +50,7 @@ CommandSettings CommandPrivacy -------------- -.. autoclass:: aiogram.dispatcher.filters.builtin.CommandPrivacy +.. autoclass:: aiogram.dispatcher.filters.CommandPrivacy :members: :show-inheritance: @@ -58,7 +58,7 @@ CommandPrivacy Text ---- -.. autoclass:: aiogram.dispatcher.filters.builtin.Text +.. autoclass:: aiogram.dispatcher.filters.Text :members: :show-inheritance: @@ -66,7 +66,7 @@ Text HashTag ------- -.. autoclass:: aiogram.dispatcher.filters.builtin.HashTag +.. autoclass:: aiogram.dispatcher.filters.HashTag :members: :show-inheritance: @@ -74,7 +74,7 @@ HashTag Regexp ------ -.. autoclass:: aiogram.dispatcher.filters.builtin.Regexp +.. autoclass:: aiogram.dispatcher.filters.Regexp :members: :show-inheritance: @@ -82,7 +82,7 @@ Regexp RegexpCommandsFilter -------------------- -.. autoclass:: aiogram.dispatcher.filters.builtin.RegexpCommandsFilter +.. autoclass:: aiogram.dispatcher.filters.RegexpCommandsFilter :members: :show-inheritance: @@ -90,21 +90,21 @@ RegexpCommandsFilter ContentTypeFilter ----------------- -.. autoclass:: aiogram.dispatcher.filters.builtin.ContentTypeFilter +.. autoclass:: aiogram.dispatcher.filters.ContentTypeFilter :members: :show-inheritance: IsSenderContact --------------- -.. autoclass:: aiogram.dispatcher.filters.builtin.IsSenderContact +.. autoclass:: aiogram.dispatcher.filters.IsSenderContact :members: :show-inheritance: StateFilter ----------- -.. autoclass:: aiogram.dispatcher.filters.builtin.StateFilter +.. autoclass:: aiogram.dispatcher.filters.StateFilter :members: :show-inheritance: @@ -112,13 +112,13 @@ StateFilter ExceptionsFilter ---------------- -.. autoclass:: aiogram.dispatcher.filters.builtin.ExceptionsFilter +.. autoclass:: aiogram.dispatcher.filters.ExceptionsFilter :members: :show-inheritance: IDFilter ----------------- +-------- .. autoclass:: aiogram.dispatcher.filters.builtin.IDFilter :members: @@ -126,9 +126,9 @@ IDFilter AdminFilter ----------------- +----------- -.. autoclass:: aiogram.dispatcher.filters.builtin.AdminFilter +.. autoclass:: aiogram.dispatcher.filters.AdminFilter :members: :show-inheritance: @@ -136,23 +136,23 @@ AdminFilter IsReplyFilter ------------- -.. autoclass:: aiogram.dispatcher.filters.filters.IsReplyFilter +.. autoclass:: aiogram.dispatcher.filters.IsReplyFilter :members: :show-inheritance: ForwardedMessageFilter -------------- +---------------------- -.. autoclass:: aiogram.dispatcher.filters.filters.ForwardedMessageFilter +.. autoclass:: aiogram.dispatcher.filters.ForwardedMessageFilter :members: :show-inheritance: ChatTypeFilter -------------- +-------------- -.. autoclass:: aiogram.dispatcher.filters.filters.ChatTypeFilter +.. autoclass:: aiogram.dispatcher.filters.ChatTypeFilter :members: :show-inheritance: @@ -170,19 +170,19 @@ Own filter can be: AbstractFilter -------------- -.. autoclass:: aiogram.dispatcher.filters.filters.AbstractFilter +.. autoclass:: aiogram.dispatcher.filters.AbstractFilter :members: :show-inheritance: Filter ------ -.. autoclass:: aiogram.dispatcher.filters.filters.Filter +.. autoclass:: aiogram.dispatcher.filters.Filter :members: :show-inheritance: BoundFilter ----------- -.. autoclass:: aiogram.dispatcher.filters.filters.BoundFilter +.. autoclass:: aiogram.dispatcher.filters.BoundFilter :members: :show-inheritance: diff --git a/docs/source/dispatcher/fsm.rst b/docs/source/dispatcher/fsm.rst index 93c94aa6..1b00e81e 100644 --- a/docs/source/dispatcher/fsm.rst +++ b/docs/source/dispatcher/fsm.rst @@ -12,15 +12,29 @@ Coming soon... Memory storage ~~~~~~~~~~~~~~ -Coming soon... + +.. autoclass:: aiogram.contrib.fsm_storage.memory.MemoryStorage + :show-inheritance: Redis storage ~~~~~~~~~~~~~ -Coming soon... + +.. autoclass:: aiogram.contrib.fsm_storage.redis.RedisStorage + :show-inheritance: + +Mongo storage +~~~~~~~~~~~~~ + +.. autoclass:: aiogram.contrib.fsm_storage.mongo.MongoStorage + :show-inheritance: + Rethink DB storage ~~~~~~~~~~~~~~~~~~ -Coming soon... + +.. autoclass:: aiogram.contrib.fsm_storage.rethinkdb.RethinkDBStorage + :show-inheritance: + Making own storage's ~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/source/examples/advanced_executor_example.rst b/docs/source/examples/advanced_executor_example.rst index 9eb5d950..a824ebaf 100644 --- a/docs/source/examples/advanced_executor_example.rst +++ b/docs/source/examples/advanced_executor_example.rst @@ -1,28 +1,8 @@ -.. Autogenerated file at 2018-10-28 19:31:48.335963 - ========================= Advanced executor example ========================= -!/usr/bin/env python3 -**This example is outdated** -In this example used ArgumentParser for configuring Your bot. -Provided to start bot with webhook: -python advanced_executor_example.py \ ---token TOKEN_HERE \ ---host 0.0.0.0 \ ---port 8084 \ ---host-name example.com \ ---webhook-port 443 -Or long polling: -python advanced_executor_example.py --token TOKEN_HERE -So... In this example found small trouble: -can't get bot instance in handlers. -If you want to automatic change getting updates method use executor utils (from aiogram.utils.executor) - TODO: Move token to environment variables. - .. literalinclude:: ../../../examples/advanced_executor_example.py :caption: advanced_executor_example.py :language: python :linenos: - :lines: 25- diff --git a/docs/source/examples/broadcast_example.rst b/docs/source/examples/broadcast_example.rst index 97556e73..837ad02f 100644 --- a/docs/source/examples/broadcast_example.rst +++ b/docs/source/examples/broadcast_example.rst @@ -1,5 +1,3 @@ -.. Autogenerated file at 2018-09-08 02:07:37.593501 - ================= Broadcast example ================= diff --git a/docs/source/examples/check_user_language.rst b/docs/source/examples/check_user_language.rst index 0fc2d90e..5d859d43 100644 --- a/docs/source/examples/check_user_language.rst +++ b/docs/source/examples/check_user_language.rst @@ -1,5 +1,3 @@ -.. Autogenerated file at 2018-09-08 02:07:37.558059 - =================== Check user language =================== @@ -10,4 +8,3 @@ Babel is required. :caption: check_user_language.py :language: python :linenos: - :lines: 5- diff --git a/docs/source/examples/echo_bot.rst b/docs/source/examples/echo_bot.rst index 18c45569..dfbecce1 100644 --- a/docs/source/examples/echo_bot.rst +++ b/docs/source/examples/echo_bot.rst @@ -1,8 +1,7 @@ +======== Echo bot ======== -Very simple example of the bot which will sent text of the received messages to the sender - .. literalinclude:: ../../../examples/echo_bot.py :caption: echo_bot.py :language: python diff --git a/docs/source/examples/finite_state_machine_example.rst b/docs/source/examples/finite_state_machine_example.rst index 3eea4a22..29e251b8 100644 --- a/docs/source/examples/finite_state_machine_example.rst +++ b/docs/source/examples/finite_state_machine_example.rst @@ -1,5 +1,3 @@ -.. Autogenerated file at 2018-09-08 02:07:37.595032 - ============================ Finite state machine example ============================ diff --git a/docs/source/examples/i18n_example.rst b/docs/source/examples/i18n_example.rst index 875006be..dc794619 100644 --- a/docs/source/examples/i18n_example.rst +++ b/docs/source/examples/i18n_example.rst @@ -1,28 +1,8 @@ -.. Autogenerated file at 2018-09-08 02:07:37.591007 - ============ I18n example ============ -Internalize your bot -Step 1: extract texts -# pybabel extract i18n_example.py -o locales/mybot.pot -Step 2: create *.po files. For e.g. create en, ru, uk locales. -# echo {en,ru,uk} | xargs -n1 pybabel init -i locales/mybot.pot -d locales -D mybot -l -Step 3: translate texts -Step 4: compile translations -# pybabel compile -d locales -D mybot -Step 5: When you change the code of your bot you need to update po & mo files. -Step 5.1: regenerate pot file: -command from step 1 -Step 5.2: update po files -# pybabel update -d locales -D mybot -i locales/mybot.pot -Step 5.3: update your translations -Step 5.4: compile mo files -command from step 4 - .. literalinclude:: ../../../examples/i18n_example.py :caption: i18n_example.py :language: python :linenos: - :lines: 22- diff --git a/docs/source/examples/index.rst b/docs/source/examples/index.rst index 2bedaa52..c5be4bfc 100644 --- a/docs/source/examples/index.rst +++ b/docs/source/examples/index.rst @@ -19,3 +19,4 @@ Examples payments broadcast_example media_group + local_server diff --git a/docs/source/examples/inline_bot.rst b/docs/source/examples/inline_bot.rst index b6059974..ca3d227c 100644 --- a/docs/source/examples/inline_bot.rst +++ b/docs/source/examples/inline_bot.rst @@ -1,5 +1,3 @@ -.. Autogenerated file at 2018-09-08 02:07:37.561907 - ========== Inline bot ========== diff --git a/docs/source/examples/local_server.rst b/docs/source/examples/local_server.rst new file mode 100644 index 00000000..6e056a6f --- /dev/null +++ b/docs/source/examples/local_server.rst @@ -0,0 +1,8 @@ +============ +Local server +============ + +.. literalinclude:: ../../../examples/local_server.py + :caption: local_server.py + :language: python + :linenos: diff --git a/docs/source/examples/media_group.rst b/docs/source/examples/media_group.rst index ebf2d3f2..1eb12e4f 100644 --- a/docs/source/examples/media_group.rst +++ b/docs/source/examples/media_group.rst @@ -1,5 +1,3 @@ -.. Autogenerated file at 2018-09-08 02:07:37.566615 - =========== Media group =========== diff --git a/docs/source/examples/middleware_and_antiflood.rst b/docs/source/examples/middleware_and_antiflood.rst index 4f634c93..ce9e99db 100644 --- a/docs/source/examples/middleware_and_antiflood.rst +++ b/docs/source/examples/middleware_and_antiflood.rst @@ -1,5 +1,3 @@ -.. Autogenerated file at 2018-09-08 02:07:37.560132 - ======================== Middleware and antiflood ======================== diff --git a/docs/source/examples/payments.rst b/docs/source/examples/payments.rst index 7b634ce7..f663c8ee 100644 --- a/docs/source/examples/payments.rst +++ b/docs/source/examples/payments.rst @@ -1,5 +1,3 @@ -.. Autogenerated file at 2018-09-08 02:07:37.579017 - ======== Payments ======== diff --git a/docs/source/examples/proxy_and_emojize.rst b/docs/source/examples/proxy_and_emojize.rst index 3dbaa268..96a4f9a7 100644 --- a/docs/source/examples/proxy_and_emojize.rst +++ b/docs/source/examples/proxy_and_emojize.rst @@ -1,5 +1,3 @@ -.. Autogenerated file at 2018-09-08 02:07:37.555359 - ================= Proxy and emojize ================= diff --git a/docs/source/examples/regexp_commands_filter_example.rst b/docs/source/examples/regexp_commands_filter_example.rst index 36452350..e524640a 100644 --- a/docs/source/examples/regexp_commands_filter_example.rst +++ b/docs/source/examples/regexp_commands_filter_example.rst @@ -1,5 +1,3 @@ -.. Autogenerated file at 2018-09-08 02:07:37.568530 - ============================== Regexp commands filter example ============================== diff --git a/docs/source/examples/throtling_example.rst b/docs/source/examples/throtling_example.rst index eaeb337e..258d3d22 100644 --- a/docs/source/examples/throtling_example.rst +++ b/docs/source/examples/throtling_example.rst @@ -1,14 +1,8 @@ -.. Autogenerated file at 2018-09-08 02:07:37.563878 +================== +Throttling example +================== -================= -Throtling example -================= - -Example for throttling manager. -You can use that for flood controlling. - -.. literalinclude:: ../../../examples/throtling_example.py - :caption: throtling_example.py +.. literalinclude:: ../../../examples/throttling_example.py + :caption: throttling_example.py :language: python :linenos: - :lines: 7- diff --git a/docs/source/examples/webhook_example.rst b/docs/source/examples/webhook_example.rst index 48de8622..ce71339a 100644 --- a/docs/source/examples/webhook_example.rst +++ b/docs/source/examples/webhook_example.rst @@ -1,13 +1,8 @@ -.. Autogenerated file at 2018-10-28 19:31:48.341172 - =============== Webhook example =============== -Example outdated - .. literalinclude:: ../../../examples/webhook_example.py :caption: webhook_example.py :language: python :linenos: - :lines: 5- diff --git a/docs/source/examples/webhook_example_2.rst b/docs/source/examples/webhook_example_2.rst index 2ffdfed9..8c104f12 100644 --- a/docs/source/examples/webhook_example_2.rst +++ b/docs/source/examples/webhook_example_2.rst @@ -1,10 +1,8 @@ -.. Autogenerated file at 2018-09-08 02:07:37.576034 +=================== +Webhook example old +=================== -================= -Webhook example 2 -================= - -.. literalinclude:: ../../../examples/webhook_example_2.py +.. literalinclude:: ../../../examples/webhook_example_old.py :caption: webhook_example_2.py :language: python :linenos: diff --git a/docs/source/index.rst b/docs/source/index.rst index 0ac6eccd..e08e8830 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -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-4.9-blue.svg?style=flat-square&logo=telegram + .. image:: https://img.shields.io/badge/Telegram%20Bot%20API-5.0-blue.svg?style=flat-square&logo=telegram :target: https://core.telegram.org/bots/api :alt: Telegram Bot API diff --git a/docs/source/quick_start.rst b/docs/source/quick_start.rst index 319886ce..eb8551db 100644 --- a/docs/source/quick_start.rst +++ b/docs/source/quick_start.rst @@ -24,7 +24,7 @@ Next step: interaction with bots starts with one command. Register your first co :language: python :lines: 20-25 -If you want to handle all messages in the chat simply add handler without filters: +If you want to handle all text messages in the chat simply add handler without filters: .. literalinclude:: ../../examples/echo_bot.py :language: python diff --git a/docs/source/utils/index.rst b/docs/source/utils/index.rst index 1ac3777c..4865518e 100644 --- a/docs/source/utils/index.rst +++ b/docs/source/utils/index.rst @@ -13,3 +13,4 @@ Utils parts json emoji + deep_linking diff --git a/examples/local_server.py b/examples/local_server.py new file mode 100644 index 00000000..7dbc4aca --- /dev/null +++ b/examples/local_server.py @@ -0,0 +1,27 @@ +import logging + +from aiogram import Bot, Dispatcher, executor, types +from aiogram.bot.api import TelegramAPIServer +from aiogram.types import ContentType + +API_TOKEN = 'BOT TOKEN HERE' + +# Configure logging +logging.basicConfig(level=logging.INFO) + +# Create private Bot API server endpoints wrapper +local_server = TelegramAPIServer.from_base('http://localhost') + +# Initialize bot with using local server +bot = Bot(token=API_TOKEN, server=local_server) +# ... and dispatcher +dp = Dispatcher(bot) + + +@dp.message_handler(content_types=ContentType.ANY) +async def echo(message: types.Message): + await message.copy_to(message.chat.id) + + +if __name__ == '__main__': + executor.start_polling(dp, skip_updates=True) diff --git a/requirements.txt b/requirements.txt index 7f7dc1ac..6f393257 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,3 @@ -aiohttp>=3.5.4,<4.0.0 -Babel>=2.6.0 -certifi>=2019.3.9 +aiohttp>=3.7.2,<4.0.0 +Babel>=2.8.0 +certifi>=2020.6.20 diff --git a/setup.py b/setup.py index 00f617ee..6f12b437 100755 --- a/setup.py +++ b/setup.py @@ -57,12 +57,13 @@ setup( 'License :: OSI Approved :: MIT License', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', 'Topic :: Software Development :: Libraries :: Application Frameworks', ], install_requires=[ - 'aiohttp>=3.5.4,<4.0.0', - 'Babel>=2.6.0', - 'certifi>=2019.3.9', + 'aiohttp>=3.7.2,<4.0.0', + 'Babel>=2.8.0', + 'certifi>=2020.6.20', ], extras_require={ 'proxy': [ diff --git a/tests/test_bot.py b/tests/test_bot.py index cf1c3c3b..45d3a3fa 100644 --- a/tests/test_bot.py +++ b/tests/test_bot.py @@ -24,6 +24,22 @@ async def test_get_me(bot: Bot, event_loop): assert result == user +async def test_log_out(bot: Bot, event_loop): + """ logOut method test """ + + async with FakeTelegram(message_data=True, loop=event_loop): + result = await bot.log_out() + assert result is True + + +async def test_close_bot(bot: Bot, event_loop): + """ close method test """ + + async with FakeTelegram(message_data=True, loop=event_loop): + result = await bot.close_bot() + assert result is True + + async def test_send_message(bot: Bot, event_loop): """ sendMessage method test """ from .types.dataset import MESSAGE diff --git a/tox.ini b/tox.ini index aff44213..063a9e9c 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py37 +envlist = py38 [testenv] deps = -rdev_requirements.txt