mirror of
https://github.com/aiogram/aiogram.git
synced 2025-12-11 18:01:04 +00:00
[3.x] Bot API 5.3 + Improvements (#618)
* Regenerate API * Update code * Fixed command filter for photos * Fix tests so they are able to run * Test new and renamed API methods * Reformat files * Fix outer_middleware resolution (#637) (#640) * Fix outer_middleware resolution (#637) * Reformat files * Reorder routers when resolve middlewares Co-authored-by: Alex Root Junior <jroot.junior@gmail.com> * Added possibility to use empty callback data factory filter * Rename KeyboardConstructor to KeyboardBuilder * Fixed type Co-authored-by: evgfilim1 <evgfilim1@yandex.ru>
This commit is contained in:
parent
4599913e18
commit
ac2b0bb198
69 changed files with 1223 additions and 206 deletions
|
|
@ -28,6 +28,7 @@ from ..methods import (
|
|||
AnswerInlineQuery,
|
||||
AnswerPreCheckoutQuery,
|
||||
AnswerShippingQuery,
|
||||
BanChatMember,
|
||||
Close,
|
||||
CopyMessage,
|
||||
CreateChatInviteLink,
|
||||
|
|
@ -35,6 +36,7 @@ from ..methods import (
|
|||
DeleteChatPhoto,
|
||||
DeleteChatStickerSet,
|
||||
DeleteMessage,
|
||||
DeleteMyCommands,
|
||||
DeleteStickerFromSet,
|
||||
DeleteWebhook,
|
||||
EditChatInviteLink,
|
||||
|
|
@ -48,6 +50,7 @@ from ..methods import (
|
|||
GetChat,
|
||||
GetChatAdministrators,
|
||||
GetChatMember,
|
||||
GetChatMemberCount,
|
||||
GetChatMembersCount,
|
||||
GetFile,
|
||||
GetGameHighScores,
|
||||
|
|
@ -105,9 +108,15 @@ from ..methods import (
|
|||
from ..types import (
|
||||
UNSET,
|
||||
BotCommand,
|
||||
BotCommandScope,
|
||||
Chat,
|
||||
ChatInviteLink,
|
||||
ChatMember,
|
||||
ChatMemberAdministrator,
|
||||
ChatMemberBanned,
|
||||
ChatMemberLeft,
|
||||
ChatMemberMember,
|
||||
ChatMemberOwner,
|
||||
ChatMemberRestricted,
|
||||
ChatPermissions,
|
||||
Downloadable,
|
||||
File,
|
||||
|
|
@ -1410,6 +1419,35 @@ class Bot(ContextInstanceMixin["Bot"]):
|
|||
)
|
||||
return await self(call, request_timeout=request_timeout)
|
||||
|
||||
async def ban_chat_member(
|
||||
self,
|
||||
chat_id: Union[int, str],
|
||||
user_id: int,
|
||||
until_date: Optional[Union[datetime.datetime, datetime.timedelta, int]] = None,
|
||||
revoke_messages: Optional[bool] = None,
|
||||
request_timeout: Optional[int] = None,
|
||||
) -> bool:
|
||||
"""
|
||||
Use this method to ban a user in a group, a supergroup or a channel. In the case of supergroups and channels, the user will not be able to return to the chat on their own using invite links, etc., unless `unbanned <https://core.telegram.org/bots/api#unbanchatmember>`_ first. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns :code:`True` on success.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#banchatmember
|
||||
|
||||
:param chat_id: Unique identifier for the target group or username of the target supergroup or channel (in the format :code:`@channelusername`)
|
||||
:param user_id: Unique identifier of the target user
|
||||
:param until_date: Date when the user will be unbanned, unix time. If user is banned for more than 366 days or less than 30 seconds from the current time they are considered to be banned forever. Applied for supergroups and channels only.
|
||||
:param revoke_messages: Pass :code:`True` to delete all messages from the chat for the user that is being removed. If :code:`False`, the user will be able to see messages in the group that were sent before the user was removed. Always :code:`True` for supergroups and channels.
|
||||
:param request_timeout: Request timeout
|
||||
:return: In the case of supergroups and channels, the user will not be able to return to
|
||||
the chat on their own using invite links, etc. Returns True on success.
|
||||
"""
|
||||
call = BanChatMember(
|
||||
chat_id=chat_id,
|
||||
user_id=user_id,
|
||||
until_date=until_date,
|
||||
revoke_messages=revoke_messages,
|
||||
)
|
||||
return await self(call, request_timeout=request_timeout)
|
||||
|
||||
async def kick_chat_member(
|
||||
self,
|
||||
chat_id: Union[int, str],
|
||||
|
|
@ -1419,9 +1457,13 @@ class Bot(ContextInstanceMixin["Bot"]):
|
|||
request_timeout: Optional[int] = None,
|
||||
) -> bool:
|
||||
"""
|
||||
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 chat on their own using invite links, etc., unless `unbanned <https://core.telegram.org/bots/api#unbanchatmember>`_ first. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns :code:`True` on success.
|
||||
.. warning:
|
||||
|
||||
Source: https://core.telegram.org/bots/api#kickchatmember
|
||||
Renamed from :code:`kickChatMember` in 5.3 bot API version and can be removed in near future
|
||||
|
||||
Use this method to ban a user in a group, a supergroup or a channel. In the case of supergroups and channels, the user will not be able to return to the chat on their own using invite links, etc., unless `unbanned <https://core.telegram.org/bots/api#unbanchatmember>`_ first. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns :code:`True` on success.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#banchatmember
|
||||
|
||||
:param chat_id: Unique identifier for the target group or username of the target supergroup or channel (in the format :code:`@channelusername`)
|
||||
:param user_id: Unique identifier of the target user
|
||||
|
|
@ -1447,7 +1489,7 @@ class Bot(ContextInstanceMixin["Bot"]):
|
|||
request_timeout: Optional[int] = None,
|
||||
) -> bool:
|
||||
"""
|
||||
Use this method to unban a previously kicked user in a supergroup or channel. The user will **not** return to the group or channel automatically, but will be able to join via link, etc. The bot must be an administrator for this to work. 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 :code:`True` on success.
|
||||
Use this method to unban a previously banned 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 :code:`True` on success.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#unbanchatmember
|
||||
|
||||
|
|
@ -1884,7 +1926,16 @@ class Bot(ContextInstanceMixin["Bot"]):
|
|||
self,
|
||||
chat_id: Union[int, str],
|
||||
request_timeout: Optional[int] = None,
|
||||
) -> List[ChatMember]:
|
||||
) -> List[
|
||||
Union[
|
||||
ChatMemberOwner,
|
||||
ChatMemberAdministrator,
|
||||
ChatMemberMember,
|
||||
ChatMemberRestricted,
|
||||
ChatMemberLeft,
|
||||
ChatMemberBanned,
|
||||
]
|
||||
]:
|
||||
"""
|
||||
Use this method to get a list of administrators in a chat. On success, returns an Array of :class:`aiogram.types.chat_member.ChatMember` objects that contains information about all chat administrators except other bots. If the chat is a group or a supergroup and no administrators were appointed, only the creator will be returned.
|
||||
|
||||
|
|
@ -1902,7 +1953,7 @@ class Bot(ContextInstanceMixin["Bot"]):
|
|||
)
|
||||
return await self(call, request_timeout=request_timeout)
|
||||
|
||||
async def get_chat_members_count(
|
||||
async def get_chat_member_count(
|
||||
self,
|
||||
chat_id: Union[int, str],
|
||||
request_timeout: Optional[int] = None,
|
||||
|
|
@ -1910,7 +1961,30 @@ class Bot(ContextInstanceMixin["Bot"]):
|
|||
"""
|
||||
Use this method to get the number of members in a chat. Returns *Int* on success.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#getchatmemberscount
|
||||
Source: https://core.telegram.org/bots/api#getchatmembercount
|
||||
|
||||
:param chat_id: Unique identifier for the target chat or username of the target supergroup or channel (in the format :code:`@channelusername`)
|
||||
:param request_timeout: Request timeout
|
||||
:return: Returns Int on success.
|
||||
"""
|
||||
call = GetChatMemberCount(
|
||||
chat_id=chat_id,
|
||||
)
|
||||
return await self(call, request_timeout=request_timeout)
|
||||
|
||||
async def get_chat_members_count(
|
||||
self,
|
||||
chat_id: Union[int, str],
|
||||
request_timeout: Optional[int] = None,
|
||||
) -> int:
|
||||
"""
|
||||
.. warning:
|
||||
|
||||
Renamed from :code:`getChatMembersCount` in 5.3 bot API version and can be removed in near future
|
||||
|
||||
Use this method to get the number of members in a chat. Returns *Int* on success.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#getchatmembercount
|
||||
|
||||
:param chat_id: Unique identifier for the target chat or username of the target supergroup or channel (in the format :code:`@channelusername`)
|
||||
:param request_timeout: Request timeout
|
||||
|
|
@ -1926,7 +2000,14 @@ class Bot(ContextInstanceMixin["Bot"]):
|
|||
chat_id: Union[int, str],
|
||||
user_id: int,
|
||||
request_timeout: Optional[int] = None,
|
||||
) -> ChatMember:
|
||||
) -> Union[
|
||||
ChatMemberOwner,
|
||||
ChatMemberAdministrator,
|
||||
ChatMemberMember,
|
||||
ChatMemberRestricted,
|
||||
ChatMemberLeft,
|
||||
ChatMemberBanned,
|
||||
]:
|
||||
"""
|
||||
Use this method to get information about a member of a chat. Returns a :class:`aiogram.types.chat_member.ChatMember` object on success.
|
||||
|
||||
|
|
@ -2022,35 +2103,71 @@ class Bot(ContextInstanceMixin["Bot"]):
|
|||
async def set_my_commands(
|
||||
self,
|
||||
commands: List[BotCommand],
|
||||
scope: Optional[BotCommandScope] = None,
|
||||
language_code: Optional[str] = None,
|
||||
request_timeout: Optional[int] = None,
|
||||
) -> bool:
|
||||
"""
|
||||
Use this method to change the list of the bot's commands. Returns :code:`True` on success.
|
||||
Use this method to change the list of the bot's commands. See `https://core.telegram.org/bots#commands <https://core.telegram.org/bots#commands>`_`https://core.telegram.org/bots#commands <https://core.telegram.org/bots#commands>`_ for more details about bot commands. Returns :code:`True` on success.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#setmycommands
|
||||
|
||||
:param commands: A JSON-serialized list of bot commands to be set as the list of the bot's commands. At most 100 commands can be specified.
|
||||
:param scope: A JSON-serialized object, describing scope of users for which the commands are relevant. Defaults to :class:`aiogram.types.bot_command_scope_default.BotCommandScopeDefault`.
|
||||
:param language_code: A two-letter ISO 639-1 language code. If empty, commands will be applied to all users from the given scope, for whose language there are no dedicated commands
|
||||
:param request_timeout: Request timeout
|
||||
:return: Returns True on success.
|
||||
"""
|
||||
call = SetMyCommands(
|
||||
commands=commands,
|
||||
scope=scope,
|
||||
language_code=language_code,
|
||||
)
|
||||
return await self(call, request_timeout=request_timeout)
|
||||
|
||||
async def delete_my_commands(
|
||||
self,
|
||||
scope: Optional[BotCommandScope] = None,
|
||||
language_code: Optional[str] = None,
|
||||
request_timeout: Optional[int] = None,
|
||||
) -> bool:
|
||||
"""
|
||||
Use this method to delete the list of the bot's commands for the given scope and user language. After deletion, `higher level commands <https://core.telegram.org/bots/api#determining-list-of-commands>`_ will be shown to affected users. Returns :code:`True` on success.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#deletemycommands
|
||||
|
||||
:param scope: A JSON-serialized object, describing scope of users for which the commands are relevant. Defaults to :class:`aiogram.types.bot_command_scope_default.BotCommandScopeDefault`.
|
||||
:param language_code: A two-letter ISO 639-1 language code. If empty, commands will be applied to all users from the given scope, for whose language there are no dedicated commands
|
||||
:param request_timeout: Request timeout
|
||||
:return: Returns True on success.
|
||||
"""
|
||||
call = DeleteMyCommands(
|
||||
scope=scope,
|
||||
language_code=language_code,
|
||||
)
|
||||
return await self(call, request_timeout=request_timeout)
|
||||
|
||||
async def get_my_commands(
|
||||
self,
|
||||
scope: Optional[BotCommandScope] = None,
|
||||
language_code: Optional[str] = None,
|
||||
request_timeout: Optional[int] = None,
|
||||
) -> List[BotCommand]:
|
||||
"""
|
||||
Use this method to get the current list of the bot's commands. Requires no parameters. Returns Array of :class:`aiogram.types.bot_command.BotCommand` on success.
|
||||
Use this method to get the current list of the bot's commands for the given scope and user language. Returns Array of :class:`aiogram.types.bot_command.BotCommand` on success. If commands aren't set, an empty list is returned.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#getmycommands
|
||||
|
||||
:param scope: A JSON-serialized object, describing scope of users. Defaults to :class:`aiogram.types.bot_command_scope_default.BotCommandScopeDefault`.
|
||||
:param language_code: A two-letter ISO 639-1 language code or an empty string
|
||||
:param request_timeout: Request timeout
|
||||
:return: Returns Array of BotCommand on success.
|
||||
:return: Returns Array of BotCommand on success. If commands aren't set, an empty list is
|
||||
returned.
|
||||
"""
|
||||
call = GetMyCommands()
|
||||
call = GetMyCommands(
|
||||
scope=scope,
|
||||
language_code=language_code,
|
||||
)
|
||||
return await self(call, request_timeout=request_timeout)
|
||||
|
||||
# =============================================================================================
|
||||
|
|
|
|||
|
|
@ -60,14 +60,18 @@ class TelegramEventObserver:
|
|||
yield filter_
|
||||
registry.append(filter_)
|
||||
|
||||
def _resolve_inner_middlewares(self) -> List[MiddlewareType]:
|
||||
def _resolve_middlewares(self, *, outer: bool = False) -> List[MiddlewareType]:
|
||||
"""
|
||||
Get all inner middlewares in an tree
|
||||
Get all middlewares in a tree
|
||||
:param *:
|
||||
"""
|
||||
middlewares = []
|
||||
|
||||
for router in self.router.chain_head:
|
||||
for router in reversed(list(self.router.chain_head)):
|
||||
observer = router.observers[self.event_name]
|
||||
if outer:
|
||||
middlewares.extend(observer.outer_middlewares)
|
||||
else:
|
||||
middlewares.extend(observer.middlewares)
|
||||
return middlewares
|
||||
|
||||
|
|
@ -131,7 +135,7 @@ class TelegramEventObserver:
|
|||
Propagate event to handlers and stops propagation on first match.
|
||||
Handler will be called when all its filters is pass.
|
||||
"""
|
||||
wrapped_outer = self._wrap_middleware(self.outer_middlewares, self._trigger)
|
||||
wrapped_outer = self._wrap_middleware(self._resolve_middlewares(outer=True), self._trigger)
|
||||
return await wrapped_outer(event, kwargs)
|
||||
|
||||
async def _trigger(self, event: TelegramObject, **kwargs: Any) -> Any:
|
||||
|
|
@ -141,7 +145,7 @@ class TelegramEventObserver:
|
|||
kwargs.update(data)
|
||||
try:
|
||||
wrapped_inner = self._wrap_middleware(
|
||||
self._resolve_inner_middlewares(), handler.call
|
||||
self._resolve_middlewares(), handler.call
|
||||
)
|
||||
return await wrapped_inner(event, kwargs)
|
||||
except SkipHandler:
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ from __future__ import annotations
|
|||
from decimal import Decimal
|
||||
from enum import Enum
|
||||
from fractions import Fraction
|
||||
from typing import TYPE_CHECKING, Any, Dict, Optional, Type, TypeVar, Union
|
||||
from typing import TYPE_CHECKING, Any, Dict, Literal, Optional, Type, TypeVar, Union
|
||||
from uuid import UUID
|
||||
|
||||
from magic_filter import MagicFilter
|
||||
|
|
@ -86,7 +86,7 @@ class CallbackData(BaseModel):
|
|||
return cls(**payload)
|
||||
|
||||
@classmethod
|
||||
def filter(cls, rule: MagicFilter) -> CallbackQueryFilter:
|
||||
def filter(cls, rule: Optional[MagicFilter] = None) -> CallbackQueryFilter:
|
||||
return CallbackQueryFilter(callback_data=cls, rule=rule)
|
||||
|
||||
class Config:
|
||||
|
|
@ -95,9 +95,9 @@ class CallbackData(BaseModel):
|
|||
|
||||
class CallbackQueryFilter(BaseFilter):
|
||||
callback_data: Type[CallbackData]
|
||||
rule: MagicFilter
|
||||
rule: Optional[MagicFilter] = None
|
||||
|
||||
async def __call__(self, query: CallbackQuery) -> Union[bool, Dict[str, Any]]:
|
||||
async def __call__(self, query: CallbackQuery) -> Union[Literal[False], Dict[str, Any]]:
|
||||
if not isinstance(query, CallbackQuery) or not query.data:
|
||||
return False
|
||||
try:
|
||||
|
|
@ -105,7 +105,7 @@ class CallbackQueryFilter(BaseFilter):
|
|||
except (TypeError, ValueError):
|
||||
return False
|
||||
|
||||
if self.rule.resolve(callback_data):
|
||||
if self.rule is None or self.rule.resolve(callback_data):
|
||||
return {"callback_data": callback_data}
|
||||
return False
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ class Command(BaseFilter):
|
|||
return False
|
||||
|
||||
try:
|
||||
command = await self.parse_command(text=cast(str, message.text), bot=bot)
|
||||
command = await self.parse_command(text=text, bot=bot)
|
||||
except CommandException:
|
||||
return False
|
||||
return {"command": command}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from .answer_callback_query import AnswerCallbackQuery
|
|||
from .answer_inline_query import AnswerInlineQuery
|
||||
from .answer_pre_checkout_query import AnswerPreCheckoutQuery
|
||||
from .answer_shipping_query import AnswerShippingQuery
|
||||
from .ban_chat_member import BanChatMember
|
||||
from .base import Request, Response, TelegramMethod
|
||||
from .close import Close
|
||||
from .copy_message import CopyMessage
|
||||
|
|
@ -11,6 +12,7 @@ from .create_new_sticker_set import CreateNewStickerSet
|
|||
from .delete_chat_photo import DeleteChatPhoto
|
||||
from .delete_chat_sticker_set import DeleteChatStickerSet
|
||||
from .delete_message import DeleteMessage
|
||||
from .delete_my_commands import DeleteMyCommands
|
||||
from .delete_sticker_from_set import DeleteStickerFromSet
|
||||
from .delete_webhook import DeleteWebhook
|
||||
from .edit_chat_invite_link import EditChatInviteLink
|
||||
|
|
@ -24,6 +26,7 @@ from .forward_message import ForwardMessage
|
|||
from .get_chat import GetChat
|
||||
from .get_chat_administrators import GetChatAdministrators
|
||||
from .get_chat_member import GetChatMember
|
||||
from .get_chat_member_count import GetChatMemberCount
|
||||
from .get_chat_members_count import GetChatMembersCount
|
||||
from .get_file import GetFile
|
||||
from .get_game_high_scores import GetGameHighScores
|
||||
|
|
@ -109,6 +112,7 @@ __all__ = (
|
|||
"SendChatAction",
|
||||
"GetUserProfilePhotos",
|
||||
"GetFile",
|
||||
"BanChatMember",
|
||||
"KickChatMember",
|
||||
"UnbanChatMember",
|
||||
"RestrictChatMember",
|
||||
|
|
@ -129,12 +133,14 @@ __all__ = (
|
|||
"LeaveChat",
|
||||
"GetChat",
|
||||
"GetChatAdministrators",
|
||||
"GetChatMemberCount",
|
||||
"GetChatMembersCount",
|
||||
"GetChatMember",
|
||||
"SetChatStickerSet",
|
||||
"DeleteChatStickerSet",
|
||||
"AnswerCallbackQuery",
|
||||
"SetMyCommands",
|
||||
"DeleteMyCommands",
|
||||
"GetMyCommands",
|
||||
"EditMessageText",
|
||||
"EditMessageCaption",
|
||||
|
|
|
|||
33
aiogram/methods/ban_chat_member.py
Normal file
33
aiogram/methods/ban_chat_member.py
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
|
||||
|
||||
from .base import Request, TelegramMethod
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from ..client.bot import Bot
|
||||
|
||||
|
||||
class BanChatMember(TelegramMethod[bool]):
|
||||
"""
|
||||
Use this method to ban a user in a group, a supergroup or a channel. In the case of supergroups and channels, the user will not be able to return to the chat on their own using invite links, etc., unless `unbanned <https://core.telegram.org/bots/api#unbanchatmember>`_ first. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns :code:`True` on success.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#banchatmember
|
||||
"""
|
||||
|
||||
__returning__ = bool
|
||||
|
||||
chat_id: Union[int, str]
|
||||
"""Unique identifier for the target group or username of the target supergroup or channel (in the format :code:`@channelusername`)"""
|
||||
user_id: int
|
||||
"""Unique identifier of the target user"""
|
||||
until_date: Optional[Union[datetime.datetime, datetime.timedelta, int]] = None
|
||||
"""Date when the user will be unbanned, unix time. If user is banned for more than 366 days or less than 30 seconds from the current time they are considered to be banned forever. Applied for supergroups and channels only."""
|
||||
revoke_messages: Optional[bool] = None
|
||||
"""Pass :code:`True` to delete all messages from the chat for the user that is being removed. If :code:`False`, the user will be able to see messages in the group that were sent before the user was removed. Always :code:`True` for supergroups and channels."""
|
||||
|
||||
def build_request(self, bot: Bot) -> Request:
|
||||
data: Dict[str, Any] = self.dict()
|
||||
|
||||
return Request(method="banChatMember", data=data)
|
||||
29
aiogram/methods/delete_my_commands.py
Normal file
29
aiogram/methods/delete_my_commands.py
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any, Dict, Optional
|
||||
|
||||
from ..types import BotCommandScope
|
||||
from .base import Request, TelegramMethod
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from ..client.bot import Bot
|
||||
|
||||
|
||||
class DeleteMyCommands(TelegramMethod[bool]):
|
||||
"""
|
||||
Use this method to delete the list of the bot's commands for the given scope and user language. After deletion, `higher level commands <https://core.telegram.org/bots/api#determining-list-of-commands>`_ will be shown to affected users. Returns :code:`True` on success.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#deletemycommands
|
||||
"""
|
||||
|
||||
__returning__ = bool
|
||||
|
||||
scope: Optional[BotCommandScope] = None
|
||||
"""A JSON-serialized object, describing scope of users for which the commands are relevant. Defaults to :class:`aiogram.types.bot_command_scope_default.BotCommandScopeDefault`."""
|
||||
language_code: Optional[str] = None
|
||||
"""A two-letter ISO 639-1 language code. If empty, commands will be applied to all users from the given scope, for whose language there are no dedicated commands"""
|
||||
|
||||
def build_request(self, bot: Bot) -> Request:
|
||||
data: Dict[str, Any] = self.dict()
|
||||
|
||||
return Request(method="deleteMyCommands", data=data)
|
||||
|
|
@ -2,21 +2,50 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING, Any, Dict, List, Union
|
||||
|
||||
from ..types import ChatMember
|
||||
from ..types import (
|
||||
ChatMemberAdministrator,
|
||||
ChatMemberBanned,
|
||||
ChatMemberLeft,
|
||||
ChatMemberMember,
|
||||
ChatMemberOwner,
|
||||
ChatMemberRestricted,
|
||||
)
|
||||
from .base import Request, TelegramMethod
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from ..client.bot import Bot
|
||||
|
||||
|
||||
class GetChatAdministrators(TelegramMethod[List[ChatMember]]):
|
||||
class GetChatAdministrators(
|
||||
TelegramMethod[
|
||||
List[
|
||||
Union[
|
||||
ChatMemberOwner,
|
||||
ChatMemberAdministrator,
|
||||
ChatMemberMember,
|
||||
ChatMemberRestricted,
|
||||
ChatMemberLeft,
|
||||
ChatMemberBanned,
|
||||
]
|
||||
]
|
||||
]
|
||||
):
|
||||
"""
|
||||
Use this method to get a list of administrators in a chat. On success, returns an Array of :class:`aiogram.types.chat_member.ChatMember` objects that contains information about all chat administrators except other bots. If the chat is a group or a supergroup and no administrators were appointed, only the creator will be returned.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#getchatadministrators
|
||||
"""
|
||||
|
||||
__returning__ = List[ChatMember]
|
||||
__returning__ = List[
|
||||
Union[
|
||||
ChatMemberOwner,
|
||||
ChatMemberAdministrator,
|
||||
ChatMemberMember,
|
||||
ChatMemberRestricted,
|
||||
ChatMemberLeft,
|
||||
ChatMemberBanned,
|
||||
]
|
||||
]
|
||||
|
||||
chat_id: Union[int, str]
|
||||
"""Unique identifier for the target chat or username of the target supergroup or channel (in the format :code:`@channelusername`)"""
|
||||
|
|
|
|||
|
|
@ -2,21 +2,46 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING, Any, Dict, Union
|
||||
|
||||
from ..types import ChatMember
|
||||
from ..types import (
|
||||
ChatMemberAdministrator,
|
||||
ChatMemberBanned,
|
||||
ChatMemberLeft,
|
||||
ChatMemberMember,
|
||||
ChatMemberOwner,
|
||||
ChatMemberRestricted,
|
||||
)
|
||||
from .base import Request, TelegramMethod
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from ..client.bot import Bot
|
||||
|
||||
|
||||
class GetChatMember(TelegramMethod[ChatMember]):
|
||||
class GetChatMember(
|
||||
TelegramMethod[
|
||||
Union[
|
||||
ChatMemberOwner,
|
||||
ChatMemberAdministrator,
|
||||
ChatMemberMember,
|
||||
ChatMemberRestricted,
|
||||
ChatMemberLeft,
|
||||
ChatMemberBanned,
|
||||
]
|
||||
]
|
||||
):
|
||||
"""
|
||||
Use this method to get information about a member of a chat. Returns a :class:`aiogram.types.chat_member.ChatMember` object on success.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#getchatmember
|
||||
"""
|
||||
|
||||
__returning__ = ChatMember
|
||||
__returning__ = Union[
|
||||
ChatMemberOwner,
|
||||
ChatMemberAdministrator,
|
||||
ChatMemberMember,
|
||||
ChatMemberRestricted,
|
||||
ChatMemberLeft,
|
||||
ChatMemberBanned,
|
||||
]
|
||||
|
||||
chat_id: Union[int, str]
|
||||
"""Unique identifier for the target chat or username of the target supergroup or channel (in the format :code:`@channelusername`)"""
|
||||
|
|
|
|||
26
aiogram/methods/get_chat_member_count.py
Normal file
26
aiogram/methods/get_chat_member_count.py
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any, Dict, Union
|
||||
|
||||
from .base import Request, TelegramMethod
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from ..client.bot import Bot
|
||||
|
||||
|
||||
class GetChatMemberCount(TelegramMethod[int]):
|
||||
"""
|
||||
Use this method to get the number of members in a chat. Returns *Int* on success.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#getchatmembercount
|
||||
"""
|
||||
|
||||
__returning__ = int
|
||||
|
||||
chat_id: Union[int, str]
|
||||
"""Unique identifier for the target chat or username of the target supergroup or channel (in the format :code:`@channelusername`)"""
|
||||
|
||||
def build_request(self, bot: Bot) -> Request:
|
||||
data: Dict[str, Any] = self.dict()
|
||||
|
||||
return Request(method="getChatMemberCount", data=data)
|
||||
|
|
@ -10,9 +10,13 @@ if TYPE_CHECKING: # pragma: no cover
|
|||
|
||||
class GetChatMembersCount(TelegramMethod[int]):
|
||||
"""
|
||||
.. warning:
|
||||
|
||||
Renamed from :code:`getChatMembersCount` in 5.3 bot API version and can be removed in near future
|
||||
|
||||
Use this method to get the number of members in a chat. Returns *Int* on success.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#getchatmemberscount
|
||||
Source: https://core.telegram.org/bots/api#getchatmembercount
|
||||
"""
|
||||
|
||||
__returning__ = int
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any, Dict, List
|
||||
from typing import TYPE_CHECKING, Any, Dict, List, Optional
|
||||
|
||||
from ..types import BotCommand
|
||||
from ..types import BotCommand, BotCommandScope
|
||||
from .base import Request, TelegramMethod
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
|
|
@ -11,13 +11,18 @@ if TYPE_CHECKING: # pragma: no cover
|
|||
|
||||
class GetMyCommands(TelegramMethod[List[BotCommand]]):
|
||||
"""
|
||||
Use this method to get the current list of the bot's commands. Requires no parameters. Returns Array of :class:`aiogram.types.bot_command.BotCommand` on success.
|
||||
Use this method to get the current list of the bot's commands for the given scope and user language. Returns Array of :class:`aiogram.types.bot_command.BotCommand` on success. If commands aren't set, an empty list is returned.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#getmycommands
|
||||
"""
|
||||
|
||||
__returning__ = List[BotCommand]
|
||||
|
||||
scope: Optional[BotCommandScope] = None
|
||||
"""A JSON-serialized object, describing scope of users. Defaults to :class:`aiogram.types.bot_command_scope_default.BotCommandScopeDefault`."""
|
||||
language_code: Optional[str] = None
|
||||
"""A two-letter ISO 639-1 language code or an empty string"""
|
||||
|
||||
def build_request(self, bot: Bot) -> Request:
|
||||
data: Dict[str, Any] = self.dict()
|
||||
|
||||
|
|
|
|||
|
|
@ -11,9 +11,13 @@ if TYPE_CHECKING: # pragma: no cover
|
|||
|
||||
class KickChatMember(TelegramMethod[bool]):
|
||||
"""
|
||||
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 chat on their own using invite links, etc., unless `unbanned <https://core.telegram.org/bots/api#unbanchatmember>`_ first. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns :code:`True` on success.
|
||||
.. warning:
|
||||
|
||||
Source: https://core.telegram.org/bots/api#kickchatmember
|
||||
Renamed from :code:`kickChatMember` in 5.3 bot API version and can be removed in near future
|
||||
|
||||
Use this method to ban a user in a group, a supergroup or a channel. In the case of supergroups and channels, the user will not be able to return to the chat on their own using invite links, etc., unless `unbanned <https://core.telegram.org/bots/api#unbanchatmember>`_ first. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Returns :code:`True` on success.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#banchatmember
|
||||
"""
|
||||
|
||||
__returning__ = bool
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Any, Dict, List
|
||||
from typing import TYPE_CHECKING, Any, Dict, List, Optional
|
||||
|
||||
from ..types import BotCommand
|
||||
from ..types import BotCommand, BotCommandScope
|
||||
from .base import Request, TelegramMethod
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
|
|
@ -11,7 +11,7 @@ if TYPE_CHECKING: # pragma: no cover
|
|||
|
||||
class SetMyCommands(TelegramMethod[bool]):
|
||||
"""
|
||||
Use this method to change the list of the bot's commands. Returns :code:`True` on success.
|
||||
Use this method to change the list of the bot's commands. See `https://core.telegram.org/bots#commands <https://core.telegram.org/bots#commands>`_`https://core.telegram.org/bots#commands <https://core.telegram.org/bots#commands>`_ for more details about bot commands. Returns :code:`True` on success.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#setmycommands
|
||||
"""
|
||||
|
|
@ -20,6 +20,10 @@ class SetMyCommands(TelegramMethod[bool]):
|
|||
|
||||
commands: List[BotCommand]
|
||||
"""A JSON-serialized list of bot commands to be set as the list of the bot's commands. At most 100 commands can be specified."""
|
||||
scope: Optional[BotCommandScope] = None
|
||||
"""A JSON-serialized object, describing scope of users for which the commands are relevant. Defaults to :class:`aiogram.types.bot_command_scope_default.BotCommandScopeDefault`."""
|
||||
language_code: Optional[str] = None
|
||||
"""A two-letter ISO 639-1 language code. If empty, commands will be applied to all users from the given scope, for whose language there are no dedicated commands"""
|
||||
|
||||
def build_request(self, bot: Bot) -> Request:
|
||||
data: Dict[str, Any] = self.dict()
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ if TYPE_CHECKING: # pragma: no cover
|
|||
|
||||
class UnbanChatMember(TelegramMethod[bool]):
|
||||
"""
|
||||
Use this method to unban a previously kicked user in a supergroup or channel. The user will **not** return to the group or channel automatically, but will be able to join via link, etc. The bot must be an administrator for this to work. 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 :code:`True` on success.
|
||||
Use this method to unban a previously banned 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 :code:`True` on success.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#unbanchatmember
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -2,12 +2,26 @@ from .animation import Animation
|
|||
from .audio import Audio
|
||||
from .base import UNSET, TelegramObject
|
||||
from .bot_command import BotCommand
|
||||
from .bot_command_scope import BotCommandScope
|
||||
from .bot_command_scope_all_chat_administrators import BotCommandScopeAllChatAdministrators
|
||||
from .bot_command_scope_all_group_chats import BotCommandScopeAllGroupChats
|
||||
from .bot_command_scope_all_private_chats import BotCommandScopeAllPrivateChats
|
||||
from .bot_command_scope_chat import BotCommandScopeChat
|
||||
from .bot_command_scope_chat_administrators import BotCommandScopeChatAdministrators
|
||||
from .bot_command_scope_chat_member import BotCommandScopeChatMember
|
||||
from .bot_command_scope_default import BotCommandScopeDefault
|
||||
from .callback_game import CallbackGame
|
||||
from .callback_query import CallbackQuery
|
||||
from .chat import Chat
|
||||
from .chat_invite_link import ChatInviteLink
|
||||
from .chat_location import ChatLocation
|
||||
from .chat_member import ChatMember
|
||||
from .chat_member_administrator import ChatMemberAdministrator
|
||||
from .chat_member_banned import ChatMemberBanned
|
||||
from .chat_member_left import ChatMemberLeft
|
||||
from .chat_member_member import ChatMemberMember
|
||||
from .chat_member_owner import ChatMemberOwner
|
||||
from .chat_member_restricted import ChatMemberRestricted
|
||||
from .chat_member_updated import ChatMemberUpdated
|
||||
from .chat_permissions import ChatPermissions
|
||||
from .chat_photo import ChatPhoto
|
||||
|
|
@ -160,10 +174,24 @@ __all__ = (
|
|||
"ChatPhoto",
|
||||
"ChatInviteLink",
|
||||
"ChatMember",
|
||||
"ChatMemberOwner",
|
||||
"ChatMemberAdministrator",
|
||||
"ChatMemberMember",
|
||||
"ChatMemberRestricted",
|
||||
"ChatMemberLeft",
|
||||
"ChatMemberBanned",
|
||||
"ChatMemberUpdated",
|
||||
"ChatPermissions",
|
||||
"ChatLocation",
|
||||
"BotCommand",
|
||||
"BotCommandScope",
|
||||
"BotCommandScopeDefault",
|
||||
"BotCommandScopeAllPrivateChats",
|
||||
"BotCommandScopeAllGroupChats",
|
||||
"BotCommandScopeAllChatAdministrators",
|
||||
"BotCommandScopeChat",
|
||||
"BotCommandScopeChatAdministrators",
|
||||
"BotCommandScopeChatMember",
|
||||
"ResponseParameters",
|
||||
"InputMedia",
|
||||
"InputMediaPhoto",
|
||||
|
|
|
|||
19
aiogram/types/bot_command_scope.py
Normal file
19
aiogram/types/bot_command_scope.py
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from .base import TelegramObject
|
||||
|
||||
|
||||
class BotCommandScope(TelegramObject):
|
||||
"""
|
||||
This object represents the scope to which bot commands are applied. Currently, the following 7 scopes are supported:
|
||||
|
||||
- :class:`aiogram.types.bot_command_scope_default.BotCommandScopeDefault`
|
||||
- :class:`aiogram.types.bot_command_scope_all_private_chats.BotCommandScopeAllPrivateChats`
|
||||
- :class:`aiogram.types.bot_command_scope_all_group_chats.BotCommandScopeAllGroupChats`
|
||||
- :class:`aiogram.types.bot_command_scope_all_chat_administrators.BotCommandScopeAllChatAdministrators`
|
||||
- :class:`aiogram.types.bot_command_scope_chat.BotCommandScopeChat`
|
||||
- :class:`aiogram.types.bot_command_scope_chat_administrators.BotCommandScopeChatAdministrators`
|
||||
- :class:`aiogram.types.bot_command_scope_chat_member.BotCommandScopeChatMember`
|
||||
|
||||
Source: https://core.telegram.org/bots/api#botcommandscope
|
||||
"""
|
||||
16
aiogram/types/bot_command_scope_all_chat_administrators.py
Normal file
16
aiogram/types/bot_command_scope_all_chat_administrators.py
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
from .bot_command_scope import BotCommandScope
|
||||
|
||||
|
||||
class BotCommandScopeAllChatAdministrators(BotCommandScope):
|
||||
"""
|
||||
Represents the `scope <https://core.telegram.org/bots/api#botcommandscope>`_ of bot commands, covering all group and supergroup chat administrators.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#botcommandscopeallchatadministrators
|
||||
"""
|
||||
|
||||
type: str = Field("all_chat_administrators", const=True)
|
||||
"""Scope type, must be *all_chat_administrators*"""
|
||||
16
aiogram/types/bot_command_scope_all_group_chats.py
Normal file
16
aiogram/types/bot_command_scope_all_group_chats.py
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
from .bot_command_scope import BotCommandScope
|
||||
|
||||
|
||||
class BotCommandScopeAllGroupChats(BotCommandScope):
|
||||
"""
|
||||
Represents the `scope <https://core.telegram.org/bots/api#botcommandscope>`_ of bot commands, covering all group and supergroup chats.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#botcommandscopeallgroupchats
|
||||
"""
|
||||
|
||||
type: str = Field("all_group_chats", const=True)
|
||||
"""Scope type, must be *all_group_chats*"""
|
||||
16
aiogram/types/bot_command_scope_all_private_chats.py
Normal file
16
aiogram/types/bot_command_scope_all_private_chats.py
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
from .bot_command_scope import BotCommandScope
|
||||
|
||||
|
||||
class BotCommandScopeAllPrivateChats(BotCommandScope):
|
||||
"""
|
||||
Represents the `scope <https://core.telegram.org/bots/api#botcommandscope>`_ of bot commands, covering all private chats.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#botcommandscopeallprivatechats
|
||||
"""
|
||||
|
||||
type: str = Field("all_private_chats", const=True)
|
||||
"""Scope type, must be *all_private_chats*"""
|
||||
20
aiogram/types/bot_command_scope_chat.py
Normal file
20
aiogram/types/bot_command_scope_chat.py
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import Union
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
from .bot_command_scope import BotCommandScope
|
||||
|
||||
|
||||
class BotCommandScopeChat(BotCommandScope):
|
||||
"""
|
||||
Represents the `scope <https://core.telegram.org/bots/api#botcommandscope>`_ of bot commands, covering a specific chat.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#botcommandscopechat
|
||||
"""
|
||||
|
||||
type: str = Field("chat", const=True)
|
||||
"""Scope type, must be *chat*"""
|
||||
chat_id: Union[int, str]
|
||||
"""Unique identifier for the target chat or username of the target supergroup (in the format :code:`@supergroupusername`)"""
|
||||
20
aiogram/types/bot_command_scope_chat_administrators.py
Normal file
20
aiogram/types/bot_command_scope_chat_administrators.py
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import Union
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
from .bot_command_scope import BotCommandScope
|
||||
|
||||
|
||||
class BotCommandScopeChatAdministrators(BotCommandScope):
|
||||
"""
|
||||
Represents the `scope <https://core.telegram.org/bots/api#botcommandscope>`_ of bot commands, covering all administrators of a specific group or supergroup chat.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#botcommandscopechatadministrators
|
||||
"""
|
||||
|
||||
type: str = Field("chat_administrators", const=True)
|
||||
"""Scope type, must be *chat_administrators*"""
|
||||
chat_id: Union[int, str]
|
||||
"""Unique identifier for the target chat or username of the target supergroup (in the format :code:`@supergroupusername`)"""
|
||||
22
aiogram/types/bot_command_scope_chat_member.py
Normal file
22
aiogram/types/bot_command_scope_chat_member.py
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import Union
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
from .bot_command_scope import BotCommandScope
|
||||
|
||||
|
||||
class BotCommandScopeChatMember(BotCommandScope):
|
||||
"""
|
||||
Represents the `scope <https://core.telegram.org/bots/api#botcommandscope>`_ of bot commands, covering a specific member of a group or supergroup chat.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#botcommandscopechatmember
|
||||
"""
|
||||
|
||||
type: str = Field("chat_member", const=True)
|
||||
"""Scope type, must be *chat_member*"""
|
||||
chat_id: Union[int, str]
|
||||
"""Unique identifier for the target chat or username of the target supergroup (in the format :code:`@supergroupusername`)"""
|
||||
user_id: int
|
||||
"""Unique identifier of the target user"""
|
||||
16
aiogram/types/bot_command_scope_default.py
Normal file
16
aiogram/types/bot_command_scope_default.py
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
from .bot_command_scope import BotCommandScope
|
||||
|
||||
|
||||
class BotCommandScopeDefault(BotCommandScope):
|
||||
"""
|
||||
Represents the default `scope <https://core.telegram.org/bots/api#botcommandscope>`_ of bot commands. Default commands are used if no commands with a `narrower scope <https://core.telegram.org/bots/api#determining-list-of-commands>`_ are specified for the user.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#botcommandscopedefault
|
||||
"""
|
||||
|
||||
type: str = Field("default", const=True)
|
||||
"""Scope type, must be *default*"""
|
||||
|
|
@ -1,87 +1,18 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
from typing import TYPE_CHECKING, Optional, Union
|
||||
|
||||
from aiogram.utils import helper
|
||||
|
||||
from .base import TelegramObject
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from .user import User
|
||||
|
||||
|
||||
class ChatMember(TelegramObject):
|
||||
"""
|
||||
This object contains information about one member of a chat.
|
||||
This object contains information about one member of a chat. Currently, the following 6 types of chat members are supported:
|
||||
|
||||
- :class:`aiogram.types.chat_member_owner.ChatMemberOwner`
|
||||
- :class:`aiogram.types.chat_member_administrator.ChatMemberAdministrator`
|
||||
- :class:`aiogram.types.chat_member_member.ChatMemberMember`
|
||||
- :class:`aiogram.types.chat_member_restricted.ChatMemberRestricted`
|
||||
- :class:`aiogram.types.chat_member_left.ChatMemberLeft`
|
||||
- :class:`aiogram.types.chat_member_banned.ChatMemberBanned`
|
||||
|
||||
Source: https://core.telegram.org/bots/api#chatmember
|
||||
"""
|
||||
|
||||
user: User
|
||||
"""Information about the user"""
|
||||
status: str
|
||||
"""The member's status in the chat. Can be 'creator', 'administrator', 'member', 'restricted', 'left' or 'kicked'"""
|
||||
custom_title: Optional[str] = None
|
||||
"""*Optional*. Owner and administrators only. Custom title for this user"""
|
||||
is_anonymous: Optional[bool] = None
|
||||
"""*Optional*. Owner and administrators only. True, if the user's presence in the chat is hidden"""
|
||||
can_be_edited: Optional[bool] = None
|
||||
"""*Optional*. Administrators only. True, if the bot is allowed to edit administrator privileges of that user"""
|
||||
can_manage_chat: Optional[bool] = None
|
||||
"""*Optional*. Administrators only. True, if the administrator can access the chat event log, chat statistics, message statistics in channels, see channel members, see anonymous administrators in supergroups and ignore slow mode. Implied by any other administrator privilege"""
|
||||
can_post_messages: Optional[bool] = None
|
||||
"""*Optional*. Administrators only. True, if the administrator can post in the channel; channels only"""
|
||||
can_edit_messages: Optional[bool] = None
|
||||
"""*Optional*. Administrators only. True, if the administrator can edit messages of other users and can pin messages; channels only"""
|
||||
can_delete_messages: Optional[bool] = None
|
||||
"""*Optional*. Administrators only. True, if the administrator can delete messages of other users"""
|
||||
can_manage_voice_chats: Optional[bool] = None
|
||||
"""*Optional*. Administrators only. True, if the administrator can manage voice chats"""
|
||||
can_restrict_members: Optional[bool] = None
|
||||
"""*Optional*. Administrators only. True, if the administrator can restrict, ban or unban chat members"""
|
||||
can_promote_members: Optional[bool] = None
|
||||
"""*Optional*. Administrators only. True, if the administrator can add new administrators with a subset of their own privileges or demote administrators that he has promoted, directly or indirectly (promoted by administrators that were appointed by the user)"""
|
||||
can_change_info: Optional[bool] = None
|
||||
"""*Optional*. Administrators and restricted only. True, if the user is allowed to change the chat title, photo and other settings"""
|
||||
can_invite_users: Optional[bool] = None
|
||||
"""*Optional*. Administrators and restricted only. True, if the user is allowed to invite new users to the chat"""
|
||||
can_pin_messages: Optional[bool] = None
|
||||
"""*Optional*. Administrators and restricted only. True, if the user is allowed to pin messages; groups and supergroups only"""
|
||||
is_member: Optional[bool] = None
|
||||
"""*Optional*. Restricted only. True, if the user is a member of the chat at the moment of the request"""
|
||||
can_send_messages: Optional[bool] = None
|
||||
"""*Optional*. Restricted only. True, if the user is allowed to send text messages, contacts, locations and venues"""
|
||||
can_send_media_messages: Optional[bool] = None
|
||||
"""*Optional*. Restricted only. True, if the user is allowed to send audios, documents, photos, videos, video notes and voice notes"""
|
||||
can_send_polls: Optional[bool] = None
|
||||
"""*Optional*. Restricted only. True, if the user is allowed to send polls"""
|
||||
can_send_other_messages: Optional[bool] = None
|
||||
"""*Optional*. Restricted only. True, if the user is allowed to send animations, games, stickers and use inline bots"""
|
||||
can_add_web_page_previews: Optional[bool] = None
|
||||
"""*Optional*. Restricted only. True, if the user is allowed to add web page previews to their messages"""
|
||||
until_date: Optional[Union[datetime.datetime, datetime.timedelta, int]] = None
|
||||
"""*Optional*. Restricted and kicked only. Date when restrictions will be lifted for this user; unix time"""
|
||||
|
||||
@property
|
||||
def is_chat_admin(self) -> bool:
|
||||
return self.status in {ChatMemberStatus.CREATOR, ChatMemberStatus.ADMINISTRATOR}
|
||||
|
||||
@property
|
||||
def is_chat_member(self) -> bool:
|
||||
return self.status not in {ChatMemberStatus.LEFT, ChatMemberStatus.KICKED}
|
||||
|
||||
|
||||
class ChatMemberStatus(helper.Helper):
|
||||
"""
|
||||
Chat member status
|
||||
"""
|
||||
|
||||
mode = helper.HelperMode.lowercase
|
||||
|
||||
CREATOR = helper.Item() # creator
|
||||
ADMINISTRATOR = helper.Item() # administrator
|
||||
MEMBER = helper.Item() # member
|
||||
RESTRICTED = helper.Item() # restricted
|
||||
LEFT = helper.Item() # left
|
||||
KICKED = helper.Item() # kicked
|
||||
|
|
|
|||
49
aiogram/types/chat_member_administrator.py
Normal file
49
aiogram/types/chat_member_administrator.py
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
from .chat_member import ChatMember
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from .user import User
|
||||
|
||||
|
||||
class ChatMemberAdministrator(ChatMember):
|
||||
"""
|
||||
Represents a `chat member <https://core.telegram.org/bots/api#chatmember>`_ that has some additional privileges.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#chatmemberadministrator
|
||||
"""
|
||||
|
||||
status: str = Field("administrator", const=True)
|
||||
"""The member's status in the chat, always 'administrator'"""
|
||||
user: User
|
||||
"""Information about the user"""
|
||||
can_be_edited: bool
|
||||
"""True, if the bot is allowed to edit administrator privileges of that user"""
|
||||
is_anonymous: bool
|
||||
"""True, if the user's presence in the chat is hidden"""
|
||||
can_manage_chat: bool
|
||||
"""True, if the administrator can access the chat event log, chat statistics, message statistics in channels, see channel members, see anonymous administrators in supergroups and ignore slow mode. Implied by any other administrator privilege"""
|
||||
can_delete_messages: bool
|
||||
"""True, if the administrator can delete messages of other users"""
|
||||
can_manage_voice_chats: bool
|
||||
"""True, if the administrator can manage voice chats"""
|
||||
can_restrict_members: bool
|
||||
"""True, if the administrator can restrict, ban or unban chat members"""
|
||||
can_promote_members: bool
|
||||
"""True, if the administrator can add new administrators with a subset of their own privileges or demote administrators that he has promoted, directly or indirectly (promoted by administrators that were appointed by the user)"""
|
||||
can_change_info: bool
|
||||
"""True, if the user is allowed to change the chat title, photo and other settings"""
|
||||
can_invite_users: bool
|
||||
"""True, if the user is allowed to invite new users to the chat"""
|
||||
can_post_messages: Optional[bool] = None
|
||||
"""*Optional*. True, if the administrator can post in the channel; channels only"""
|
||||
can_edit_messages: Optional[bool] = None
|
||||
"""*Optional*. True, if the administrator can edit messages of other users and can pin messages; channels only"""
|
||||
can_pin_messages: Optional[bool] = None
|
||||
"""*Optional*. True, if the user is allowed to pin messages; groups and supergroups only"""
|
||||
custom_title: Optional[str] = None
|
||||
"""*Optional*. Custom title for this user"""
|
||||
26
aiogram/types/chat_member_banned.py
Normal file
26
aiogram/types/chat_member_banned.py
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
from typing import TYPE_CHECKING, Union
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
from .chat_member import ChatMember
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from .user import User
|
||||
|
||||
|
||||
class ChatMemberBanned(ChatMember):
|
||||
"""
|
||||
Represents a `chat member <https://core.telegram.org/bots/api#chatmember>`_ that was banned in the chat and can't return to the chat or view chat messages.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#chatmemberbanned
|
||||
"""
|
||||
|
||||
status: str = Field("kicked", const=True)
|
||||
"""The member's status in the chat, always 'kicked'"""
|
||||
user: User
|
||||
"""Information about the user"""
|
||||
until_date: Union[datetime.datetime, datetime.timedelta, int]
|
||||
"""Date when restrictions will be lifted for this user; unix time"""
|
||||
23
aiogram/types/chat_member_left.py
Normal file
23
aiogram/types/chat_member_left.py
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
from .chat_member import ChatMember
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from .user import User
|
||||
|
||||
|
||||
class ChatMemberLeft(ChatMember):
|
||||
"""
|
||||
Represents a `chat member <https://core.telegram.org/bots/api#chatmember>`_ that isn't currently a member of the chat, but may join it themselves.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#chatmemberleft
|
||||
"""
|
||||
|
||||
status: str = Field("left", const=True)
|
||||
"""The member's status in the chat, always 'left'"""
|
||||
user: User
|
||||
"""Information about the user"""
|
||||
23
aiogram/types/chat_member_member.py
Normal file
23
aiogram/types/chat_member_member.py
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
from .chat_member import ChatMember
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from .user import User
|
||||
|
||||
|
||||
class ChatMemberMember(ChatMember):
|
||||
"""
|
||||
Represents a `chat member <https://core.telegram.org/bots/api#chatmember>`_ that has no additional privileges or restrictions.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#chatmembermember
|
||||
"""
|
||||
|
||||
status: str = Field("member", const=True)
|
||||
"""The member's status in the chat, always 'member'"""
|
||||
user: User
|
||||
"""Information about the user"""
|
||||
27
aiogram/types/chat_member_owner.py
Normal file
27
aiogram/types/chat_member_owner.py
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
from .chat_member import ChatMember
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from .user import User
|
||||
|
||||
|
||||
class ChatMemberOwner(ChatMember):
|
||||
"""
|
||||
Represents a `chat member <https://core.telegram.org/bots/api#chatmember>`_ that owns the chat and has all administrator privileges.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#chatmemberowner
|
||||
"""
|
||||
|
||||
status: str = Field("creator", const=True)
|
||||
"""The member's status in the chat, always 'creator'"""
|
||||
user: User
|
||||
"""Information about the user"""
|
||||
is_anonymous: bool
|
||||
"""True, if the user's presence in the chat is hidden"""
|
||||
custom_title: Optional[str] = None
|
||||
"""*Optional*. Custom title for this user"""
|
||||
44
aiogram/types/chat_member_restricted.py
Normal file
44
aiogram/types/chat_member_restricted.py
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
from typing import TYPE_CHECKING, Union
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
from .chat_member import ChatMember
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
from .user import User
|
||||
|
||||
|
||||
class ChatMemberRestricted(ChatMember):
|
||||
"""
|
||||
Represents a `chat member <https://core.telegram.org/bots/api#chatmember>`_ that is under certain restrictions in the chat. Supergroups only.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#chatmemberrestricted
|
||||
"""
|
||||
|
||||
status: str = Field("restricted", const=True)
|
||||
"""The member's status in the chat, always 'restricted'"""
|
||||
user: User
|
||||
"""Information about the user"""
|
||||
is_member: bool
|
||||
"""True, if the user is a member of the chat at the moment of the request"""
|
||||
can_change_info: bool
|
||||
"""True, if the user is allowed to change the chat title, photo and other settings"""
|
||||
can_invite_users: bool
|
||||
"""True, if the user is allowed to invite new users to the chat"""
|
||||
can_pin_messages: bool
|
||||
"""True, if the user is allowed to pin messages; groups and supergroups only"""
|
||||
can_send_messages: bool
|
||||
"""True, if the user is allowed to send text messages, contacts, locations and venues"""
|
||||
can_send_media_messages: bool
|
||||
"""True, if the user is allowed to send audios, documents, photos, videos, video notes and voice notes"""
|
||||
can_send_polls: bool
|
||||
"""True, if the user is allowed to send polls"""
|
||||
can_send_other_messages: bool
|
||||
"""True, if the user is allowed to send animations, games, stickers and use inline bots"""
|
||||
can_add_web_page_previews: bool
|
||||
"""True, if the user is allowed to add web page previews to their messages"""
|
||||
until_date: Union[datetime.datetime, datetime.timedelta, int]
|
||||
"""Date when restrictions will be lifted for this user; unix time"""
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
from typing import TYPE_CHECKING, Optional, Union
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
|
|
@ -10,7 +10,12 @@ from .base import TelegramObject
|
|||
if TYPE_CHECKING: # pragma: no cover
|
||||
from .chat import Chat
|
||||
from .chat_invite_link import ChatInviteLink
|
||||
from .chat_member import ChatMember
|
||||
from .chat_member_administrator import ChatMemberAdministrator
|
||||
from .chat_member_banned import ChatMemberBanned
|
||||
from .chat_member_left import ChatMemberLeft
|
||||
from .chat_member_member import ChatMemberMember
|
||||
from .chat_member_owner import ChatMemberOwner
|
||||
from .chat_member_restricted import ChatMemberRestricted
|
||||
from .user import User
|
||||
|
||||
|
||||
|
|
@ -27,9 +32,23 @@ class ChatMemberUpdated(TelegramObject):
|
|||
"""Performer of the action, which resulted in the change"""
|
||||
date: datetime.datetime
|
||||
"""Date the change was done in Unix time"""
|
||||
old_chat_member: ChatMember
|
||||
old_chat_member: Union[
|
||||
ChatMemberOwner,
|
||||
ChatMemberAdministrator,
|
||||
ChatMemberMember,
|
||||
ChatMemberRestricted,
|
||||
ChatMemberLeft,
|
||||
ChatMemberBanned,
|
||||
]
|
||||
"""Previous information about the chat member"""
|
||||
new_chat_member: ChatMember
|
||||
new_chat_member: Union[
|
||||
ChatMemberOwner,
|
||||
ChatMemberAdministrator,
|
||||
ChatMemberMember,
|
||||
ChatMemberRestricted,
|
||||
ChatMemberLeft,
|
||||
ChatMemberBanned,
|
||||
]
|
||||
"""New information about the chat member"""
|
||||
invite_link: Optional[ChatInviteLink] = None
|
||||
"""*Optional*. Chat invite link, which was used by the user to join the chat; for joining by invite link events only."""
|
||||
|
|
|
|||
|
|
@ -21,5 +21,7 @@ class ForceReply(MutableTelegramObject):
|
|||
|
||||
force_reply: bool
|
||||
"""Shows reply interface to the user, as if they manually selected the bot's message and tapped 'Reply'"""
|
||||
input_field_placeholder: Optional[str] = None
|
||||
"""*Optional*. The placeholder to be shown in the input field when the reply is active; 1-64 characters"""
|
||||
selective: Optional[bool] = None
|
||||
"""*Optional*. Use this parameter if you want to force reply from specific users only. Targets: 1) users that are @mentioned in the *text* of the :class:`aiogram.types.message.Message` object; 2) if the bot's message is a reply (has *reply_to_message_id*), sender of the original message."""
|
||||
|
|
|
|||
|
|
@ -1,12 +1,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from .base import TelegramObject
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
pass
|
||||
|
||||
|
||||
class MessageAutoDeleteTimerChanged(TelegramObject):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -21,5 +21,7 @@ class ReplyKeyboardMarkup(MutableTelegramObject):
|
|||
"""*Optional*. Requests clients to resize the keyboard vertically for optimal fit (e.g., make the keyboard smaller if there are just two rows of buttons). Defaults to *false*, in which case the custom keyboard is always of the same height as the app's standard keyboard."""
|
||||
one_time_keyboard: Optional[bool] = None
|
||||
"""*Optional*. Requests clients to hide the keyboard as soon as it's been used. The keyboard will still be available, but clients will automatically display the usual letter-keyboard in the chat – the user can press a special button in the input field to see the custom keyboard again. Defaults to *false*."""
|
||||
input_field_placeholder: Optional[str] = None
|
||||
"""*Optional*. The placeholder to be shown in the input field when the keyboard is active; 1-64 characters"""
|
||||
selective: Optional[bool] = None
|
||||
"""*Optional*. Use this parameter if you want to show the keyboard to specific users only. Targets: 1) users that are @mentioned in the *text* of the :class:`aiogram.types.message.Message` object; 2) if the bot's message is a reply (has *reply_to_message_id*), sender of the original message."""
|
||||
|
|
|
|||
|
|
@ -1,12 +1,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from .base import TelegramObject
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
pass
|
||||
|
||||
|
||||
class VoiceChatEnded(TelegramObject):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -1,12 +1,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from .base import TelegramObject
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
pass
|
||||
|
||||
|
||||
class VoiceChatScheduled(TelegramObject):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -1,12 +1,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from .base import TelegramObject
|
||||
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
pass
|
||||
|
||||
|
||||
class VoiceChatStarted(TelegramObject):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ from aiogram.types import (
|
|||
InlineKeyboardButton,
|
||||
InlineKeyboardMarkup,
|
||||
KeyboardButton,
|
||||
KeyboardButtonPollType,
|
||||
LoginUrl,
|
||||
ReplyKeyboardMarkup,
|
||||
)
|
||||
|
|
@ -33,7 +34,7 @@ MIN_WIDTH = 1
|
|||
MAX_BUTTONS = 100
|
||||
|
||||
|
||||
class KeyboardConstructor(Generic[ButtonType]):
|
||||
class KeyboardBuilder(Generic[ButtonType]):
|
||||
def __init__(
|
||||
self, button_type: Type[ButtonType], markup: Optional[List[List[ButtonType]]] = None
|
||||
) -> None:
|
||||
|
|
@ -128,9 +129,9 @@ class KeyboardConstructor(Generic[ButtonType]):
|
|||
raise ValueError(f"Row size {size} are not allowed")
|
||||
return size
|
||||
|
||||
def copy(self: "KeyboardConstructor[ButtonType]") -> "KeyboardConstructor[ButtonType]":
|
||||
def copy(self: "KeyboardBuilder[ButtonType]") -> "KeyboardBuilder[ButtonType]":
|
||||
"""
|
||||
Make full copy of current constructor with markup
|
||||
Make full copy of current builder with markup
|
||||
|
||||
:return:
|
||||
"""
|
||||
|
|
@ -142,15 +143,15 @@ class KeyboardConstructor(Generic[ButtonType]):
|
|||
|
||||
.. code-block:: python
|
||||
|
||||
>>> constructor = KeyboardConstructor(button_type=InlineKeyboardButton)
|
||||
>>> ... # Add buttons to constructor
|
||||
>>> markup = InlineKeyboardMarkup(inline_keyboard=constructor.export())
|
||||
>>> builder = KeyboardBuilder(button_type=InlineKeyboardButton)
|
||||
>>> ... # Add buttons to builder
|
||||
>>> markup = InlineKeyboardMarkup(inline_keyboard=builder.export())
|
||||
|
||||
:return:
|
||||
"""
|
||||
return self._markup.copy()
|
||||
|
||||
def add(self, *buttons: ButtonType) -> "KeyboardConstructor[ButtonType]":
|
||||
def add(self, *buttons: ButtonType) -> "KeyboardBuilder[ButtonType]":
|
||||
"""
|
||||
Add one or many buttons to markup.
|
||||
|
||||
|
|
@ -175,9 +176,7 @@ class KeyboardConstructor(Generic[ButtonType]):
|
|||
self._markup = markup
|
||||
return self
|
||||
|
||||
def row(
|
||||
self, *buttons: ButtonType, width: int = MAX_WIDTH
|
||||
) -> "KeyboardConstructor[ButtonType]":
|
||||
def row(self, *buttons: ButtonType, width: int = MAX_WIDTH) -> "KeyboardBuilder[ButtonType]":
|
||||
"""
|
||||
Add row to markup
|
||||
|
||||
|
|
@ -194,7 +193,7 @@ class KeyboardConstructor(Generic[ButtonType]):
|
|||
)
|
||||
return self
|
||||
|
||||
def adjust(self, *sizes: int, repeat: bool = False) -> "KeyboardConstructor[ButtonType]":
|
||||
def adjust(self, *sizes: int, repeat: bool = False) -> "KeyboardBuilder[ButtonType]":
|
||||
"""
|
||||
Adjust previously added buttons to specific row sizes.
|
||||
|
||||
|
|
@ -226,7 +225,7 @@ class KeyboardConstructor(Generic[ButtonType]):
|
|||
self._markup = markup
|
||||
return self
|
||||
|
||||
def button(self, **kwargs: Any) -> "KeyboardConstructor[ButtonType]":
|
||||
def button(self, **kwargs: Any) -> "KeyboardBuilder[ButtonType]":
|
||||
if isinstance(callback_data := kwargs.get("callback_data", None), CallbackData):
|
||||
kwargs["callback_data"] = callback_data.pack()
|
||||
button = self._button_type(**kwargs)
|
||||
|
|
@ -255,7 +254,7 @@ def repeat_last(items: Iterable[T]) -> Generator[T, None, None]:
|
|||
yield value
|
||||
|
||||
|
||||
class InlineKeyboardConstructor(KeyboardConstructor[InlineKeyboardButton]):
|
||||
class InlineKeyboardBuilder(KeyboardBuilder[InlineKeyboardButton]):
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
|
||||
@no_type_check
|
||||
|
|
@ -270,7 +269,7 @@ class InlineKeyboardConstructor(KeyboardConstructor[InlineKeyboardButton]):
|
|||
callback_game: Optional[CallbackGame] = None,
|
||||
pay: Optional[bool] = None,
|
||||
**kwargs: Any,
|
||||
) -> "KeyboardConstructor[InlineKeyboardButton]":
|
||||
) -> "KeyboardBuilder[InlineKeyboardButton]":
|
||||
...
|
||||
|
||||
def as_markup(self, **kwargs: Any) -> InlineKeyboardMarkup:
|
||||
|
|
@ -278,3 +277,24 @@ class InlineKeyboardConstructor(KeyboardConstructor[InlineKeyboardButton]):
|
|||
|
||||
def __init__(self) -> None:
|
||||
super().__init__(InlineKeyboardButton)
|
||||
|
||||
|
||||
class ReplyKeyboardBuilder(KeyboardBuilder[KeyboardButton]):
|
||||
if TYPE_CHECKING: # pragma: no cover
|
||||
|
||||
@no_type_check
|
||||
def button(
|
||||
self,
|
||||
text: str,
|
||||
request_contact: Optional[bool] = None,
|
||||
request_location: Optional[bool] = None,
|
||||
request_poll: Optional[KeyboardButtonPollType] = None,
|
||||
**kwargs: Any,
|
||||
) -> "KeyboardBuilder[KeyboardButton]":
|
||||
...
|
||||
|
||||
def as_markup(self, **kwargs: Any) -> ReplyKeyboardMarkup:
|
||||
...
|
||||
|
||||
def __init__(self) -> None:
|
||||
super().__init__(KeyboardButton)
|
||||
|
|
|
|||
51
docs/api/methods/ban_chat_member.rst
Normal file
51
docs/api/methods/ban_chat_member.rst
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#############
|
||||
banChatMember
|
||||
#############
|
||||
|
||||
Returns: :obj:`bool`
|
||||
|
||||
.. automodule:: aiogram.methods.ban_chat_member
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: True
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
As bot method
|
||||
-------------
|
||||
|
||||
.. code-block::
|
||||
|
||||
result: bool = await bot.ban_chat_member(...)
|
||||
|
||||
|
||||
Method as object
|
||||
----------------
|
||||
|
||||
Imports:
|
||||
|
||||
- :code:`from aiogram.methods.ban_chat_member import BanChatMember`
|
||||
- alias: :code:`from aiogram.methods import BanChatMember`
|
||||
|
||||
In handlers with current bot
|
||||
----------------------------
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
result: bool = await BanChatMember(...)
|
||||
|
||||
With specific bot
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
result: bool = await bot(BanChatMember(...))
|
||||
|
||||
As reply into Webhook in handler
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
return BanChatMember(...)
|
||||
51
docs/api/methods/delete_my_commands.rst
Normal file
51
docs/api/methods/delete_my_commands.rst
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
################
|
||||
deleteMyCommands
|
||||
################
|
||||
|
||||
Returns: :obj:`bool`
|
||||
|
||||
.. automodule:: aiogram.methods.delete_my_commands
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: True
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
As bot method
|
||||
-------------
|
||||
|
||||
.. code-block::
|
||||
|
||||
result: bool = await bot.delete_my_commands(...)
|
||||
|
||||
|
||||
Method as object
|
||||
----------------
|
||||
|
||||
Imports:
|
||||
|
||||
- :code:`from aiogram.methods.delete_my_commands import DeleteMyCommands`
|
||||
- alias: :code:`from aiogram.methods import DeleteMyCommands`
|
||||
|
||||
In handlers with current bot
|
||||
----------------------------
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
result: bool = await DeleteMyCommands(...)
|
||||
|
||||
With specific bot
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
result: bool = await bot(DeleteMyCommands(...))
|
||||
|
||||
As reply into Webhook in handler
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
return DeleteMyCommands(...)
|
||||
44
docs/api/methods/get_chat_member_count.rst
Normal file
44
docs/api/methods/get_chat_member_count.rst
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
##################
|
||||
getChatMemberCount
|
||||
##################
|
||||
|
||||
Returns: :obj:`int`
|
||||
|
||||
.. automodule:: aiogram.methods.get_chat_member_count
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: True
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
As bot method
|
||||
-------------
|
||||
|
||||
.. code-block::
|
||||
|
||||
result: int = await bot.get_chat_member_count(...)
|
||||
|
||||
|
||||
Method as object
|
||||
----------------
|
||||
|
||||
Imports:
|
||||
|
||||
- :code:`from aiogram.methods.get_chat_member_count import GetChatMemberCount`
|
||||
- alias: :code:`from aiogram.methods import GetChatMemberCount`
|
||||
|
||||
In handlers with current bot
|
||||
----------------------------
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
result: int = await GetChatMemberCount(...)
|
||||
|
||||
With specific bot
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
result: int = await bot(GetChatMemberCount(...))
|
||||
|
|
@ -48,6 +48,7 @@ Available methods
|
|||
send_chat_action
|
||||
get_user_profile_photos
|
||||
get_file
|
||||
ban_chat_member
|
||||
kick_chat_member
|
||||
unban_chat_member
|
||||
restrict_chat_member
|
||||
|
|
@ -68,12 +69,14 @@ Available methods
|
|||
leave_chat
|
||||
get_chat
|
||||
get_chat_administrators
|
||||
get_chat_member_count
|
||||
get_chat_members_count
|
||||
get_chat_member
|
||||
set_chat_sticker_set
|
||||
delete_chat_sticker_set
|
||||
answer_callback_query
|
||||
set_my_commands
|
||||
delete_my_commands
|
||||
get_my_commands
|
||||
|
||||
Updating messages
|
||||
|
|
|
|||
9
docs/api/types/bot_command_scope.rst
Normal file
9
docs/api/types/bot_command_scope.rst
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
###############
|
||||
BotCommandScope
|
||||
###############
|
||||
|
||||
|
||||
.. automodule:: aiogram.types.bot_command_scope
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: True
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
####################################
|
||||
BotCommandScopeAllChatAdministrators
|
||||
####################################
|
||||
|
||||
|
||||
.. automodule:: aiogram.types.bot_command_scope_all_chat_administrators
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: True
|
||||
9
docs/api/types/bot_command_scope_all_group_chats.rst
Normal file
9
docs/api/types/bot_command_scope_all_group_chats.rst
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
############################
|
||||
BotCommandScopeAllGroupChats
|
||||
############################
|
||||
|
||||
|
||||
.. automodule:: aiogram.types.bot_command_scope_all_group_chats
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: True
|
||||
9
docs/api/types/bot_command_scope_all_private_chats.rst
Normal file
9
docs/api/types/bot_command_scope_all_private_chats.rst
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
##############################
|
||||
BotCommandScopeAllPrivateChats
|
||||
##############################
|
||||
|
||||
|
||||
.. automodule:: aiogram.types.bot_command_scope_all_private_chats
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: True
|
||||
9
docs/api/types/bot_command_scope_chat.rst
Normal file
9
docs/api/types/bot_command_scope_chat.rst
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
###################
|
||||
BotCommandScopeChat
|
||||
###################
|
||||
|
||||
|
||||
.. automodule:: aiogram.types.bot_command_scope_chat
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: True
|
||||
9
docs/api/types/bot_command_scope_chat_administrators.rst
Normal file
9
docs/api/types/bot_command_scope_chat_administrators.rst
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#################################
|
||||
BotCommandScopeChatAdministrators
|
||||
#################################
|
||||
|
||||
|
||||
.. automodule:: aiogram.types.bot_command_scope_chat_administrators
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: True
|
||||
9
docs/api/types/bot_command_scope_chat_member.rst
Normal file
9
docs/api/types/bot_command_scope_chat_member.rst
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#########################
|
||||
BotCommandScopeChatMember
|
||||
#########################
|
||||
|
||||
|
||||
.. automodule:: aiogram.types.bot_command_scope_chat_member
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: True
|
||||
9
docs/api/types/bot_command_scope_default.rst
Normal file
9
docs/api/types/bot_command_scope_default.rst
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
######################
|
||||
BotCommandScopeDefault
|
||||
######################
|
||||
|
||||
|
||||
.. automodule:: aiogram.types.bot_command_scope_default
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: True
|
||||
9
docs/api/types/chat_member_administrator.rst
Normal file
9
docs/api/types/chat_member_administrator.rst
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#######################
|
||||
ChatMemberAdministrator
|
||||
#######################
|
||||
|
||||
|
||||
.. automodule:: aiogram.types.chat_member_administrator
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: True
|
||||
9
docs/api/types/chat_member_banned.rst
Normal file
9
docs/api/types/chat_member_banned.rst
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
################
|
||||
ChatMemberBanned
|
||||
################
|
||||
|
||||
|
||||
.. automodule:: aiogram.types.chat_member_banned
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: True
|
||||
9
docs/api/types/chat_member_left.rst
Normal file
9
docs/api/types/chat_member_left.rst
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
##############
|
||||
ChatMemberLeft
|
||||
##############
|
||||
|
||||
|
||||
.. automodule:: aiogram.types.chat_member_left
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: True
|
||||
9
docs/api/types/chat_member_member.rst
Normal file
9
docs/api/types/chat_member_member.rst
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
################
|
||||
ChatMemberMember
|
||||
################
|
||||
|
||||
|
||||
.. automodule:: aiogram.types.chat_member_member
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: True
|
||||
9
docs/api/types/chat_member_owner.rst
Normal file
9
docs/api/types/chat_member_owner.rst
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
###############
|
||||
ChatMemberOwner
|
||||
###############
|
||||
|
||||
|
||||
.. automodule:: aiogram.types.chat_member_owner
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: True
|
||||
9
docs/api/types/chat_member_restricted.rst
Normal file
9
docs/api/types/chat_member_restricted.rst
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
####################
|
||||
ChatMemberRestricted
|
||||
####################
|
||||
|
||||
|
||||
.. automodule:: aiogram.types.chat_member_restricted
|
||||
:members:
|
||||
:member-order: bysource
|
||||
:undoc-members: True
|
||||
|
|
@ -60,10 +60,24 @@ Available types
|
|||
chat_photo
|
||||
chat_invite_link
|
||||
chat_member
|
||||
chat_member_owner
|
||||
chat_member_administrator
|
||||
chat_member_member
|
||||
chat_member_restricted
|
||||
chat_member_left
|
||||
chat_member_banned
|
||||
chat_member_updated
|
||||
chat_permissions
|
||||
chat_location
|
||||
bot_command
|
||||
bot_command_scope
|
||||
bot_command_scope_default
|
||||
bot_command_scope_all_private_chats
|
||||
bot_command_scope_all_group_chats
|
||||
bot_command_scope_all_chat_administrators
|
||||
bot_command_scope_chat
|
||||
bot_command_scope_chat_administrators
|
||||
bot_command_scope_chat_member
|
||||
response_parameters
|
||||
input_media
|
||||
input_media_photo
|
||||
|
|
|
|||
23
docs/dispatcher/finite_state_machine/storages.rst
Normal file
23
docs/dispatcher/finite_state_machine/storages.rst
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
########
|
||||
Storages
|
||||
########
|
||||
|
||||
Storages out of the box
|
||||
=======================
|
||||
|
||||
MemoryStorage
|
||||
-------------
|
||||
|
||||
.. autoclass:: aiogram.dispatcher.fsm.storage.memory.MemoryStorage
|
||||
:members: __init__, from_url
|
||||
:member-order: bysource
|
||||
|
||||
RedisStorage
|
||||
------------
|
||||
|
||||
.. autoclass:: aiogram.dispatcher.fsm.storage.redis.RedisStorage
|
||||
:members: __init__, from_url
|
||||
:member-order: bysource
|
||||
|
||||
Writing own storages
|
||||
====================
|
||||
|
|
@ -42,6 +42,10 @@ async def redis_storage(redis_server):
|
|||
if not redis_server:
|
||||
pytest.skip("Redis is not available here")
|
||||
storage = RedisStorage.from_url(redis_server)
|
||||
try:
|
||||
await storage.redis.info()
|
||||
except ConnectionError as e:
|
||||
pytest.skip(str(e))
|
||||
try:
|
||||
yield storage
|
||||
finally:
|
||||
|
|
|
|||
24
tests/test_api/test_methods/test_ban_chat_member.py
Normal file
24
tests/test_api/test_methods/test_ban_chat_member.py
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import pytest
|
||||
|
||||
from aiogram.methods import BanChatMember, Request
|
||||
from tests.mocked_bot import MockedBot
|
||||
|
||||
|
||||
class TestKickChatMember:
|
||||
@pytest.mark.asyncio
|
||||
async def test_method(self, bot: MockedBot):
|
||||
prepare_result = bot.add_result_for(BanChatMember, ok=True, result=True)
|
||||
|
||||
response: bool = await BanChatMember(chat_id=-42, user_id=42)
|
||||
request: Request = bot.get_request()
|
||||
assert request.method == "banChatMember"
|
||||
assert response == prepare_result.result
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_bot_method(self, bot: MockedBot):
|
||||
prepare_result = bot.add_result_for(BanChatMember, ok=True, result=True)
|
||||
|
||||
response: bool = await bot.ban_chat_member(chat_id=-42, user_id=42)
|
||||
request: Request = bot.get_request()
|
||||
assert request.method == "banChatMember"
|
||||
assert response == prepare_result.result
|
||||
24
tests/test_api/test_methods/test_delete_my_commands.py
Normal file
24
tests/test_api/test_methods/test_delete_my_commands.py
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import pytest
|
||||
|
||||
from aiogram.methods import BanChatMember, DeleteMyCommands, Request
|
||||
from tests.mocked_bot import MockedBot
|
||||
|
||||
|
||||
class TestKickChatMember:
|
||||
@pytest.mark.asyncio
|
||||
async def test_method(self, bot: MockedBot):
|
||||
prepare_result = bot.add_result_for(DeleteMyCommands, ok=True, result=True)
|
||||
|
||||
response: bool = await DeleteMyCommands()
|
||||
request: Request = bot.get_request()
|
||||
assert request.method == "deleteMyCommands"
|
||||
assert response == prepare_result.result
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_bot_method(self, bot: MockedBot):
|
||||
prepare_result = bot.add_result_for(DeleteMyCommands, ok=True, result=True)
|
||||
|
||||
response: bool = await bot.delete_my_commands()
|
||||
request: Request = bot.get_request()
|
||||
assert request.method == "deleteMyCommands"
|
||||
assert response == prepare_result.result
|
||||
|
|
@ -3,7 +3,7 @@ from typing import List
|
|||
import pytest
|
||||
|
||||
from aiogram.methods import GetChatAdministrators, Request
|
||||
from aiogram.types import ChatMember, User
|
||||
from aiogram.types import ChatMember, ChatMemberOwner, User
|
||||
from tests.mocked_bot import MockedBot
|
||||
|
||||
|
||||
|
|
@ -14,7 +14,9 @@ class TestGetChatAdministrators:
|
|||
GetChatAdministrators,
|
||||
ok=True,
|
||||
result=[
|
||||
ChatMember(user=User(id=42, is_bot=False, first_name="User"), status="creator")
|
||||
ChatMemberOwner(
|
||||
user=User(id=42, is_bot=False, first_name="User"), is_anonymous=False
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
|
|
@ -29,7 +31,9 @@ class TestGetChatAdministrators:
|
|||
GetChatAdministrators,
|
||||
ok=True,
|
||||
result=[
|
||||
ChatMember(user=User(id=42, is_bot=False, first_name="User"), status="creator")
|
||||
ChatMemberOwner(
|
||||
user=User(id=42, is_bot=False, first_name="User"), is_anonymous=False
|
||||
)
|
||||
],
|
||||
)
|
||||
response: List[ChatMember] = await bot.get_chat_administrators(chat_id=-42)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import pytest
|
||||
|
||||
from aiogram.methods import GetChatMember, Request
|
||||
from aiogram.types import ChatMember, User
|
||||
from aiogram.types import ChatMember, ChatMemberOwner, User
|
||||
from tests.mocked_bot import MockedBot
|
||||
|
||||
|
||||
|
|
@ -11,7 +11,9 @@ class TestGetChatMember:
|
|||
prepare_result = bot.add_result_for(
|
||||
GetChatMember,
|
||||
ok=True,
|
||||
result=ChatMember(user=User(id=42, is_bot=False, first_name="User"), status="creator"),
|
||||
result=ChatMemberOwner(
|
||||
user=User(id=42, is_bot=False, first_name="User"), is_anonymous=False
|
||||
),
|
||||
)
|
||||
|
||||
response: ChatMember = await GetChatMember(chat_id=-42, user_id=42)
|
||||
|
|
@ -24,7 +26,9 @@ class TestGetChatMember:
|
|||
prepare_result = bot.add_result_for(
|
||||
GetChatMember,
|
||||
ok=True,
|
||||
result=ChatMember(user=User(id=42, is_bot=False, first_name="User"), status="creator"),
|
||||
result=ChatMemberOwner(
|
||||
user=User(id=42, is_bot=False, first_name="User"), is_anonymous=False
|
||||
),
|
||||
)
|
||||
|
||||
response: ChatMember = await bot.get_chat_member(chat_id=-42, user_id=42)
|
||||
|
|
|
|||
24
tests/test_api/test_methods/test_get_chat_member_count.py
Normal file
24
tests/test_api/test_methods/test_get_chat_member_count.py
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import pytest
|
||||
|
||||
from aiogram.methods import GetChatMemberCount, Request
|
||||
from tests.mocked_bot import MockedBot
|
||||
|
||||
|
||||
class TestGetChatMembersCount:
|
||||
@pytest.mark.asyncio
|
||||
async def test_method(self, bot: MockedBot):
|
||||
prepare_result = bot.add_result_for(GetChatMemberCount, ok=True, result=42)
|
||||
|
||||
response: int = await GetChatMemberCount(chat_id=-42)
|
||||
request: Request = bot.get_request()
|
||||
assert request.method == "getChatMemberCount"
|
||||
assert response == prepare_result.result
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_bot_method(self, bot: MockedBot):
|
||||
prepare_result = bot.add_result_for(GetChatMemberCount, ok=True, result=42)
|
||||
|
||||
response: int = await bot.get_chat_member_count(chat_id=-42)
|
||||
request: Request = bot.get_request()
|
||||
assert request.method == "getChatMemberCount"
|
||||
assert response == prepare_result.result
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
import pytest
|
||||
|
||||
from aiogram.types import ChatMember, User
|
||||
|
||||
user = User(id=42, is_bot=False, first_name="User", last_name=None)
|
||||
|
||||
|
||||
class TestChatMember:
|
||||
@pytest.mark.parametrize(
|
||||
"status,result", [["administrator", True], ["creator", True], ["member", False]]
|
||||
)
|
||||
def test_is_chat_admin(self, status: str, result: bool):
|
||||
chat_member = ChatMember(user=user, status=status)
|
||||
assert chat_member.is_chat_admin == result
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"status,result",
|
||||
[
|
||||
["administrator", True],
|
||||
["creator", True],
|
||||
["member", True],
|
||||
["restricted", True],
|
||||
["kicked", False],
|
||||
["left", False],
|
||||
],
|
||||
)
|
||||
def test_is_chat_member(self, status: str, result: bool):
|
||||
chat_member = ChatMember(user=user, status=status)
|
||||
assert chat_member.is_chat_member == result
|
||||
|
|
@ -2,6 +2,7 @@ import asyncio
|
|||
import datetime
|
||||
import time
|
||||
import warnings
|
||||
from collections import Counter
|
||||
from typing import Any
|
||||
|
||||
import pytest
|
||||
|
|
@ -14,7 +15,7 @@ from aiogram.methods import GetMe, GetUpdates, SendMessage
|
|||
from aiogram.types import (
|
||||
CallbackQuery,
|
||||
Chat,
|
||||
ChatMember,
|
||||
ChatMemberMember,
|
||||
ChatMemberUpdated,
|
||||
ChosenInlineResult,
|
||||
InlineQuery,
|
||||
|
|
@ -375,11 +376,11 @@ class TestDispatcher:
|
|||
chat=Chat(id=42, type="private"),
|
||||
from_user=User(id=42, is_bot=False, first_name="Test"),
|
||||
date=datetime.datetime.now(),
|
||||
old_chat_member=ChatMember(
|
||||
user=User(id=42, is_bot=False, first_name="Test"), status="restricted"
|
||||
old_chat_member=ChatMemberMember(
|
||||
user=User(id=42, is_bot=False, first_name="Test")
|
||||
),
|
||||
new_chat_member=ChatMember(
|
||||
user=User(id=42, is_bot=False, first_name="Test"), status="restricted"
|
||||
new_chat_member=ChatMemberMember(
|
||||
user=User(id=42, is_bot=False, first_name="Test")
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -394,11 +395,11 @@ class TestDispatcher:
|
|||
chat=Chat(id=42, type="private"),
|
||||
from_user=User(id=42, is_bot=False, first_name="Test"),
|
||||
date=datetime.datetime.now(),
|
||||
old_chat_member=ChatMember(
|
||||
user=User(id=42, is_bot=False, first_name="Test"), status="restricted"
|
||||
old_chat_member=ChatMemberMember(
|
||||
user=User(id=42, is_bot=False, first_name="Test")
|
||||
),
|
||||
new_chat_member=ChatMember(
|
||||
user=User(id=42, is_bot=False, first_name="Test"), status="restricted"
|
||||
new_chat_member=ChatMemberMember(
|
||||
user=User(id=42, is_bot=False, first_name="Test")
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -494,6 +495,50 @@ class TestDispatcher:
|
|||
assert result["event_router"] == router1
|
||||
assert result["test"] == "PASS"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_nested_router_middleware_resolution(self, bot: MockedBot):
|
||||
counter = Counter()
|
||||
|
||||
def mw(type_: str, inject_data: dict):
|
||||
async def middleware(h, event, data):
|
||||
counter[type_] += 1
|
||||
data.update(inject_data)
|
||||
return await h(event, data)
|
||||
|
||||
return middleware
|
||||
|
||||
async def handler(event, foo, bar, baz, fizz, buzz):
|
||||
counter["child.handler"] += 1
|
||||
|
||||
root = Dispatcher()
|
||||
child = Router()
|
||||
|
||||
root.message.outer_middleware(mw("root.outer_middleware", {"foo": True}))
|
||||
root.message.middleware(mw("root.middleware", {"bar": None}))
|
||||
child.message.outer_middleware(mw("child.outer_middleware", {"fizz": 42}))
|
||||
child.message.middleware(mw("child.middleware", {"buzz": -42}))
|
||||
child.message.register(handler)
|
||||
|
||||
root.include_router(child)
|
||||
await root.feed_update(
|
||||
bot=bot,
|
||||
update=Update(
|
||||
update_id=42,
|
||||
message=Message(
|
||||
message_id=42,
|
||||
date=datetime.datetime.fromtimestamp(0),
|
||||
chat=Chat(id=-42, type="group"),
|
||||
),
|
||||
),
|
||||
baz=...,
|
||||
)
|
||||
|
||||
assert counter["root.outer_middleware"] == 2
|
||||
assert counter["root.middleware"] == 1
|
||||
assert counter["child.outer_middleware"] == 1
|
||||
assert counter["child.middleware"] == 1
|
||||
assert counter["child.handler"] == 1
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_process_update_call_request(self, bot: MockedBot):
|
||||
dispatcher = Dispatcher()
|
||||
|
|
|
|||
|
|
@ -156,7 +156,11 @@ class TestCallbackDataFilter:
|
|||
["test", F.foo == "test", False],
|
||||
["test:spam:42", F.foo == "test", False],
|
||||
["test:test:42", F.foo == "test", {"callback_data": MyCallback(foo="test", bar=42)}],
|
||||
["test:test:42", None, {"callback_data": MyCallback(foo="test", bar=42)}],
|
||||
["test:test:777", None, {"callback_data": MyCallback(foo="test", bar=777)}],
|
||||
["spam:test:777", None, False],
|
||||
["test:test:", F.foo == "test", False],
|
||||
["test:test:", None, False],
|
||||
],
|
||||
)
|
||||
@pytest.mark.asyncio
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from typing import Any
|
|||
import pytest
|
||||
|
||||
from aiogram.dispatcher.handler.chat_member import ChatMemberHandler
|
||||
from aiogram.types import Chat, ChatMember, ChatMemberUpdated, User
|
||||
from aiogram.types import Chat, ChatMemberMember, ChatMemberUpdated, User
|
||||
|
||||
|
||||
class TestChatMemberUpdated:
|
||||
|
|
@ -14,12 +14,8 @@ class TestChatMemberUpdated:
|
|||
chat=Chat(id=42, type="private"),
|
||||
from_user=User(id=42, is_bot=False, first_name="Test"),
|
||||
date=datetime.datetime.now(),
|
||||
old_chat_member=ChatMember(
|
||||
user=User(id=42, is_bot=False, first_name="Test"), status="restricted"
|
||||
),
|
||||
new_chat_member=ChatMember(
|
||||
user=User(id=42, is_bot=False, first_name="Test"), status="restricted"
|
||||
),
|
||||
old_chat_member=ChatMemberMember(user=User(id=42, is_bot=False, first_name="Test")),
|
||||
new_chat_member=ChatMemberMember(user=User(id=42, is_bot=False, first_name="Test")),
|
||||
)
|
||||
|
||||
class MyHandler(ChatMemberHandler):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue