- 后端
- 即时通讯
- API设计
【免费下载链接】aiogram
aiogram is a modern and fully asynchronous framework for Telegram Bot API written in Python using asyncio
本文以 aiogram 仓库中 docs/api/types/inline_keyboard_button.rst 对应的类型对象为核心,系统讲解InlineKeyboardButton的全部字段、十四种交互行为(回调、URL、登录、Web App、切换 inline 模式、复制文本、支付等)以及与之配套的InlineKeyboardMarkup与InlineKeyboardBuilder用法。读完本文,你将能够准确选用每一种按钮类型,写出可运行、可维护的内联键盘代码,并理解 aiogram 底层对 callback_data 长度校验、按钮行宽限制等的实现原理。
一、InlineKeyboardButton 是什么
InlineKeyboardButton是 Telegram Bot API 中"内联键盘"(inline keyboard)的最小组成单元。与普通回复键盘(Reply Keyboard)不同,内联键盘直接附着在消息下方,随消息一起展示,无论用户位于私聊、群组还是频道中。
在 aiogram 中,它的模型定义位于 aiogram/types/inline_keyboard_button.py,继承自MutableTelegramObject(意味着构建后仍可通过属性赋值修改),并通过butcher工具自动生成类型友好的__init__签名,保证 IDE 补全与类型检查开箱即用:
class InlineKeyboardButton(MutableTelegramObject): text: str icon_custom_emoji_id: str | None = None style: str | None = None url: str | None = None callback_data: str | None = None web_app: WebAppInfo | None = None login_url: LoginUrl | None = None switch_inline_query: str | None = None switch_inline_query_current_chat: str | None = None switch_inline_query_chosen_chat: SwitchInlineQueryChosenChat | None = None copy_text: CopyTextButton | None = None callback_game: CallbackGame | None = None pay: bool | None = None disabled: DisabledButton | None = NoneTelegram 官方 API 对按钮有一条硬性约束:除了text、icon_custom_emoji_id和style之外,其余字段(动作字段)每次至多启用一个。一个按钮只能干一件事:要么回传 callback,要么打开链接,要么启动 Web App……不能同时配置多个动作。
二、字段全解:参数表与逐字段说明
下表汇总了InlineKeyboardButton的全部字段(以当前仓库源码为准):
| 字段 | 类型 | 必填 | 约束与说明 |
|---|---|---|---|
text | str | 是 | 按钮上显示的文本 |
icon_custom_emoji_id | str \| None | 否 | 文本前展示的自定义 emoji 唯一标识 |
style | str \| None | 否 | 按钮样式:danger(红)/success(绿)/primary(蓝);缺省时由 App 决定 |
url | str \| None | 否 | 点击打开的 HTTP 或tg://链接;tg://user?id=<id>可 @ 用户 |
callback_data | str \| None | 否 | 点击后回传给 Bot 的 callback query 数据,1–64 字节 |
web_app | WebAppInfo \| None | 否 | 点击启动的 Web App,仅限 Bot 与用户的私聊 |
login_url | LoginUrl \| None | 否 | 用于自动授权登录的 HTTPS URL |
switch_inline_query | str \| None | 否 | 提示用户选择一个会话并在输入框插入 bot 用户名与 inline query |
switch_inline_query_current_chat | str \| None | 否 | 在当前会话输入框插入 bot 用户名与 inline query |
switch_inline_query_chosen_chat | SwitchInlineQueryChosenChat \| None | 否 | 提示用户选择指定类型的会话后插入 inline query |
copy_text | CopyTextButton \| None | 否 | 点击即复制指定文本到剪贴板 |
callback_game | CallbackGame \| None | 否 | 点击启动游戏(占位对象) |
pay | bool \| None | 否 | 置True生成支付按钮;文本中的⭐与XTR会被替换为 Telegram Star 图标 |
disabled | DisabledButton \| None | 否 | 设置后按钮被禁用、点击无反应 |
下面按交互类型分组深入讲解。
1. 回传数据:callback_data
callback_data是最常用的动作字段。点击按钮后,Telegram 会向 Bot 发送一条CallbackQuery,携带该字符串。源码注释明确了长度边界:"1-64 bytes"。aiogram 在 aiogram/filters/callback_data.py 中定义了MAX_CALLBACK_LENGTH: int = 64,并在CallbackData.pack()中强制执行:
if len(callback_data.encode()) > MAX_CALLBACK_LENGTH: msg = ( f"Resulted callback data is too long! " f"len({callback_data!r}.encode()) > {MAX_CALLBACK_LENGTH}" ) raise ValueError(msg)因此,直接传裸字符串时若超过 64 字节,调用pack()或构建按钮时会抛出ValueError,避免把非法 payload 发给 Telegram。推荐做法是定义结构化回调:
from aiogram.filters.callback_data import CallbackData class ProductCallback(CallbackData, prefix="product", sep=":"): product_id: int action: str button = InlineKeyboardButton( text="查看详情", callback_data=ProductCallback(product_id=42, action="view").pack(), ) # 实际序列化为 "product:42:view"CallbackData要求子类必须声明prefix,默认分隔符为:,且校验「分隔符不能出现在 prefix 中」;支持int/str/float/bool/Enum/UUID/Decimal/Fraction等值的自动编码(bool会编码为0/1)。在unpack()时则会校验前缀与参数个数,CallbackData.unpack与CallbackDataException共同构成安全的双向编解码机制。
2. 打开链接:url
url接受 HTTP(S) 链接,也接受tg://协议链接。特殊用法tg://user?id=<user_id>可以在不提供用户名的情况下 @ 某位用户(受对方隐私设置约束)。它非常适合放置外部文档、帮助中心或商店链接。
3. 自动登录:login_url
login_url对应 aiogram/types/login_url.py 中的LoginUrl对象,是 Telegram Login Widget 在键盘场景下的替代方案:用户点击按钮并确认后即可完成登录,授权数据会以 query string 追加到 URL 上。其字段包括:
url(必填):HTTPS 地址;用户拒绝授权时打开不带用户信息的原始 URL;forward_text:消息被转发后按钮显示的新文本;bot_username:用于授权的 bot 用户名,须与url域名完成绑定,缺省取当前 bot;request_write_access:置True可请求 bot 向该用户发消息的权限。
4. 启动 Web App:web_app
web_app字段接收 aiogram/types/web_app_info.py 中的WebAppInfo(仅有必填字段url)。点击后会在 Telegram 内打开指定 HTTPS 地址的 Mini App。注意约束:仅可用于 Bot 与用户之间的私聊,且不支持以商业账户(business account)名义发送的消息。仓库示例 examples/web_app/handlers.py 展示了标准写法:
await message.answer( "Good. Now you can try to send it via Webview", reply_markup=InlineKeyboardMarkup( inline_keyboard=[ [ InlineKeyboardButton( text="Open Webview", web_app=WebAppInfo(url=f"{base_url}/demo"), ), ], ], ), )5. 切换到 inline 模式:switch_inline_query 系列
这三个字段用于把用户引导到内联模式(inline mode):
switch_inline_query:用户先选择目标会话,再在该会话输入框插入@bot_username 查询文本;字符串可为空(只插入 bot 用户名);switch_inline_query_current_chat:直接在当前会话输入框插入,无需选择会话;switch_inline_query_chosen_chat:对应 aiogram/types/switch_inline_query_chosen_chat.py 中的SwitchInlineQueryChosenChat,可限定可选会话类型:
InlineKeyboardButton( text="在群里搜索", switch_inline_query_chosen_chat=SwitchInlineQueryChosenChat( query="hello", allow_group_chats=True, allow_channel_chats=True, ), )SwitchInlineQueryChosenChat支持query(默认 inline query)、allow_user_chats、allow_bot_chats、allow_group_chats、allow_channel_chats五个布尔开关,全部可选。后两个字段同样不支持渠道 DM 与 business account 场景。
6. 复制文本:copy_text
copy_text接收 aiogram/types/copy_text_button.py 中的CopyTextButton,其唯一字段text为点击后写入剪贴板的内容,长度限制1–256 字符:
InlineKeyboardButton( text="复制邀请码", copy_text=CopyTextButton(text="WELCOME-2026"), )7. 游戏与支付:callback_game、pay
callback_game:对应 aiogram/types/callback_game.py 中的占位对象CallbackGame("currently holds no information"),游戏本体通过 @BotFather 配置;pay:置True生成支付按钮。若把按钮文本写成⭐ 购买或XTR 购买,Telegram 会自动把⭐与XTR替换成 Telegram Star 图标。
8. 禁用按钮:disabled
disabled对应 aiogram/types/disabled_button.py 中的DisabledButton(目前不携带任何信息),设置后按钮呈现为禁用态,点击无任何效果:
InlineKeyboardButton(text="稍后开放", disabled=DisabledButton())9. 视觉增强:style 与 icon_custom_emoji_id
style:取值为danger(红色)、success(绿色)、primary(蓝色)三者之一,缺省时由客户端应用自定样式。这在 tests/test_utils/test_keyboard.py 中被验证过:InlineKeyboardButton(text="test", style="primary", callback_data="callback")会被原样构建并导出;icon_custom_emoji_id:在按钮文本前展示自定义 emoji(Custom Emoji),仅对购买过 Fragment 额外用户名、或向拥有 Telegram Premium 订阅的私聊/群组/超级群组直接发送消息的 bot 可用。
三、组装键盘:InlineKeyboardMarkup 与行列结构
单个按钮必须放进 aiogram/types/inline_keyboard_markup.py 定义的InlineKeyboardMarkup中才能随消息发出。它的核心结构是二维数组:
class InlineKeyboardMarkup(MutableTelegramObject): inline_keyboard: list[list[InlineKeyboardButton]] force_reply: bool | None = Noneinline_keyboard的每一行是一个按钮列表,行内按钮最多8 个;force_reply置True可同时显示回复界面(编辑键盘时该值不可更改)。最朴素的写法:
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup markup = InlineKeyboardMarkup( inline_keyboard=[ [InlineKeyboardButton(text="上一页", callback_data="prev"), InlineKeyboardButton(text="下一页", callback_data="next")], [InlineKeyboardButton(text="打开官网", url="https://example.com")], ], )随后通过message.answer(..., reply_markup=markup)、bot.edit_message_reply_markup(...)(参见测试 tests/test_api/test_methods/test_edit_message_reply_markup.py)等方式发送或更新。仓库示例 examples/specify_updates.py 与 examples/scene.py 也都采用这种直接构造方式。
四、更高效的生产方式:InlineKeyboardBuilder
手写二维数组容易出错,aiogram 在 aiogram/utils/keyboard.py 提供InlineKeyboardBuilder,其行宽、按钮数上限由源码常量控制:
max_width = 8(每行最多 8 个按钮)min_width = 1max_buttons = 100(整个键盘最多 100 个按钮)
常用 API 一览:
| 方法 | 作用 |
|---|---|
button(**kwargs) | 添加一个按钮,kwargs 与InlineKeyboardButton字段一一对应 |
add(*buttons) | 追加按钮,自动填充最后一行,满了再开新行 |
row(*buttons, width=None) | 显式按行添加,超宽自动切行 |
adjust(*sizes, repeat=False) | 把已添加的按钮按指定尺寸重排;repeat=True循环套用 |
export() | 导出list[list[InlineKeyboardButton]](深拷贝) |
as_markup(**kwargs) | 直接产出InlineKeyboardMarkup |
attach(builder) | 合并另一个同类型 builder |
copy()/from_markup(markup) | 深拷贝 / 从现有 markup 恢复 builder |
典型用法:
from aiogram.utils.keyboard import InlineKeyboardBuilder builder = InlineKeyboardBuilder() builder.button(text="确认", callback_data="confirm") builder.button(text="取消", callback_data="cancel") builder.button(text="帮助", url="https://example.com/help") builder.adjust(2) # 前两个一行,剩余按钮一行 markup = builder.as_markup()builder.button()有个贴心细节:底层_button方法(aiogram/utils/keyboard.py)会检查callback_data是否为CallbackData实例,若是则自动调用pack()序列化,因此可以直接传结构化回调对象而无需手动 pack:
builder.button(text="打开", callback_data=ProductCallback(product_id=1, action="open"))该行为同样被 tests/test_utils/test_keyboard.py 验证:传入MyCallback(value="test")会导出为callback_data="test:test"的按钮。测试还覆盖了style="primary"、icon_custom_emoji_id组合构建等场景。
五、接收点击:处理 CallbackQuery
配合callback_data按钮,通常用 dispatcher 的CallbackQueryhandler 接收点击:
from aiogram import Router, F from aiogram.types import CallbackQuery router = Router() @router.callback_query(ProductCallback.filter(F.action == "view")) async def view_product(callback: CallbackQuery, callback_data: ProductCallback): await callback.answer() await callback.message.answer(f"产品 #{callback_data.product_id}")用CallbackData定义子类后,filter()与unpack()配合即可在 handler 中直接拿到类型化参数,避免手工split(":")解析字符串。
六、使用边界与注意事项小结
- 动作互斥:除
text、icon_custom_emoji_id、style外,每次只能设置一种动作字段; - callback_data 长度:1–64 字节,aiogram 在
CallbackData.pack()中会提前抛错(见 aiogram/filters/callback_data.py); - 行宽与总数:单行 ≤ 8,总按钮 ≤ 100(
InlineKeyboardBuilder常量);直接手写二维数组超出也不会报错,但 Telegram 端行为不可预期,建议始终走 builder; - 场景限制:
web_app仅限私聊;switch_inline_query/switch_inline_query_chosen_chat不支持渠道 DM 与 business account 消息;login_url不支持临时消息(ephemeral message); - 编辑键盘:
force_reply在键盘被编辑时不可变更;需要改键盘应使用edit_message_reply_markup等编辑方法。
掌握以上内容,你就能从零搭建从"回调分页"到"登录授权"再到"Web App 启动"的完整内联交互体系,并借助InlineKeyboardBuilder把键盘代码写得既紧凑又易于维护。
- 后端
- 即时通讯
- API设计
【免费下载链接】aiogram
aiogram is a modern and fully asynchronous framework for Telegram Bot API written in Python using asyncio
相关推荐
aiogram 内联键盘 InlineKeyboardMarkup 完全指南:数据结构、按钮类型与动态构建器实战
aiogram 内联键盘 InlineKeyboardMarkup 完全指南:数据结构、按钮类型与动态构建器实战 本文以 aiogram 3.x 仓库中 Inl
后端即时通讯API设计aiogram 内联结果类型 InlineQueryResultVenue 完全指南:字段、构造与实战示例
aiogram 内联结果类型 InlineQueryResultVenue 完全指南:字段、构造与实战示例 本文围绕 aiogram 中用于“地点/门店”类内联
后端即时通讯API设计aiogram LoginUrl 登录按钮指南:用内联键盘一键完成 Telegram 授权
aiogram LoginUrl 登录按钮指南:用内联键盘一键完成 Telegram 授权 LoginUrl 是 aiogram 框架中用于内联键盘登录按钮的类
后端即时通讯API设计
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考