news 2026/10/22 15:58:44

aiogram 富文本类型 RichTextEmailAddress 详解:邮箱地址节点的字段、判别联合与消息发送实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
aiogram 富文本类型 RichTextEmailAddress 详解:邮箱地址节点的字段、判别联合与消息发送实战
  • 后端
  • 即时通讯
  • 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
点击查看免费下载

RichTextEmailAddress 是 aiogram 中用于表示"带有邮箱地址的富文本"的核心类型节点,它隶属于 Telegram Bot API 的 Rich Text(富文本消息)体系,服务于sendRichMessage等新一代富消息发送接口。本文以 RichTextEmailAddress API 文档 为主线,结合 类型源码、判别联合实现 与 回归测试,讲解该节点的字段语义、在RichTextUnion中的反序列化机制,以及如何在实际 bot 中构造并发送包含邮箱地址的富文本消息。

一、文档与源码定位:一个 autodoc 驱动的类型页

docs/api/types/rich_text_email_address.rst是 aiogram 文档站中该类型的唯一入口,其内容非常精简,仅包含标题与一段 Sphinxautomodule指令:

#################### RichTextEmailAddress #################### .. automodule:: aiogram.types.rich_text_email_address :members: :member-order: bysource :undoc-members: True :exclude-members: model_config,model_fields

这说明该文档页是完全由源码 docstring 与类型注解自动生成的:automodule从 aiogram/types/rich_text_email_address.py 拉取类定义、字段与构造函数签名,member-order: bysource按源码顺序排列成员,undoc-members: True保证未写 docstring 的成员也会被收录,而model_config、model_fields两个 Pydantic 内部属性被排除在文档之外。因此,要完整理解该类型,必须直接阅读其源码实现——这正是本文展开的核心依据。

二、类定义与字段语义

RichTextEmailAddress定义在 aiogram/types/rich_text_email_address.py,继承自RichText(即 aiogram/types/rich_text.py 中的RichText基类),本质是一个基于 PydanticBaseModel的 Telegram API 对象模型。其官方语义为:"A text with an email address."(一段带邮箱地址的文本)。

类中共有三个字段:

字段类型必填语义
typeLiteral[RichTextType.EMAIL_ADDRESS]否(有默认值)富文本类型,固定为'email_address',由 RichTextType 枚举 中的EMAIL_ADDRESS = "email_address"提供
textRichTextUnion是该节点承载的文本内容
email_addressstr是关联的邮箱地址字符串

其中type被声明为Literal[RichTextType.EMAIL_ADDRESS] = RichTextType.EMAIL_ADDRESS,即它是一个常量标签字段,构造时无需(也不应)手动指定。text的类型是RichTextUnion,这是一个非常关键的联合类型,下文单独展开。

源码在TYPE_CHECKING块中还提供了由butcher工具自动生成的__init__签名,它不参与运行时逻辑,仅用于让 IDE 与静态类型检查器在没有 Pydantic 插件的情况下也能获得完整的构造提示:

def __init__( __pydantic__self__, *, type: Literal[RichTextType.EMAIL_ADDRESS] = RichTextType.EMAIL_ADDRESS, text: RichTextUnion, email_address: str, **__pydantic_kwargs: Any, ) -> None: super().__init__(type=type, text=text, email_address=email_address, **__pydantic_kwargs)

2.1 基类链路:TelegramObject → RichText

类型继承链为RichTextEmailAddress→RichText→TelegramObject。RichText本身只承载一段说明性 docstring,列举了当前全部 25 种富文本子类型(Bold、Italic、Underline、Strikethrough、Spoiler、DateTime、TextMention、Subscript、Superscript、Marked、Code、CustomEmoji、MathematicalExpression、Url、EmailAddress、PhoneNumber、BankCardNumber、Mention、Hashtag、Cashtag、BotCommand、Button、Anchor、AnchorLink、Reference、ReferenceLink),见 aiogram/types/rich_text.py。

真正提供数据能力的是TelegramObject(aiogram/types/base.py),它配置了 Pydantic 的关键行为:

  • use_enum_values=True:枚举字段(包括type)在序列化时直接使用枚举的字符串值,因此发送给 Telegram 时type就是"email_address";
  • frozen=True:模型不可变,实例构造后字段只读;
  • extra="allow":允许额外字段,对 Telegram 侧新增字段保持向前兼容;
  • validate_assignment=True:赋值时同样触发校验;
  • defer_build=True:延迟构建模型,配合递归联合类型(如RichTextUnion)使用。

三、text字段与 RichTextUnion 判别联合

RichTextUnion定义在 aiogram/types/rich_text_union.py,它是 aiogram 富文本体系中最重要的类型之一,其类型别名可归纳为三类合法取值:

  1. 纯字符串:如"hello@example.com",表示普通文本;
  2. 字符串/节点的数组:如["a", RichTextBold(text="b")],表示一组依次渲染的子片段;
  3. 任意一种RichText*模型:包括RichTextBold、RichTextItalic、RichTextSpoiler、RichTextUrl、RichTextEmailAddress等 25 个具体子类。

由于联合成员既包含str、list这样的 Python 原生类型,又包含以type字段区分的 Pydantic 模型,它不能像普通 Telegram 联合类型那样直接使用Field(discriminator="type")。aiogram 的解决方案是自定义一个运行时判别函数_rich_text_union_tag:

def _rich_text_union_tag(value: Any) -> Any: if isinstance(value, str): return "str" if isinstance(value, (list, tuple)): return "list" if isinstance(value, dict): return value.get("type") return getattr(value, "type", None)

即:字符串按其 Python 类型打"str"标签,数组打"list"标签,字典与模型实例则读取其type字段(如"email_address")作为标签。最终通过TypeAliasType与Annotated/Tag/Discriminator组合成一个以type为判别键的判别联合。

3.1 为什么需要判别联合:回归测试 #1925

CHANGES/1925.bugfix.rst 记录了一次重要修复:此前RichTextUnion是一个普通的智能联合,Pydantic 会在每一层嵌套上逐个尝试所有成员,导致"加粗套斜体套剧透"这类多层嵌套富文本的校验呈指数级变慢,甚至冻结事件循环。修复后改为按type判别的联合,回归测试 中用一个 5 层嵌套的更新负载验证了每个节点都能正确解析为具体类型,并用 POSIX 的SIGALRM计时器断言:30 层嵌套的RichTextUnion校验耗时小于 1 秒(超过 5 秒即判定回归)。

这对使用者的实际意义是:RichTextEmailAddress作为RichTextUnion的成员之一,可以放心地与RichTextBold、RichTextItalic等节点无限嵌套组合,而不会遭遇解析性能陷阱。

四、从节点到消息:构造带邮箱地址的富文本

RichTextEmailAddress不会独立出现,它总是被嵌套在富消息(Rich Message)结构中。发送富消息使用SendRichMessage方法(aiogram/methods/send_rich_message.py),其 API 方法名为sendRichMessage,核心参数为chat_id与rich_message(类型为InputRichMessage)。

InputRichMessage(aiogram/types/input_rich_message.py)提供三种互斥的内容描述方式:html、markdown或blocks。其中blocks是结构化方式——一个InputRichBlockUnion列表,每个块可以是段落(InputRichBlockParagraph)、标题、引用、表格等(完整清单见 aiogram/types/input_rich_block.py)。而段落块的text字段正是RichTextUnion,邮箱地址节点就挂在这里。

以下示例构造一条"正文 + 可点击邮箱地址"的富消息并通过send_rich_message发送:

from aiogram import Bot from aiogram.types import ( InputRichBlockParagraph, InputRichMessage, RichText, RichTextEmailAddress, ) bot = Bot("TOKEN") await bot.send_rich_message( chat_id=chat_id, rich_message=InputRichMessage( blocks=[ InputRichBlockParagraph( text=RichText( [ "欢迎来信:", RichTextEmailAddress( text="contact@example.com", email_address="contact@example.com", ), ] ) ) ] ), )

关键点说明:

  • RichText与RichTextEmailAddress同为RichTextUnion的合法成员,可直接混用;
  • text字段是"用户看到的渲染文本",email_address是"被识别并关联的邮箱地址",两者既可以相同(如上例),也可以不同,例如显示"联系我们"而关联真实邮箱;
  • type字段无需传参,默认即为"email_address";
  • 若消息同时包含媒体块,bot 需具备对应媒体的发送权限(见SendRichMessagedocstring)。

InputRichMessage还支持is_rtl(从右到左渲染)与skip_entity_detection(跳过 URL、邮箱、@用户名、话题标签等实体的自动识别),后者对显式构造的富文本节点没有影响。

