Bot API 5.0 (#454)

* increased Telegram Bot API version

* AIOG-T-64 added logOut method

* AIOG-T-64 added logOut method test

* AIOG-T-64 logOut type annotation fix

* AIOG-T-65 added close (close_bot) method

* AIOG-T-65 old `close` method deprecation warn

* AIOG-T-65 `close_bot` test added

* AIOG-T-67 added ip_address param to set_webhook, updated docs

* updated deprecation text

Co-authored-by: Martin Winks <mpa@snejugal.ru>

* AIOG-T-69 param `drop_pending_updates` added in methods `setWebhook` and `deleteWebhook`

* AIOG-T-71 new `ChatLocation` class

* AIOG-T-70 updated `Chat` class: bio, linked chats, location

* AIOG-T-68 field `ip_address` added to class `WebhookInfo`

* AIOG-T-72 param `only_if_banned` added to `unbanChatMember` method

* AIOG-T-72 updated Chat.unban shortcut

* AIOG-T-73 field `file_name` added to `Audio` and `Video` classes

* AIOG-T-74 param `disable_content_type_detection` added in `sendDocument` method and `InputMediaDocument` class

* AIOG-T-75 Added the ability to pin messages in private chats (docs update)

* AIOG-T-76 Added the parameter message_id to the method unpinChatMessage to allow unpinning of the specific pinned message

* AIOG-T-77 Added the method unpinAllChatMessages, which can be used to unpin all pinned messages in a chat.

* AIOG-T-78 updated send_media_group description; added media qty check

* AIOG-T-80 field `live_period` added to `Location` class

* AIOG-T-81 Added support for live location heading

* AIOG-T-82 added the field proximity_alert_distance to the classes Location, InlineQueryResultLocation, InputLocationMessageContent; fixed heading in InputLocationMessageContent

* AIOG-T-82 added parameter proximity_alert_distance to the methods sendLocation and editMessageLiveLocation

* AIOG-T-83 Added the type ProximityAlertTriggered

* AIOG-T-83 Added field proximity_alert_triggered to the class Message

* AIOG-T-84 Added the field horizontal_accuracy to the classes Location, InlineQueryResultLocation, InputLocationMessageContent

* AIOG-T-84 Added the parameter horizontal_accuracy to the methods sendLocation and editMessageLiveLocation.

* Added live_period to InputLocationMessageContent (missed?)

* AIOG-T-85 Added the field sender_chat to the class Message

* AIOG-T-86 Added `is_anonymous` field to `chatMember` class

* AIOG-T-87 Added the parameter is_anonymous to the method promoteChatMember

* AIOG-T-89 Added the method `copyMessage`

* AIOG-T-90 Poll docs update

* AIOG-T-91 ability to manually specify text entities

* AIOG-T-92 Google Places as a venue API provider

* AIOG-T-93 Added the field allow_sending_without_reply to the methods

* AIOG-T-94 football and slot machine dice

* removed Optional

Co-authored-by: Ramzan Bekbulatov <bekbulatov.ramzan@ya.ru>

* Apply suggestions from code review

removed Optional

Co-authored-by: Ramzan Bekbulatov <bekbulatov.ramzan@ya.ru>

* Don't use deprecated Bot.close method from dispatcher (Replaced by session.close)

* Fix copyMessage method, update alias (with deprecation)
Fix imports

* AIOG-T-79: Easy way to use custom API server

* Update docs

* Bump requirements

* Rollback email

* AIOG-T-93 allow_sending_without_reply to send_message shortcuts

* AIOG-T-93 added allow_sending_without_reply to send_photo shortcuts

* AIOG-T-93 added allow_sending_without_reply to send_video shortcuts

* Union[type, None] -> Optional[type] refactoring

* AIOG-T-93 added allow_sending_without_reply to send_animation shortcuts

* added type hint to reply field

* AIOG-T-93 added allow_sending_without_reply to send_audio shortcuts

* AIOG-T-93 added allow_sending_without_reply to send_document shortcuts

* AIOG-T-93 added allow_sending_without_reply to send_sticker shortcuts

* AIOG-T-93 added allow_sending_without_reply to send_video_note shortcuts

* AIOG-T-93 added allow_sending_without_reply to send_voice shortcuts

* AIOG-T-93 added allow_sending_without_reply to send_location shortcuts

* AIOG-T-93 added allow_sending_without_reply to send_venue shortcuts

* AIOG-T-93 added allow_sending_without_reply to send_contact shortcuts

* AIOG-T-93 added allow_sending_without_reply to send_poll shortcuts

* AIOG-T-93 added allow_sending_without_reply to send_dice shortcuts

* AIOG-T-93 added allow_sending_without_reply to send_media_group shortcuts

* AIOG-T-92 added google_place_ to send_venue shortcuts

* AIOG-T-91 added entities to send_message shortcuts

* AIOG-T-91 added caption_entities to send_photo shortcuts

* AIOG-T-91 added caption_entities to send_video shortcuts

* AIOG-T-91 added caption_entities to send_animation shortcuts

* AIOG-T-91 added caption_entities to send_audio shortcuts

* AIOG-T-91 added caption_entities to send_document shortcuts

* AIOG-T-91 added caption_entities to send_voice shortcuts

* AIOG-T-91 added explanation_parse_mode to send_poll shortcuts

* AIOG-T-91 added entities to edit_message_text shortcuts

* AIOG-T-91 added caption_entities to edit_message_caption shortcuts

* fixed types.MessageEntity -> MessageEntity in docs

Co-authored-by: Martin Winks <mpa@snejugal.ru>
Co-authored-by: Ramzan Bekbulatov <bekbulatov.ramzan@ya.ru>
Co-authored-by: Alex Root Junior <jroot.junior@gmail.com>
This commit is contained in:
Oleg A 2020-11-08 18:51:39 +03:00 committed by GitHub
parent 8c43c209e0
commit 2b060d9ad4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
49 changed files with 2847 additions and 1194 deletions

View file

@ -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)

View file

@ -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]:
"""

File diff suppressed because it is too large Load diff