RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1537674
Accepted
Colorado
Colorado
Asked:2023-08-26 03:42:13 +0000 UTC2023-08-26 03:42:13 +0000 UTC 2023-08-26 03:42:13 +0000 UTC

无法弄清楚“aiogram v3.x”中的“FSMContext”、“State”。编写一个注册系统

  • 772

由于我的“误解”,show_summary下面代码中的函数输出值不正确。以下是 ( ) 中的输出结果show_summary:

The following is a summary of the information you provided:
Student Name: (Parent) # Здесь по какой-то причине выводится/принимается первое значение (`Parent`) из первой в коде функции `command_start`, вместо `student_name`, следовательно, нарушается и остальная "последовательность".
Date of birth: (full name)
Parent's name: (YYYYY-MM-DD)
Parent's phone number: (full name of (parent))
Thank you for enrolling your child. You will receive further instructions.

括号中的内容是我在 Telegram 机器人中测试时手动输入的(用于演示目的)

消息/show_summary应该是这样的:

Here is the summary of the information you provided:
Student Name: (Student Name) # И так оно и должно быть по идеи.
Date of Birth: (Date of Birth)
Parent Name: (Parent Name)
Parent Phone: (Parent Phone)
Thank you for enrolling your child. You will receive further instructions.

这是完整的代码:

class Form(StatesGroup):
    select = State()
    student_name = State()
    student_dob = State()
    parent_name = State()
    parent_phone = State()
    finish = State()

@router.message(CommandStart())
async def command_start(message: Message, state: FSMContext) -> None:
    await state.set_state(Form.select)
    await message.answer(
        "Welcome! We are happy to welcome you to our bot. "
        "By continuing, you automatically agree to the terms of use and privacy policy. "
        "Are you a parent or a student?",
    reply_markup=ReplyKeyboardMarkup(
        keyboard=[
            [
                KeyboardButton(text="Parent"),
                KeyboardButton(text="Student")
            ]
        ],
        resize_keyboard=True,
        ),
    )

@router.message(Form.select, F.text.casefold() == "student")
async def student(message: Message, state: FSMContext) -> None:
    await state.clear()
    await message.answer(
        "Not bad not terrible.\nSee you soon.",
        reply_markup=ReplyKeyboardRemove(),
    )

@router.message(Form.select, F.text.casefold() == "parent")
async def student_name(message: Message, state: FSMContext) -> None:
    await state.update_data(student_name=message.text)
    await state.set_state(Form.student_dob)
    await message.reply(
        "Great! To enroll your child, please enter the student's full name:",
        reply_markup=ReplyKeyboardRemove(),
    )

@router.message(Form.student_dob)
async def student_dob(message: Message, state: FSMContext) -> None:
    await state.update_data(student_dob=message.text)
    await state.set_state(Form.parent_name)
    await message.reply(
        "Thank you! Please enter the student's date of birth (YYYYY-MM-DD).",
        reply_markup=ReplyKeyboardRemove(),
    )

@router.message(Form.parent_name)
async def parent_name(message: Message, state: FSMContext) -> None:
    await state.update_data(parent_name=message.text)
    await state.set_state(Form.parent_phone)
    await message.reply(
        "Please enter your full name (parent):",
        reply_markup=ReplyKeyboardRemove(),
    )

@router.message(Form.parent_phone)
async def parent_phone(message: Message, state:FSMContext) -> None:
    await state.update_data(parent_phone=message.text)
    await state.set_state(Form.finish)
    await message.reply(
        "Last step - enter your phone number (parent).",
        reply_markup=ReplyKeyboardRemove(),
    )

@router.message(Form.finish)
async def process_register(message: Message, state: FSMContext) -> None:
    data = await state.get_data()
    await state.clear()
    await message.answer(
        "Congratulations! You have successfully enrolled your child.",
        reply_markup=ReplyKeyboardRemove(),
    )
    await show_summary(message=message, data=data)

async def show_summary(message: Message, data: Dict[str, Any], positive: bool = True) -> None:
    student_name = data.get("student_name", "Unknown")
    student_dob = data.get("student_dob", "Unknown")
    parent_name = data.get("parent_name", "Unknown")
    parent_phone = data.get("parent_phone", "Unknown")
    
    summary_text = "Here is the summary of the information you provided:\n"
    summary_text += f"Student Name: {student_name}\n"
    summary_text += f"Date of Birth: {student_dob}\n"
    summary_text += f"Parent Name: {parent_name}\n"
    summary_text += f"Parent Phone: {parent_phone}\n"
    
    if positive:
        summary_text += "Thank you for enrolling your child. You will receive further instructions."
    else:
        summary_text += "We're sorry to hear that you encountered issues during the registration process."
    
    await message.answer(text=summary_text, reply_markup=ReplyKeyboardRemove())
telegram
  • 2 2 个回答
  • 22 Views

2 个回答

  • Voted
  1. Yellow Astronaut
    2023-08-26T08:54:32Z2023-08-26T08:54:32Z

    student_name()当用户按下按钮时,您的函数将被调用KeyboardButton(text="Parent"),因为相应的处理程序已分配给它:F.text.casefold() == "parent"。在同一个函数中,您将值写入 FSMContext student_name=message.text,这显然是“Parent”。在此函数中,将状态转换为Form.student_dob,但向用户写入“输入学生的全名:”,但混乱仍然存在。

    вам нужно в этой же функции перевести стейт в Form.student_name, и что бы такой стейт был обьявлен у класса Form, убрать из этой функции сохранение значений в стейт. и добавить еще одну функцию, которая будет ловить текст при состоянии Form.student_name

    • 1
  2. Best Answer
    Colorado
    2023-08-28T03:31:42Z2023-08-28T03:31:42Z

    Для "понимания" мне потребовалось упростить свой код, и вот каких результов я добился, когда по концу в Telegram боте можно наблюдать сообщение:

    {
    'student_name': 'мое первое написанное/принимаемое сообщение',
    'student_dob': 'мое второе написанное/принимаемое сообщение'
    } 
    

    Далее собираюсь на основе этого писать другую последовательно-выстроенную архитектуру/логику FSMContext с регистрацией.

    Вот full-code для вашего собственного тестирования. Мне помогла статья: https://mastergroosha.github.io/aiogram-3-guide/fsm/, а так же спасибо всем кто пытался объяснить словами, на словах я не очень понимаю (начинающий)

    import asyncio
    import logging
    import sys
    from typing import Any, Dict
    
    from aiogram import Bot, Dispatcher, F, Router, html
    from aiogram.enums import ParseMode
    from aiogram.filters import CommandStart
    from aiogram.fsm.context import FSMContext
    from aiogram.fsm.state import State, StatesGroup
    from aiogram.types import Message, ReplyKeyboardMarkup, KeyboardButton, ReplyKeyboardRemove
    from aiogram import Bot, Dispatcher
    from aiogram.fsm.storage.memory import MemoryStorage
    
    from config import BOT_TOKEN
    
    router = Router()
    
    bot = Bot(token=BOT_TOKEN)
    dp = Dispatcher()
    
    # Класс "Form" для хранения состояний и так далее.
    class Form(StatesGroup):
        student_name = State()
        student_dob = State()
    
    # Обработчик "1-го шага" и так далее.
    @router.message(CommandStart())
    async def command_start(message: Message, state: FSMContext):
        await message.answer(
            text="Напишите ваше ФИО:",
            reply_markup=ReplyKeyboardRemove()
        )
        # Устанавливаем пользователю состояние "пишет своё ФИО" 
        # и/или
        # Переводим пользователя в состояние `Form.student_name`.
        await state.set_state(Form.student_name)
    
    # Следующий обработчик и так далее.
    @router.message(Form.student_name)
    async def student_name(message: Message, state: FSMContext):
        await state.update_data(student_name=message.text)
        await message.answer(
            text="Спасибо. Теперь, пожалуйста, напишите ваш возраст:", 
            reply_markup=ReplyKeyboardRemove()
        )
        # Переводим пользователя в состояние `Form.student_dob`.
        await state.set_state(Form.student_dob)
    
    # Cледующий обработчик и так далее.
    @router.message(Form.student_dob)
    async def student_dob(message: Message, state: FSMContext):
        await state.update_data(student_dob=message.text)
        user_data = await state.get_data()
        await message.answer(
            text=f"{user_data}",
            reply_markup=ReplyKeyboardRemove()
        )
        await state.clear()
    
    async def main():
        bot = Bot(token=BOT_TOKEN, parse_mode=ParseMode.HTML)
        dp = Dispatcher()
        dp.include_router(router)
        await dp.start_polling(bot)
    
    if __name__ == '__main__':
        logging.basicConfig(level=logging.INFO, stream=sys.stdout)
        try:
            asyncio.run(main())
        except (KeyboardInterrupt, SystemExit):
            logging.info("Bot stopped!")
    
    • 0

相关问题

  • 是否可以让机器人识别电报中的组 ID?

  • Telegram bot 的内联模式下相同的 randint 值

  • 如何找出电报用户ID

  • 链接到电报频道绕过阻塞而不使用服务

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