Python Telegram Bot无法同时获取用户的多张图片

0 投票
1 回答
49 浏览
提问于 2025-04-14 17:07

我在写一个Python脚本,目的是创建一个Telegram机器人,这个机器人的一个功能是收集用户发送的图片。问题出现在用户同时选择多张图片并发送的时候,机器人没有正确获取到每张图片的文件ID。以下是我的代码:

# Function to handle picture collection
def collect_pictures(message):
    user_id = message.chat.id
    if message.photo:
        # Iterate through each photo in the array
        for photo_data in message.photo:
            file_id = photo_data.file_id
            user_data[user_id]['pictures'].append(file_id)

            # Print information about the received picture
            print(f"User {message.from_user.username} sent a picture with file_id: {file_id}")

        # Total number of pictures received
        total_pictures = len(user_data[user_id]['pictures'])
        print(f"User {message.from_user.username} has sent {total_pictures} pictures in total.")

        # You can proceed with further processing or confirmation here
        markup = create_confirm_keyboard()
        bot.send_message(message.chat.id, "Do you want to submit the collected information and pictures?", reply_markup=markup)
        bot.register_next_step_handler(message, handle_additional_pictures)
    else:
        bot.send_message(message.chat.id, "Invalid input. Please send pictures.")
        bot.register_next_step_handler(message, collect_pictures)

  1. 我尝试使用循环来获取每张图片的文件ID,但结果并不如我所愿。虽然它能正确统计上传的图片数量,但在获取ID的过程中,所有图片的文件ID都被存储成了第一张图片的文件ID。

1 个回答

0

简单来说,在Telegram中,组合媒体是一些视觉上分组在一起的独立消息。你可以使用中间件把它们捕捉到一个处理函数里。

import asyncio
from abc import ABC
from typing import Callable, Dict, Any, Awaitable
from aiogram.types import Message

from aiogram import BaseMiddleware
from aiogram import types
from aiogram.dispatcher.event.bases import CancelHandler


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

    album_data: dict = {}

    def __init__(self, latency: 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 __call__(
        self,
        handler: Callable[[Message, Dict[str, Any]], Awaitable[Any]],
        event: Message,
        data: Dict[str, Any],
    ) -> Any:
        if not event.media_group_id:
            return

        try:
            self.album_data[event.media_group_id].append(event)
            return  # Tell aiogram to cancel handler for this group element
        except KeyError:
            self.album_data[event.media_group_id] = [event]
            await asyncio.sleep(self.latency)

            event.model_config["is_last"] = True
            data["album"] = self.album_data[event.media_group_id]

            result = await handler(event, data)

            if event.media_group_id and event.model_config.get("is_last"):
                del self.album_data[event.media_group_id]

            return result

然后通过在处理函数中添加album参数,你就可以获取data["album"]

@router.message(F.content_type.in_({'photo', 'document'}))
async def receive_album(message: Message, album: list[Message] = None):
    for file in album:
        print(file)

在启动机器人之前注册中间件,你可以使用:

middleware = AlbumMiddleware()

dp.message.outer_middleware(middleware)
dp.callback_query.outer_middleware(middleware)

撰写回答