简体   繁体   中英

how can I store the next text in telegram bot using python

I want the bot to handle "/add" command in a certain way. I would like to save three inputs from the user (title, text, comments)

@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)
""")

the problem is when a user sends "/add" it becomes the message variable for the function, and so I wanna update this variable to the next message that will be sent by the user, I tried something like

title = updater.message.text

I want the user to send title of an article and that becomes the variable title, next we ask for the article and store it in another value all in plain text, and so on.

But I got an error like

    title = updater.message.text
AttributeError: 'Updater' object has no attribute 'message'

It is minimal example which uses ConversationHandler to get title , text , and comments in separated messages

You start conversation using command /add .

Function add() sends message to user with information what to do and it returns value TITLE to inform bot that next message has to get function get_title() .

Function get_title() gets text and keep it in global dictionary as title , and it returns value TEXT to inform bot that next message has to get function get_text() .

Function get_text() gets text and keep it in global dictionary as text , and it returns value COMMENTS to inform bot that next message has to get function get_comments() .

Function get_comments() gets text and keep it in global dictionary as comments , and it display all data from dictionary (but it could save it in database). It returns ConversationHandler.END to inform bot that it is end of conversation. It could return COMMENTS to get more comments but it would have to keep comments as list in dictionary. And it would need some command to stop getting comments and then save all data.


Base on example code conversationbot.py from 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()      

EDIT: something similar with telebot . I use global variable state and message_handler which catchs unknow messages

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()

EDIT: simpler version

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()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM