☰
aiogram 语音消息类型 Voice 完全指南:字段解析、发送与接收实战
2026/10/13 8:44:03 网站建设 项目流程
  • 后端
  • 即时通讯
  • API设计

【免费下载链接】aiogram

aiogram is a modern and fully asynchronous framework for Telegram Bot API written in Python using asyncio

项目地址:https://gitcode.com/gh_mirrors/ai/aiogram
点击查看免费下载

语音消息(Voice Note)是 Telegram Bot API 中一类高频使用的媒体消息。在 aiogram 中,Voice对象承载了语音消息的全部元数据(文件标识、时长、大小等),是理解"收到语音 → 解析 → 回复/转发"这条完整链路的关键类型。本指南以 docs/api/types/voice.rst 为骨架,结合 aiogram 源码中Voice类型定义、sendVoice方法实现、Message对象集成方式以及对应测试用例,系统讲解语音消息的字段含义、接收识别、发送方法与底层原理,读完即可在真实 bot 中正确处理与收发语音消息。

一、Voice 类型概述:一个表示语音消息的 Pydantic 模型

在 aiogram 中,Voice是TelegramObject的子类,定义于 aiogram/types/voice.py,其 docstring 明确指出:

This object represents a voice note.

它对应 Telegram Bot API 官方文档中的Voice对象,用于描述一条语音消息(voice note)的静态信息,例如文件 ID、时长、MIME 类型与文件大小。与Audio(音乐文件,见 aiogram/types/audio.py)不同,Voice专指用户在聊天中按住麦克风录制的"语音条",在 Telegram 客户端中呈现为可播放的语音气泡。

从代码结构看,Voice的所有字段都由 Pydantic 驱动(继承自TelegramObject),并额外通过butcher自动生成了TYPE_CHECKING块下的__init__签名,用于在无插件环境下提供完整的 IDE 类型提示支持。

二、字段详解:五个核心属性的语义与默认值

根据 aiogram/types/voice.py 的类定义,Voice共有 5 个字段,其中 3 个为必填、2 个为可选:

字段类型默认值说明
file_idstr必填文件标识符,可用于下载或复用该文件
file_unique_idstr必填文件的唯一标识,跨时间、跨 bot 保持不变;不能用于下载或复用文件
durationint必填音频时长(秒),由发送方定义
mime_typestr | NoneNone可选。文件的 MIME 类型,由发送方定义
file_sizeint | NoneNone可选。文件大小(字节)

2.1 file_id 与 file_unique_id:最容易混淆的一对字段

这两个字段是 Telegram 媒体对象的通用设计(Animation、Audio、Document、Video、VideoNote等类型均遵循同一模式,见 aiogram/types/audio.py 中的对照实现):

  • file_id:是"可用"的标识符。你可以直接把它作为sendVoice等方法的voice参数传入,Telegram 服务器会依据它复用已存在的文件,而无需再次上传;也可以在getFile中用来换取下载路径。它的稳定性只局限于"同一个 bot + 当前时间窗口"内,长时间后可能失效。
  • file_unique_id:是"可识别"的标识符。它在任意 bot、任意时间段内都唯一且稳定,适合作为数据库主键或去重依据,但 Telegram 明确禁止用它下载或复用文件。

aiogram 进一步将"可下载"这一能力抽象为Downloadable协议,见 aiogram/types/downloadable.py:任何实现了file_id属性的类型都可以被通用下载逻辑处理。

2.2 duration:语音条的核心业务字段

duration表示语音秒数。在实现"语音时长限制""自动转写""超长语音提示"等业务逻辑时,这是最常用的字段。发送方定义后由 Telegram 服务器透传,aiogram 不做任何加工,直接映射为int。

2.3 mime_type 与 file_size:可选的扩展信息

  • mime_type由发送方声明,常见取值如audio/ogg、audio/mpeg等,可用于在播放前判断编码格式;
  • file_size以字节为单位。源码 docstring 特别提示:该值可能大于 2³¹,部分编程语言在解释它时可能出现困难或静默缺陷,但其最多只有 52 个有效位,因此有符号 64 位整数或双精度浮点类型都能安全存储。在 Python 中int无此顾虑,但若将该值经 JSON 或数据库传输到其他语言环境,应留意此限制。

三、如何接收语音消息:Message.voice 与 ContentType 判定

语音消息在 aiogram 中通过Message对象的voice字段暴露。在 aiogram/types/message.py 中可以看到:

voice: Voice | None = None """*Optional*. Message is a voice message, information about the file"""

即:只有消息是语音消息时,message.voice才非空;其余媒体类型(audio、document、photo等)各自拥有独立字段,互不冲突。

与之配套的是ContentType判定。在 aiogram/types/message.py 的content_type属性实现中:

if self.voice: return ContentType.VOICE

因此在实际开发中,识别语音消息有两种等价方式:

