Python电报API如何使用ForceReply?

2024-04-19 16:04:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我希望有一个python中的小电报机器人,其中一个命令由用户发出,机器人询问一个问题并根据答案做出反应。官方电报API提到可以使用ForceReply()实现这一点,例如,要逐步创建轮询,请参见此处Official Telegram API # ForceReply

我编写了以下代码:

def test_function(update: Update, context: CallbackContext) -> None:
    msg = context.bot.send_message(chat_id=update.message.chat_id, 
                                   text="Please enter some text.",
                                   reply_markup=telegram.ForceReply(True))

if __name__ == '__main__':
    dispatcher.add_handler(CommandHandler("test", test_function))
    updater.start_polling()
    updater.idle()

因此,当用户发出/test时,他被要求输入一些文本,并且由于ForceReply(True),用户被迫回复消息。但是,如何获得此回复的结果,即用户回复的文本?API文档中没有任何提示,我也花了一些时间在互联网上搜索,但没有找到任何东西。因此,答案很可能是简单明了的,但我现在还不明白

感谢您的任何帮助


Tags: 答案text用户testapiidtruemessage
1条回答
网友
1楼 · 发布于 2024-04-19 16:04:03

aiogram框架已经解决了您的任务

每一步都是用户的状态

它被称为FSMfinite state machine

你甚至不需要对ForceReply做什么

示例

import logging

import aiogram.utils.markdown as md
from aiogram import Bot, Dispatcher, types
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters import Text
from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.types import ParseMode
from aiogram.utils import executor


bot = Bot(token='your:token')


storage = MemoryStorage()  # external storage is supported!
dp = Dispatcher(bot, storage=storage)


# Defining available states
class Form(StatesGroup):
    name = State()
    age = State()
    gender = State()


@dp.message_handler(commands='start')
async def cmd_start(message: types.Message):
    """
    Conversation's entry point
    """
    # Set state
    await Form.name.set()
    
    await message.reply("Hi there! What's your name?")


# You can use state '*' if you need to handle all states
@dp.message_handler(state='*', commands='cancel')
@dp.message_handler(Text(equals='cancel', ignore_case=True), state='*')
async def cancel_handler(message: types.Message, state: FSMContext):
    """
    Allow user to cancel any action
    """
    current_state = await state.get_state()
    if current_state is None:
        return

    # Cancel state and inform user about it
    await state.finish()
    # And remove keyboard (just in case)
    await message.reply('Cancelled.', reply_markup=types.ReplyKeyboardRemove())


@dp.message_handler(state=Form.name)
async def process_name(message: types.Message, state: FSMContext):
    """
    Process user name
    """
    async with state.proxy() as data:
        data['name'] = message.text

    await Form.next()
    await message.reply("How old are you?")


# Check age. Age gotta be digit
@dp.message_handler(lambda message: not message.text.isdigit(), state=Form.age)
async def process_age_invalid(message: types.Message):
    """
    If age is invalid
    """
    return await message.reply("Age gotta be a number.\nHow old are you? (digits only)")


@dp.message_handler(lambda message: message.text.isdigit(), state=Form.age)
async def process_age(message: types.Message, state: FSMContext):
    # Update state and data
    await Form.next()
    await state.update_data(age=int(message.text))

    # Configure ReplyKeyboardMarkup
    markup = types.ReplyKeyboardMarkup(resize_keyboard=True, selective=True)
    markup.add("Male", "Female")
    markup.add("Other")

    await message.reply("What is your gender?", reply_markup=markup)


@dp.message_handler(lambda message: message.text not in ["Male", "Female", "Other"], state=Form.gender)
async def process_gender_invalid(message: types.Message):
    """
    In this example gender has to be one of: Male, Female, Other.
    """
    return await message.reply("Bad gender name. Choose your gender from the keyboard.")


@dp.message_handler(state=Form.gender)
async def process_gender(message: types.Message, state: FSMContext):
    async with state.proxy() as data:
        data['gender'] = message.text

        # Remove keyboard
        markup = types.ReplyKeyboardRemove()

        # And send message
        await bot.send_message(
            message.chat.id,
            md.text(
                md.text('Hi! Nice to meet you,', md.bold(data['name'])),
                md.text('Age:', md.code(data['age'])),
                md.text('Gender:', data['gender']),
                sep='\n',
            ),
            reply_markup=markup,
            parse_mode=ParseMode.MARKDOWN,
        )

    # Finish conversation
    await state.finish()


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

相关问题 更多 >