Telegram机器人识别并发送媒体组(相册)消息的API用法全解析

深入讲解Telegram机器人如何识别相册消息(媒体组)以及如何通过API发送媒体组,附带完整代码示例和常见问题解答。

阅读提示涉及账号和安全设置时,请边阅读边核对当前设备界面。

在Telegram机器人开发中,媒体组(Media Group)通常被称为“相册”或“媒体相册”,是用户或机器人发送的一组图片、视频或混合媒体消息。对于开发者而言,正确识别机器人收到的媒体组消息,并能够主动发送媒体组,是构建多媒体交互功能(如相册分享、轮播图、多图报告等)的关键能力。本文将全面解析Telegram Bot API中媒体组的识别与发送方法,并提供可直接运行的代码示例。

什么是媒体组(相册)消息?

媒体组是Telegram中一种特殊的消息形式,用户可以通过选择多张图片或视频一次性发送,它们会合并成一个可滑动浏览的相册。在Bot API中,媒体组由一条主消息和若干附属消息组成,所有消息共享同一个media_group_id。该ID是识别一组消息是否属于同一相册的唯一标识。值得注意的是,媒体组的消息类型可以是photovideodocument(以图片/视频作为附件),但不能混合音频和纯文字。

识别收到的媒体组消息

1. 从更新中提取media_group_id

当用户向机器人发送相册时,机器人会收到一条或多条Update。每个Update的message对象中,如果消息属于媒体组,则必定包含media_group_id字段。因此,识别方法非常简单:检查消息对象中是否存在该字段。


# 使用python-telegram-bot库示例(v20.x)
async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
    message = update.effective_message
    if message.media_group_id:
        # 该消息属于媒体组
        print(f"收到媒体组,ID: {message.media_group_id}")
        print(f"消息类型: {message.photo or message.video or message.document}")
    else:
        print("普通消息,不属于媒体组")

对于使用getUpdates长轮询的普通HTTP请求,也可以直接在JSON中检查media_group_id键。

2. 媒体组消息的完整性判断

Telegram会一次性发送媒体组的全部消息,但每个消息独立到达。为了处理整个相册,通常会缓存同一media_group_id下的所有消息,直到一段时间(如2-3秒)不再收到新消息,再统一处理。以下是一个简单的缓存策略:


# 简单的内存缓存示例
from collections import defaultdict
media_cache = defaultdict(list)

async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
    message = update.effective_message
    mgid = message.media_group_id
    if mgid:
        media_cache[mgid].append(message)
        # 设置定时器,例如1秒后处理
        context.application.create_task(process_media_group(mgid))

async def process_media_group(mgid: str):
    import asyncio
    await asyncio.sleep(1)  # 等待后续消息
    messages = media_cache.pop(mgid, [])
    # 此时可对完整的媒体组进行业务处理

通过API发送媒体组消息

sendMediaGroup方法

发送媒体组的核心API是sendMediaGroup,它接受一个包含多个InputMedia对象的数组。常见的InputMedia类型有:

  • InputMediaPhoto:发送图片(可附说明文字);
  • InputMediaVideo:发送视频(可附说明文字);
  • InputMediaDocument:发送文件(以媒体组形式发送时需指定force_document=True,否则可能被识别为普通文件)。

同一个媒体组最多可发送10个媒体文件,所有媒体必须类型相同(全图片或全视频)或允许混合(当前版本支持图片+视频混合)。

代码示例:使用python-telegram-bot发送图片相册


from telegram import InputMediaPhoto
from telegram.ext import Application, CommandHandler

async def send_album(update: Update, context: ContextTypes.DEFAULT_TYPE):
    chat_id = update.effective_chat.id
    photo_urls = [
        "https://example.com/image1.jpg",
        "https://example.com/image2.jpg",
        "https://example.com/image3.jpg"
    ]
    media_group = [InputMediaPhoto(media=url) for url in photo_urls]
    # 可给第一个媒体附带说明文字
    if media_group:
        media_group[0].caption = "这是相册的说明"
    await context.bot.send_media_group(chat_id=chat_id, media=media_group)

使用aiogram框架的异步实现


from aiogram import Bot, Dispatcher, types
from aiogram.filters import Command
from aiogram.types import InputMediaPhoto, MediaGroup

@dp.message(Command("album"))
async def send_album(message: types.Message, bot: Bot):
    media_group = MediaGroup(
        InputMediaPhoto(media="https://example.com/1.jpg", caption="第一张"),
        InputMediaPhoto(media="https://example.com/2.jpg"),
        InputMediaPhoto(media="https://example.com/3.jpg")
    )
    await bot.send_media_group(chat_id=message.chat.id, media=media_group)

通过原生HTTP API调用

如果不使用库,可以直接multipart/form-data方式请求sendMediaGroup,每个文件作为文件字段,并附带JSON参数。注意,官方要求所有媒体文件必须通过multipart上传,因此无法简单拼接JSON数组(除非使用URL)。对于URL类型的媒体,可以使用attach://方式引用已上传的文件。

发送后的消息处理

sendMediaGroup返回一个Message对象数组,每个对象对应一条媒体组中的消息。这些消息共享同一个media_group_id。开发者可以保存这些消息ID,用于后续编辑或删除整个媒体组(只需删除其中一条即可删除整个相册)。


sent_messages = await context.bot.send_media_group(chat_id, media_group)
# sent_messages是一个列表,其中每个元素有message_id
print([msg.message_id for msg in sent_messages])

注意事项与最佳实践

  • 文件大小限制:通过机器人发送的文件最大为50 MB(普通用户为2 GB),媒体组内每个文件同样受此限制。
  • 混合类型:Telegram官方允许在同一媒体组中混合图片和视频,但部分旧客户端可能显示不佳,建议根据场景选择。
  • 说明文字:只有第一个媒体可以设置标题(caption),且最多1024字符。
  • 发送顺序:媒体组会按照数组顺序显示,请确保排列正确。
  • 日志记录:在生产环境中,建议记录media_group_id与业务ID的映射,便于问题排查。

常见问题解答

问:为什么收到的媒体组消息只有一条?
答:Telegram有时只会发送一条代表性的消息(例如用户只选择了一张图片),此时仍需检查media_group_id来判断是否属于相册,并等待可能已丢失的其他消息。

问:能否将普通消息转换为媒体组?
答:不能,发送时必须一次性用sendMediaGroup发送,不能把已有的独立消息合并。

问:媒体组中的视频能否携带缩略图?
答:可以,在InputMediaVideo中设置thumbnail参数。

总结

掌握媒体组的识别与发送是Telegram机器人开发中进阶而重要的一步。通过media_group_id识别收到的相册,利用sendMediaGroup发送组合媒体,可以极大丰富机器人的交互形式。本文提供的代码示例覆盖了常见框架,你可以根据项目需求灵活调整。遇到问题时可查阅官方Bot API文档或与社区开发者交流。

FAQ

下载与安装

常见问题

如何判断收到的消息是否为媒体组?

检查消息对象中是否存在 media_group_id 字段,如果存在则属于媒体组。

sendMediaGroup 最多能发送多少个媒体?

最多10个,且所有媒体不能超过50MB(通过机器人)。

媒体组的说明文字如何添加?

只有第一个媒体可以设置 caption,且长度不超过1024字符。