Добавлен types.InputMedia для простой загрузки медиафайлов

This commit is contained in:
2025-06-20 02:24:14 +03:00
parent 85f58913c3
commit 1374d863f0
33 changed files with 332 additions and 262 deletions

View File

@@ -1,20 +1,33 @@
import asyncio
from typing import List, TYPE_CHECKING
from json import loads as json_loads
from ..enums.upload_type import UploadType
from ..types.attachments.upload import AttachmentPayload, AttachmentUpload
from ..types.errors import Error
from .types.sended_message import SendedMessage
from ..types.message import NewMessageLink
from ..types.input_media import InputMedia
from ..types.attachments.attachment import Attachment
from ..enums.parse_mode import ParseMode
from ..enums.http_method import HTTPMethod
from ..enums.api_path import ApiPath
from ..connection.base import BaseConnection
from ..loggers import logger_bot
if TYPE_CHECKING:
from ..bot import Bot
class UploadResponse:
token: str = None
class SendMessage(BaseConnection):
def __init__(
self,
@@ -23,7 +36,7 @@ class SendMessage(BaseConnection):
user_id: int = None,
disable_link_preview: bool = False,
text: str = None,
attachments: List[Attachment] = None,
attachments: List[Attachment | InputMedia] = None,
link: NewMessageLink = None,
notify: bool = True,
parse_mode: ParseMode = None
@@ -38,10 +51,41 @@ class SendMessage(BaseConnection):
self.notify = notify
self.parse_mode = parse_mode
async def __process_input_media(
self,
att: InputMedia
):
upload = await self.bot.get_upload_url(att.type)
upload_file_response = await self.upload_file(
url=upload.url,
path=att.path,
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:
params = self.bot.params.copy()
json = {}
json = {'attachments': []}
if self.chat_id: params['chat_id'] = self.chat_id
elif self.user_id: params['user_id'] = self.user_id
@@ -49,17 +93,37 @@ class SendMessage(BaseConnection):
json['text'] = self.text
json['disable_link_preview'] = str(self.disable_link_preview).lower()
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):
input_media = await self.__process_input_media(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.notify is None: json['notify'] = self.notify
if not self.parse_mode is None: json['format'] = self.parse_mode.value
return await super().request(
method=HTTPMethod.POST,
path=ApiPath.MESSAGES,
model=SendedMessage,
params=params,
json=json
)
response = None
for attempt in range(5):
response = await super().request(
method=HTTPMethod.POST,
path=ApiPath.MESSAGES,
model=SendedMessage,
params=params,
json=json
)
if isinstance(response, Error):
if response.raw.get('code') == 'attachment.not.ready':
logger_bot.info(f'Ошибка при отправке загруженного медиа, попытка {attempt+1}, жду 2 секунды')
await asyncio.sleep(2)
continue
return response
return response