You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在aiogram中重置机器人状态?解决登录信息残留问题

问题分析

你的代码存在两个核心问题:

  1. 使用全局变量gets管理运行状态,会导致多用户冲突——一个用户点击「СТОП」会终止所有用户的循环任务。
  2. /start命令未实现状态重置逻辑,既没有终止用户之前的循环,也没有清空旧的user_login/user_password值,导致复用旧状态。

此外你尝试的状态管理(states)未正确落地,aiogram的FSM(有限状态机)是用来隔离每个用户独立状态的标准方案,下面是重构后的完整解决方案。

解决方案

1. 核心改造点

  • 用FSMContext替代全局变量,存储每个用户的独立状态和认证信息
  • 用任务字典跟踪每个用户的循环任务,确保/start能终止旧任务
  • 在/start中强制清空用户所有旧状态、终止旧循环、重置认证信息

2. 重构后的完整代码

import asyncio
from aiogram import Bot, Dispatcher, executor, types
from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.dispatcher import FSMContext

API_TOKEN = "你的API_TOKEN"
bot = Bot(token=API_TOKEN)
dp = Dispatcher(bot)

# 存储每个用户的循环任务,key为chat_id
user_tasks = {}

# 定义用户状态类
class UserState(StatesGroup):
    active = State()  # 标记用户是否处于运行状态
    login = State()   # 存储用户登录名
    password = State()# 存储用户密码

@dp.message_handler(commands=['start'])
async def start(message: types.Message, state: FSMContext):
    # 1. 终止用户之前的循环任务(如果存在)
    if message.chat.id in user_tasks:
        user_tasks[message.chat.id].cancel()
        del user_tasks[message.chat.id]
    
    # 2. 清空用户所有旧状态和认证信息
    await state.finish()
    await state.update_data(login=None, password=None)
    
    # 3. 初始化交互键盘
    keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
    keyboard.add(types.KeyboardButton(text="Да"))
    keyboard.add(types.KeyboardButton(text="Нет"))
    
    await message.answer("Привет! Я бот для площадки moodle.")
    await message.answer("Хотите начать работу с новым профилем?", reply_markup=keyboard)

@dp.message_handler(lambda message: message.text in ['Да', 'Нет'])
async def handle_response(message: types.Message, state: FSMContext):
    keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True)
    keyboard.add(types.KeyboardButton(text="СТОП"))

    if message.text == 'Да':
        await message.answer("Хорошо, начинаю работу. Если произойдёт ошибка, то нажми кнопку 'СТОП'.", reply_markup=keyboard)
        # 设置用户为活跃状态
        await UserState.active.set()
        # 启动循环任务并存储到字典
        task = asyncio.create_task(some_loop(message.chat.id, state))
        user_tasks[message.chat.id] = task
    elif message.text == 'Нет':
        await message.answer("Ну нет, так нет.", reply_markup=None)
        await state.finish()

@dp.message_handler(lambda message: message.text == 'СТОП', state=UserState.active)
async def stop_res(message: types.Message, state: FSMContext):
    # 终止循环任务
    if message.chat.id in user_tasks:
        user_tasks[message.chat.id].cancel()
        del user_tasks[message.chat.id]
    
    # 重置用户状态
    await state.finish()
    await message.answer("Бот остановлен. Используйте /start для перезапуска.", reply_markup=None)

async def some_loop(chat_id, state: FSMContext):
    counter = 0
    try:
        while True:
            # 检查用户状态是否仍为活跃
            current_state = await state.get_state()
            if current_state != UserState.active.state:
                break
            
            counter += 1
            # 获取当前用户的认证信息
            data = await state.get_data()
            user_login = data.get('login')
            user_password = data.get('password')
            
            # 若未设置认证信息,终止循环并提示
            if not user_login or not user_password:
                await bot.send_message(chat_id, "Ошибка: не найдены данные авторизации. Используйте /start для перезапуска.")
                break
            
            # 执行你的业务逻辑
            await bot.send_message(chat_id, response.resless())
            await asyncio.sleep(10)
    except asyncio.CancelledError:
        # 捕获任务取消异常,提示用户循环已终止
        await bot.send_message(chat_id, "Цикл работы остановлен.")

if __name__ == '__main__':
    executor.start_polling(dp, skip_updates=True)

3. 关键说明

  • 每个用户的状态和任务完全隔离,不会互相干扰
  • /start命令会强制重置所有旧状态,确保每次启动都是全新会话
  • 新增了认证信息的空值检查,避免调用response.get_profile时出现错误

内容的提问来源于stack exchange,提问作者ezios23

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 06:34:55