Задать вопрос
@thenewdaniels

Python aiogram 3 AlbumHandler. Как исправить проблему того, что при отправке медиа-группы хендлер ловит только первую фотографию?

Работая в одном из проектов в PyCharm понадобилась возможность ловить одним хендлером альбом из фотографий, отправленных одним сообщением. Как оказалось, в aiogram 3 нет встроенных инструментов, для того, чтобы это делать, но получилось найти обходной путь, а именно создать мидлварь для альбомов
middleware.py

import asyncio
from typing import Callable, Any, Awaitable, Union

from aiogram import BaseMiddleware
from aiogram.types import Message


class AlbumMiddleware(BaseMiddleware):
    album_data: dict = {}

    def __init__(self, latency: Union[int, float] = 0.01):
        self.latency = latency

    async def __call__(
            self,
            handler: Callable[[Message, dict[str, Any]], Awaitable[Any]],
            message: Message,
            data: dict[str, Any]
    ) -> Any:
        if not message.media_group_id:
            await handler(message, data)
            return
        try:
            self.album_data[message.media_group_id].append(message)
        except KeyError:
            self.album_data[message.media_group_id] = [message]
            await asyncio.sleep(self.latency)

            data['_is_last'] = True
            data["album"] = self.album_data[message.media_group_id]
            await handler(message, data)

        if message.media_group_id and data.get("_is_last"):
            del self.album_data[message.media_group_id]
            del data['_is_last']



Объявив мидлварь перед хендлерами мы получаем вот такую связку:
anyPythonScript.py

from aiogram import Router, F
from aiogram.types import Message, InputMediaPhoto, ContentType as CT
router = Router()

router.message.middleware(AlbumMiddleware())

@router.message(F.content_type.in_([CT.PHOTO]))
async def handle_photo(message: Message, state: FSMContext, album: list[Message] = []):
answer_text = 'Фотографии прикреплены.'
        media_group = []
        for msg in album:
            if msg.photo:
                file_id = msg.photo[-1].file_id
                media_group.append(InputMediaPhoto(media=file_id))
        try:
            media_group[0].caption = answer_text
        except IndexError:
            if message.content_type == 'photo':
                photo = message.photo[-1].file_id
                chat_id = message.from_user.id
                answer_text = answer_text
                from main import bot
                await bot.send_photo(chat_id, photo=photo,
                                     caption=answer_text)
                await state.update_data(media_group=photo,
                                        isAlbum=False)
                await message.answer('Подтвердить?')
                return
        await state.update_data(media_group=media_group,
                                isAlbum=True)
        await message.answer_media_group(media_group)
        await message.answer('Подтвердить?')



Казалось бы, всё должно работать правильно, каждая фотография в альбоме обработается как отдельное событие и код пройдёт по необходимому сценарию. Когда фотография одна - обработает одну, когда фотографий несколько, в ход идёт мидлварь. Так я и сделал в своём проекте и все сработало отлично и правильно:
6776ada3b19fb652470197.png

Код сначала схавал все три фотографии, а уже потом, предварительно зафиксировав их своём "альбоме", обработал и вывел ответ один раз, а не три, сколько было фотографий

Экран юзера выглядит следующим образом:
67689081d2768179392716.png

Но когда я перешёл к другому проекту и вставил туда абсолютно тот же самый код, меня ждала неудача. Фотографии ловятся совершенно по другому:

6776aaf3753ec288963179.png

Текст из консоли:

6776ab89f33f5648484652.png

Итак, вопрос: Как исправить проблему того, что при отправке медиа-группы хендлер ловит только первую фотографию? И как в будущем избежать этой проблемы при загрузке на сервер? Пользуюсь Пайчармом, python 3.10 во всех проектах одинаковый

upd:
Бот работает некорректно только по отношению к иностранным тг-аккаунтам

russian sim-card tg account

Правильная работа бота с тг аккаунтом, зарегистрированным на русскую симку +7(ХХХ)
6776c28b55af0927926987.jpeg


Non-russian sim-card tg account

Неправильная работа бота с тг аккаунтом, зарегистрированным на иностранную симку, не на +7(ХХХ)
6776c260a6a42454471989.jpeg
  • Вопрос задан
  • 209 просмотров
Подписаться 2 Простой 1 комментарий
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы