使用Aiogram开发Telegram Bot时无法获取用户输入的问题
问题分析与解决方案
你的问题核心在于Aiogram的处理器匹配逻辑,以及可能的版本适配问题,以下分两种情况给出解决方案:
情况1:使用Aiogram v2版本
问题原因
- 处理器按注册顺序匹配:当用户发送
start时,第一个处理器的条件满足,消息会被该处理器处理,默认不会继续传递给后续处理器(这是正常行为)。但如果用户发送其他文本(比如名字)时get_user_input仍未触发,可能是代码缺少启动polling的逻辑,或者你需要会话式的状态管理来捕获start后的输入。 - 全局处理器无法区分会话阶段:你的
get_user_input是全局匹配任意文本,但如果没有状态控制,它会匹配所有文本(包括start),但因为第一个处理器先匹配了start,所以不会触发它。而你期望的是start命令后,后续输入被get_user_input捕获,这需要用状态机(FSM)实现。
解决方案
1. 确保添加启动polling的代码
在代码末尾添加:
if __name__ == '__main__': from aiogram.utils import executor executor.start_polling(dp, skip_updates=True)
2. 使用FSM实现会话式输入捕获
如果需要在用户发送start后,专门捕获后续的名字输入,引入状态机:
from aiogram import Bot, Dispatcher, types from aiogram.types import Message from aiogram.dispatcher.filters.state import State, StatesGroup from aiogram.dispatcher import FSMContext API_TOKEN = '' bot = Bot(token=API_TOKEN) dp = Dispatcher(bot) # 定义会话状态 class UserForm(StatesGroup): waiting_for_name = State() @dp.message_handler(lambda message: message.text.lower() == 'start') async def start(message: Message): # 切换到等待名字的状态 await UserForm.waiting_for_name.set() await message.answer("Enter your name: ") # 仅当处于等待名字状态时,触发该处理器 @dp.message_handler(state=UserForm.waiting_for_name) async def get_user_input(message: Message, state: FSMContext): user_input = message.text await message.answer(f"Thanks, {user_input}! You've entered your name. Proceed setting a password...") # 结束当前状态 await state.finish() # 启动polling if __name__ == '__main__': from aiogram.utils import executor executor.start_polling(dp, skip_updates=True)
情况2:使用Aiogram v3版本
问题原因
Aiogram v3已移除message_handler装饰器,改用dp.message()装饰器,且Dispatcher初始化方式不同。你的代码是v2的写法,导致get_user_input处理器未被正确注册。
解决方案
修改为v3的标准写法:
from aiogram import Bot, Dispatcher, types from aiogram.types import Message from aiogram.filters import Text from aiogram.fsm.state import State, StatesGroup from aiogram.fsm.context import FSMContext API_TOKEN = '' bot = Bot(token=API_TOKEN) dp = Dispatcher() class UserForm(StatesGroup): waiting_for_name = State() @dp.message(Text(text='start', ignore_case=True)) async def start(message: Message, state: FSMContext): await state.set_state(UserForm.waiting_for_name) await message.answer("Enter your name: ") @dp.message(UserForm.waiting_for_name) async def get_user_input(message: Message, state: FSMContext): user_input = message.text await message.answer(f"Thanks, {user_input}! You've entered your name. Proceed setting a password...") await state.clear() if __name__ == '__main__': import asyncio asyncio.run(dp.start_polling(bot))
内容的提问来源于stack exchange,提问作者localboy
相关产品推荐
相关产品推荐