from aiogram import F from aiogram.types import Message, ContentType # 方式一:基于 content_type @router.message(F.content_type == ContentType.VOICE) async def handle_voice_ct(message: Message): await message.answer(f"收到语音:时长 {message.voice.duration} 秒") # 方式二:直接基于 voice 字段 @router.message(F.voice) async def handle_voice_field(message: Message): voice: Voice = message.voice await message.answer( f"file_id={voice.file_id}\n" f"unique_id={voice.file_unique_id}\n" f"duration={voice.duration}s\n" f"mime={voice.mime_type}\n" f"size={voice.file_size} bytes" )

在测试层面,仓库的 tests/test_api/test_types/test_message.py 构造了一个典型的语音消息测试样例:

voice=Voice(file_id="file id", file_unique_id="file id", duration=0),

这印证了三个必填字段(file_id、file_unique_id、duration)即可构造出合法的Voice对象,两个可选字段在未提供时自动为None。

四、如何发送语音消息:bot.send_voice 与 sendVoice 方法

发送语音消息对应 Telegram API 的sendVoice方法。aiogram 在 aiogram/methods/send_voice.py 中将其封装为SendVoice请求对象(__api_method__ = "sendVoice",成功时返回Message),并在 aiogram/client/bot.py 提供了异步快捷方法bot.send_voice。

4.1 三种传文件方式

voice参数的类型为InputFileUnion,其定义见 aiogram/types/input_file_union.py:

InputFileUnion: TypeAlias = str | InputFile

即支持三种传法:

  1. 传 file_id(推荐):直接传str类型的file_id,复用 Telegram 服务器上已存在的文件,无需重新上传;
  2. 传 HTTP URL:传一个以http开头的字符串,Telegram 会自行从互联网抓取该文件;
  3. 上传新文件:传InputFile实例(如本地文件路径、BufferedInputFile包装的字节流等),aiogram 会通过 multipart/form-data 完成上传。

4.2 格式要求与大小限制

SendVoice的 docstring(aiogram/methods/send_voice.py)明确指出:

要让 Telegram 客户端将音频显示为可播放的语音消息,音频必须是.OGG(OPUS 编码)、.MP3或.M4A格式;其他格式将作为Audio或Document发送。Bot 当前可发送的语音消息上限为50 MB。

这一限制同时出现在 aiogram/client/bot.py 与Message.reply_voice的 docstring 中,是官方 API 的硬性约束。

4.3 常用参数一览

bot.send_voice(签名见 aiogram/client/bot.py)支持丰富的可选参数,常用如下:

参数类型说明
chat_idChatIdUnion目标聊天 ID,或@username格式的群组/频道/机器人用户名
voiceInputFileUnion语音文件(file_id / URL / InputFile)
captionstr | None语音消息的说明文字,实体解析后 0–1024 字符
parse_modestr | Default | None标题实体解析模式(HTML / MarkdownV2 等),默认Default("parse_mode"),即跟随全局默认配置
caption_entitieslist[MessageEntity] | None显式指定的实体列表,可用于替代parse_mode
durationint | None语音时长(秒),由发送方填写
disable_notificationbool | None静默发送
protect_contentbool | Default | None禁止转发与保存消息内容
reply_parametersReplyParameters | None回复的目标消息描述
reply_markupReplyMarkupUnion | None内联键盘、自定义键盘等附加界面选项

从源码结构看,parse_mode与protect_content的默认值均使用Default(...)占位符(见 aiogram/methods/send_voice.py 与 aiogram/methods/send_voice.py),这表示它们会继承Bot实例上配置的全局默认值,而不是固定为None——这是 aiogram 3.x 的Default机制的典型用法。

4.4 完整示例:上传本地文件发送语音

from aiogram import Bot, Dispatcher from aiogram.client.default import DefaultBotProperties from aiogram.enums import ParseMode from aiogram.types import BufferedInputFile TOKEN = "YOUR_BOT_TOKEN" bot = Bot( TOKEN, default=DefaultBotProperties(parse_mode=ParseMode.HTML), ) dp = Dispatcher() @dp.message() async def send_voice_to_user(message): # 方式一:复用 file_id(收到的语音直接转给用户) if message.voice: await message.answer_voice(message.voice.file_id, caption="转发你的语音") # 方式二:上传本地 OGG/OPUS 文件 with open("note.ogg", "rb") as f: data = f.read() await bot.send_voice( chat_id=message.chat.id, voice=BufferedInputFile(data, filename="note.ogg"), duration=12, # 发送方声明的时长 caption="<b>语音播报</b>", )

4.5 方法级测试验证

仓库为send_voice提供了完整的单元测试 tests/test_api/test_methods/test_send_voice.py:

prepare_result = bot.add_result_for( SendVoice, ok=True, result=Message( message_id=42, date=datetime.datetime.now(), voice=Voice(file_id="file id", duration=0, file_unique_id="file id"), chat=Chat(id=42, type="private"), ), ) response: Message = await bot.send_voice(chat_id=42, voice="file id")

该测试验证了两个关键事实:bot.send_voice接受裸字符串file_id作为voice参数;调用成功后返回的Message中voice字段即为Voice实例,与测试预期完全相等。

五、配套能力:回复、复制与聊天动作

5.1 Message.reply_voice / answer_voice 快捷方法

在收到消息后,若想"就地回复"语音,可使用Message上的reply_voice快捷方法。其实现位于 aiogram/types/message.py,docstring 明确说明它会自动填充以下属性:

  • chat_id
  • message_thread_id(论坛主题场景)
  • business_connection_id
  • reply_parameters(基于当前消息构造)
  • ephemeral_message_parameters

answer_voice是语义等价的方法(同样映射到SendVoice,见 aiogram/types/message.py 的对应生成代码),在测试 tests/test_api/test_types/test_message.py 中以["voice", {"voice": "voice"}, SendVoice]形式验证了其返回SendVoice请求对象的行为。二者区别仅在于命名习惯:answer_*强调"作为回应发出",实现上等价。

5.2 复制语音消息:send_copy 链路

当需要"复制"(而非转发)一条语音消息时,Message.send_copy会在 aiogram/types/message.py 中命中以下分支:

if self.voice: return SendVoice( voice=self.voice.file_id, **kwargs, ).as_(self._bot)

即自动提取voice.file_id构造SendVoice,实现无上传的复用发送。这也从侧面说明file_id在"下载或复用"场景中的核心价值。

5.3 发送前的聊天动作:record_voice 与 upload_voice

Telegram 要求上传大文件前先发送对应的 Chat Action,让用户看到"正在录音 / 正在上传"的状态提示。aiogram 在 aiogram/utils/chat_action.py 提供了两个现成构造器:

  • ChatActionSender.record_voice(chat_id, bot):对应record_voice动作;
  • ChatActionSender.upload_voice(chat_id, bot):对应upload_voice动作。

两者均支持message_thread_id、interval(默认DEFAULT_INTERVAL)与initial_sleep参数,可通过async with上下文或在后台任务中使用,典型搭配如下:

from aiogram.utils.chat_action import ChatActionSender async def send_voice_with_action(bot, chat_id): action = ChatActionSender.record_voice(chat_id=chat_id, bot=bot) async with action: # 在此执行耗时较长的语音生成 / 上传逻辑 await bot.send_voice(chat_id=chat_id, voice="file_id")

六、Voice 与相邻类型的关系边界

在 Telegram 媒体体系中,语音相关类型容易混淆,明确边界有助于正确建模:

类型定位关键差异
Voice语音消息(voice note)仅含duration、mime_type、file_size等基础元数据,无缩略图
Audio(见 aiogram/types/audio.py)音乐文件额外含performer、title、file_name、thumbnail字段
VideoNote圆形视频消息额外含thumbnail、file_size等,带画面
Document普通文件任意格式均可,不保证可播放

从Voice缺少performer、title、thumbnail字段这一源码事实(对照 aiogram/types/audio.py)可以看出:语音消息面向的是"即录即发"场景,Telegram 不为其附加音乐标签或封面图。

七、总结:Voice 类型在 aiogram 中的完整生命周期

回顾全文,Voice类型贯穿语音消息处理的完整链路:

  1. 接收:Message.voice字段承载Voice实例,content_type == ContentType.VOICE或F.voice过滤器均可识别(见 aiogram/types/message.py);
  2. 解析:file_id用于复用/下载,file_unique_id用于稳定去重,duration用于业务判断,mime_type/file_size作为可选扩展信息;
  3. 发送:通过bot.send_voice(aiogram/client/bot.py)或message.reply_voice/answer_voice(aiogram/types/message.py)以 file_id、URL 或InputFile三种方式发出,注意 .OGG/OPUS、.MP3、.M4A 格式要求与 50 MB 上限;
  4. 复制:send_copy自动提取voice.file_id构造SendVoice(aiogram/types/message.py);
  5. 体验优化:配合ChatActionSender.record_voice/upload_voice(aiogram/utils/chat_action.py)提升上传过程的用户体验。

掌握这五个环节,即可在 aiogram 项目中完整、正确地实现语音消息的接收、识别、回复与转发功能。

  • 后端
  • 即时通讯
  • API设计

【免费下载链接】aiogram

aiogram is a modern and fully asynchronous framework for Telegram Bot API written in Python using asyncio

项目地址:https://gitcode.com/gh_mirrors/ai/aiogram
点击查看免费下载
上一篇:Pixie Stirling 深度解析:基于 eBPF 的 Kubernetes 节点级数据采集器架构与实战指南
下一篇:NYU-DLSP20 第10周实战指南:自监督学习(SSL)、对比学习与 Truck Backer-Upper 实践

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询