Как избежать дублирования при отправке с помощью Media.Group()?

Я пишу бота на python библиотека aiogram, проблема следующая, при использовании метода Media.Group(), например когда я хочу сгруппировать 2 фотографии и отправить в чат, происходит дублирование контента, то есть сначала он первое фото присылает отдельным сообщением, затем он тоже самое фото добавляет 2 раза в коллаж , а второе фото нормально приходит в итоге из 2 сообщений приходит 4, так же если увеличить количество фото, они так же дублируются. Я предположил что он из-за content_type когда отправляет фото, сам же на них и реагирует, написал проверку что это не бот, а так же сделал очистку переменной, думал возможно в ней дело, но к сожалению проблема осталась. Код ниже:

media = MediaGroup()
PHOTOS_ID = []
@dp.message_handler(content_types=['photo','video'])
async def contentsearch(message: types.Message):
    if message.from_user.id is not message.from_user.is_bot:
        photo = message.photo[-1].file_id
        PHOTOS_ID.append(message.photo[-1].file_id)
        idphoto = list(set(PHOTOS_ID))
        print(idphoto)
        print(message.message_id)
        for photo_id in idphoto:
            media.attach_photo(photo_id)
        await bot.send_media_group(chat_id=chat_id, media=media)
        PHOTOS_ID.clear() 

Ответы (1 шт):

Автор решения: Alex

Решением данной проблемы является данный репозиторий git-hub, которым поделился пользователь @oleksandrigo

вот его код:

import asyncio
from typing import List, Union

from aiogram import Bot, Dispatcher, executor, types
from aiogram.dispatcher.handler import CancelHandler
from aiogram.dispatcher.middlewares import BaseMiddleware

bot = Bot(token="TOKEN_HERE")  # Place your token here
dp = Dispatcher(bot)


class AlbumMiddleware(BaseMiddleware):
    """This middleware is for capturing media groups."""

    album_data: dict = {}

    def __init__(self, latency: Union[int, float] = 0.01):
        """
        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:
            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]


@dp.message_handler(is_media_group=True, content_types=types.ContentType.ANY)
async def handle_albums(message: types.Message, album: List[types.Message]):
    """This handler will receive a complete album of any type."""
    media_group = types.MediaGroup()
    for obj in album:
        if obj.photo:
            file_id = obj.photo[-1].file_id
        else:
            file_id = obj[obj.content_type].file_id

        try:
            # We can also add a caption to each file by specifying `"caption": "text"`
            media_group.attach({"media": file_id, "type": obj.content_type})
        except ValueError:
            return await message.answer("This type of album is not supported by aiogram.")

    await message.answer_media_group(media_group)


if __name__ == "__main__":
    dp.middleware.setup(AlbumMiddleware())
    executor.start_polling(dp, skip_updates=True)

Данный вспомогательный софт помогает боту формировать альбомы из любого типа контента, это позволяет боту группировать их и отправлять как нам требуется . После добавления данного софта, бот начал группировать фото и даже фото с наличием среди них видео.

→ Ссылка