mirror of
https://github.com/aiogram/aiogram.git
synced 2026-04-08 16:37:47 +00:00
Merge branch 'dev-2.x'
# Conflicts: # aiogram/__init__.py
This commit is contained in:
commit
dc235c66c2
58 changed files with 2939 additions and 1242 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -43,5 +43,5 @@ __all__ = (
|
|||
'utils',
|
||||
)
|
||||
|
||||
__version__ = '2.10.1'
|
||||
__api_version__ = '4.9'
|
||||
__version__ = '2.11'
|
||||
__api_version__ = '5.0'
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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]:
|
||||
"""
|
||||
|
|
|
|||
1455
aiogram/bot/bot.py
1455
aiogram/bot/bot.py
File diff suppressed because it is too large
Load diff
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
16
aiogram/types/chat_location.py
Normal file
16
aiogram/types/chat_location.py
Normal file
|
|
@ -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)
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -17,3 +17,5 @@ class DiceEmoji:
|
|||
DICE = '🎲'
|
||||
DART = '🎯'
|
||||
BASKETBALL = '🏀'
|
||||
FOOTBALL = '⚽'
|
||||
SLOT_MACHINE = '🎰'
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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.')
|
||||
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
10
aiogram/types/message_id.py
Normal file
10
aiogram/types/message_id.py
Normal file
|
|
@ -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()
|
||||
15
aiogram/types/proximity_alert_triggered.py
Normal file
15
aiogram/types/proximity_alert_triggered.py
Normal file
|
|
@ -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()
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
|||
|
|
@ -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-
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
.. Autogenerated file at 2018-09-08 02:07:37.593501
|
||||
|
||||
=================
|
||||
Broadcast example
|
||||
=================
|
||||
|
|
|
|||
|
|
@ -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-
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
.. Autogenerated file at 2018-09-08 02:07:37.595032
|
||||
|
||||
============================
|
||||
Finite state machine example
|
||||
============================
|
||||
|
|
|
|||
|
|
@ -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-
|
||||
|
|
|
|||
|
|
@ -19,3 +19,4 @@ Examples
|
|||
payments
|
||||
broadcast_example
|
||||
media_group
|
||||
local_server
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
.. Autogenerated file at 2018-09-08 02:07:37.561907
|
||||
|
||||
==========
|
||||
Inline bot
|
||||
==========
|
||||
|
|
|
|||
8
docs/source/examples/local_server.rst
Normal file
8
docs/source/examples/local_server.rst
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
============
|
||||
Local server
|
||||
============
|
||||
|
||||
.. literalinclude:: ../../../examples/local_server.py
|
||||
:caption: local_server.py
|
||||
:language: python
|
||||
:linenos:
|
||||
|
|
@ -1,5 +1,3 @@
|
|||
.. Autogenerated file at 2018-09-08 02:07:37.566615
|
||||
|
||||
===========
|
||||
Media group
|
||||
===========
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
.. Autogenerated file at 2018-09-08 02:07:37.560132
|
||||
|
||||
========================
|
||||
Middleware and antiflood
|
||||
========================
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
.. Autogenerated file at 2018-09-08 02:07:37.579017
|
||||
|
||||
========
|
||||
Payments
|
||||
========
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
.. Autogenerated file at 2018-09-08 02:07:37.555359
|
||||
|
||||
=================
|
||||
Proxy and emojize
|
||||
=================
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
.. Autogenerated file at 2018-09-08 02:07:37.568530
|
||||
|
||||
==============================
|
||||
Regexp commands filter example
|
||||
==============================
|
||||
|
|
|
|||
|
|
@ -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-
|
||||
|
|
|
|||
|
|
@ -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-
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -13,3 +13,4 @@ Utils
|
|||
parts
|
||||
json
|
||||
emoji
|
||||
deep_linking
|
||||
|
|
|
|||
27
examples/local_server.py
Normal file
27
examples/local_server.py
Normal file
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
|
|||
7
setup.py
7
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': [
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
2
tox.ini
2
tox.ini
|
|
@ -1,5 +1,5 @@
|
|||
[tox]
|
||||
envlist = py37
|
||||
envlist = py38
|
||||
|
||||
[testenv]
|
||||
deps = -rdev_requirements.txt
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue