Правки по mypy
This commit is contained in:
parent
2cd3d64bb8
commit
7d2826c4b5
131
maxapi/bot.py
131
maxapi/bot.py
@ -1,7 +1,9 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Any, Dict, List, Optional, TYPE_CHECKING
|
from typing import Any, Dict, List, Optional, Union, TYPE_CHECKING
|
||||||
|
|
||||||
|
from .client.default import DefaultConnectionProperties
|
||||||
|
|
||||||
from .types.input_media import InputMedia, InputMediaBuffer
|
from .types.input_media import InputMedia, InputMediaBuffer
|
||||||
|
|
||||||
@ -82,6 +84,7 @@ class Bot(BaseConnection):
|
|||||||
parse_mode: Optional[ParseMode] = None,
|
parse_mode: Optional[ParseMode] = None,
|
||||||
notify: Optional[bool] = None,
|
notify: Optional[bool] = None,
|
||||||
auto_requests: bool = True,
|
auto_requests: bool = True,
|
||||||
|
default_connection: Optional[DefaultConnectionProperties] = None
|
||||||
):
|
):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -91,22 +94,24 @@ class Bot(BaseConnection):
|
|||||||
:param parse_mode: Форматирование по умолчанию
|
:param parse_mode: Форматирование по умолчанию
|
||||||
:param notify: Отключение уведомлений при отправке сообщений (по умолчанию игнорируется) (не работает на стороне MAX)
|
:param notify: Отключение уведомлений при отправке сообщений (по умолчанию игнорируется) (не работает на стороне MAX)
|
||||||
:param auto_requests: Автоматическое заполнение полей chat и from_user в Update
|
:param auto_requests: Автоматическое заполнение полей chat и from_user в Update
|
||||||
|
:param default_connection: Настройки aiohttp
|
||||||
с помощью API запросов если они не заложены как полноценные объекты в Update (по умолчанию True, при False chat и from_user в некоторых событиях будут выдавать None)
|
с помощью API запросов если они не заложены как полноценные объекты в Update (по умолчанию True, при False chat и from_user в некоторых событиях будут выдавать None)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self.bot = self
|
self.bot = self
|
||||||
|
self.default_connection = default_connection or DefaultConnectionProperties()
|
||||||
|
|
||||||
self.__token = token
|
self.__token = token
|
||||||
self.params = {'access_token': self.__token}
|
self.params: Dict[str, Any] = {'access_token': self.__token}
|
||||||
self.marker_updates = None
|
self.marker_updates = None
|
||||||
|
|
||||||
self.parse_mode = parse_mode
|
self.parse_mode = parse_mode
|
||||||
self.notify = notify
|
self.notify = notify
|
||||||
self.auto_requests = auto_requests
|
self.auto_requests = auto_requests
|
||||||
|
|
||||||
self._me: User = None
|
self._me: User | None = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def me(self):
|
def me(self):
|
||||||
@ -120,11 +125,11 @@ class Bot(BaseConnection):
|
|||||||
|
|
||||||
async def send_message(
|
async def send_message(
|
||||||
self,
|
self,
|
||||||
chat_id: int = None,
|
chat_id: Optional[int] = None,
|
||||||
user_id: int = None,
|
user_id: Optional[int] = None,
|
||||||
text: str = None,
|
text: Optional[str] = None,
|
||||||
attachments: List[Attachment | InputMedia | InputMediaBuffer] = None,
|
attachments: Optional[List[Attachment | InputMedia | InputMediaBuffer]] = None,
|
||||||
link: NewMessageLink = None,
|
link: Optional[NewMessageLink] = None,
|
||||||
notify: Optional[bool] = None,
|
notify: Optional[bool] = None,
|
||||||
parse_mode: Optional[ParseMode] = None
|
parse_mode: Optional[ParseMode] = None
|
||||||
) -> SendedMessage:
|
) -> SendedMessage:
|
||||||
@ -152,11 +157,11 @@ class Bot(BaseConnection):
|
|||||||
link=link,
|
link=link,
|
||||||
notify=self._resolve_notify(notify),
|
notify=self._resolve_notify(notify),
|
||||||
parse_mode=self._resolve_parse_mode(parse_mode)
|
parse_mode=self._resolve_parse_mode(parse_mode)
|
||||||
).request()
|
).fetch()
|
||||||
|
|
||||||
async def send_action(
|
async def send_action(
|
||||||
self,
|
self,
|
||||||
chat_id: int = None,
|
chat_id: Optional[int] = None,
|
||||||
action: SenderAction = SenderAction.TYPING_ON
|
action: SenderAction = SenderAction.TYPING_ON
|
||||||
) -> SendedAction:
|
) -> SendedAction:
|
||||||
|
|
||||||
@ -173,14 +178,14 @@ class Bot(BaseConnection):
|
|||||||
bot=self,
|
bot=self,
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
action=action
|
action=action
|
||||||
).request()
|
).fetch()
|
||||||
|
|
||||||
async def edit_message(
|
async def edit_message(
|
||||||
self,
|
self,
|
||||||
message_id: str,
|
message_id: str,
|
||||||
text: str = None,
|
text: Optional[str] = None,
|
||||||
attachments: List[Attachment | InputMedia | InputMediaBuffer] = None,
|
attachments: Optional[List[Attachment | InputMedia | InputMediaBuffer]] = None,
|
||||||
link: NewMessageLink = None,
|
link: Optional[NewMessageLink] = None,
|
||||||
notify: Optional[bool] = None,
|
notify: Optional[bool] = None,
|
||||||
parse_mode: Optional[ParseMode] = None
|
parse_mode: Optional[ParseMode] = None
|
||||||
) -> EditedMessage:
|
) -> EditedMessage:
|
||||||
@ -206,7 +211,7 @@ class Bot(BaseConnection):
|
|||||||
link=link,
|
link=link,
|
||||||
notify=self._resolve_notify(notify),
|
notify=self._resolve_notify(notify),
|
||||||
parse_mode=self._resolve_parse_mode(parse_mode)
|
parse_mode=self._resolve_parse_mode(parse_mode)
|
||||||
).request()
|
).fetch()
|
||||||
|
|
||||||
async def delete_message(
|
async def delete_message(
|
||||||
self,
|
self,
|
||||||
@ -224,7 +229,7 @@ class Bot(BaseConnection):
|
|||||||
return await DeleteMessage(
|
return await DeleteMessage(
|
||||||
bot=self,
|
bot=self,
|
||||||
message_id=message_id,
|
message_id=message_id,
|
||||||
).request()
|
).fetch()
|
||||||
|
|
||||||
async def delete_chat(
|
async def delete_chat(
|
||||||
self,
|
self,
|
||||||
@ -242,14 +247,14 @@ class Bot(BaseConnection):
|
|||||||
return await DeleteChat(
|
return await DeleteChat(
|
||||||
bot=self,
|
bot=self,
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
).request()
|
).fetch()
|
||||||
|
|
||||||
async def get_messages(
|
async def get_messages(
|
||||||
self,
|
self,
|
||||||
chat_id: int = None,
|
chat_id: Optional[int] = None,
|
||||||
message_ids: List[str] = None,
|
message_ids: Optional[List[str]] = None,
|
||||||
from_time: datetime | int = None,
|
from_time: Optional[Union[datetime, int]] = None,
|
||||||
to_time: datetime | int = None,
|
to_time: Optional[Union[datetime, int]] = None,
|
||||||
count: int = 50,
|
count: int = 50,
|
||||||
) -> Messages:
|
) -> Messages:
|
||||||
|
|
||||||
@ -272,7 +277,7 @@ class Bot(BaseConnection):
|
|||||||
from_time=from_time,
|
from_time=from_time,
|
||||||
to_time=to_time,
|
to_time=to_time,
|
||||||
count=count
|
count=count
|
||||||
).request()
|
).fetch()
|
||||||
|
|
||||||
async def get_message(
|
async def get_message(
|
||||||
self,
|
self,
|
||||||
@ -299,7 +304,7 @@ class Bot(BaseConnection):
|
|||||||
:return: Объект пользователя бота
|
:return: Объект пользователя бота
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return await GetMe(self).request()
|
return await GetMe(self).fetch()
|
||||||
|
|
||||||
async def get_pin_message(
|
async def get_pin_message(
|
||||||
self,
|
self,
|
||||||
@ -317,14 +322,14 @@ class Bot(BaseConnection):
|
|||||||
return await GetPinnedMessage(
|
return await GetPinnedMessage(
|
||||||
bot=self,
|
bot=self,
|
||||||
chat_id=chat_id
|
chat_id=chat_id
|
||||||
).request()
|
).fetch()
|
||||||
|
|
||||||
async def change_info(
|
async def change_info(
|
||||||
self,
|
self,
|
||||||
name: str = None,
|
name: Optional[str] = None,
|
||||||
description: str = None,
|
description: Optional[str] = None,
|
||||||
commands: List[BotCommand] = None,
|
commands: Optional[List[BotCommand]] = None,
|
||||||
photo: Dict[str, Any] = None
|
photo: Optional[Dict[str, Any]] = None
|
||||||
) -> User:
|
) -> User:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -344,12 +349,12 @@ class Bot(BaseConnection):
|
|||||||
description=description,
|
description=description,
|
||||||
commands=commands,
|
commands=commands,
|
||||||
photo=photo
|
photo=photo
|
||||||
).request()
|
).fetch()
|
||||||
|
|
||||||
async def get_chats(
|
async def get_chats(
|
||||||
self,
|
self,
|
||||||
count: int = 50,
|
count: int = 50,
|
||||||
marker: int = None
|
marker: Optional[int] = None
|
||||||
) -> Chats:
|
) -> Chats:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -365,7 +370,7 @@ class Bot(BaseConnection):
|
|||||||
bot=self,
|
bot=self,
|
||||||
count=count,
|
count=count,
|
||||||
marker=marker
|
marker=marker
|
||||||
).request()
|
).fetch()
|
||||||
|
|
||||||
async def get_chat_by_link(
|
async def get_chat_by_link(
|
||||||
self,
|
self,
|
||||||
@ -380,7 +385,7 @@ class Bot(BaseConnection):
|
|||||||
:return: Объект чата
|
:return: Объект чата
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return await GetChatByLink(bot=self, link=link).request()
|
return await GetChatByLink(bot=self, link=link).fetch()
|
||||||
|
|
||||||
async def get_chat_by_id(
|
async def get_chat_by_id(
|
||||||
self,
|
self,
|
||||||
@ -395,14 +400,14 @@ class Bot(BaseConnection):
|
|||||||
:return: Объект чата
|
:return: Объект чата
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return await GetChatById(bot=self, id=id).request()
|
return await GetChatById(bot=self, id=id).fetch()
|
||||||
|
|
||||||
async def edit_chat(
|
async def edit_chat(
|
||||||
self,
|
self,
|
||||||
chat_id: int,
|
chat_id: int,
|
||||||
icon: PhotoAttachmentRequestPayload = None,
|
icon: Optional[PhotoAttachmentRequestPayload] = None,
|
||||||
title: str = None,
|
title: Optional[str] = None,
|
||||||
pin: str = None,
|
pin: Optional[str] = None,
|
||||||
notify: Optional[bool] = None,
|
notify: Optional[bool] = None,
|
||||||
) -> Chat:
|
) -> Chat:
|
||||||
|
|
||||||
@ -425,7 +430,7 @@ class Bot(BaseConnection):
|
|||||||
title=title,
|
title=title,
|
||||||
pin=pin,
|
pin=pin,
|
||||||
notify=self._resolve_notify(notify),
|
notify=self._resolve_notify(notify),
|
||||||
).request()
|
).fetch()
|
||||||
|
|
||||||
async def get_video(
|
async def get_video(
|
||||||
self,
|
self,
|
||||||
@ -443,13 +448,13 @@ class Bot(BaseConnection):
|
|||||||
return await GetVideo(
|
return await GetVideo(
|
||||||
bot=self,
|
bot=self,
|
||||||
video_token=video_token
|
video_token=video_token
|
||||||
).request()
|
).fetch()
|
||||||
|
|
||||||
async def send_callback(
|
async def send_callback(
|
||||||
self,
|
self,
|
||||||
callback_id: str,
|
callback_id: str,
|
||||||
message: Message = None,
|
message: Optional[Message] = None,
|
||||||
notification: str = None
|
notification: Optional[str] = None
|
||||||
) -> SendedCallback:
|
) -> SendedCallback:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -467,7 +472,7 @@ class Bot(BaseConnection):
|
|||||||
callback_id=callback_id,
|
callback_id=callback_id,
|
||||||
message=message,
|
message=message,
|
||||||
notification=notification
|
notification=notification
|
||||||
).request()
|
).fetch()
|
||||||
|
|
||||||
async def pin_message(
|
async def pin_message(
|
||||||
self,
|
self,
|
||||||
@ -491,7 +496,7 @@ class Bot(BaseConnection):
|
|||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
message_id=message_id,
|
message_id=message_id,
|
||||||
notify=self._resolve_notify(notify),
|
notify=self._resolve_notify(notify),
|
||||||
).request()
|
).fetch()
|
||||||
|
|
||||||
async def delete_pin_message(
|
async def delete_pin_message(
|
||||||
self,
|
self,
|
||||||
@ -509,7 +514,7 @@ class Bot(BaseConnection):
|
|||||||
return await DeletePinMessage(
|
return await DeletePinMessage(
|
||||||
bot=self,
|
bot=self,
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
).request()
|
).fetch()
|
||||||
|
|
||||||
async def get_me_from_chat(
|
async def get_me_from_chat(
|
||||||
self,
|
self,
|
||||||
@ -527,7 +532,7 @@ class Bot(BaseConnection):
|
|||||||
return await GetMeFromChat(
|
return await GetMeFromChat(
|
||||||
bot=self,
|
bot=self,
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
).request()
|
).fetch()
|
||||||
|
|
||||||
async def delete_me_from_chat(
|
async def delete_me_from_chat(
|
||||||
self,
|
self,
|
||||||
@ -545,7 +550,7 @@ class Bot(BaseConnection):
|
|||||||
return await DeleteMeFromMessage(
|
return await DeleteMeFromMessage(
|
||||||
bot=self,
|
bot=self,
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
).request()
|
).fetch()
|
||||||
|
|
||||||
async def get_list_admin_chat(
|
async def get_list_admin_chat(
|
||||||
self,
|
self,
|
||||||
@ -563,13 +568,13 @@ class Bot(BaseConnection):
|
|||||||
return await GetListAdminChat(
|
return await GetListAdminChat(
|
||||||
bot=self,
|
bot=self,
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
).request()
|
).fetch()
|
||||||
|
|
||||||
async def add_list_admin_chat(
|
async def add_list_admin_chat(
|
||||||
self,
|
self,
|
||||||
chat_id: int,
|
chat_id: int,
|
||||||
admins: List[ChatAdmin],
|
admins: List[ChatAdmin],
|
||||||
marker: int = None
|
marker: Optional[int] = None
|
||||||
) -> AddedListAdminChat:
|
) -> AddedListAdminChat:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -587,7 +592,7 @@ class Bot(BaseConnection):
|
|||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
admins=admins,
|
admins=admins,
|
||||||
marker=marker,
|
marker=marker,
|
||||||
).request()
|
).fetch()
|
||||||
|
|
||||||
async def remove_admin(
|
async def remove_admin(
|
||||||
self,
|
self,
|
||||||
@ -608,14 +613,14 @@ class Bot(BaseConnection):
|
|||||||
bot=self,
|
bot=self,
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
user_id=user_id,
|
user_id=user_id,
|
||||||
).request()
|
).fetch()
|
||||||
|
|
||||||
async def get_chat_members(
|
async def get_chat_members(
|
||||||
self,
|
self,
|
||||||
chat_id: int,
|
chat_id: int,
|
||||||
user_ids: List[int] = None,
|
user_ids: Optional[List[int]] = None,
|
||||||
marker: int = None,
|
marker: Optional[int] = None,
|
||||||
count: int = None,
|
count: Optional[int] = None,
|
||||||
) -> GettedMembersChat:
|
) -> GettedMembersChat:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -635,13 +640,13 @@ class Bot(BaseConnection):
|
|||||||
user_ids=user_ids,
|
user_ids=user_ids,
|
||||||
marker=marker,
|
marker=marker,
|
||||||
count=count,
|
count=count,
|
||||||
).request()
|
).fetch()
|
||||||
|
|
||||||
async def get_chat_member(
|
async def get_chat_member(
|
||||||
self,
|
self,
|
||||||
chat_id: int,
|
chat_id: int,
|
||||||
user_id: int,
|
user_id: int,
|
||||||
) -> GettedMembersChat:
|
) -> Optional[ChatMember]:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Получает участника чата.
|
Получает участника чата.
|
||||||
@ -659,11 +664,13 @@ class Bot(BaseConnection):
|
|||||||
|
|
||||||
if members.members:
|
if members.members:
|
||||||
return members.members[0]
|
return members.members[0]
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
async def add_chat_members(
|
async def add_chat_members(
|
||||||
self,
|
self,
|
||||||
chat_id: int,
|
chat_id: int,
|
||||||
user_ids: List[str],
|
user_ids: List[int],
|
||||||
) -> AddedMembersChat:
|
) -> AddedMembersChat:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -679,7 +686,7 @@ class Bot(BaseConnection):
|
|||||||
bot=self,
|
bot=self,
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
user_ids=user_ids,
|
user_ids=user_ids,
|
||||||
).request()
|
).fetch()
|
||||||
|
|
||||||
async def kick_chat_member(
|
async def kick_chat_member(
|
||||||
self,
|
self,
|
||||||
@ -703,11 +710,11 @@ class Bot(BaseConnection):
|
|||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
user_id=user_id,
|
user_id=user_id,
|
||||||
block=block,
|
block=block,
|
||||||
).request()
|
).fetch()
|
||||||
|
|
||||||
async def get_updates(
|
async def get_updates(
|
||||||
self,
|
self,
|
||||||
) -> UpdateUnion:
|
) -> Dict:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Получает обновления для бота.
|
Получает обновления для бота.
|
||||||
@ -717,7 +724,7 @@ class Bot(BaseConnection):
|
|||||||
|
|
||||||
return await GetUpdates(
|
return await GetUpdates(
|
||||||
bot=self,
|
bot=self,
|
||||||
).request()
|
).fetch()
|
||||||
|
|
||||||
async def get_upload_url(
|
async def get_upload_url(
|
||||||
self,
|
self,
|
||||||
@ -735,7 +742,7 @@ class Bot(BaseConnection):
|
|||||||
return await GetUploadURL(
|
return await GetUploadURL(
|
||||||
bot=self,
|
bot=self,
|
||||||
type=type
|
type=type
|
||||||
).request()
|
).fetch()
|
||||||
|
|
||||||
async def set_my_commands(
|
async def set_my_commands(
|
||||||
self,
|
self,
|
||||||
@ -753,7 +760,7 @@ class Bot(BaseConnection):
|
|||||||
return await ChangeInfo(
|
return await ChangeInfo(
|
||||||
bot=self,
|
bot=self,
|
||||||
commands=list(commands)
|
commands=list(commands)
|
||||||
).request()
|
).fetch()
|
||||||
|
|
||||||
async def download_file(
|
async def download_file(
|
||||||
self,
|
self,
|
||||||
@ -777,4 +784,4 @@ class Bot(BaseConnection):
|
|||||||
path=path,
|
path=path,
|
||||||
media_url=url,
|
media_url=url,
|
||||||
media_token=token
|
media_token=token
|
||||||
).request()
|
).fetch()
|
10
maxapi/client/default.py
Normal file
10
maxapi/client/default.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
|
||||||
|
from aiohttp import ClientTimeout
|
||||||
|
|
||||||
|
|
||||||
|
class DefaultConnectionProperties:
|
||||||
|
|
||||||
|
def __init__(self, timeout: int = 5 * 30, sock_connect: int = 30, **kwargs):
|
||||||
|
self.timeout = ClientTimeout(total=timeout, sock_connect=sock_connect)
|
||||||
|
self.kwargs = kwargs
|
@ -1,7 +1,9 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import mimetypes
|
import mimetypes
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING, Any, Optional
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
import aiofiles
|
import aiofiles
|
||||||
@ -18,7 +20,7 @@ from ..enums.http_method import HTTPMethod
|
|||||||
from ..enums.api_path import ApiPath
|
from ..enums.api_path import ApiPath
|
||||||
from ..enums.upload_type import UploadType
|
from ..enums.upload_type import UploadType
|
||||||
|
|
||||||
from ..loggers import logger_bot, logger_connection
|
from ..loggers import logger_bot
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from ..bot import Bot
|
from ..bot import Bot
|
||||||
@ -36,15 +38,15 @@ class BaseConnection:
|
|||||||
|
|
||||||
API_URL = 'https://botapi.max.ru'
|
API_URL = 'https://botapi.max.ru'
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
self.bot: 'Bot' = None
|
self.bot: Optional[Bot] = None
|
||||||
self.session: ClientSession = None
|
self.session: Optional[ClientSession] = None
|
||||||
|
|
||||||
async def request(
|
async def request(
|
||||||
self,
|
self,
|
||||||
method: HTTPMethod,
|
method: HTTPMethod,
|
||||||
path: ApiPath,
|
path: ApiPath | str,
|
||||||
model: BaseModel = None,
|
model: BaseModel | Any = None,
|
||||||
is_return_raw: bool = False,
|
is_return_raw: bool = False,
|
||||||
**kwargs
|
**kwargs
|
||||||
):
|
):
|
||||||
@ -64,8 +66,14 @@ class BaseConnection:
|
|||||||
- dict (если is_return_raw=True)
|
- dict (если is_return_raw=True)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
assert self.bot is not None
|
||||||
|
|
||||||
if not self.bot.session:
|
if not self.bot.session:
|
||||||
self.bot.session = ClientSession(self.bot.API_URL)
|
self.bot.session = ClientSession(
|
||||||
|
base_url=self.bot.API_URL,
|
||||||
|
timeout=self.bot.default_connection.timeout,
|
||||||
|
**self.bot.default_connection.kwargs
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
r = await self.bot.session.request(
|
r = await self.bot.session.request(
|
||||||
@ -90,7 +98,7 @@ class BaseConnection:
|
|||||||
|
|
||||||
if is_return_raw: return raw
|
if is_return_raw: return raw
|
||||||
|
|
||||||
model = model(**raw)
|
model = model(**raw) # type: ignore
|
||||||
|
|
||||||
if hasattr(model, 'message'):
|
if hasattr(model, 'message'):
|
||||||
attr = getattr(model, 'message')
|
attr = getattr(model, 'message')
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict, Optional, Union
|
||||||
|
|
||||||
from ..context.state_machine import State, StatesGroup
|
from ..context.state_machine import State, StatesGroup
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ class MemoryContext:
|
|||||||
self.chat_id = chat_id
|
self.chat_id = chat_id
|
||||||
self.user_id = user_id
|
self.user_id = user_id
|
||||||
self._context: Dict[str, Any] = {}
|
self._context: Dict[str, Any] = {}
|
||||||
self._state: State | None = None
|
self._state: State | str | None = None
|
||||||
self._lock = asyncio.Lock()
|
self._lock = asyncio.Lock()
|
||||||
|
|
||||||
async def get_data(self) -> dict[str, Any]:
|
async def get_data(self) -> dict[str, Any]:
|
||||||
@ -58,7 +58,7 @@ class MemoryContext:
|
|||||||
async with self._lock:
|
async with self._lock:
|
||||||
self._context.update(kwargs)
|
self._context.update(kwargs)
|
||||||
|
|
||||||
async def set_state(self, state: State | str = None):
|
async def set_state(self, state: Optional[Union[State, str]] = None):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Устанавливает новое состояние.
|
Устанавливает новое состояние.
|
||||||
|
@ -2,7 +2,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
from typing import Any, Callable, Dict, List, TYPE_CHECKING
|
from typing import Any, Callable, Dict, List, TYPE_CHECKING, Optional, cast
|
||||||
|
|
||||||
from fastapi import FastAPI, Request
|
from fastapi import FastAPI, Request
|
||||||
from fastapi.responses import JSONResponse
|
from fastapi.responses import JSONResponse
|
||||||
@ -45,7 +45,7 @@ class Dispatcher:
|
|||||||
применение middleware, фильтров и вызов соответствующих обработчиков.
|
применение middleware, фильтров и вызов соответствующих обработчиков.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self) -> None:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Инициализация диспетчера.
|
Инициализация диспетчера.
|
||||||
@ -53,12 +53,12 @@ class Dispatcher:
|
|||||||
|
|
||||||
self.event_handlers: List[Handler] = []
|
self.event_handlers: List[Handler] = []
|
||||||
self.contexts: List[MemoryContext] = []
|
self.contexts: List[MemoryContext] = []
|
||||||
self.routers: List[Router] = []
|
self.routers: List[Router | Dispatcher] = []
|
||||||
self.filters: List[MagicFilter] = []
|
self.filters: List[MagicFilter] = []
|
||||||
self.middlewares: List[BaseMiddleware] = []
|
self.middlewares: List[BaseMiddleware] = []
|
||||||
|
|
||||||
self.bot: Bot = None
|
self.bot: Optional[Bot] = None
|
||||||
self.on_started_func: Callable = None
|
self.on_started_func: Optional[Callable] = None
|
||||||
|
|
||||||
self.message_created = Event(update_type=UpdateType.MESSAGE_CREATED, router=self)
|
self.message_created = Event(update_type=UpdateType.MESSAGE_CREATED, router=self)
|
||||||
self.bot_added = Event(update_type=UpdateType.BOT_ADDED, router=self)
|
self.bot_added = Event(update_type=UpdateType.BOT_ADDED, router=self)
|
||||||
@ -249,18 +249,18 @@ class Dispatcher:
|
|||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
events = await self.bot.get_updates()
|
events: Dict = await self.bot.get_updates() # type: ignore
|
||||||
|
|
||||||
if isinstance(events, Error):
|
if isinstance(events, Error):
|
||||||
logger_dp.info(f'Ошибка при получении обновлений: {events}, жду {GET_UPDATES_RETRY_DELAY} секунд')
|
logger_dp.info(f'Ошибка при получении обновлений: {events}, жду {GET_UPDATES_RETRY_DELAY} секунд')
|
||||||
await asyncio.sleep(GET_UPDATES_RETRY_DELAY)
|
await asyncio.sleep(GET_UPDATES_RETRY_DELAY)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.bot.marker_updates = events.get('marker')
|
self.bot.marker_updates = events.get('marker') # type: ignore
|
||||||
|
|
||||||
processed_events = await process_update_request(
|
processed_events = await process_update_request(
|
||||||
events=events,
|
events=events,
|
||||||
bot=self.bot
|
bot=self.bot # type: ignore
|
||||||
)
|
)
|
||||||
|
|
||||||
for event in processed_events:
|
for event in processed_events:
|
||||||
@ -270,7 +270,7 @@ class Dispatcher:
|
|||||||
logger_dp.error(f'Ошибка подключения, жду {CONNECTION_RETRY_DELAY} секунд')
|
logger_dp.error(f'Ошибка подключения, жду {CONNECTION_RETRY_DELAY} секунд')
|
||||||
await asyncio.sleep(CONNECTION_RETRY_DELAY)
|
await asyncio.sleep(CONNECTION_RETRY_DELAY)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger_dp.error(f'Общая ошибка при обработке событий: {e}')
|
logger_dp.error(f'Общая ошибка при обработке событий: {e.__class__} - {e}')
|
||||||
|
|
||||||
async def handle_webhook(self, bot: Bot, host: str = '0.0.0.0', port: int = 8080):
|
async def handle_webhook(self, bot: Bot, host: str = '0.0.0.0', port: int = 8080):
|
||||||
|
|
||||||
@ -289,7 +289,7 @@ class Dispatcher:
|
|||||||
|
|
||||||
event_object = await process_update_webhook(
|
event_object = await process_update_webhook(
|
||||||
event_json=event_json,
|
event_json=event_json,
|
||||||
bot=self.bot
|
bot=self.bot # type: ignore
|
||||||
)
|
)
|
||||||
|
|
||||||
await self.handle(event_object)
|
await self.handle(event_object)
|
||||||
|
@ -16,4 +16,5 @@ class AttachmentType(str, Enum):
|
|||||||
STICKER = 'sticker'
|
STICKER = 'sticker'
|
||||||
CONTACT = 'contact'
|
CONTACT = 'contact'
|
||||||
INLINE_KEYBOARD = 'inline_keyboard'
|
INLINE_KEYBOARD = 'inline_keyboard'
|
||||||
LOCATION = 'location'
|
LOCATION = 'location'
|
||||||
|
SHARE = 'share'
|
@ -1,3 +1,11 @@
|
|||||||
|
|
||||||
class MaxConnection(BaseException):
|
class MaxConnection(BaseException):
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
class MaxUploadFileFailed(BaseException):
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
class MaxIconParamsException(BaseException):
|
||||||
...
|
...
|
@ -1,4 +1,4 @@
|
|||||||
from typing import TYPE_CHECKING, List
|
from typing import TYPE_CHECKING, Any, Dict, List, Optional
|
||||||
|
|
||||||
from .types.added_admin_chat import AddedListAdminChat
|
from .types.added_admin_chat import AddedListAdminChat
|
||||||
from ..types.users import ChatAdmin
|
from ..types.users import ChatAdmin
|
||||||
@ -30,14 +30,14 @@ class AddAdminChat(BaseConnection):
|
|||||||
bot: 'Bot',
|
bot: 'Bot',
|
||||||
chat_id: int,
|
chat_id: int,
|
||||||
admins: List[ChatAdmin],
|
admins: List[ChatAdmin],
|
||||||
marker: int = None
|
marker: Optional[int] = None
|
||||||
):
|
):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.chat_id = chat_id
|
self.chat_id = chat_id
|
||||||
self.admins = admins
|
self.admins = admins
|
||||||
self.marker = marker
|
self.marker = marker
|
||||||
|
|
||||||
async def request(self) -> AddedListAdminChat:
|
async def fetch(self) -> AddedListAdminChat:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Выполняет HTTP POST запрос для добавления администраторов в чат.
|
Выполняет HTTP POST запрос для добавления администраторов в чат.
|
||||||
@ -48,7 +48,9 @@ class AddAdminChat(BaseConnection):
|
|||||||
AddedListAdminChat: Результат операции с информацией об успешности.
|
AddedListAdminChat: Результат операции с информацией об успешности.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
json = {}
|
assert self.bot is not None
|
||||||
|
|
||||||
|
json: Dict[str, Any] = {}
|
||||||
|
|
||||||
json['admins'] = [admin.model_dump() for admin in self.admins]
|
json['admins'] = [admin.model_dump() for admin in self.admins]
|
||||||
json['marker'] = self.marker
|
json['marker'] = self.marker
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from typing import TYPE_CHECKING, List
|
from typing import TYPE_CHECKING, Any, Dict, List
|
||||||
|
|
||||||
from ..methods.types.added_members_chat import AddedMembersChat
|
from ..methods.types.added_members_chat import AddedMembersChat
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ class AddMembersChat(BaseConnection):
|
|||||||
self.chat_id = chat_id
|
self.chat_id = chat_id
|
||||||
self.user_ids = user_ids
|
self.user_ids = user_ids
|
||||||
|
|
||||||
async def request(self) -> AddedMembersChat:
|
async def fetch(self) -> AddedMembersChat:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Отправляет POST-запрос на добавление пользователей в чат.
|
Отправляет POST-запрос на добавление пользователей в чат.
|
||||||
@ -45,7 +45,9 @@ class AddMembersChat(BaseConnection):
|
|||||||
AddedMembersChat: Результат операции с информацией об успешности добавления.
|
AddedMembersChat: Результат операции с информацией об успешности добавления.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
json = {}
|
assert self.bot is not None
|
||||||
|
|
||||||
|
json: Dict[str, Any] = {}
|
||||||
|
|
||||||
json['user_ids'] = self.user_ids
|
json['user_ids'] = self.user_ids
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from typing import Any, Dict, List, TYPE_CHECKING
|
from typing import Any, Dict, List, TYPE_CHECKING, Optional
|
||||||
|
|
||||||
from ..types.users import User
|
from ..types.users import User
|
||||||
from ..types.command import BotCommand
|
from ..types.command import BotCommand
|
||||||
@ -29,10 +29,10 @@ class ChangeInfo(BaseConnection):
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
bot: 'Bot',
|
bot: 'Bot',
|
||||||
name: str = None,
|
name: Optional[str] = None,
|
||||||
description: str = None,
|
description: Optional[str] = None,
|
||||||
commands: List[BotCommand] = None,
|
commands: Optional[List[BotCommand]] = None,
|
||||||
photo: Dict[str, Any] = None
|
photo: Optional[Dict[str, Any]] = None
|
||||||
):
|
):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.name = name
|
self.name = name
|
||||||
@ -40,7 +40,7 @@ class ChangeInfo(BaseConnection):
|
|||||||
self.commands = commands
|
self.commands = commands
|
||||||
self.photo = photo
|
self.photo = photo
|
||||||
|
|
||||||
async def request(self) -> User:
|
async def fetch(self) -> User:
|
||||||
|
|
||||||
"""Отправляет запрос на изменение информации о боте.
|
"""Отправляет запрос на изменение информации о боте.
|
||||||
|
|
||||||
@ -48,7 +48,9 @@ class ChangeInfo(BaseConnection):
|
|||||||
User: Объект с обновленными данными бота
|
User: Объект с обновленными данными бота
|
||||||
"""
|
"""
|
||||||
|
|
||||||
json = {}
|
assert self.bot is not None
|
||||||
|
|
||||||
|
json: Dict[str, Any] = {}
|
||||||
|
|
||||||
if self.name: json['name'] = self.name
|
if self.name: json['name'] = self.name
|
||||||
if self.description: json['description'] = self.description
|
if self.description: json['description'] = self.description
|
||||||
|
@ -30,7 +30,7 @@ class DeleteMeFromMessage(BaseConnection):
|
|||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.chat_id = chat_id
|
self.chat_id = chat_id
|
||||||
|
|
||||||
async def request(self) -> DeletedBotFromChat:
|
async def fetch(self) -> DeletedBotFromChat:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Отправляет DELETE-запрос для удаления бота из чата.
|
Отправляет DELETE-запрос для удаления бота из чата.
|
||||||
@ -39,6 +39,7 @@ class DeleteMeFromMessage(BaseConnection):
|
|||||||
DeletedBotFromChat: Результат операции удаления.
|
DeletedBotFromChat: Результат операции удаления.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
assert self.bot is not None
|
||||||
return await super().request(
|
return await super().request(
|
||||||
method=HTTPMethod.DELETE,
|
method=HTTPMethod.DELETE,
|
||||||
path=ApiPath.CHATS + '/' + str(self.chat_id) + ApiPath.MEMBERS + ApiPath.ME,
|
path=ApiPath.CHATS + '/' + str(self.chat_id) + ApiPath.MEMBERS + ApiPath.ME,
|
||||||
|
@ -29,7 +29,7 @@ class DeleteChat(BaseConnection):
|
|||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.chat_id = chat_id
|
self.chat_id = chat_id
|
||||||
|
|
||||||
async def request(self) -> DeletedChat:
|
async def fetch(self) -> DeletedChat:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Отправляет DELETE-запрос для удаления указанного чата.
|
Отправляет DELETE-запрос для удаления указанного чата.
|
||||||
@ -38,6 +38,7 @@ class DeleteChat(BaseConnection):
|
|||||||
DeletedChat: Результат операции удаления чата.
|
DeletedChat: Результат операции удаления чата.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
assert self.bot is not None
|
||||||
return await super().request(
|
return await super().request(
|
||||||
method=HTTPMethod.DELETE,
|
method=HTTPMethod.DELETE,
|
||||||
path=ApiPath.CHATS.value + '/' + str(self.chat_id),
|
path=ApiPath.CHATS.value + '/' + str(self.chat_id),
|
||||||
|
@ -29,7 +29,7 @@ class DeleteMessage(BaseConnection):
|
|||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.message_id = message_id
|
self.message_id = message_id
|
||||||
|
|
||||||
async def request(self) -> DeletedMessage:
|
async def fetch(self) -> DeletedMessage:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Выполняет DELETE-запрос для удаления сообщения.
|
Выполняет DELETE-запрос для удаления сообщения.
|
||||||
@ -40,6 +40,7 @@ class DeleteMessage(BaseConnection):
|
|||||||
DeletedMessage: Результат операции удаления сообщения.
|
DeletedMessage: Результат операции удаления сообщения.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
assert self.bot is not None
|
||||||
params = self.bot.params.copy()
|
params = self.bot.params.copy()
|
||||||
|
|
||||||
params['message_id'] = self.message_id
|
params['message_id'] = self.message_id
|
||||||
|
@ -19,18 +19,18 @@ class DeletePinMessage(BaseConnection):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
bot (Bot): Экземпляр бота для выполнения запроса.
|
bot (Bot): Экземпляр бота для выполнения запроса.
|
||||||
chat_id (str): Идентификатор чата, из которого нужно удалить закреплённое сообщение.
|
chat_id (int): Идентификатор чата, из которого нужно удалить закреплённое сообщение.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
bot: 'Bot',
|
bot: 'Bot',
|
||||||
chat_id: str,
|
chat_id: int,
|
||||||
):
|
):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.chat_id = chat_id
|
self.chat_id = chat_id
|
||||||
|
|
||||||
async def request(self) -> DeletedPinMessage:
|
async def fetch(self) -> DeletedPinMessage:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Выполняет DELETE-запрос для удаления закреплённого сообщения.
|
Выполняет DELETE-запрос для удаления закреплённого сообщения.
|
||||||
@ -38,7 +38,7 @@ class DeletePinMessage(BaseConnection):
|
|||||||
Returns:
|
Returns:
|
||||||
DeletedPinMessage: Результат операции удаления закреплённого сообщения.
|
DeletedPinMessage: Результат операции удаления закреплённого сообщения.
|
||||||
"""
|
"""
|
||||||
|
assert self.bot is not None
|
||||||
return await super().request(
|
return await super().request(
|
||||||
method=HTTPMethod.DELETE,
|
method=HTTPMethod.DELETE,
|
||||||
path=ApiPath.CHATS + '/' + str(self.chat_id) + ApiPath.PIN,
|
path=ApiPath.CHATS + '/' + str(self.chat_id) + ApiPath.PIN,
|
||||||
|
@ -36,7 +36,7 @@ class DownloadMedia(BaseConnection):
|
|||||||
self.media_url = media_url
|
self.media_url = media_url
|
||||||
self.media_token = media_token
|
self.media_token = media_token
|
||||||
|
|
||||||
async def request(self) -> int:
|
async def fetch(self) -> int:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Выполняет GET-запрос для скачивания медиафайла
|
Выполняет GET-запрос для скачивания медиафайла
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
|
|
||||||
|
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING, Any, Dict, Optional
|
||||||
from collections import Counter
|
from collections import Counter
|
||||||
|
|
||||||
|
from ..exceptions.max import MaxIconParamsException
|
||||||
|
|
||||||
from ..types.attachments.image import PhotoAttachmentRequestPayload
|
from ..types.attachments.image import PhotoAttachmentRequestPayload
|
||||||
from ..types.chats import Chat
|
from ..types.chats import Chat
|
||||||
|
|
||||||
@ -37,10 +39,10 @@ class EditChat(BaseConnection):
|
|||||||
self,
|
self,
|
||||||
bot: 'Bot',
|
bot: 'Bot',
|
||||||
chat_id: int,
|
chat_id: int,
|
||||||
icon: PhotoAttachmentRequestPayload = None,
|
icon: Optional[PhotoAttachmentRequestPayload] = None,
|
||||||
title: str = None,
|
title: Optional[str] = None,
|
||||||
pin: str = None,
|
pin: Optional[str] = None,
|
||||||
notify: bool = True,
|
notify: Optional[bool] = None,
|
||||||
):
|
):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.chat_id = chat_id
|
self.chat_id = chat_id
|
||||||
@ -49,7 +51,7 @@ class EditChat(BaseConnection):
|
|||||||
self.pin = pin
|
self.pin = pin
|
||||||
self.notify = notify
|
self.notify = notify
|
||||||
|
|
||||||
async def request(self) -> Chat:
|
async def fetch(self) -> Chat:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Выполняет PATCH-запрос для обновления параметров чата.
|
Выполняет PATCH-запрос для обновления параметров чата.
|
||||||
@ -62,7 +64,8 @@ class EditChat(BaseConnection):
|
|||||||
Chat: Обновлённый объект чата.
|
Chat: Обновлённый объект чата.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
json = {}
|
assert self.bot is not None
|
||||||
|
json: Dict[str, Any] = {}
|
||||||
|
|
||||||
if self.icon:
|
if self.icon:
|
||||||
dump = self.icon.model_dump()
|
dump = self.icon.model_dump()
|
||||||
@ -70,7 +73,8 @@ class EditChat(BaseConnection):
|
|||||||
|
|
||||||
if not None in counter or \
|
if not None in counter or \
|
||||||
not counter[None] == 2:
|
not counter[None] == 2:
|
||||||
return logger.error(
|
|
||||||
|
raise MaxIconParamsException(
|
||||||
'Все атрибуты модели Icon являются взаимоисключающими | '
|
'Все атрибуты модели Icon являются взаимоисключающими | '
|
||||||
'https://dev.max.ru/docs-api/methods/PATCH/chats/-chatId-'
|
'https://dev.max.ru/docs-api/methods/PATCH/chats/-chatId-'
|
||||||
)
|
)
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import List, TYPE_CHECKING, Optional
|
from typing import Any, Dict, List, TYPE_CHECKING, Optional
|
||||||
|
|
||||||
|
from ..utils.message import process_input_media
|
||||||
|
|
||||||
from .types.edited_message import EditedMessage
|
from .types.edited_message import EditedMessage
|
||||||
from ..types.message import NewMessageLink
|
from ..types.message import NewMessageLink
|
||||||
@ -37,10 +39,10 @@ class EditMessage(BaseConnection):
|
|||||||
self,
|
self,
|
||||||
bot: Bot,
|
bot: Bot,
|
||||||
message_id: str,
|
message_id: str,
|
||||||
text: str = None,
|
text: Optional[str] = None,
|
||||||
attachments: List[Attachment | InputMedia | InputMediaBuffer] = None,
|
attachments: Optional[List[Attachment | InputMedia | InputMediaBuffer]] = None,
|
||||||
link: NewMessageLink = None,
|
link: Optional[NewMessageLink] = None,
|
||||||
notify: bool = True,
|
notify: Optional[bool] = None,
|
||||||
parse_mode: Optional[ParseMode] = None
|
parse_mode: Optional[ParseMode] = None
|
||||||
):
|
):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
@ -51,7 +53,7 @@ class EditMessage(BaseConnection):
|
|||||||
self.notify = notify
|
self.notify = notify
|
||||||
self.parse_mode = parse_mode
|
self.parse_mode = parse_mode
|
||||||
|
|
||||||
async def request(self) -> EditedMessage:
|
async def fetch(self) -> EditedMessage:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Выполняет PUT-запрос для обновления сообщения.
|
Выполняет PUT-запрос для обновления сообщения.
|
||||||
@ -62,15 +64,31 @@ class EditMessage(BaseConnection):
|
|||||||
EditedMessage: Обновлённое сообщение.
|
EditedMessage: Обновлённое сообщение.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
assert self.bot is not None
|
||||||
params = self.bot.params.copy()
|
params = self.bot.params.copy()
|
||||||
|
|
||||||
json = {}
|
json: Dict[str, Any] = {}
|
||||||
|
|
||||||
params['message_id'] = self.message_id
|
params['message_id'] = self.message_id
|
||||||
|
|
||||||
if not self.text is None: json['text'] = self.text
|
if not self.text is None: json['text'] = self.text
|
||||||
if self.attachments: json['attachments'] = \
|
|
||||||
[att.model_dump() for att in self.attachments]
|
if self.attachments:
|
||||||
|
|
||||||
|
for att in self.attachments:
|
||||||
|
|
||||||
|
if isinstance(att, InputMedia) or isinstance(att, InputMediaBuffer):
|
||||||
|
input_media = await process_input_media(
|
||||||
|
base_connection=self,
|
||||||
|
bot=self.bot,
|
||||||
|
att=att
|
||||||
|
)
|
||||||
|
json['attachments'].append(
|
||||||
|
input_media.model_dump()
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
json['attachments'].append(att.model_dump())
|
||||||
|
|
||||||
if not self.link is None: json['link'] = self.link.model_dump()
|
if not self.link is None: json['link'] = self.link.model_dump()
|
||||||
if not self.notify is None: json['notify'] = self.notify
|
if not self.notify is None: json['notify'] = self.notify
|
||||||
if not self.parse_mode is None: json['format'] = self.parse_mode.value
|
if not self.parse_mode is None: json['format'] = self.parse_mode.value
|
||||||
|
@ -30,7 +30,7 @@ class GetChatById(BaseConnection):
|
|||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.id = id
|
self.id = id
|
||||||
|
|
||||||
async def request(self) -> Chat:
|
async def fetch(self) -> Chat:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Выполняет GET-запрос для получения данных чата.
|
Выполняет GET-запрос для получения данных чата.
|
||||||
@ -39,6 +39,7 @@ class GetChatById(BaseConnection):
|
|||||||
Chat: Объект чата с полной информацией.
|
Chat: Объект чата с полной информацией.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
assert self.bot is not None
|
||||||
return await super().request(
|
return await super().request(
|
||||||
method=HTTPMethod.GET,
|
method=HTTPMethod.GET,
|
||||||
path=ApiPath.CHATS.value + '/' + str(self.id),
|
path=ApiPath.CHATS.value + '/' + str(self.id),
|
||||||
|
@ -40,7 +40,7 @@ class GetChatByLink(BaseConnection):
|
|||||||
if not self.link:
|
if not self.link:
|
||||||
return
|
return
|
||||||
|
|
||||||
async def request(self) -> Chat:
|
async def fetch(self) -> Chat:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Выполняет GET-запрос для получения данных чата по ссылке.
|
Выполняет GET-запрос для получения данных чата по ссылке.
|
||||||
@ -49,6 +49,7 @@ class GetChatByLink(BaseConnection):
|
|||||||
Chat: Объект с информацией о чате.
|
Chat: Объект с информацией о чате.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
assert self.bot is not None
|
||||||
return await super().request(
|
return await super().request(
|
||||||
method=HTTPMethod.GET,
|
method=HTTPMethod.GET,
|
||||||
path=ApiPath.CHATS.value + '/' + self.link[-1],
|
path=ApiPath.CHATS.value + '/' + self.link[-1],
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING, Optional
|
||||||
|
|
||||||
from ..types.chats import Chats
|
from ..types.chats import Chats
|
||||||
|
|
||||||
@ -32,13 +32,13 @@ class GetChats(BaseConnection):
|
|||||||
self,
|
self,
|
||||||
bot: 'Bot',
|
bot: 'Bot',
|
||||||
count: int = 50,
|
count: int = 50,
|
||||||
marker: int = None
|
marker: Optional[int] = None
|
||||||
):
|
):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.count = count
|
self.count = count
|
||||||
self.marker = marker
|
self.marker = marker
|
||||||
|
|
||||||
async def request(self) -> Chats:
|
async def fetch(self) -> Chats:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Выполняет GET-запрос для получения списка чатов.
|
Выполняет GET-запрос для получения списка чатов.
|
||||||
@ -46,7 +46,7 @@ class GetChats(BaseConnection):
|
|||||||
Returns:
|
Returns:
|
||||||
Chats: Объект с данными по списку чатов.
|
Chats: Объект с данными по списку чатов.
|
||||||
"""
|
"""
|
||||||
|
assert self.bot is not None
|
||||||
params = self.bot.params.copy()
|
params = self.bot.params.copy()
|
||||||
|
|
||||||
params['count'] = self.count
|
params['count'] = self.count
|
||||||
|
@ -34,7 +34,7 @@ class GetListAdminChat(BaseConnection):
|
|||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.chat_id = chat_id
|
self.chat_id = chat_id
|
||||||
|
|
||||||
async def request(self) -> GettedListAdminChat:
|
async def fetch(self) -> GettedListAdminChat:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Выполняет GET-запрос для получения списка администраторов указанного чата.
|
Выполняет GET-запрос для получения списка администраторов указанного чата.
|
||||||
@ -42,7 +42,7 @@ class GetListAdminChat(BaseConnection):
|
|||||||
Returns:
|
Returns:
|
||||||
GettedListAdminChat: Объект с информацией о администраторах чата.
|
GettedListAdminChat: Объект с информацией о администраторах чата.
|
||||||
"""
|
"""
|
||||||
|
assert self.bot is not None
|
||||||
return await super().request(
|
return await super().request(
|
||||||
method=HTTPMethod.GET,
|
method=HTTPMethod.GET,
|
||||||
path=ApiPath.CHATS.value + '/' + str(self.chat_id) + ApiPath.MEMBERS + ApiPath.ADMINS,
|
path=ApiPath.CHATS.value + '/' + str(self.chat_id) + ApiPath.MEMBERS + ApiPath.ADMINS,
|
||||||
|
@ -24,7 +24,7 @@ class GetMe(BaseConnection):
|
|||||||
def __init__(self, bot: 'Bot'):
|
def __init__(self, bot: 'Bot'):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
async def request(self) -> User:
|
async def fetch(self) -> User:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Выполняет GET-запрос для получения данных о боте.
|
Выполняет GET-запрос для получения данных о боте.
|
||||||
@ -32,7 +32,7 @@ class GetMe(BaseConnection):
|
|||||||
Returns:
|
Returns:
|
||||||
User: Объект пользователя с полной информацией.
|
User: Объект пользователя с полной информацией.
|
||||||
"""
|
"""
|
||||||
|
assert self.bot is not None
|
||||||
return await super().request(
|
return await super().request(
|
||||||
method=HTTPMethod.GET,
|
method=HTTPMethod.GET,
|
||||||
path=ApiPath.ME,
|
path=ApiPath.ME,
|
||||||
|
@ -34,7 +34,7 @@ class GetMeFromChat(BaseConnection):
|
|||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.chat_id = chat_id
|
self.chat_id = chat_id
|
||||||
|
|
||||||
async def request(self) -> ChatMember:
|
async def fetch(self) -> ChatMember:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Выполняет GET-запрос для получения информации о боте в указанном чате.
|
Выполняет GET-запрос для получения информации о боте в указанном чате.
|
||||||
@ -42,7 +42,7 @@ class GetMeFromChat(BaseConnection):
|
|||||||
Returns:
|
Returns:
|
||||||
ChatMember: Информация о боте как участнике чата.
|
ChatMember: Информация о боте как участнике чата.
|
||||||
"""
|
"""
|
||||||
|
assert self.bot is not None
|
||||||
return await super().request(
|
return await super().request(
|
||||||
method=HTTPMethod.GET,
|
method=HTTPMethod.GET,
|
||||||
path=ApiPath.CHATS + '/' + str(self.chat_id) + ApiPath.MEMBERS + ApiPath.ME,
|
path=ApiPath.CHATS + '/' + str(self.chat_id) + ApiPath.MEMBERS + ApiPath.ME,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from typing import TYPE_CHECKING, List
|
from typing import TYPE_CHECKING, List, Optional
|
||||||
|
|
||||||
from ..methods.types.getted_members_chat import GettedMembersChat
|
from ..methods.types.getted_members_chat import GettedMembersChat
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ class GetMembersChat(BaseConnection):
|
|||||||
Attributes:
|
Attributes:
|
||||||
bot (Bot): Экземпляр бота.
|
bot (Bot): Экземпляр бота.
|
||||||
chat_id (int): Идентификатор чата.
|
chat_id (int): Идентификатор чата.
|
||||||
user_ids (List[str] | None): Список ID пользователей для фильтра.
|
user_ids (List[int] | None): Список ID пользователей для фильтра.
|
||||||
marker (int | None): Позиция для пагинации.
|
marker (int | None): Позиция для пагинации.
|
||||||
count (int | None): Максимальное количество участников.
|
count (int | None): Максимальное количество участников.
|
||||||
"""
|
"""
|
||||||
@ -36,9 +36,9 @@ class GetMembersChat(BaseConnection):
|
|||||||
self,
|
self,
|
||||||
bot: 'Bot',
|
bot: 'Bot',
|
||||||
chat_id: int,
|
chat_id: int,
|
||||||
user_ids: List[str] = None,
|
user_ids: Optional[List[int]] = None,
|
||||||
marker: int = None,
|
marker: Optional[int] = None,
|
||||||
count: int = None,
|
count: Optional[int] = None,
|
||||||
|
|
||||||
):
|
):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
@ -47,7 +47,7 @@ class GetMembersChat(BaseConnection):
|
|||||||
self.marker = marker
|
self.marker = marker
|
||||||
self.count = count
|
self.count = count
|
||||||
|
|
||||||
async def request(self) -> GettedMembersChat:
|
async def fetch(self) -> GettedMembersChat:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Выполняет GET-запрос для получения участников чата с опциональной фильтрацией.
|
Выполняет GET-запрос для получения участников чата с опциональной фильтрацией.
|
||||||
@ -57,12 +57,12 @@ class GetMembersChat(BaseConnection):
|
|||||||
Returns:
|
Returns:
|
||||||
GettedMembersChat: Объект с данными по участникам чата.
|
GettedMembersChat: Объект с данными по участникам чата.
|
||||||
"""
|
"""
|
||||||
|
assert self.bot is not None
|
||||||
params = self.bot.params.copy()
|
params = self.bot.params.copy()
|
||||||
|
|
||||||
if self.user_ids:
|
if self.user_ids:
|
||||||
self.user_ids = [str(user_id) for user_id in self.user_ids]
|
params['user_ids'] = ','.join([str(user_id) for user_id in self.user_ids])
|
||||||
params['user_ids'] = ','.join(self.user_ids)
|
|
||||||
if self.marker: params['marker'] = self.marker
|
if self.marker: params['marker'] = self.marker
|
||||||
if self.count: params['marker'] = self.count
|
if self.count: params['marker'] = self.count
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import TYPE_CHECKING, List
|
from typing import TYPE_CHECKING, List, Optional, Union
|
||||||
|
|
||||||
from ..types.message import Messages
|
from ..types.message import Messages
|
||||||
from ..enums.http_method import HTTPMethod
|
from ..enums.http_method import HTTPMethod
|
||||||
@ -36,10 +36,10 @@ class GetMessages(BaseConnection):
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
bot: 'Bot',
|
bot: 'Bot',
|
||||||
chat_id: int,
|
chat_id: Optional[int] = None,
|
||||||
message_ids: List[str] = None,
|
message_ids: Optional[List[str]] = None,
|
||||||
from_time: datetime | int = None,
|
from_time: Optional[Union[datetime, int]] = None,
|
||||||
to_time: datetime | int = None,
|
to_time: Optional[Union[datetime, int]] = None,
|
||||||
count: int = 50,
|
count: int = 50,
|
||||||
):
|
):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
@ -49,7 +49,7 @@ class GetMessages(BaseConnection):
|
|||||||
self.to_time = to_time
|
self.to_time = to_time
|
||||||
self.count = count
|
self.count = count
|
||||||
|
|
||||||
async def request(self) -> Messages:
|
async def fetch(self) -> Messages:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Выполняет GET-запрос для получения сообщений с учётом параметров фильтрации.
|
Выполняет GET-запрос для получения сообщений с учётом параметров фильтрации.
|
||||||
@ -59,7 +59,7 @@ class GetMessages(BaseConnection):
|
|||||||
Returns:
|
Returns:
|
||||||
Messages: Объект с полученными сообщениями.
|
Messages: Объект с полученными сообщениями.
|
||||||
"""
|
"""
|
||||||
|
assert self.bot is not None
|
||||||
params = self.bot.params.copy()
|
params = self.bot.params.copy()
|
||||||
|
|
||||||
if self.chat_id: params['chat_id'] = self.chat_id
|
if self.chat_id: params['chat_id'] = self.chat_id
|
||||||
|
@ -29,7 +29,7 @@ class GetPinnedMessage(BaseConnection):
|
|||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.chat_id = chat_id
|
self.chat_id = chat_id
|
||||||
|
|
||||||
async def request(self) -> GettedPin:
|
async def fetch(self) -> GettedPin:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Выполняет GET-запрос для получения закреплённого сообщения.
|
Выполняет GET-запрос для получения закреплённого сообщения.
|
||||||
@ -37,7 +37,7 @@ class GetPinnedMessage(BaseConnection):
|
|||||||
Returns:
|
Returns:
|
||||||
GettedPin: Объект с информацией о закреплённом сообщении.
|
GettedPin: Объект с информацией о закреплённом сообщении.
|
||||||
"""
|
"""
|
||||||
|
assert self.bot is not None
|
||||||
return await super().request(
|
return await super().request(
|
||||||
method=HTTPMethod.GET,
|
method=HTTPMethod.GET,
|
||||||
path=ApiPath.CHATS + '/' + str(self.chat_id) + ApiPath.PIN,
|
path=ApiPath.CHATS + '/' + str(self.chat_id) + ApiPath.PIN,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from typing import TYPE_CHECKING
|
from __future__ import annotations
|
||||||
|
from typing import TYPE_CHECKING, Dict
|
||||||
|
|
||||||
from ..types.updates import UpdateUnion
|
from ..types.updates import UpdateUnion
|
||||||
|
|
||||||
@ -28,13 +29,13 @@ class GetUpdates(BaseConnection):
|
|||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
bot: 'Bot',
|
bot: Bot,
|
||||||
limit: int = 100,
|
limit: int = 100,
|
||||||
):
|
):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.limit = limit
|
self.limit = limit
|
||||||
|
|
||||||
async def request(self) -> UpdateUnion:
|
async def fetch(self) -> Dict:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Выполняет GET-запрос для получения обновлений с указанным лимитом.
|
Выполняет GET-запрос для получения обновлений с указанным лимитом.
|
||||||
@ -44,7 +45,7 @@ class GetUpdates(BaseConnection):
|
|||||||
Returns:
|
Returns:
|
||||||
UpdateUnion: Объединённый тип данных обновлений.
|
UpdateUnion: Объединённый тип данных обновлений.
|
||||||
"""
|
"""
|
||||||
|
assert self.bot is not None
|
||||||
params = self.bot.params.copy()
|
params = self.bot.params.copy()
|
||||||
|
|
||||||
params['limit'] = self.limit
|
params['limit'] = self.limit
|
||||||
|
@ -33,7 +33,7 @@ class GetUploadURL(BaseConnection):
|
|||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.type = type
|
self.type = type
|
||||||
|
|
||||||
async def request(self) -> GettedUploadUrl:
|
async def fetch(self) -> GettedUploadUrl:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Выполняет POST-запрос для получения URL загрузки файла.
|
Выполняет POST-запрос для получения URL загрузки файла.
|
||||||
@ -43,7 +43,7 @@ class GetUploadURL(BaseConnection):
|
|||||||
Returns:
|
Returns:
|
||||||
GettedUploadUrl: Результат с URL для загрузки.
|
GettedUploadUrl: Результат с URL для загрузки.
|
||||||
"""
|
"""
|
||||||
|
assert self.bot is not None
|
||||||
params = self.bot.params.copy()
|
params = self.bot.params.copy()
|
||||||
|
|
||||||
params['type'] = self.type.value
|
params['type'] = self.type.value
|
||||||
|
@ -30,7 +30,7 @@ class GetVideo(BaseConnection):
|
|||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.video_token = video_token
|
self.video_token = video_token
|
||||||
|
|
||||||
async def request(self) -> Video:
|
async def fetch(self) -> Video:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Выполняет GET-запрос для получения данных видео по токену.
|
Выполняет GET-запрос для получения данных видео по токену.
|
||||||
@ -38,7 +38,7 @@ class GetVideo(BaseConnection):
|
|||||||
Returns:
|
Returns:
|
||||||
Video: Объект с информацией о видео.
|
Video: Объект с информацией о видео.
|
||||||
"""
|
"""
|
||||||
|
assert self.bot is not None
|
||||||
return await super().request(
|
return await super().request(
|
||||||
method=HTTPMethod.GET,
|
method=HTTPMethod.GET,
|
||||||
path=ApiPath.VIDEOS.value + '/' + self.video_token,
|
path=ApiPath.VIDEOS.value + '/' + self.video_token,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING, Any, Dict, Optional
|
||||||
|
|
||||||
from .types.pinned_message import PinnedMessage
|
from .types.pinned_message import PinnedMessage
|
||||||
|
|
||||||
@ -35,14 +35,14 @@ class PinMessage(BaseConnection):
|
|||||||
bot: 'Bot',
|
bot: 'Bot',
|
||||||
chat_id: int,
|
chat_id: int,
|
||||||
message_id: str,
|
message_id: str,
|
||||||
notify: bool = True
|
notify: Optional[bool] = None
|
||||||
):
|
):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.chat_id = chat_id
|
self.chat_id = chat_id
|
||||||
self.message_id = message_id
|
self.message_id = message_id
|
||||||
self.notify = notify
|
self.notify = notify
|
||||||
|
|
||||||
async def request(self) -> PinnedMessage:
|
async def fetch(self) -> PinnedMessage:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Выполняет PUT-запрос для закрепления сообщения в чате.
|
Выполняет PUT-запрос для закрепления сообщения в чате.
|
||||||
@ -52,8 +52,8 @@ class PinMessage(BaseConnection):
|
|||||||
Returns:
|
Returns:
|
||||||
PinnedMessage: Объект с информацией о закреплённом сообщении.
|
PinnedMessage: Объект с информацией о закреплённом сообщении.
|
||||||
"""
|
"""
|
||||||
|
assert self.bot is not None
|
||||||
json = {}
|
json: Dict[str, Any] = {}
|
||||||
|
|
||||||
json['message_id'] = self.message_id
|
json['message_id'] = self.message_id
|
||||||
json['notify'] = self.notify
|
json['notify'] = self.notify
|
||||||
|
@ -38,7 +38,7 @@ class RemoveAdmin(BaseConnection):
|
|||||||
self.chat_id = chat_id
|
self.chat_id = chat_id
|
||||||
self.user_id = user_id
|
self.user_id = user_id
|
||||||
|
|
||||||
async def request(self) -> RemovedAdmin:
|
async def fetch(self) -> RemovedAdmin:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Выполняет DELETE-запрос для отмены прав администратора в чате.
|
Выполняет DELETE-запрос для отмены прав администратора в чате.
|
||||||
@ -46,11 +46,11 @@ class RemoveAdmin(BaseConnection):
|
|||||||
Returns:
|
Returns:
|
||||||
RemovedAdmin: Объект с результатом отмены прав администратора.
|
RemovedAdmin: Объект с результатом отмены прав администратора.
|
||||||
"""
|
"""
|
||||||
|
assert self.bot is not None
|
||||||
return await super().request(
|
return await super().request(
|
||||||
method=HTTPMethod.DELETE,
|
method=HTTPMethod.DELETE,
|
||||||
path=ApiPath.CHATS + '/' + str(self.chat_id) + \
|
path=ApiPath.CHATS + '/' + str(self.chat_id) + \
|
||||||
ApiPath.MEMBERS + ApiPath.ADMINS + '/' + str(self.user_id),
|
ApiPath.MEMBERS + ApiPath.ADMINS + '/' + str(self.user_id),
|
||||||
model=RemovedAdmin,
|
model=RemovedAdmin,
|
||||||
params=self.bot.params,
|
params=self.bot.params,
|
||||||
)
|
)
|
@ -43,7 +43,7 @@ class RemoveMemberChat(BaseConnection):
|
|||||||
self.user_id = user_id
|
self.user_id = user_id
|
||||||
self.block = block
|
self.block = block
|
||||||
|
|
||||||
async def request(self) -> RemovedMemberChat:
|
async def fetch(self) -> RemovedMemberChat:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Выполняет DELETE-запрос для удаления пользователя из чата.
|
Выполняет DELETE-запрос для удаления пользователя из чата.
|
||||||
@ -54,6 +54,7 @@ class RemoveMemberChat(BaseConnection):
|
|||||||
RemovedMemberChat: Результат удаления участника.
|
RemovedMemberChat: Результат удаления участника.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
assert self.bot is not None
|
||||||
params = self.bot.params.copy()
|
params = self.bot.params.copy()
|
||||||
|
|
||||||
params['chat_id'] = self.chat_id
|
params['chat_id'] = self.chat_id
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING, Any, Dict, Optional
|
||||||
|
|
||||||
from ..methods.types.sended_action import SendedAction
|
from ..methods.types.sended_action import SendedAction
|
||||||
|
|
||||||
@ -34,14 +34,14 @@ class SendAction(BaseConnection):
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
bot: 'Bot',
|
bot: 'Bot',
|
||||||
chat_id: int = None,
|
chat_id: Optional[int] = None,
|
||||||
action: SenderAction = SenderAction.TYPING_ON
|
action: SenderAction = SenderAction.TYPING_ON
|
||||||
):
|
):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.chat_id = chat_id
|
self.chat_id = chat_id
|
||||||
self.action = action
|
self.action = action
|
||||||
|
|
||||||
async def request(self) -> SendedAction:
|
async def fetch(self) -> SendedAction:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Выполняет POST-запрос для отправки действия в указанный чат.
|
Выполняет POST-запрос для отправки действия в указанный чат.
|
||||||
@ -49,8 +49,9 @@ class SendAction(BaseConnection):
|
|||||||
Returns:
|
Returns:
|
||||||
SendedAction: Результат выполнения запроса.
|
SendedAction: Результат выполнения запроса.
|
||||||
"""
|
"""
|
||||||
|
assert self.bot is not None
|
||||||
|
|
||||||
json = {}
|
json: Dict[str, Any] = {}
|
||||||
|
|
||||||
json['action'] = self.action.value
|
json['action'] = self.action.value
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING, Any, Dict, Optional
|
||||||
|
|
||||||
from ..methods.types.sended_callback import SendedCallback
|
from ..methods.types.sended_callback import SendedCallback
|
||||||
|
|
||||||
@ -36,15 +36,15 @@ class SendCallback(BaseConnection):
|
|||||||
self,
|
self,
|
||||||
bot: 'Bot',
|
bot: 'Bot',
|
||||||
callback_id: str,
|
callback_id: str,
|
||||||
message: Message = None,
|
message: Optional[Message] = None,
|
||||||
notification: str = None
|
notification: Optional[str] = None
|
||||||
):
|
):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.callback_id = callback_id
|
self.callback_id = callback_id
|
||||||
self.message = message
|
self.message = message
|
||||||
self.notification = notification
|
self.notification = notification
|
||||||
|
|
||||||
async def request(self) -> SendedCallback:
|
async def fetch(self) -> SendedCallback:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Выполняет POST-запрос для отправки callback-ответа.
|
Выполняет POST-запрос для отправки callback-ответа.
|
||||||
@ -55,11 +55,12 @@ class SendCallback(BaseConnection):
|
|||||||
SendedCallback: Объект с результатом отправки callback.
|
SendedCallback: Объект с результатом отправки callback.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
assert self.bot is not None
|
||||||
params = self.bot.params.copy()
|
params = self.bot.params.copy()
|
||||||
|
|
||||||
params['callback_id'] = self.callback_id
|
params['callback_id'] = self.callback_id
|
||||||
|
|
||||||
json = {}
|
json: Dict[str, Any] = {}
|
||||||
|
|
||||||
if self.message: json['message'] = self.message.model_dump()
|
if self.message: json['message'] = self.message.model_dump()
|
||||||
if self.notification: json['notification'] = self.notification
|
if self.notification: json['notification'] = self.notification
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
|
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
from typing import List, TYPE_CHECKING, Optional
|
from typing import Any, Dict, List, TYPE_CHECKING, Optional
|
||||||
|
|
||||||
from json import loads as json_loads
|
from json import loads as json_loads
|
||||||
|
|
||||||
|
from ..utils.message import process_input_media
|
||||||
|
|
||||||
|
from ..exceptions.max import MaxUploadFileFailed
|
||||||
|
|
||||||
from .types.sended_message import SendedMessage
|
from .types.sended_message import SendedMessage
|
||||||
from ..types.attachments.upload import AttachmentPayload, AttachmentUpload
|
from ..types.attachments.upload import AttachmentPayload, AttachmentUpload
|
||||||
from ..types.errors import Error
|
from ..types.errors import Error
|
||||||
@ -39,7 +43,7 @@ class SendMessage(BaseConnection):
|
|||||||
chat_id (int, optional): Идентификатор чата, куда отправлять сообщение.
|
chat_id (int, optional): Идентификатор чата, куда отправлять сообщение.
|
||||||
user_id (int, optional): Идентификатор пользователя, если нужно отправить личное сообщение.
|
user_id (int, optional): Идентификатор пользователя, если нужно отправить личное сообщение.
|
||||||
text (str, optional): Текст сообщения.
|
text (str, optional): Текст сообщения.
|
||||||
attachments (List[Attachment | InputMedia], optional): Список вложений к сообщению.
|
attachments (List[Attachment | InputMedia | InputMediaBuffer], optional): Список вложений к сообщению.
|
||||||
link (NewMessageLink, optional): Связь с другим сообщением (например, ответ или пересылка).
|
link (NewMessageLink, optional): Связь с другим сообщением (например, ответ или пересылка).
|
||||||
notify (bool, optional): Отправлять ли уведомление о сообщении. По умолчанию True.
|
notify (bool, optional): Отправлять ли уведомление о сообщении. По умолчанию True.
|
||||||
parse_mode (ParseMode, optional): Режим разбора текста (например, Markdown, HTML).
|
parse_mode (ParseMode, optional): Режим разбора текста (например, Markdown, HTML).
|
||||||
@ -48,12 +52,12 @@ class SendMessage(BaseConnection):
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
bot: 'Bot',
|
bot: 'Bot',
|
||||||
chat_id: int = None,
|
chat_id: Optional[int] = None,
|
||||||
user_id: int = None,
|
user_id: Optional[int] = None,
|
||||||
text: str = None,
|
text: Optional[str] = None,
|
||||||
attachments: List[Attachment | InputMedia] = None,
|
attachments: Optional[List[Attachment | InputMedia | InputMediaBuffer]] = None,
|
||||||
link: NewMessageLink = None,
|
link: Optional[NewMessageLink] = None,
|
||||||
notify: bool = True,
|
notify: Optional[bool] = None,
|
||||||
parse_mode: Optional[ParseMode] = None
|
parse_mode: Optional[ParseMode] = None
|
||||||
):
|
):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
@ -65,59 +69,7 @@ class SendMessage(BaseConnection):
|
|||||||
self.notify = notify
|
self.notify = notify
|
||||||
self.parse_mode = parse_mode
|
self.parse_mode = parse_mode
|
||||||
|
|
||||||
async def __process_input_media(
|
async def fetch(self) -> Optional[SendedMessage | Error]:
|
||||||
self,
|
|
||||||
att: InputMedia | InputMediaBuffer
|
|
||||||
):
|
|
||||||
|
|
||||||
# очень нестабильный метод независящий от модуля
|
|
||||||
# ждем обновлений MAX API
|
|
||||||
|
|
||||||
"""
|
|
||||||
Загружает файл вложения и формирует объект AttachmentUpload.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
att (InputMedia): Объект вложения для загрузки.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
AttachmentUpload: Загруженное вложение с токеном.
|
|
||||||
"""
|
|
||||||
|
|
||||||
upload = await self.bot.get_upload_url(att.type)
|
|
||||||
|
|
||||||
if isinstance(att, InputMedia):
|
|
||||||
upload_file_response = await self.upload_file(
|
|
||||||
url=upload.url,
|
|
||||||
path=att.path,
|
|
||||||
type=att.type,
|
|
||||||
)
|
|
||||||
elif isinstance(att, InputMediaBuffer):
|
|
||||||
upload_file_response = await self.upload_file_buffer(
|
|
||||||
url=upload.url,
|
|
||||||
buffer=att.buffer,
|
|
||||||
type=att.type,
|
|
||||||
)
|
|
||||||
|
|
||||||
if att.type in (UploadType.VIDEO, UploadType.AUDIO):
|
|
||||||
token = upload.token
|
|
||||||
|
|
||||||
elif att.type == UploadType.FILE:
|
|
||||||
json_r = json_loads(upload_file_response)
|
|
||||||
token = json_r['token']
|
|
||||||
|
|
||||||
elif att.type == UploadType.IMAGE:
|
|
||||||
json_r = json_loads(upload_file_response)
|
|
||||||
json_r_keys = list(json_r['photos'].keys())
|
|
||||||
token = json_r['photos'][json_r_keys[0]]['token']
|
|
||||||
|
|
||||||
return AttachmentUpload(
|
|
||||||
type=att.type,
|
|
||||||
payload=AttachmentPayload(
|
|
||||||
token=token
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
async def request(self) -> SendedMessage:
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Отправляет сообщение с вложениями (если есть), с обработкой задержки готовности вложений.
|
Отправляет сообщение с вложениями (если есть), с обработкой задержки готовности вложений.
|
||||||
@ -128,9 +80,10 @@ class SendMessage(BaseConnection):
|
|||||||
SendedMessage или Error
|
SendedMessage или Error
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
assert self.bot is not None
|
||||||
params = self.bot.params.copy()
|
params = self.bot.params.copy()
|
||||||
|
|
||||||
json = {'attachments': []}
|
json: Dict[str, Any] = {'attachments': []}
|
||||||
|
|
||||||
if self.chat_id: params['chat_id'] = self.chat_id
|
if self.chat_id: params['chat_id'] = self.chat_id
|
||||||
elif self.user_id: params['user_id'] = self.user_id
|
elif self.user_id: params['user_id'] = self.user_id
|
||||||
@ -142,7 +95,11 @@ class SendMessage(BaseConnection):
|
|||||||
for att in self.attachments:
|
for att in self.attachments:
|
||||||
|
|
||||||
if isinstance(att, InputMedia) or isinstance(att, InputMediaBuffer):
|
if isinstance(att, InputMedia) or isinstance(att, InputMediaBuffer):
|
||||||
input_media = await self.__process_input_media(att)
|
input_media = await process_input_media(
|
||||||
|
base_connection=self,
|
||||||
|
bot=self.bot,
|
||||||
|
att=att
|
||||||
|
)
|
||||||
json['attachments'].append(
|
json['attachments'].append(
|
||||||
input_media.model_dump()
|
input_media.model_dump()
|
||||||
)
|
)
|
||||||
|
@ -3,5 +3,5 @@ from pydantic import BaseModel
|
|||||||
|
|
||||||
|
|
||||||
class GettedUploadUrl(BaseModel):
|
class GettedUploadUrl(BaseModel):
|
||||||
url: Optional[str] = None
|
url: str
|
||||||
token: Optional[str] = None
|
token: Optional[str] = None
|
@ -32,35 +32,35 @@ from .input_media import InputMedia
|
|||||||
from .input_media import InputMediaBuffer
|
from .input_media import InputMediaBuffer
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
CommandStart,
|
'CommandStart',
|
||||||
OpenAppButton,
|
'OpenAppButton',
|
||||||
Message,
|
'Message',
|
||||||
Attachment,
|
'Attachment',
|
||||||
InputMediaBuffer,
|
'InputMediaBuffer',
|
||||||
MessageButton,
|
'MessageButton',
|
||||||
UpdateUnion,
|
'UpdateUnion',
|
||||||
InputMedia,
|
'InputMedia',
|
||||||
BotCommand,
|
'BotCommand',
|
||||||
CallbackButton,
|
'CallbackButton',
|
||||||
ChatButton,
|
'ChatButton',
|
||||||
LinkButton,
|
'LinkButton',
|
||||||
RequestContactButton,
|
'RequestContactButton',
|
||||||
RequestGeoLocationButton,
|
'RequestGeoLocationButton',
|
||||||
Command,
|
'Command',
|
||||||
PhotoAttachmentPayload,
|
'PhotoAttachmentPayload',
|
||||||
OtherAttachmentPayload,
|
'OtherAttachmentPayload',
|
||||||
ContactAttachmentPayload,
|
'ContactAttachmentPayload',
|
||||||
ButtonsPayload,
|
'ButtonsPayload',
|
||||||
StickerAttachmentPayload,
|
'StickerAttachmentPayload',
|
||||||
BotAdded,
|
'BotAdded',
|
||||||
BotRemoved,
|
'BotRemoved',
|
||||||
BotStarted,
|
'BotStarted',
|
||||||
ChatTitleChanged,
|
'ChatTitleChanged',
|
||||||
MessageCallback,
|
'MessageCallback',
|
||||||
MessageChatCreated,
|
'MessageChatCreated',
|
||||||
MessageCreated,
|
'MessageCreated',
|
||||||
MessageEdited,
|
'MessageEdited',
|
||||||
MessageRemoved,
|
'MessageRemoved',
|
||||||
UserAdded,
|
'UserAdded',
|
||||||
UserRemoved
|
'UserRemoved',
|
||||||
]
|
]
|
||||||
|
@ -112,33 +112,33 @@ class Attachment(BaseModel):
|
|||||||
bot: Optional[Any] = Field(default=None, exclude=True)
|
bot: Optional[Any] = Field(default=None, exclude=True)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
bot: Optional[Bot]
|
bot: Optional[Bot] # type: ignore
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
use_enum_values = True
|
use_enum_values = True
|
||||||
|
|
||||||
async def download(
|
# async def download(
|
||||||
self,
|
# self,
|
||||||
path: str
|
# path: str
|
||||||
):
|
# ):
|
||||||
|
|
||||||
"""
|
# """
|
||||||
Скачивает медиа, сохраняя по определенному пути
|
# Скачивает медиа, сохраняя по определенному пути
|
||||||
|
|
||||||
:param path: Путь сохранения медиа
|
# :param path: Путь сохранения медиа
|
||||||
|
|
||||||
:return: Числовой статус
|
# :return: Числовой статус
|
||||||
"""
|
# """
|
||||||
|
|
||||||
if not hasattr(self.payload, 'token') or \
|
# if not hasattr(self.payload, 'token') or \
|
||||||
not hasattr(self.payload, 'url'):
|
# not hasattr(self.payload, 'url'):
|
||||||
raise NotAvailableForDownload()
|
# raise NotAvailableForDownload()
|
||||||
|
|
||||||
elif not self.payload.token or not self.payload.url:
|
# elif not self.payload.token or not self.payload.url:
|
||||||
raise NotAvailableForDownload(f'Медиа типа `{self.type}` недоступно для скачивания')
|
# raise NotAvailableForDownload(f'Медиа типа `{self.type}` недоступно для скачивания')
|
||||||
|
|
||||||
return await self.bot.download_file(
|
# return await self.bot.download_file(
|
||||||
path=path,
|
# path=path,
|
||||||
url=self.payload.url,
|
# url=self.payload.url,
|
||||||
token=self.payload.token,
|
# token=self.payload.token,
|
||||||
)
|
# )
|
@ -1,4 +1,6 @@
|
|||||||
from typing import Literal, Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
from ...enums.attachment import AttachmentType
|
||||||
|
|
||||||
from .attachment import Attachment
|
from .attachment import Attachment
|
||||||
|
|
||||||
@ -13,5 +15,5 @@ class Audio(Attachment):
|
|||||||
transcription (Optional[str]): Транскрипция аудио (если есть).
|
transcription (Optional[str]): Транскрипция аудио (если есть).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
type: Literal['audio'] = 'audio'
|
type: AttachmentType = AttachmentType.AUDIO
|
||||||
transcription: Optional[str] = None
|
transcription: Optional[str] = None
|
@ -1,4 +1,4 @@
|
|||||||
from typing import Literal
|
from ...enums.attachment import AttachmentType
|
||||||
|
|
||||||
from .attachment import Attachment
|
from .attachment import Attachment
|
||||||
|
|
||||||
@ -12,4 +12,4 @@ class Contact(Attachment):
|
|||||||
type (Literal['contact']): Тип вложения, всегда 'contact'.
|
type (Literal['contact']): Тип вложения, всегда 'contact'.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
type: Literal['contact'] = 'contact'
|
type: AttachmentType = AttachmentType.CONTACT
|
@ -1,4 +1,6 @@
|
|||||||
from typing import Literal, Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
from ...enums.attachment import AttachmentType
|
||||||
|
|
||||||
from .attachment import Attachment
|
from .attachment import Attachment
|
||||||
|
|
||||||
@ -14,6 +16,6 @@ class File(Attachment):
|
|||||||
size (Optional[int]): Размер файла в байтах.
|
size (Optional[int]): Размер файла в байтах.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
type: Literal['file'] = 'file'
|
type: AttachmentType = AttachmentType.FILE
|
||||||
filename: Optional[str] = None
|
filename: Optional[str] = None
|
||||||
size: Optional[int] = None
|
size: Optional[int] = None
|
@ -1,7 +1,9 @@
|
|||||||
from typing import Literal, Optional
|
from typing import Optional
|
||||||
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
from .attachment import Attachment
|
from .attachment import Attachment
|
||||||
|
from ...enums.attachment import AttachmentType
|
||||||
|
|
||||||
|
|
||||||
class PhotoAttachmentRequestPayload(BaseModel):
|
class PhotoAttachmentRequestPayload(BaseModel):
|
||||||
@ -29,4 +31,4 @@ class Image(Attachment):
|
|||||||
type (Literal['image']): Тип вложения, всегда 'image'.
|
type (Literal['image']): Тип вложения, всегда 'image'.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
type: Literal['image'] = 'image'
|
type: AttachmentType = AttachmentType.IMAGE
|
@ -1,4 +1,6 @@
|
|||||||
from typing import Literal, Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
from ...enums.attachment import AttachmentType
|
||||||
|
|
||||||
from .attachment import Attachment
|
from .attachment import Attachment
|
||||||
|
|
||||||
@ -14,6 +16,6 @@ class Location(Attachment):
|
|||||||
longitude (Optional[float]): Долгота.
|
longitude (Optional[float]): Долгота.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
type: Literal['location'] = 'location'
|
type: AttachmentType = AttachmentType.LOCATION
|
||||||
latitude: Optional[float] = None
|
latitude: Optional[float] = None
|
||||||
longitude: Optional[float] = None
|
longitude: Optional[float] = None
|
@ -1,4 +1,6 @@
|
|||||||
from typing import Literal, Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
from ...enums.attachment import AttachmentType
|
||||||
|
|
||||||
from .attachment import Attachment
|
from .attachment import Attachment
|
||||||
|
|
||||||
@ -15,7 +17,7 @@ class Share(Attachment):
|
|||||||
image_url (Optional[str]): URL изображения для предпросмотра.
|
image_url (Optional[str]): URL изображения для предпросмотра.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
type: Literal['share'] = 'share'
|
type: AttachmentType = AttachmentType.SHARE
|
||||||
title: Optional[str] = None
|
title: Optional[str] = None
|
||||||
description: Optional[str] = None
|
description: Optional[str] = None
|
||||||
image_url: Optional[str] = None
|
image_url: Optional[str] = None
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
from typing import Literal, Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
from ...enums.attachment import AttachmentType
|
||||||
|
|
||||||
from .attachment import Attachment
|
from .attachment import Attachment
|
||||||
|
|
||||||
@ -14,6 +16,6 @@ class Sticker(Attachment):
|
|||||||
height (Optional[int]): Высота стикера в пикселях.
|
height (Optional[int]): Высота стикера в пикселях.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
type: Literal['sticker'] = 'sticker'
|
type: AttachmentType = AttachmentType.STICKER
|
||||||
width: Optional[int] = None
|
width: Optional[int] = None
|
||||||
height: Optional[int] = None
|
height: Optional[int] = None
|
@ -1,6 +1,8 @@
|
|||||||
from typing import TYPE_CHECKING, Any, Literal, Optional
|
from typing import TYPE_CHECKING, Any, Literal, Optional
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
|
from ...enums.attachment import AttachmentType
|
||||||
|
|
||||||
from .attachment import Attachment
|
from .attachment import Attachment
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@ -59,7 +61,7 @@ class Video(Attachment):
|
|||||||
bot (Optional[Any]): Ссылка на экземпляр бота, не сериализуется.
|
bot (Optional[Any]): Ссылка на экземпляр бота, не сериализуется.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
type: Optional[Literal['video']] = 'video'
|
type: AttachmentType = AttachmentType.VIDEO
|
||||||
token: Optional[str] = None
|
token: Optional[str] = None
|
||||||
urls: Optional[VideoUrl] = None
|
urls: Optional[VideoUrl] = None
|
||||||
thumbnail: VideoThumbnail
|
thumbnail: VideoThumbnail
|
||||||
@ -69,4 +71,4 @@ class Video(Attachment):
|
|||||||
bot: Optional[Any] = Field(default=None, exclude=True)
|
bot: Optional[Any] = Field(default=None, exclude=True)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
bot: Optional['Bot']
|
bot: Optional['Bot'] # type: ignore
|
||||||
|
@ -70,11 +70,11 @@ class InputMediaBuffer:
|
|||||||
Класс для представления медиафайла из буфера.
|
Класс для представления медиафайла из буфера.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
buffer (BytesIO): Буфер с содержимым файла.
|
buffer (bytes): Буфер с содержимым файла.
|
||||||
type (UploadType): Тип файла, определенный по содержимому.
|
type (UploadType): Тип файла, определенный по содержимому.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, buffer: BytesIO):
|
def __init__(self, buffer: bytes):
|
||||||
"""
|
"""
|
||||||
Инициализирует объект медиафайла из буфера.
|
Инициализирует объект медиафайла из буфера.
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ class InputMediaBuffer:
|
|||||||
self.buffer = buffer
|
self.buffer = buffer
|
||||||
self.type = self.__detect_file_type(buffer)
|
self.type = self.__detect_file_type(buffer)
|
||||||
|
|
||||||
def __detect_file_type(self, buffer: BytesIO) -> UploadType:
|
def __detect_file_type(self, buffer: bytes) -> UploadType:
|
||||||
try:
|
try:
|
||||||
matches = puremagic.magic_string(buffer)
|
matches = puremagic.magic_string(buffer)
|
||||||
if matches:
|
if matches:
|
||||||
|
@ -89,7 +89,7 @@ class MessageBody(BaseModel):
|
|||||||
|
|
||||||
mid: str
|
mid: str
|
||||||
seq: int
|
seq: int
|
||||||
text: str = None
|
text: Optional[str] = None
|
||||||
attachments: Optional[
|
attachments: Optional[
|
||||||
List[
|
List[
|
||||||
Union[
|
Union[
|
||||||
@ -103,7 +103,7 @@ class MessageBody(BaseModel):
|
|||||||
Location
|
Location
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
] = Field(default_factory=list)
|
] = Field(default_factory=list) # type: ignore
|
||||||
|
|
||||||
markup: Optional[
|
markup: Optional[
|
||||||
List[
|
List[
|
||||||
@ -111,7 +111,7 @@ class MessageBody(BaseModel):
|
|||||||
MarkupLink, MarkupElement
|
MarkupLink, MarkupElement
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
] = Field(default_factory=list)
|
] = Field(default_factory=list) # type: ignore
|
||||||
|
|
||||||
|
|
||||||
class MessageStat(BaseModel):
|
class MessageStat(BaseModel):
|
||||||
@ -164,19 +164,19 @@ class Message(BaseModel):
|
|||||||
recipient: Recipient
|
recipient: Recipient
|
||||||
timestamp: int
|
timestamp: int
|
||||||
link: Optional[LinkedMessage] = None
|
link: Optional[LinkedMessage] = None
|
||||||
body: Optional[MessageBody] = None
|
body: MessageBody
|
||||||
stat: Optional[MessageStat] = None
|
stat: Optional[MessageStat] = None
|
||||||
url: Optional[str] = None
|
url: Optional[str] = None
|
||||||
bot: Optional[Any] = Field(default=None, exclude=True)
|
bot: Optional[Any] = Field(default=None, exclude=True)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
bot: Optional[Bot]
|
bot: Optional[Bot] # type: ignore
|
||||||
|
|
||||||
async def answer(
|
async def answer(
|
||||||
self,
|
self,
|
||||||
text: str = None,
|
text: Optional[str] = None,
|
||||||
attachments: List[Attachment | InputMedia | InputMediaBuffer] = None,
|
attachments: Optional[List[Attachment | InputMedia | InputMediaBuffer]] = None,
|
||||||
link: NewMessageLink = None,
|
link: Optional[NewMessageLink] = None,
|
||||||
notify: Optional[bool] = None,
|
notify: Optional[bool] = None,
|
||||||
parse_mode: Optional[ParseMode] = None
|
parse_mode: Optional[ParseMode] = None
|
||||||
):
|
):
|
||||||
@ -195,6 +195,7 @@ class Message(BaseModel):
|
|||||||
Any: Результат выполнения метода send_message бота.
|
Any: Результат выполнения метода send_message бота.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
assert self.bot is not None
|
||||||
return await self.bot.send_message(
|
return await self.bot.send_message(
|
||||||
chat_id=self.recipient.chat_id,
|
chat_id=self.recipient.chat_id,
|
||||||
user_id=self.recipient.user_id,
|
user_id=self.recipient.user_id,
|
||||||
@ -207,8 +208,8 @@ class Message(BaseModel):
|
|||||||
|
|
||||||
async def reply(
|
async def reply(
|
||||||
self,
|
self,
|
||||||
text: str = None,
|
text: Optional[str] = None,
|
||||||
attachments: List[Attachment | InputMedia | InputMediaBuffer] = None,
|
attachments: Optional[List[Attachment | InputMedia | InputMediaBuffer]] = None,
|
||||||
notify: Optional[bool] = None,
|
notify: Optional[bool] = None,
|
||||||
parse_mode: Optional[ParseMode] = None
|
parse_mode: Optional[ParseMode] = None
|
||||||
):
|
):
|
||||||
@ -226,6 +227,7 @@ class Message(BaseModel):
|
|||||||
Any: Результат выполнения метода send_message бота.
|
Any: Результат выполнения метода send_message бота.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
assert self.bot is not None
|
||||||
return await self.bot.send_message(
|
return await self.bot.send_message(
|
||||||
chat_id=self.recipient.chat_id,
|
chat_id=self.recipient.chat_id,
|
||||||
user_id=self.recipient.user_id,
|
user_id=self.recipient.user_id,
|
||||||
@ -242,8 +244,8 @@ class Message(BaseModel):
|
|||||||
async def forward(
|
async def forward(
|
||||||
self,
|
self,
|
||||||
chat_id,
|
chat_id,
|
||||||
user_id: int = None,
|
user_id: Optional[int] = None,
|
||||||
attachments: List[Attachment | InputMedia | InputMediaBuffer] = None,
|
attachments: Optional[List[Attachment | InputMedia | InputMediaBuffer]] = None,
|
||||||
notify: Optional[bool] = None,
|
notify: Optional[bool] = None,
|
||||||
parse_mode: Optional[ParseMode] = None
|
parse_mode: Optional[ParseMode] = None
|
||||||
):
|
):
|
||||||
@ -262,6 +264,7 @@ class Message(BaseModel):
|
|||||||
Any: Результат выполнения метода send_message бота.
|
Any: Результат выполнения метода send_message бота.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
assert self.bot is not None
|
||||||
return await self.bot.send_message(
|
return await self.bot.send_message(
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
user_id=user_id,
|
user_id=user_id,
|
||||||
@ -276,9 +279,9 @@ class Message(BaseModel):
|
|||||||
|
|
||||||
async def edit(
|
async def edit(
|
||||||
self,
|
self,
|
||||||
text: str = None,
|
text: Optional[str] = None,
|
||||||
attachments: List[Attachment | InputMedia | InputMediaBuffer] = None,
|
attachments: Optional[List[Attachment | InputMedia | InputMediaBuffer]] = None,
|
||||||
link: NewMessageLink = None,
|
link: Optional[NewMessageLink] = None,
|
||||||
notify: bool = True,
|
notify: bool = True,
|
||||||
parse_mode: Optional[ParseMode] = None
|
parse_mode: Optional[ParseMode] = None
|
||||||
):
|
):
|
||||||
@ -297,6 +300,7 @@ class Message(BaseModel):
|
|||||||
Any: Результат выполнения метода edit_message бота.
|
Any: Результат выполнения метода edit_message бота.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
assert self.bot is not None
|
||||||
return await self.bot.edit_message(
|
return await self.bot.edit_message(
|
||||||
message_id=self.body.mid,
|
message_id=self.body.mid,
|
||||||
text=text,
|
text=text,
|
||||||
@ -331,6 +335,7 @@ class Message(BaseModel):
|
|||||||
Any: Результат выполнения метода pin_message бота.
|
Any: Результат выполнения метода pin_message бота.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
assert self.bot is not None
|
||||||
return await self.bot.pin_message(
|
return await self.bot.pin_message(
|
||||||
chat_id=self.recipient.chat_id,
|
chat_id=self.recipient.chat_id,
|
||||||
message_id=self.body.mid,
|
message_id=self.body.mid,
|
||||||
@ -352,7 +357,7 @@ class Messages(BaseModel):
|
|||||||
bot: Optional[Any] = Field(default=None, exclude=True)
|
bot: Optional[Any] = Field(default=None, exclude=True)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
bot: Optional[Bot]
|
bot: Optional[Bot] # type: ignore
|
||||||
|
|
||||||
|
|
||||||
class NewMessageLink(BaseModel):
|
class NewMessageLink(BaseModel):
|
||||||
|
@ -2,6 +2,8 @@ from typing import List, Optional, TYPE_CHECKING, Union
|
|||||||
|
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
|
from ...types.attachments.location import Location
|
||||||
|
|
||||||
from .update import Update
|
from .update import Update
|
||||||
|
|
||||||
from ...enums.parse_mode import ParseMode
|
from ...enums.parse_mode import ParseMode
|
||||||
@ -49,10 +51,11 @@ class MessageForCallback(BaseModel):
|
|||||||
File,
|
File,
|
||||||
Image,
|
Image,
|
||||||
Sticker,
|
Sticker,
|
||||||
Share
|
Share,
|
||||||
|
Location
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
] = Field(default_factory=list)
|
] = Field(default_factory=list) # type: ignore
|
||||||
link: Optional[NewMessageLink] = None
|
link: Optional[NewMessageLink] = None
|
||||||
notify: Optional[bool] = True
|
notify: Optional[bool] = True
|
||||||
format: Optional[ParseMode] = None
|
format: Optional[ParseMode] = None
|
||||||
@ -86,9 +89,9 @@ class MessageCallback(Update):
|
|||||||
|
|
||||||
async def answer(
|
async def answer(
|
||||||
self,
|
self,
|
||||||
notification: str = None,
|
notification: Optional[str] = None,
|
||||||
new_text: str = None,
|
new_text: Optional[str] = None,
|
||||||
link: NewMessageLink = None,
|
link: Optional[NewMessageLink] = None,
|
||||||
notify: bool = True,
|
notify: bool = True,
|
||||||
format: Optional[ParseMode] = None,
|
format: Optional[ParseMode] = None,
|
||||||
):
|
):
|
||||||
@ -115,6 +118,7 @@ class MessageCallback(Update):
|
|||||||
message.notify = notify
|
message.notify = notify
|
||||||
message.format = format
|
message.format = format
|
||||||
|
|
||||||
|
assert self.bot is not None
|
||||||
return await self.bot.send_callback(
|
return await self.bot.send_callback(
|
||||||
callback_id=self.callback.callback_id,
|
callback_id=self.callback.callback_id,
|
||||||
message=message,
|
message=message,
|
||||||
|
72
maxapi/utils/message.py
Normal file
72
maxapi/utils/message.py
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
from json import loads
|
||||||
|
|
||||||
|
from ..types.input_media import InputMedia, InputMediaBuffer
|
||||||
|
from ..enums.upload_type import UploadType
|
||||||
|
from ..exceptions.max import MaxUploadFileFailed
|
||||||
|
from ..types.attachments.upload import AttachmentPayload, AttachmentUpload
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from ..bot import Bot
|
||||||
|
from ..connection.base import BaseConnection
|
||||||
|
|
||||||
|
|
||||||
|
async def process_input_media(
|
||||||
|
base_connection: BaseConnection,
|
||||||
|
bot: Bot,
|
||||||
|
att: InputMedia | InputMediaBuffer
|
||||||
|
):
|
||||||
|
|
||||||
|
# очень нестабильный метод независящий от модуля
|
||||||
|
# ждем обновлений MAX API
|
||||||
|
|
||||||
|
"""
|
||||||
|
Загружает файл вложения и формирует объект AttachmentUpload.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
att (InputMedia): Объект вложения для загрузки.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
AttachmentUpload: Загруженное вложение с токеном.
|
||||||
|
"""
|
||||||
|
|
||||||
|
upload = await bot.get_upload_url(att.type)
|
||||||
|
|
||||||
|
if isinstance(att, InputMedia):
|
||||||
|
upload_file_response = await base_connection.upload_file(
|
||||||
|
url=upload.url,
|
||||||
|
path=att.path,
|
||||||
|
type=att.type,
|
||||||
|
)
|
||||||
|
elif isinstance(att, InputMediaBuffer):
|
||||||
|
upload_file_response = await base_connection.upload_file_buffer(
|
||||||
|
url=upload.url,
|
||||||
|
buffer=att.buffer,
|
||||||
|
type=att.type,
|
||||||
|
)
|
||||||
|
|
||||||
|
if att.type in (UploadType.VIDEO, UploadType.AUDIO):
|
||||||
|
if upload.token is None:
|
||||||
|
assert bot.session is not None
|
||||||
|
await bot.session.close()
|
||||||
|
raise MaxUploadFileFailed('По неизвестной причине token не был получен')
|
||||||
|
|
||||||
|
token = upload.token
|
||||||
|
|
||||||
|
elif att.type == UploadType.FILE:
|
||||||
|
json_r = loads(upload_file_response)
|
||||||
|
token = json_r['token']
|
||||||
|
|
||||||
|
elif att.type == UploadType.IMAGE:
|
||||||
|
json_r = loads(upload_file_response)
|
||||||
|
json_r_keys = list(json_r['photos'].keys())
|
||||||
|
token = json_r['photos'][json_r_keys[0]]['token']
|
||||||
|
|
||||||
|
return AttachmentUpload(
|
||||||
|
type=att.type,
|
||||||
|
payload=AttachmentPayload(
|
||||||
|
token=token
|
||||||
|
)
|
||||||
|
)
|
@ -46,7 +46,7 @@ MemoryContext(chat_id: int, user_id: int)
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### `async def set_state(state: State | str = None)`
|
### `async def set_state(state: Optional[Union[State, str]] = None)`
|
||||||
|
|
||||||
Устанавливает новое состояние пользователя или сбрасывает его.
|
Устанавливает новое состояние пользователя или сбрасывает его.
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user