我希望机器人以某种方式处理“/add”命令。我想保存用户的三个输入(标题、文本、评论)
@bot.message_handler(commands=['add'])
def add_to_database(message):
msg = bot.reply_to(message, """\
We are glad that you are helping us to grow please provide us with the following:-
title of article (the head of the article)
""")
问题是当用户发送“/add”时,它会成为该函数的消息变量,所以我想将此变量更新为用户将发送的下一条消息,我尝试了类似的操作
title = updater.message.text
我希望用户发送一篇文章的标题,该标题将成为变量标题,接下来我们请求该文章并将其以纯文本形式存储在另一个值中,依此类推。
但是我遇到了类似的错误
title = updater.message.text
AttributeError: 'Updater' object has no attribute 'message'
最佳答案
这是一个最小的示例,它使用 ConversationHandler
来获取分隔消息中的 title
、text
和 comments
您可以使用命令/add
开始对话。
函数add()
向用户发送消息,其中包含要做什么的信息,并返回值TITLE
以通知机器人下一条消息必须获取函数get_title( )
。
函数get_title()
获取文本并将其作为title
保存在全局字典中,并返回值TEXT
以通知机器人下一条消息必须获取函数get_text()
。
函数get_text()
获取文本并将其作为text
保存在全局字典中,并返回值COMMENTS
以通知机器人下一条消息必须获取函数get_comments()
。
函数get_comments()
获取文本并将其作为comments
保存在全局字典中,并显示字典中的所有数据(但它可以将其保存在数据库中)。它返回 ConversationHandler.END
以通知机器人对话已结束。它可以返回 COMMENTS 来获取更多评论,但它必须将评论保留为字典中的列表。并且需要一些命令来停止获取评论,然后保存所有数据。
基于示例代码conversationbot.py来自documentation
from telegram.ext import Updater, CommandHandler, ConversationHandler, MessageHandler, Filters
TOKEN = 'YOUR_TOKEN'
updater = Updater(token=TOKEN, use_context=True)
dispatcher = updater.dispatcher
# --- structure for data ---
data = {'title': "", 'text': "", 'comments': ""}
# --- states use in conversation ---
TITLE = 1
TEXT = 2
COMMENTS = 3
# --- functions use in conversation ---
# Command Handler which starts conversation
def add(update, context):
global data # to assign new dictionary to external/global variable
# create new empty dictionary
data = {'title': "", 'text': "", 'comments': ""}
update.message.reply_text("add title, text, comments in separated messages\n\nnow write title")
# next state in conversation
return TITLE
def get_title(update, context):
data['title'] = update.message.text
update.message.reply_text(f"title: {update.message.text}\n\nnow write text")
# next state in conversation
return TEXT
def get_text(update, context):
data['text'] = update.message.text
update.message.reply_text(f"text: {update.message.text}\n\nnow write comments")
# next state in conversation
return COMMENTS
def get_comments(update, context):
data['comments'] = update.message.text
update.message.reply_text(f"comments: {update.message.text}")
msg = """I got all data
title: {}
text: {}
comments: {}""".format(data['title'], data['text'], data['comments'])
update.message.reply_text(msg)
# end of conversation
return ConversationHandler.END
def cancel(update, context):
update.message.reply_text('canceled')
# end of conversation
return ConversationHandler.END
# --- create conversation ---
my_conversation_handler = ConversationHandler(
entry_points=[CommandHandler('add', add)],
states={
TITLE: [
CommandHandler('cancel', cancel), # has to be before MessageHandler to catch `/cancel` as command, not as `title`
MessageHandler(Filters.text, get_title)
],
TEXT: [
CommandHandler('cancel', cancel), # has to be before MessageHandler to catch `/cancel` as command, not as `text`
MessageHandler(Filters.text, get_text)
],
COMMENTS: [
CommandHandler('cancel', cancel), # has to be before MessageHandler to catch `/cancel` as command, not as `comments`
MessageHandler(Filters.text, get_comments)
],
},
fallbacks=[CommandHandler('cancel', cancel)]
)
dispatcher.add_handler(my_conversation_handler)
# --- run bot ---
updater.start_polling()
print('Running... [Press Ctrl+C to stop]')
updater.idle()
print('Stoping...')
updater.stop()
编辑:与远程机器人
类似。我使用全局变量 state
和 message_handler 来捕获未知消息
import telebot
TOKEN = 'TOKEN'
bot = telebot.TeleBot(TOKEN)
#print(bot.get_me())
# --- structure for data ---
data = {'title': "", 'text': "", 'comments': ""}
# --- states use in conversation ---
state = None
TITLE = 1
TEXT = 2
COMMENTS = 3
@bot.message_handler(commands=['add'])
def test(message):
global state
global data
data = {'title': "", 'text': "", 'comments': ""}
bot.send_message(message.chat.id, 'add title, text, comments in separated messages\n\nnow write title')
state = TITLE
@bot.message_handler()
def unknown(message):
global state
if state == TITLE:
data['title'] = message.text
bot.send_message(message.chat.id, f"title: {message.text}\n\nnow write text")
state = TEXT
elif state == TEXT:
data['text'] = message.text
bot.send_message(message.chat.id, f"text: {message.text}\n\nnow write comments")
state = COMMENTS
elif state == COMMENTS:
data['comments'] = message.text
bot.send_message(message.chat.id, f"comments: {message.text}")
msg = """I got all data
title: {}
text: {}
comments: {}""".format(data['title'], data['text'], data['comments'])
bot.send_message(message.chat.id, msg)
state = None
#else:
# print('unknown message')
# bot.send_message(msg.chat.id, 'unknown message')
@bot.message_handler(commands=['cancel'])
def test(message):
global state
bot.send_message(message.chat.id, 'canceled')
state = None
bot.polling()
编辑:更简单的版本
import telebot
TOKEN = 'TOKEN'
bot = telebot.TeleBot(TOKEN)
# --- structure for data ---
data = {'title': "", 'text': "", 'comments': ""}
# --- states use in conversation ---
bot.state = None # create own value `.state` in `bot` - so I don't have to use `global state`. Similar way I could create and use `bot.data`
TITLE = 1
TEXT = 2
COMMENTS = 3
@bot.message_handler(commands=['add'])
def test(message):
global data
data = {'title': "", 'text': "", 'comments': ""}
bot.send_message(message.chat.id, 'add title, text, comments in separated messages\n\nnow write title')
bot.state = TITLE
# it has to be before functions which check `bot.state`
@bot.message_handler(commands=['cancel'])
def test(message):
bot.send_message(message.chat.id, 'canceled')
bot.state = None
@bot.message_handler(func=lambda msg:bot.state==TITLE)
def get_title(message):
data['title'] = message.text
bot.send_message(message.chat.id, f"title: {message.text}\n\nnow write text")
bot.state = TEXT
@bot.message_handler(func=lambda msg:bot.state==TEXT)
def get_title(message):
data['text'] = message.text
bot.send_message(message.chat.id, f"text: {message.text}\n\nnow write comments")
bot.state = COMMENTS
@bot.message_handler(func=lambda msg:bot.state==COMMENTS)
def get_title(message):
data['comments'] = message.text
bot.send_message(message.chat.id, f"comments: {message.text}")
msg = """I got all data
title: {}
text: {}
comments: {}""".format(data['title'], data['text'], data['comments'])
bot.send_message(message.chat.id, msg)
bot.state = None
bot.polling()
关于python - 如何使用 python 将下一个文本存储在 Telegram Bot 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61298307/