send_media_group 使用 BytesIO 来电报机器人

send_media_group with BytesIO to telegram bot

我正在使用 PIL 创建图像并将其存储在剪贴板中 BytesIO.I 想将相册发送到电报机器人,但出现错误:

代码:

from PIL import Image, ImageDraw, ImageFont
from io import BytesIO
from aiogram import Bot, Dispatcher, executor, types
import logging

API_TOKEN = 'xxxxxx'
logging.basicConfig(level=logging.INFO)
bot = Bot(token=API_TOKEN)
dp = Dispatcher(bot)

def createimg()
    im = Image.new('RGB', (256, 256), color='black')
    bio = BytesIO()
    bio.name = 'res.png'
    im.save(bio, 'PNG')
    bio.seek(0)
    return bio

@dp.message_handler(commands=['start'])
async def send_welcome(message: types.Message):
    await bot.send_media_group(message.from_user.id, [createimg(), createimg()])

错误:

   raise TypeError(f"Media must be an instance of InputMedia or dict, not {type(media).__name__}")
TypeError: Media must be an instance of InputMedia or dict, not BytesIO

您必须在列表中使用 aiogram.types.InputMedia 对象的子类,而不是普通的 io.BytesIO 对象。在您的情况下,它必须是 aiogram.types.InputMediaPhoto,它接受 aiogram.types.InputFile 对象作为第一个参数,您可以在其中直接放置普通的 io.BytesIO 对象。

此外,请考虑在代码中使用快捷方式,因为它可以使代码更简洁、更易读。例如,您可以 .reply().answer()aiogram.types.Message,这是 aiogram.Bot.send_message() 的快捷方式。在您的情况下,您应该使用 aiogram.types.Message.answer_media_group.

所以,你的代码应该是这样的:

# Some code is omitted in favor of brievity

def wrap_media(bytesio, **kwargs):
    """Wraps plain BytesIO objects into InputMediaPhoto"""
    # First, rewind internal file pointer to the beginning so the contents
    #  can be read by InputFile class
    bytesio.seek(0)
    return types.InputMediaPhoto(types.InputFile(bytesio), **kwargs)

@dp.message_handler(commands=['start'])
async def send_welcome(message: types.Message):
    await message.answer_media_group([wrap_media(createimg()), wrap_media(createimg())])

有关 aiogram.types.InputMediaPhoto 接受的内容的更多信息,请参阅 aiogram documentation