RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1412140
Accepted
Skyman2413
Skyman2413
Asked:2022-07-21 04:05:57 +0000 UTC2022-07-21 04:05:57 +0000 UTC 2022-07-21 04:05:57 +0000 UTC

在 pethon + aiogram bot 中等待用户响应

  • 772

我正在尝试制作一个对用户进行测试的机器人。为了不做很多状态,我尝试循环出问题,但机器人一次发送所有问题。如何让机器人等待用户对每个响应的响应,而不为每个响应附加状态。我希望有办法...

class dialog(StatesGroup):
    name = State()
    victorina = State()

# тут стартует викторина
@dp.message_handler(state=dialog.name, content_types=['text'])
async def take_name_and_start_questions(msg: types.Message, state: FSMContext):
    await dialog.victorina.set()
    async with state.proxy() as data:
        data['answers'] = []
    await state.update_data(name=msg.text)
    for questions in replies.q:
        kb = create_kb(len(questions['a']))
        text = questions['q'] + "\n"
        i = 1
        for ans in questions['a']:
            text += f'{i}) {ans} \n'
            i += 1
        await msg.answer(text, reply_markup=kb)

# тут должны обрабатываться ответы
@dp.message_handler(state=dialog.victorina, content_types=['text'])
async def save_answer(msg: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['answers'].add(int(msg.text))

# создание клавиатуры с ответами 1-2-3 в зависимости от их числа
def create_kb(cnt: int):
    kb = ReplyKeyboardMarkup()
    for but in range(1, cnt):
        b = KeyboardButton(but)
        kb.add(b)
    return kb
python aiogram
  • 2 2 个回答
  • 219 Views

2 个回答

  • Voted
  1. Best Answer
    oleksandrigo
    2022-07-23T23:28:58Z2022-07-23T23:28:58Z

    您可以将问题计数器推入状态。也就是说,您将写入和读取问题编号的某个变量签入状态数据。好吧,既然你给猫的代码哭了,我就让它有点不同

    from aiogram import Bot, Dispatcher, executor, 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 ReplyKeyboardMarkup, KeyboardButton, ReplyKeyboardRemove
    
    from data import config
    
    bot = Bot(token=config.BOT_TOKEN)
    storage = MemoryStorage()
    dp = Dispatcher(bot, storage=storage)
    
    questions = {
        "вопрос 1": [
            "ответ 1",
            "ответ 2",
            "ответ 3",
        ],
        "вопрос 2": [
            "ответ 1",
            "ответ 2",
            "ответ 3",
        ],
        "вопрос 3": [
            "ответ 1",
            "ответ 2",
            "ответ 3",
        ]
    }
    
    
    class Dialog(StatesGroup):
        name = State()
        victorina = State()
    
    
    @dp.message_handler(commands="start")
    async def start(msg: types.Message):
        await Dialog.name.set()
    
    
    @dp.message_handler(state=Dialog.name)
    async def take_name_and_start_questions(msg: types.Message, state: FSMContext):
        async with state.proxy() as data:
            data['answers'] = []
            data['cur_question'] = 1
            data['name'] = msg.text
    
            for i, question in enumerate(questions):
                # тут выводим только первый вопрос
                if i != 0:
                    break
                answers = questions[question]
                kb = create_kb(len(answers))
                text = question + "\n"
                for j, answer in enumerate(answers):
                    text += f'{j + 1}) {answer} \n'
    
            await msg.answer(text, reply_markup=kb)
    
        await Dialog.victorina.set()
    
    
    # тут должны обрабатываться ответы
    @dp.message_handler(state=Dialog.victorina)
    async def save_answer(msg: types.Message, state: FSMContext):
        # добавляем ответ в массив
        async with state.proxy() as data:
            data['answers'].append(int(msg.text))
    
            # ну и выводим некст вопрос
            for i, question in enumerate(questions):
                # выводит только след вопрос
                if i == data['cur_question']:
                    kb = create_kb(len(questions[question]))
                    text = question + "\n"
                    for j, answer in enumerate(questions[question]):
                        text += f'{i}) {answer} \n'
                    # ну и чтобы зря не работал for брейкаем его
                    break
            # делаем сразу некст вопрос
            data['cur_question'] += 1
        # ну и если вопросы кончились то никакого text ни kb не будет делаем проверку
        if text:
            await msg.answer(text, reply_markup=kb)
        else:
            # собственно если нету то удалаем клавиатуру и пишем что-то
            await msg.answer("конец викторины", reply_markup=ReplyKeyboardRemove())
            # а также в зависимости как вы работаете с стейтом делате или 
            await state.finish()
            # или удаляете переменные в стейт ручками по типу
            del data['answers']  
            # и тд... Ну и само собой не забудьте забрать нужные вам данные до их удаление. Тобишь выше но в блоке елс   
    
    
    # создание клавиатуры с ответами 1-2-3 в зависимости от их числа
    def create_kb(count: int):
        kb = ReplyKeyboardMarkup()
        for num in range(1, count + 1):
            button = KeyboardButton(text=f"{num}")
            kb.add(button)
        return kb
    
    
    if __name__ == '__main__':
        executor.start_polling(dp, skip_updates=True)
    

    一般来说,我不明白你为什么决定使用键盘按钮,而不是内联,这样会更方便,而且不必用 message_handlers 弄乱你的机器人。

    这是代码如何工作的示例 例子

    • 0
  2. Danil Maltsev
    2022-07-23T22:03:44Z2022-07-23T22:03:44Z

    尝试导入时间。并使用 time.sleep() 方法,设置发送每个问题的时间。

    • -1

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5