如何在aiogram中获取用户消息并赋值给变量用于后续处理
问题解决:aiogram中实现用户出生日期输入与后续交互
核心需求
在基于aiogram的Telegram机器人中完成以下流程:
- 引导用户输入出生日期
- 将用户输入的日期传入自定义函数计算结果
- 用计算结果作为图片列表索引,向用户发送对应图片
当前问题:无法将用户输入的消息赋值给变量用于后续计算,随机数方式可正常运行,但用户输入数据无法流转。
解决方案
1. 用状态机(FSM)管理交互流程
aiogram的FSM(有限状态机)可以跟踪用户当前的交互阶段,方便在不同步骤中接收、存储和调用用户输入的数据。
2. 可靠验证日期格式
替换原有的简单字符判断逻辑,使用datetime模块解析日期,确保输入格式符合DD/MM/YYYY规范,避免无效输入干扰后续计算。
3. 实现数据流转与计算
将用户输入的有效日期转换为可计算格式,传入自定义函数得到结果,再用结果索引图片列表发送对应图片。
修改后的完整代码示例
from aiogram import Bot, Dispatcher, types from aiogram.contrib.fsm_storage.memory import MemoryStorage from aiogram.dispatcher import FSMContext from aiogram.dispatcher.filters.state import State, StatesGroup from aiogram.types import InputFile from datetime import datetime # 初始化机器人与调度器,用内存存储状态 bot = Bot(token="你的机器人Token") storage = MemoryStorage() dp = Dispatcher(bot, storage=storage) # 定义状态机,标记用户当前交互阶段 class UserState(StatesGroup): waiting_for_birthdate = State() # 等待用户输入出生日期 text1 = "欢迎使用,请输入你的出生日期(格式:DD/MM/YYYY)" mainmenu = types.ReplyKeyboardMarkup(resize_keyboard=True) mainmenu.add(types.KeyboardButton("Begin")) # 示例图片列表,根据实际路径替换 img_list = ["img1.jpg", "img2.jpg", "img3.jpg", "img4.jpg"] # 自定义计算函数(可根据需求修改逻辑) def calculate_index(birthdate_list): result = 0 # 以日期的"日"部分为例进行计算 num = birthdate_list[0] while num != 0: result += num % 10 num = num // 10 # 确保结果在图片列表索引范围内 return result % len(img_list) @dp.message_handler(commands=['start']) async def begin(message: types.Message): await UserState.waiting_for_birthdate.set() # 设置状态为等待出生日期 await message.answer(text1) # 处理用户输入的出生日期 @dp.message_handler(state=UserState.waiting_for_birthdate) async def process_birthdate(message: types.Message, state: FSMContext): try: # 解析并验证日期格式 birthdate = datetime.strptime(message.text, "%d/%m/%Y") # 转换为[日, 月, 年]的整数列表 birthdate_list = [birthdate.day, birthdate.month, birthdate.year] # 将数据存入状态 await state.update_data(birthdate=birthdate_list) await message.answer("日期已保存,点击Begin获取对应图片", reply_markup=mainmenu) await state.finish() # 结束当前状态 except ValueError: await message.answer("格式错误,请输入正确的出生日期(如:11/11/2011)") # 处理Begin按钮点击事件 @dp.message_handler(lambda message: message.text == 'Begin') async def send_image(message: types.Message): # 取出用户存储的出生日期数据 user_data = await dp.current_state(user=message.from_user.id).get_data() birthdate_list = user_data.get("birthdate") if not birthdate_list: await message.answer("请先输入你的出生日期!") return # 计算图片索引并发送图片 result_index = calculate_index(birthdate_list) try: arkankart = InputFile(path_or_bytesio=img_list[result_index]) await message.answer_photo(photo=arkankart, caption='你的对应图片') except IndexError: await message.answer("计算结果超出图片列表范围,请检查计算函数") if __name__ == '__main__': from aiogram import executor executor.start_polling(dp, skip_updates=True)
关键说明
- 状态管理:通过
UserState标记用户是否已完成出生日期输入,确保数据能在后续步骤中被调用。 - 日期验证:用
datetime.strptime严格校验输入格式,避免无效数据进入计算环节。 - 数据流转:用户输入的日期通过
state.update_data存储,点击Begin按钮时通过get_data取出,传入计算函数得到有效索引。 - 索引安全:计算结果取模图片列表长度,避免出现索引越界错误。
内容的提问来源于stack exchange,提问作者Giyas
相关产品推荐
相关产品推荐

