Как можно реализовать передачу группы медиа-сообщений от обычного пользователя админу в боте Aiogram? Как собрать медиагруппу и передать ее админу, учитывая отсутствие в Aiogram специальных методов для работы с медиагруппами и возможностью обрабатывать сообщения на лету? Как справиться с тем, что нельзя получить размер медиагруппы или определить последнее сообщение медиагруппы в Aiogram?
Для отправки медиагруппы с помощью Aiogram, вы можете использовать метод `send_media_group` объекта `aiogram.Bot`. Этот метод принимает идентификатор чата, а также список `aiogram.types.InputMedia` объектов, представляющих медиа-элементы группы, которую вы хотите отправить. Пример: ```python from aiogram import Bot, types bot = Bot(token='YOUR_API_TOKEN') async def send_media_group(chat_id, media_group): await bot.send_media_group(chat_id=chat_id, media=media_group) media_group = [ types.InputMediaPhoto(media='URL_TO_PHOTO1'), types.InputMediaPhoto(media='URL_TO_PHOTO2'), types.InputMediaPhoto(media='URL_TO_PHOTO3'), ] chat_id = 'CHAT_ID' await send_media_group(chat_id, media_group) ``` Чтобы реализовать передачу медиагруппы от обычного пользователя админу в боте Aiogram, вы можете создать соответствующий обработчик для сообщения пользователя, собрать медиагруппу и отправить ее админу. Пример: ```python from aiogram import Dispatcher, types async def forward_media_group(message): if message.media_group_id: media_group = await bot.get_media_group(chat_id=message.chat.id, media_group_id=message.media_group_id) for admin_id in ADMIN_IDS: await send_media_group(admin_id, media_group) dp.register_message_handler(forward_media_group, content_types=types.ContentTypes.PHOTO) async def send_media_group(chat_id, media_group): await bot.send_media_group(chat_id=chat_id, media=media_group) ``` Если в Aiogram нет специальных методов для работы с медиагруппами, вы можете создать свою логику обработки медиагрупп в обработчиках сообщений. Например, вы можете сохранить все медиа-элементы сообщения в базу данных и отправить их админу по завершении или при обработке следующего сообщения. Надеюсь, эти примеры помогут вам решить ваши задачи по отправке и обработке медиагрупп в Aiogram.
На aiogram 2 делал так, через middleware:
class AlbumMiddleware(BaseMiddleware): """This middleware is for capturing media groups.""" album_data: dict = {} def __init__(self, latency = 0.6): """ You can provide custom latency to make sure albums are handled properly in highload. """ self.latency = latency super().__init__() async def on_process_message(self, message: types.Message, data: dict): if not message.media_group_id: if message.photo : data["one_photo"] = message elif message.animation or message.video or message.video_note or message.voice or message.audio: data["album"] = [message] return try: self.album_data[message.media_group_id].append(message) raise CancelHandler() # Tell aiogram to cancel handler for this group element except KeyError: self.album_data[message.media_group_id] = [message] await asyncio.sleep(self.latency) message.conf["is_last"] = True data["album"] = self.album_data[message.media_group_id] async def on_post_process_message(self, message: types.Message, result: dict, data: dict): """Clean up after handling our album.""" if message.media_group_id and message.conf.get("is_last"): del self.album_data[message.media_group_id]
И потом при обработке сообщения, будет 2 переменные album, one_photo:
async def func( message: types.Message, album: Optional[List[types.Message]] = None, one_photo: Optional[types.Message] = None ):
если в сообщении только одна картинка, она будет в one_photo, в остальном случае все будет в album
На aiogram 2 делал так, через middleware:
class AlbumMiddleware(BaseMiddleware): """This middleware is for capturing media groups.""" album_data: dict = {} def __init__(self, latency = 0.6): """ You can provide custom latency to make sure albums are handled properly in highload. """ self.latency = latency super().__init__() async def on_process_message(self, message: types.Message, data: dict): if not message.media_group_id: if message.photo : data["one_photo"] = message elif message.animation or message.video or message.video_note or message.voice or message.audio: data["album"] = [message] return try: self.album_data[message.media_group_id].append(message) raise CancelHandler() # Tell aiogram to cancel handler for this group element except KeyError: self.album_data[message.media_group_id] = [message] await asyncio.sleep(self.latency) message.conf["is_last"] = True data["album"] = self.album_data[message.media_group_id] async def on_post_process_message(self, message: types.Message, result: dict, data: dict): """Clean up after handling our album.""" if message.media_group_id and message.conf.get("is_last"): del self.album_data[message.media_group_id]
И потом при обработке сообщения, будет 2 переменные album, one_photo:
async def func( message: types.Message, album: Optional[List[types.Message]] = None, one_photo: Optional[types.Message] = None ):
если в сообщении только одна картинка, она будет в one_photo, в остальном случае все будет в album