mirror of
https://github.com/aiogram/aiogram.git
synced 2026-04-08 16:37:47 +00:00
Added chat member status changed filter, update Bot API 5.7, other small changes
This commit is contained in:
parent
a846acd607
commit
ea7a000255
11 changed files with 273 additions and 22 deletions
|
|
@ -1565,7 +1565,7 @@ class Bot(ContextInstanceMixin["Bot"]):
|
|||
|
||||
Source: https://core.telegram.org/bots/api#unbanchatmember
|
||||
|
||||
:param chat_id: Unique identifier for the target group or username of the target supergroup or channel (in the format :code:`@username`)
|
||||
: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 only_if_banned: Do nothing if the user is not banned
|
||||
:param request_timeout: Request timeout
|
||||
|
|
@ -2569,7 +2569,7 @@ class Bot(ContextInstanceMixin["Bot"]):
|
|||
request_timeout: Optional[int] = None,
|
||||
) -> Message:
|
||||
"""
|
||||
Use this method to send static .WEBP or `animated <https://telegram.org/blog/animated-stickers>`_ .TGS stickers. On success, the sent :class:`aiogram.types.message.Message` is returned.
|
||||
Use this method to send static .WEBP, `animated <https://telegram.org/blog/animated-stickers>`_ .TGS, or `video <https://telegram.org/blog/video-stickers-better-reactions>`_ .WEBM stickers. On success, the sent :class:`aiogram.types.message.Message` is returned.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#sendsticker
|
||||
|
||||
|
|
@ -2643,12 +2643,13 @@ class Bot(ContextInstanceMixin["Bot"]):
|
|||
emojis: str,
|
||||
png_sticker: Optional[Union[InputFile, str]] = None,
|
||||
tgs_sticker: Optional[InputFile] = None,
|
||||
webm_sticker: Optional[InputFile] = None,
|
||||
contains_masks: Optional[bool] = None,
|
||||
mask_position: Optional[MaskPosition] = None,
|
||||
request_timeout: Optional[int] = None,
|
||||
) -> bool:
|
||||
"""
|
||||
Use this method to create a new sticker set owned by a user. The bot will be able to edit the sticker set thus created. You **must** use exactly one of the fields *png_sticker* or *tgs_sticker*. Returns :code:`True` on success.
|
||||
Use this method to create a new sticker set owned by a user. The bot will be able to edit the sticker set thus created. You **must** use exactly one of the fields *png_sticker*, *tgs_sticker*, or *webm_sticker*. Returns :code:`True` on success.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#createnewstickerset
|
||||
|
||||
|
|
@ -2657,7 +2658,8 @@ class Bot(ContextInstanceMixin["Bot"]):
|
|||
:param title: Sticker set title, 1-64 characters
|
||||
:param emojis: One or more emoji corresponding to the sticker
|
||||
:param png_sticker: **PNG** image with the sticker, must be up to 512 kilobytes in size, dimensions must not exceed 512px, and either width or height must be exactly 512px. Pass a *file_id* as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. :ref:`More info on Sending Files » <sending-files>`
|
||||
:param tgs_sticker: **TGS** animation with the sticker, uploaded using multipart/form-data. See `https://core.telegram.org/animated_stickers#technical-requirements <https://core.telegram.org/animated_stickers#technical-requirements>`_`https://core.telegram.org/animated_stickers#technical-requirements <https://core.telegram.org/animated_stickers#technical-requirements>`_ for technical requirements
|
||||
:param tgs_sticker: **TGS** animation with the sticker, uploaded using multipart/form-data. See `https://core.telegram.org/stickers#animated-sticker-requirements <https://core.telegram.org/stickers#animated-sticker-requirements>`_`https://core.telegram.org/stickers#animated-sticker-requirements <https://core.telegram.org/stickers#animated-sticker-requirements>`_ for technical requirements
|
||||
:param webm_sticker: **WEBM** video with the sticker, uploaded using multipart/form-data. See `https://core.telegram.org/stickers#video-sticker-requirements <https://core.telegram.org/stickers#video-sticker-requirements>`_`https://core.telegram.org/stickers#video-sticker-requirements <https://core.telegram.org/stickers#video-sticker-requirements>`_ for technical requirements
|
||||
:param contains_masks: Pass :code:`True`, if a set of mask stickers should be created
|
||||
:param mask_position: A JSON-serialized object for position where the mask should be placed on faces
|
||||
:param request_timeout: Request timeout
|
||||
|
|
@ -2670,6 +2672,7 @@ class Bot(ContextInstanceMixin["Bot"]):
|
|||
emojis=emojis,
|
||||
png_sticker=png_sticker,
|
||||
tgs_sticker=tgs_sticker,
|
||||
webm_sticker=webm_sticker,
|
||||
contains_masks=contains_masks,
|
||||
mask_position=mask_position,
|
||||
)
|
||||
|
|
@ -2682,11 +2685,12 @@ class Bot(ContextInstanceMixin["Bot"]):
|
|||
emojis: str,
|
||||
png_sticker: Optional[Union[InputFile, str]] = None,
|
||||
tgs_sticker: Optional[InputFile] = None,
|
||||
webm_sticker: Optional[InputFile] = None,
|
||||
mask_position: Optional[MaskPosition] = None,
|
||||
request_timeout: Optional[int] = None,
|
||||
) -> bool:
|
||||
"""
|
||||
Use this method to add a new sticker to a set created by the bot. You **must** use exactly one of the fields *png_sticker* or *tgs_sticker*. Animated stickers can be added to animated sticker sets and only to them. Animated sticker sets can have up to 50 stickers. Static sticker sets can have up to 120 stickers. Returns :code:`True` on success.
|
||||
Use this method to add a new sticker to a set created by the bot. You **must** use exactly one of the fields *png_sticker*, *tgs_sticker*, or *webm_sticker*. Animated stickers can be added to animated sticker sets and only to them. Animated sticker sets can have up to 50 stickers. Static sticker sets can have up to 120 stickers. Returns :code:`True` on success.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#addstickertoset
|
||||
|
||||
|
|
@ -2694,7 +2698,8 @@ class Bot(ContextInstanceMixin["Bot"]):
|
|||
:param name: Sticker set name
|
||||
:param emojis: One or more emoji corresponding to the sticker
|
||||
:param png_sticker: **PNG** image with the sticker, must be up to 512 kilobytes in size, dimensions must not exceed 512px, and either width or height must be exactly 512px. Pass a *file_id* as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. :ref:`More info on Sending Files » <sending-files>`
|
||||
:param tgs_sticker: **TGS** animation with the sticker, uploaded using multipart/form-data. See `https://core.telegram.org/animated_stickers#technical-requirements <https://core.telegram.org/animated_stickers#technical-requirements>`_`https://core.telegram.org/animated_stickers#technical-requirements <https://core.telegram.org/animated_stickers#technical-requirements>`_ for technical requirements
|
||||
:param tgs_sticker: **TGS** animation with the sticker, uploaded using multipart/form-data. See `https://core.telegram.org/stickers#animated-sticker-requirements <https://core.telegram.org/stickers#animated-sticker-requirements>`_`https://core.telegram.org/stickers#animated-sticker-requirements <https://core.telegram.org/stickers#animated-sticker-requirements>`_ for technical requirements
|
||||
:param webm_sticker: **WEBM** video with the sticker, uploaded using multipart/form-data. See `https://core.telegram.org/stickers#video-sticker-requirements <https://core.telegram.org/stickers#video-sticker-requirements>`_`https://core.telegram.org/stickers#video-sticker-requirements <https://core.telegram.org/stickers#video-sticker-requirements>`_ for technical requirements
|
||||
:param mask_position: A JSON-serialized object for position where the mask should be placed on faces
|
||||
:param request_timeout: Request timeout
|
||||
:return: Returns True on success.
|
||||
|
|
@ -2705,6 +2710,7 @@ class Bot(ContextInstanceMixin["Bot"]):
|
|||
emojis=emojis,
|
||||
png_sticker=png_sticker,
|
||||
tgs_sticker=tgs_sticker,
|
||||
webm_sticker=webm_sticker,
|
||||
mask_position=mask_position,
|
||||
)
|
||||
return await self(call, request_timeout=request_timeout)
|
||||
|
|
@ -2758,13 +2764,13 @@ class Bot(ContextInstanceMixin["Bot"]):
|
|||
request_timeout: Optional[int] = None,
|
||||
) -> bool:
|
||||
"""
|
||||
Use this method to set the thumbnail of a sticker set. Animated thumbnails can be set for animated sticker sets only. Returns :code:`True` on success.
|
||||
Use this method to set the thumbnail of a sticker set. Animated thumbnails can be set for animated sticker sets only. Video thumbnails can be set only for video sticker sets only. Returns :code:`True` on success.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#setstickersetthumb
|
||||
|
||||
:param name: Sticker set name
|
||||
:param user_id: User identifier of the sticker set owner
|
||||
:param thumb: A **PNG** image with the thumbnail, must be up to 128 kilobytes in size and have width and height exactly 100px, or a **TGS** animation with the thumbnail up to 32 kilobytes in size; see `https://core.telegram.org/animated_stickers#technical-requirements <https://core.telegram.org/animated_stickers#technical-requirements>`_`https://core.telegram.org/animated_stickers#technical-requirements <https://core.telegram.org/animated_stickers#technical-requirements>`_ for animated sticker technical requirements. Pass a *file_id* as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. :ref:`More info on Sending Files » <sending-files>`. Animated sticker set thumbnail can't be uploaded via HTTP URL.
|
||||
:param thumb: A **PNG** image with the thumbnail, must be up to 128 kilobytes in size and have width and height exactly 100px, or a **TGS** animation with the thumbnail up to 32 kilobytes in size; see `https://core.telegram.org/stickers#animated-sticker-requirements <https://core.telegram.org/stickers#animated-sticker-requirements>`_`https://core.telegram.org/stickers#animated-sticker-requirements <https://core.telegram.org/stickers#animated-sticker-requirements>`_ for animated sticker technical requirements, or a **WEBM** video with the thumbnail up to 32 kilobytes in size; see `https://core.telegram.org/stickers#video-sticker-requirements <https://core.telegram.org/stickers#video-sticker-requirements>`_`https://core.telegram.org/stickers#video-sticker-requirements <https://core.telegram.org/stickers#video-sticker-requirements>`_ for video sticker technical requirements. Pass a *file_id* as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. :ref:`More info on Sending Files » <sending-files>`. Animated sticker set thumbnails can't be uploaded via HTTP URL.
|
||||
:param request_timeout: Request timeout
|
||||
:return: Returns True on success.
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -1,6 +1,21 @@
|
|||
from typing import Dict, Tuple, Type
|
||||
|
||||
from .base import BaseFilter
|
||||
from .chat_member import (
|
||||
ADMINISTRATOR,
|
||||
CREATOR,
|
||||
IS_ADMIN,
|
||||
IS_MEMBER,
|
||||
IS_NOT_MEMBER,
|
||||
JOIN_TRANSITION,
|
||||
KICKED,
|
||||
LEAVE_TRANSITION,
|
||||
LEFT,
|
||||
MEMBER,
|
||||
PROMOTED_TRANSITION,
|
||||
RESTRICTED,
|
||||
ChatMemberUpdatedStatus,
|
||||
)
|
||||
from .command import Command, CommandObject
|
||||
from .content_types import ContentTypesFilter
|
||||
from .exception import ExceptionMessageFilter, ExceptionTypeFilter
|
||||
|
|
@ -19,6 +34,19 @@ __all__ = (
|
|||
"ExceptionTypeFilter",
|
||||
"StateFilter",
|
||||
"MagicData",
|
||||
"ChatMemberUpdatedStatus",
|
||||
"CREATOR",
|
||||
"ADMINISTRATOR",
|
||||
"MEMBER",
|
||||
"RESTRICTED",
|
||||
"LEFT",
|
||||
"KICKED",
|
||||
"IS_MEMBER",
|
||||
"IS_ADMIN",
|
||||
"PROMOTED_TRANSITION",
|
||||
"IS_NOT_MEMBER",
|
||||
"JOIN_TRANSITION",
|
||||
"LEAVE_TRANSITION",
|
||||
)
|
||||
|
||||
_ALL_EVENTS_FILTERS: Tuple[Type[BaseFilter], ...] = (MagicData,)
|
||||
|
|
@ -84,10 +112,12 @@ BUILTIN_FILTERS: Dict[str, Tuple[Type[BaseFilter], ...]] = {
|
|||
"my_chat_member": (
|
||||
*_ALL_EVENTS_FILTERS,
|
||||
*_TELEGRAM_EVENTS_FILTERS,
|
||||
ChatMemberUpdatedStatus,
|
||||
),
|
||||
"chat_member": (
|
||||
*_ALL_EVENTS_FILTERS,
|
||||
*_TELEGRAM_EVENTS_FILTERS,
|
||||
ChatMemberUpdatedStatus,
|
||||
),
|
||||
"chat_join_request": (
|
||||
*_ALL_EVENTS_FILTERS,
|
||||
|
|
|
|||
155
aiogram/dispatcher/filters/chat_member.py
Normal file
155
aiogram/dispatcher/filters/chat_member.py
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
from typing import Any, Dict, Optional, TypeVar, Union
|
||||
|
||||
from aiogram.dispatcher.filters import BaseFilter
|
||||
from aiogram.types import ChatMember, ChatMemberUpdated
|
||||
|
||||
MarkerT = TypeVar("MarkerT", bound="_MemberStatusMarker")
|
||||
MarkerGroupT = TypeVar("MarkerGroupT", bound="_MemberStatusGroupMarker")
|
||||
TransitionT = TypeVar("TransitionT", bound="_MemberStatusTransition")
|
||||
|
||||
|
||||
class _MemberStatusMarker:
|
||||
def __init__(self, name: str, *, is_member: Optional[bool] = None) -> None:
|
||||
self.name = name
|
||||
self.is_member = is_member
|
||||
|
||||
def __str__(self) -> str:
|
||||
result = self.name.upper()
|
||||
if self.is_member is not None:
|
||||
result = ("+" if self.is_member else "-") + result
|
||||
return result
|
||||
|
||||
def __pos__(self: MarkerT) -> MarkerT:
|
||||
return type(self)(name=self.name, is_member=True)
|
||||
|
||||
def __neg__(self: MarkerT) -> MarkerT:
|
||||
return type(self)(name=self.name, is_member=False)
|
||||
|
||||
def __or__(
|
||||
self, other: Union["_MemberStatusMarker", "_MemberStatusGroupMarker"]
|
||||
) -> "_MemberStatusGroupMarker":
|
||||
if isinstance(other, _MemberStatusMarker):
|
||||
return _MemberStatusGroupMarker(self, other)
|
||||
if isinstance(other, _MemberStatusGroupMarker):
|
||||
return other | self
|
||||
raise TypeError("can't be combined")
|
||||
|
||||
def __rshift__(
|
||||
self, other: Union["_MemberStatusMarker", "_MemberStatusGroupMarker"]
|
||||
) -> "_MemberStatusTransition":
|
||||
old = _MemberStatusGroupMarker(self)
|
||||
if isinstance(other, _MemberStatusMarker):
|
||||
return _MemberStatusTransition(old=old, new=_MemberStatusGroupMarker(other))
|
||||
if isinstance(other, _MemberStatusGroupMarker):
|
||||
return _MemberStatusTransition(old=old, new=other)
|
||||
raise TypeError("can't be combined")
|
||||
|
||||
def __lshift__(
|
||||
self, other: Union["_MemberStatusMarker", "_MemberStatusGroupMarker"]
|
||||
) -> "_MemberStatusTransition":
|
||||
new = _MemberStatusGroupMarker(self)
|
||||
if isinstance(other, _MemberStatusMarker):
|
||||
return _MemberStatusTransition(old=_MemberStatusGroupMarker(other), new=new)
|
||||
if isinstance(other, _MemberStatusGroupMarker):
|
||||
return _MemberStatusTransition(old=other, new=new)
|
||||
raise TypeError("can't be combined")
|
||||
|
||||
def __hash__(self) -> int:
|
||||
return hash((self.name, self.is_member))
|
||||
|
||||
def check_member(self, member: ChatMember) -> bool:
|
||||
if self.is_member is not None and member.is_member != self.is_member:
|
||||
return False
|
||||
return self.name == member.status
|
||||
|
||||
|
||||
class _MemberStatusGroupMarker:
|
||||
def __init__(self, *statuses: _MemberStatusMarker) -> None:
|
||||
self.statuses = set(statuses)
|
||||
|
||||
def __or__(
|
||||
self: MarkerGroupT, other: Union["_MemberStatusMarker", "_MemberStatusGroupMarker"]
|
||||
) -> MarkerGroupT:
|
||||
if isinstance(other, _MemberStatusMarker):
|
||||
return type(self)(*self.statuses, other)
|
||||
elif isinstance(other, _MemberStatusGroupMarker):
|
||||
return type(self)(*self.statuses, *other.statuses)
|
||||
raise TypeError("can't be combined")
|
||||
|
||||
def __rshift__(
|
||||
self, other: Union["_MemberStatusMarker", "_MemberStatusGroupMarker"]
|
||||
) -> "_MemberStatusTransition":
|
||||
if isinstance(other, _MemberStatusMarker):
|
||||
return _MemberStatusTransition(old=self, new=_MemberStatusGroupMarker(other))
|
||||
if isinstance(other, _MemberStatusGroupMarker):
|
||||
return _MemberStatusTransition(old=self, new=other)
|
||||
raise TypeError("can't be combined")
|
||||
|
||||
def __lshift__(
|
||||
self, other: Union["_MemberStatusMarker", "_MemberStatusGroupMarker"]
|
||||
) -> "_MemberStatusTransition":
|
||||
if isinstance(other, _MemberStatusMarker):
|
||||
return _MemberStatusTransition(old=_MemberStatusGroupMarker(other), new=self)
|
||||
if isinstance(other, _MemberStatusGroupMarker):
|
||||
return _MemberStatusTransition(old=other, new=self)
|
||||
raise TypeError("can't be combined")
|
||||
|
||||
def __str__(self) -> str:
|
||||
result = " | ".join(map(str, sorted(self.statuses, key=lambda s: (s.name, s.is_member))))
|
||||
if len(self.statuses) != 1:
|
||||
return f"({result})"
|
||||
return result
|
||||
|
||||
def check_member(self, member: ChatMember) -> bool:
|
||||
for status in self.statuses:
|
||||
if status.check_member(member):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class _MemberStatusTransition:
|
||||
def __init__(self, *, old: _MemberStatusGroupMarker, new: _MemberStatusGroupMarker) -> None:
|
||||
self.old = old
|
||||
self.new = new
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"{self.old} >> {self.new}"
|
||||
|
||||
def __invert__(self: TransitionT) -> TransitionT:
|
||||
return type(self)(old=self.new, new=self.old)
|
||||
|
||||
|
||||
CREATOR = _MemberStatusMarker("creator")
|
||||
ADMINISTRATOR = _MemberStatusMarker("administrator")
|
||||
MEMBER = _MemberStatusMarker("member")
|
||||
RESTRICTED = _MemberStatusMarker("restricted")
|
||||
LEFT = _MemberStatusMarker("left")
|
||||
KICKED = _MemberStatusMarker("kicked")
|
||||
|
||||
IS_MEMBER = CREATOR | ADMINISTRATOR | MEMBER | +RESTRICTED
|
||||
IS_ADMIN = CREATOR | ADMINISTRATOR
|
||||
PROMOTED_TRANSITION = (MEMBER | RESTRICTED | LEFT | KICKED) >> ADMINISTRATOR
|
||||
IS_NOT_MEMBER = LEFT | KICKED | -RESTRICTED
|
||||
|
||||
JOIN_TRANSITION = IS_NOT_MEMBER >> IS_MEMBER
|
||||
LEAVE_TRANSITION = ~JOIN_TRANSITION
|
||||
|
||||
|
||||
class ChatMemberUpdatedStatus(BaseFilter):
|
||||
member_status_changed: Union[
|
||||
_MemberStatusMarker, _MemberStatusGroupMarker, _MemberStatusTransition
|
||||
]
|
||||
|
||||
class Config:
|
||||
arbitrary_types_allowed = True
|
||||
|
||||
async def __call__(self, member_updated: ChatMemberUpdated) -> Union[bool, Dict[str, Any]]:
|
||||
old = member_updated.old_chat_member
|
||||
new = member_updated.new_chat_member
|
||||
rule = self.member_status_changed
|
||||
|
||||
if isinstance(rule, (_MemberStatusMarker, _MemberStatusGroupMarker)):
|
||||
return rule.check_member(new)
|
||||
if isinstance(rule, _MemberStatusTransition):
|
||||
return rule.old.check_member(old) and rule.new.check_member(new)
|
||||
return False
|
||||
|
|
@ -127,7 +127,7 @@ class RedisStorage(BaseStorage):
|
|||
redis = Redis(connection_pool=pool)
|
||||
return cls(redis=redis, **kwargs)
|
||||
|
||||
def create_isolation(self, **kwargs) -> "RedisEventIsolation":
|
||||
def create_isolation(self, **kwargs: Any) -> "RedisEventIsolation":
|
||||
return RedisEventIsolation(redis=self.redis, key_builder=self.key_builder, **kwargs)
|
||||
|
||||
async def close(self) -> None:
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ if TYPE_CHECKING:
|
|||
|
||||
class AddStickerToSet(TelegramMethod[bool]):
|
||||
"""
|
||||
Use this method to add a new sticker to a set created by the bot. You **must** use exactly one of the fields *png_sticker* or *tgs_sticker*. Animated stickers can be added to animated sticker sets and only to them. Animated sticker sets can have up to 50 stickers. Static sticker sets can have up to 120 stickers. Returns :code:`True` on success.
|
||||
Use this method to add a new sticker to a set created by the bot. You **must** use exactly one of the fields *png_sticker*, *tgs_sticker*, or *webm_sticker*. Animated stickers can be added to animated sticker sets and only to them. Animated sticker sets can have up to 50 stickers. Static sticker sets can have up to 120 stickers. Returns :code:`True` on success.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#addstickertoset
|
||||
"""
|
||||
|
|
@ -27,15 +27,18 @@ class AddStickerToSet(TelegramMethod[bool]):
|
|||
png_sticker: Optional[Union[InputFile, str]] = None
|
||||
"""**PNG** image with the sticker, must be up to 512 kilobytes in size, dimensions must not exceed 512px, and either width or height must be exactly 512px. Pass a *file_id* as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. :ref:`More info on Sending Files » <sending-files>`"""
|
||||
tgs_sticker: Optional[InputFile] = None
|
||||
"""**TGS** animation with the sticker, uploaded using multipart/form-data. See `https://core.telegram.org/animated_stickers#technical-requirements <https://core.telegram.org/animated_stickers#technical-requirements>`_`https://core.telegram.org/animated_stickers#technical-requirements <https://core.telegram.org/animated_stickers#technical-requirements>`_ for technical requirements"""
|
||||
"""**TGS** animation with the sticker, uploaded using multipart/form-data. See `https://core.telegram.org/stickers#animated-sticker-requirements <https://core.telegram.org/stickers#animated-sticker-requirements>`_`https://core.telegram.org/stickers#animated-sticker-requirements <https://core.telegram.org/stickers#animated-sticker-requirements>`_ for technical requirements"""
|
||||
webm_sticker: Optional[InputFile] = None
|
||||
"""**WEBM** video with the sticker, uploaded using multipart/form-data. See `https://core.telegram.org/stickers#video-sticker-requirements <https://core.telegram.org/stickers#video-sticker-requirements>`_`https://core.telegram.org/stickers#video-sticker-requirements <https://core.telegram.org/stickers#video-sticker-requirements>`_ for technical requirements"""
|
||||
mask_position: Optional[MaskPosition] = None
|
||||
"""A JSON-serialized object for position where the mask should be placed on faces"""
|
||||
|
||||
def build_request(self, bot: Bot) -> Request:
|
||||
data: Dict[str, Any] = self.dict(exclude={"png_sticker", "tgs_sticker"})
|
||||
data: Dict[str, Any] = self.dict(exclude={"png_sticker", "tgs_sticker", "webm_sticker"})
|
||||
|
||||
files: Dict[str, InputFile] = {}
|
||||
prepare_file(data=data, files=files, name="png_sticker", value=self.png_sticker)
|
||||
prepare_file(data=data, files=files, name="tgs_sticker", value=self.tgs_sticker)
|
||||
prepare_file(data=data, files=files, name="webm_sticker", value=self.webm_sticker)
|
||||
|
||||
return Request(method="addStickerToSet", data=data, files=files)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ if TYPE_CHECKING:
|
|||
|
||||
class CreateNewStickerSet(TelegramMethod[bool]):
|
||||
"""
|
||||
Use this method to create a new sticker set owned by a user. The bot will be able to edit the sticker set thus created. You **must** use exactly one of the fields *png_sticker* or *tgs_sticker*. Returns :code:`True` on success.
|
||||
Use this method to create a new sticker set owned by a user. The bot will be able to edit the sticker set thus created. You **must** use exactly one of the fields *png_sticker*, *tgs_sticker*, or *webm_sticker*. Returns :code:`True` on success.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#createnewstickerset
|
||||
"""
|
||||
|
|
@ -29,17 +29,20 @@ class CreateNewStickerSet(TelegramMethod[bool]):
|
|||
png_sticker: Optional[Union[InputFile, str]] = None
|
||||
"""**PNG** image with the sticker, must be up to 512 kilobytes in size, dimensions must not exceed 512px, and either width or height must be exactly 512px. Pass a *file_id* as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. :ref:`More info on Sending Files » <sending-files>`"""
|
||||
tgs_sticker: Optional[InputFile] = None
|
||||
"""**TGS** animation with the sticker, uploaded using multipart/form-data. See `https://core.telegram.org/animated_stickers#technical-requirements <https://core.telegram.org/animated_stickers#technical-requirements>`_`https://core.telegram.org/animated_stickers#technical-requirements <https://core.telegram.org/animated_stickers#technical-requirements>`_ for technical requirements"""
|
||||
"""**TGS** animation with the sticker, uploaded using multipart/form-data. See `https://core.telegram.org/stickers#animated-sticker-requirements <https://core.telegram.org/stickers#animated-sticker-requirements>`_`https://core.telegram.org/stickers#animated-sticker-requirements <https://core.telegram.org/stickers#animated-sticker-requirements>`_ for technical requirements"""
|
||||
webm_sticker: Optional[InputFile] = None
|
||||
"""**WEBM** video with the sticker, uploaded using multipart/form-data. See `https://core.telegram.org/stickers#video-sticker-requirements <https://core.telegram.org/stickers#video-sticker-requirements>`_`https://core.telegram.org/stickers#video-sticker-requirements <https://core.telegram.org/stickers#video-sticker-requirements>`_ for technical requirements"""
|
||||
contains_masks: Optional[bool] = None
|
||||
"""Pass :code:`True`, if a set of mask stickers should be created"""
|
||||
mask_position: Optional[MaskPosition] = None
|
||||
"""A JSON-serialized object for position where the mask should be placed on faces"""
|
||||
|
||||
def build_request(self, bot: Bot) -> Request:
|
||||
data: Dict[str, Any] = self.dict(exclude={"png_sticker", "tgs_sticker"})
|
||||
data: Dict[str, Any] = self.dict(exclude={"png_sticker", "tgs_sticker", "webm_sticker"})
|
||||
|
||||
files: Dict[str, InputFile] = {}
|
||||
prepare_file(data=data, files=files, name="png_sticker", value=self.png_sticker)
|
||||
prepare_file(data=data, files=files, name="tgs_sticker", value=self.tgs_sticker)
|
||||
prepare_file(data=data, files=files, name="webm_sticker", value=self.webm_sticker)
|
||||
|
||||
return Request(method="createNewStickerSet", data=data, files=files)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ if TYPE_CHECKING:
|
|||
|
||||
class SendSticker(TelegramMethod[Message]):
|
||||
"""
|
||||
Use this method to send static .WEBP or `animated <https://telegram.org/blog/animated-stickers>`_ .TGS stickers. On success, the sent :class:`aiogram.types.message.Message` is returned.
|
||||
Use this method to send static .WEBP, `animated <https://telegram.org/blog/animated-stickers>`_ .TGS, or `video <https://telegram.org/blog/video-stickers-better-reactions>`_ .WEBM stickers. On success, the sent :class:`aiogram.types.message.Message` is returned.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#sendsticker
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ if TYPE_CHECKING:
|
|||
|
||||
class SetStickerSetThumb(TelegramMethod[bool]):
|
||||
"""
|
||||
Use this method to set the thumbnail of a sticker set. Animated thumbnails can be set for animated sticker sets only. Returns :code:`True` on success.
|
||||
Use this method to set the thumbnail of a sticker set. Animated thumbnails can be set for animated sticker sets only. Video thumbnails can be set only for video sticker sets only. Returns :code:`True` on success.
|
||||
|
||||
Source: https://core.telegram.org/bots/api#setstickersetthumb
|
||||
"""
|
||||
|
|
@ -23,7 +23,7 @@ class SetStickerSetThumb(TelegramMethod[bool]):
|
|||
user_id: int
|
||||
"""User identifier of the sticker set owner"""
|
||||
thumb: Optional[Union[InputFile, str]] = None
|
||||
"""A **PNG** image with the thumbnail, must be up to 128 kilobytes in size and have width and height exactly 100px, or a **TGS** animation with the thumbnail up to 32 kilobytes in size; see `https://core.telegram.org/animated_stickers#technical-requirements <https://core.telegram.org/animated_stickers#technical-requirements>`_`https://core.telegram.org/animated_stickers#technical-requirements <https://core.telegram.org/animated_stickers#technical-requirements>`_ for animated sticker technical requirements. Pass a *file_id* as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. :ref:`More info on Sending Files » <sending-files>`. Animated sticker set thumbnail can't be uploaded via HTTP URL."""
|
||||
"""A **PNG** image with the thumbnail, must be up to 128 kilobytes in size and have width and height exactly 100px, or a **TGS** animation with the thumbnail up to 32 kilobytes in size; see `https://core.telegram.org/stickers#animated-sticker-requirements <https://core.telegram.org/stickers#animated-sticker-requirements>`_`https://core.telegram.org/stickers#animated-sticker-requirements <https://core.telegram.org/stickers#animated-sticker-requirements>`_ for animated sticker technical requirements, or a **WEBM** video with the thumbnail up to 32 kilobytes in size; see `https://core.telegram.org/stickers#video-sticker-requirements <https://core.telegram.org/stickers#video-sticker-requirements>`_`https://core.telegram.org/stickers#video-sticker-requirements <https://core.telegram.org/stickers#video-sticker-requirements>`_ for video sticker technical requirements. Pass a *file_id* as a String to send a file that already exists on the Telegram servers, pass an HTTP URL as a String for Telegram to get a file from the Internet, or upload a new one using multipart/form-data. :ref:`More info on Sending Files » <sending-files>`. Animated sticker set thumbnails can't be uploaded via HTTP URL."""
|
||||
|
||||
def build_request(self, bot: Bot) -> Request:
|
||||
data: Dict[str, Any] = self.dict(exclude={"thumb"})
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class UnbanChatMember(TelegramMethod[bool]):
|
|||
__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:`@username`)"""
|
||||
"""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"""
|
||||
only_if_banned: Optional[bool] = None
|
||||
|
|
|
|||
|
|
@ -1,7 +1,13 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
from typing import TYPE_CHECKING, Optional, Union
|
||||
|
||||
from .base import TelegramObject
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .user import User
|
||||
|
||||
|
||||
class ChatMember(TelegramObject):
|
||||
"""
|
||||
|
|
@ -16,3 +22,48 @@ class ChatMember(TelegramObject):
|
|||
|
||||
Source: https://core.telegram.org/bots/api#chatmember
|
||||
"""
|
||||
|
||||
status: str
|
||||
"""..."""
|
||||
user: Optional[User] = None
|
||||
"""*Optional*. Information about the user"""
|
||||
is_anonymous: Optional[bool] = None
|
||||
"""*Optional*. :code:`True`, if the user's presence in the chat is hidden"""
|
||||
custom_title: Optional[str] = None
|
||||
"""*Optional*. Custom title for this user"""
|
||||
can_be_edited: Optional[bool] = None
|
||||
"""*Optional*. :code:`True`, if the bot is allowed to edit administrator privileges of that user"""
|
||||
can_manage_chat: Optional[bool] = None
|
||||
"""*Optional*. :code:`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: Optional[bool] = None
|
||||
"""*Optional*. :code:`True`, if the administrator can delete messages of other users"""
|
||||
can_manage_voice_chats: Optional[bool] = None
|
||||
"""*Optional*. :code:`True`, if the administrator can manage voice chats"""
|
||||
can_restrict_members: Optional[bool] = None
|
||||
"""*Optional*. :code:`True`, if the administrator can restrict, ban or unban chat members"""
|
||||
can_promote_members: Optional[bool] = None
|
||||
"""*Optional*. :code:`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*. :code:`True`, if the user is allowed to change the chat title, photo and other settings"""
|
||||
can_invite_users: Optional[bool] = None
|
||||
"""*Optional*. :code:`True`, if the user is allowed to invite new users to the chat"""
|
||||
can_post_messages: Optional[bool] = None
|
||||
"""*Optional*. :code:`True`, if the administrator can post in the channel; channels only"""
|
||||
can_edit_messages: Optional[bool] = None
|
||||
"""*Optional*. :code:`True`, if the administrator can edit messages of other users and can pin messages; channels only"""
|
||||
can_pin_messages: Optional[bool] = None
|
||||
"""*Optional*. :code:`True`, if the user is allowed to pin messages; groups and supergroups only"""
|
||||
is_member: Optional[bool] = None
|
||||
"""*Optional*. :code:`True`, if the user is a member of the chat at the moment of the request"""
|
||||
can_send_messages: Optional[bool] = None
|
||||
"""*Optional*. :code:`True`, if the user is allowed to send text messages, contacts, locations and venues"""
|
||||
can_send_media_messages: Optional[bool] = None
|
||||
"""*Optional*. :code:`True`, if the user is allowed to send audios, documents, photos, videos, video notes and voice notes"""
|
||||
can_send_polls: Optional[bool] = None
|
||||
"""*Optional*. :code:`True`, if the user is allowed to send polls"""
|
||||
can_send_other_messages: Optional[bool] = None
|
||||
"""*Optional*. :code:`True`, if the user is allowed to send animations, games, stickers and use inline bots"""
|
||||
can_add_web_page_previews: Optional[bool] = None
|
||||
"""*Optional*. :code:`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*. Date when restrictions will be lifted for this user; unix time. If 0, then the user is restricted forever"""
|
||||
|
|
|
|||
|
|
@ -37,6 +37,10 @@ class ChatActionSender:
|
|||
self._running = False
|
||||
self._lock = Lock()
|
||||
|
||||
async def _wait(self, interval: float) -> None:
|
||||
with suppress(asyncio.TimeoutError):
|
||||
await asyncio.wait_for(self._close_event.wait(), interval)
|
||||
|
||||
async def _worker(self) -> None:
|
||||
logger.debug(
|
||||
"Started chat action %r sender in chat_id=%s via bot id=%d",
|
||||
|
|
@ -46,7 +50,7 @@ class ChatActionSender:
|
|||
)
|
||||
try:
|
||||
counter = 0
|
||||
await asyncio.sleep(self.initial_sleep)
|
||||
await self._wait(self.initial_sleep)
|
||||
while not self._close_event.is_set():
|
||||
start = time.monotonic()
|
||||
logger.debug(
|
||||
|
|
@ -60,8 +64,7 @@ class ChatActionSender:
|
|||
counter += 1
|
||||
|
||||
interval = self.interval - (time.monotonic() - start)
|
||||
with suppress(asyncio.TimeoutError):
|
||||
await asyncio.wait_for(self._close_event.wait(), interval)
|
||||
await self._wait(interval)
|
||||
finally:
|
||||
logger.debug(
|
||||
"Finished chat action %r sender in chat_id=%s via bot id=%d",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue