似乎找不到让我的 Telegram Bot 等待用户输入的方法

Can't seem to find a way to make my Telegram Bot wait for user input

我正在尝试制作一个从天才 API 那里获取歌词的电报机器人。 当机器人询问艺术家时,它会立即发送歌曲标题的问题,但我正在尝试让机器人像 python.

中的 input() 命令一样工作

我知道我可以让用户在艺术家和歌曲标题之间用逗号分隔字符串,但这是不得已的选择。

这是我正在谈论的代码。

def lyrics(update: Update, context: CallbackContext) -> None:
    update.message.reply_text("Enter artist")
    artist_name = update.message.text
    artist = genius.search_artist(artist_name, max_songs=0)
    update.message.reply_text("Enter song title")
    song_name = update.message.text
    song = artist.song(song_name)
    update.message.reply_text(song.lyrics)

还有一个没有歌词的例子

update.message.reply_text("Reply something")
reply = update.message.text
update.message.reply_text("2nd answer")
reply2 = update.message.text

您可能正在寻找可以处理对话的 ConversationHandler

准备

首先,我们需要导入以下模块并定义 Dispatcher,它会获取您的机器人的所有处理程序。

from telegram import Update
from telegram.ext import (
    Updater,
    Filters,
    CommandHandler,
    MessageHandler,
    ConversationHandler,
    CallbackContext
)

updater = Updater('your token here', use_context=True)

dispatcher = updater.dispatcher

对话处理程序

然后,我们使用 dispatcher.add_handler 将对话处理程序附加到调度程序。 您可以指定如下状态并定义对话处理程序。

注意状态必须是int,为了便于阅读,我们为不同的状态定义常量ARTISTTITLE

有关过滤器的更多信息,请查看文档 here。我们这里只需要 Filters.text 因为我们只将文本作为 MessageHandler.

的输入
ARTIST, TITLE = 0, 1
dispatcher.add_handler(ConversationHandler(
    entry_points=[CommandHandler('start', intro)],
    states={
        ARTIST: [MessageHandler(Filters.text, callback=artist)],
        TITLE: [MessageHandler(Filters.text, callback=title)]
    },
    fallbacks=[CommandHandler('quit', quit)]
))

ConversationHandler 的处理程序

对话以 entry_points 开始,并以不同的状态进行。其中每一个都需要一个处理程序。比如我们为entry_points定义了一个叫做introCommandHandler,当用户输入命令/start.

时会调用它
def intro(update: Update, context: CallbackContext) -> int:
    update.message.reply_text('Enter artist')
    # Specify the succeeding state to enter
    return ARTIST

其他处理程序如 artisttitle 也很简单。例如:

def artist(update: Update, context: CallbackContext) -> int:
    artist_name = update.message.text
    # This variable needs to be stored globally to be retrieved in the next state
    artist = genius.search_artist(artist_name, max_songs=0)
    update.message.reply_text('Enter song title')
    # Let the conversation proceed to the next state
    return TITLE
def title(update: Update, context: CallbackContext) -> int:
    song_name = update.message.text
    song = artist.song(song_name)
    update.message.reply_text(song.lyrics)
    # return ConversationHandler.END to end the conversation
    return ConversationHandler.END

此外,对话需要回退处理程序。在代码示例中,我们定义了一个简单的退出函数,以在用户键入命令 /quit.

时结束对话
def quit(update: Update, context: CallbackContext):
    return ConversationHandler.END

旁注

使用ConversationHandler的一个好处是您可以随时添加任何新状态以提出更多问题。 ConversationHandler 还可以更轻松地过滤消息。

您还可以查看使用 ConversationHandler.

的对话机器人示例 here