python - 如何使用 python 将下一个文本存储在 Telegram Bot 中

标签 python python-3.x telegram telegram-bot

我希望机器人以某种方式处理“/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 来获取分隔消息中的 titletextcomments

您可以使用命令/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/

相关文章:

java - tdlib:GetBasicGroupFullInfo 返回 "Group not found"错误

python - Pandas 数据框按值出现的顺序对值进行分组

Python:如何以编程方式更新属性?

python - 从云源存储库部署时不会触发 Firestore 云功能

python-3.x - 图像和标签在 TFRecord 中不对应

python - 为什么 Pyglet 不能正确绘制多边形?

javascript - Uncaught ReferenceError : require is not defined webpack with telegram

javascript - 聊天字段上的 Telegram Bot 键盘

用于 win 和 cygwin 的 python3 - 缓冲区中的行结尾

python - 编译 vs. 解释,Python 有意想不到的行为