Как переслать медиагруппу в Aiogram? Есть ли готовые решения?

Делаю типичный бот для связи. Задача: бот должен переслать юзеру-админу группу медиа которые отправил обычный юзер.

В Aiogram есть методы forward и copy_to, которые подразумевают работу с одним сообщением, но нет методов для работы с медиагруппой.

Так же усложняет задачу то, что в Aiogram отсутствуют get-методы даже для сообщений, которые уже видит бот. То есть половина проблемы в том, что нужно собрать в кучу медиагруппу, обрабатывая сообщения на лету.

И по сути, даже если это делать на лету, то мы не знаем размера медиагруппы или последнего сообщения медиагруппы, что усложняет обработку и группировку сообщений. И это ещё опуская тот момент, что сообщения могут содержать медиа разного типа.

Уверен, эта проблема уже поднималась, но какой по итогу выход из ситуации? Может уже есть готовые решения? Интересует только Aiogram, без других библиотек.
  • Вопрос задан
  • 81 просмотр
Пригласить эксперта
Ответы на вопрос 1
@Wispik
На 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
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы