Aiogram开发:如何获取按下内联按钮用户的用户名?
问题分析
你当前代码的核心问题有两个:
- 错误地直接调用
types.User.full_name类属性,而非获取触发回调的当前用户真实信息 - 使用函数默认参数存储课程报名状态,默认参数仅初始化一次,多用户操作会导致数据混乱且无法持久化
解决方案
1. 正确获取报名用户信息
回调查询对象call的from_user属性就是点击按钮的用户实例,直接通过它获取用户标识:
call.from_user.username:用户的Telegram用户名(可自行添加@前缀)call.from_user.full_name:用户的全名
2. 用全局字典维护报名数据
替换函数默认参数,用字典存储各时段的报名人员列表,方便后续更新和查询。
修改后的完整代码示例
from aiogram import Bot, Dispatcher, types from aiogram.utils import executor API_TOKEN = '你的Bot Token' bot = Bot(token=API_TOKEN) dp = Dispatcher(bot) # 初始化各时段报名列表,用字典统一管理 lesson_signups = { "09:30": [], "18:00": [], "19:00": [], "20:00": [] } # 构建内联键盘 keyboard_inline = types.InlineKeyboardMarkup(row_width=2) buttons = [types.InlineKeyboardButton(time, callback_data=time) for time in lesson_signups.keys()] keyboard_inline.add(*buttons) @dp.message_handler(commands=['lessons']) async def show_lessons(message: types.Message): # 动态生成初始课程消息文本 text = "Lessons\n\n" for time, signups in lesson_signups.items(): if signups: signup_list = "\n- ".join(signups) text += f"{time}\n- {signup_list}\n\n" else: text += f"{time}\n\n" await message.reply(text, reply_markup=keyboard_inline) @dp.callback_query_handler(text=list(lesson_signups.keys())) async def handle_signup(call: types.CallbackQuery): selected_time = call.data # 优先用用户名,无用户名则用全名 user_info = call.from_user.username or call.from_user.full_name # 避免重复报名 if user_info not in lesson_signups[selected_time]: lesson_signups[selected_time].append(user_info) # 重新生成更新后的消息文本 updated_text = "Lessons\n\n" for time, signups in lesson_signups.items(): if signups: signup_list = "\n- ".join(signups) updated_text += f"{time}\n- {signup_list}\n\n" else: updated_text += f"{time}\n\n" # 更新消息并保留内联键盘 await call.message.edit_text(updated_text, reply_markup=keyboard_inline) # 可选:给用户发送报名成功的提示 await call.answer(f"已成功报名{selected_time}时段课程") if __name__ == '__main__': executor.start_polling(dp, skip_updates=True)
关键改进说明
- 用
lesson_signups字典统一管理各时段报名数据,支持多用户并发操作 - 动态生成消息文本,避免固定字符串截取的维护隐患
- 增加重复报名判断,防止同一用户多次报名同一时段
- 正确获取点击按钮的用户信息,确保显示真实报名者
内容的提问来源于stack exchange,提问作者Matteo
相关产品推荐
相关产品推荐