五、与相近类型的对比:Url、PhoneNumber、BankCardNumber

RichTextEmailAddress在结构上与其"姐妹节点"高度相似,它们共享完全相同的字段布局:一个固定的type常量 + 一个text: RichTextUnion+ 一个专用承载字段。以 RichTextUrl 与 RichTextPhoneNumber 为例:

类型type 常量承载字段字段语义
RichTextUrl'url'url: str链接地址
RichTextEmailAddress'email_address'email_address: str邮箱地址
RichTextPhoneNumber'phone_number'phone_number: str电话号码

同样模式的还有RichTextBankCardNumber(银行卡号)、RichTextHashtag、RichTextCashtag、RichTextBotCommand、RichTextMention等。理解这一点后,掌握其中一个节点即可触类旁通地使用整个"实体型富文本"家族。

六、使用建议与注意事项

  • 序列化形态:由于use_enum_values=True,RichTextEmailAddress序列化后为{"type": "email_address", "text": ..., "email_address": ...},与 Telegram Bot API 的RichTextEmailAddress定义(https://core.telegram.org/bots/api#richtextemailaddress)保持一致;
  • 嵌套自由:text可以继续嵌套其他富文本节点,例如让邮箱地址局部加粗:RichTextEmailAddress(text=[RichTextBold(text="me@example.com")], email_address="me@example.com"),性能已由判别联合机制保证;
  • 只读模型:TelegramObject默认frozen=True,构造后不能修改字段,需要变更时请重新构造实例;
  • 文档查阅方式:本类型的正式 API 文档由 docs/api/types/rich_text_email_address.rst 提供,它是整个 docs/api/types 目录下 638 个 API 页面之一,体系中的其他富文本节点文档位于同目录,例如 rich_text.rst、rich_text_url.rst、input_rich_message.rst,发送方法见 send_rich_message.rst。

七、小结

RichTextEmailAddress是 aiogram 富文本消息体系中的一个"小而专"的实体节点:三个字段、一个固定类型常量、一套统一基类。它的真正复杂性体现在两点——其text字段所指向的RichTextUnion判别联合(及其防指数级退化的回归测试),以及它作为InputRichMessage.blocks结构化内容的一环如何参与sendRichMessage的实际发送。理解这两个层面,即可在 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
点击查看免费下载

相关推荐

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/22 12:38:13

COMSOL激光选区熔化仿真:温度场与应力场耦合的避坑指南

简介:该资源为COMSOL 6.1版本激光选区融化(SLM)仿真模型,面向增材制造、固体力学与热固耦合方向的研究人员及工程技术人员,用于复现单道与多道SLM成形过程中的温度场与应力场演化,并支持活化、圆柱形增材等…

作者头像 李华
网站建设 2026/10/22 15:58:33

栈与队列经典应用:括号匹配与表达式求值详解

1. 栈与队列的底层逻辑:为什么这两个问题是经典入门题先聊点背景。刚接触数据结构时,很多人会有一个困惑:栈和队列不就是两个很简单的线性结构吗?一个后进先出,一个先进先出,规则几句话就讲完了&#xff0c…

作者头像 李华
网站建设 2026/10/22 10:22:31

基于麻雀搜索算法优化LSSVM的回归预测

我注意到你还没有提供具体的项目信息。为了让我为你生成一篇贴合实际、高质量的博文,请按以下格式补充内容:项目标题:(必填,例如“基于麻雀搜索算法优化LSSVM的回归预测”这类主题)项目正文:&am…

作者头像 李华
网站建设 2026/10/18 14:20:48

IDA Pro实战:从反汇编到异或密钥还原的完整流程

简介:面向网络安全初学者与逆向工程入门者的IDA Pro反汇编工具实战资料,源于作者系统的网络安全自学笔记,重点讲解IDA Pro的安装与界面组成、PE文件装载分析,并结合具体CrackMe程序演示代码加密与逆向解密流程。资源为单个PDF文档…

作者头像 李华
网站建设 2026/10/22 13:09:44

一文讲透|2026年性价比拉满的专业一键生成论文工具

2026年AI论文写作工具已从“基础生成”升级为融合智能分析与学术合规的全流程解决方案,核心评价维度涵盖文献真实性、格式合规性、长文本逻辑、查重降重、AIGC合规等关键指标。本次测评覆盖6款主流工具,涵盖中英文、全流程与专项功能、免费与付费版本&am…

作者头像 李华