Search code examples
pythonpython-telegram-bot

python-telegram-bot Pass argument between conversation handlers


I'm trying to write a bot where a user clicks on a command, sends a link as a message, and then the bot adds the link to some database. Here's how it would look:

python-telegram-bot

So I thought I should use a ConversationHandler. Here's what I wrote, the bot.py:

from telegram.ext import (Updater, CommandHandler, MessageHandler, Filters,
        ConversationHandler)
from settings import BOT_TOKEN
import commands

def main():
    updater = Updater(BOT_TOKEN, use_context=True)
    dispatcher = updater.dispatcher

    conversation = ConversationHandler(
            entry_points=[
                MessageHandler(
                    (Filters.command & Filters.regex("al_(.*)")),
                    commands.add_link
                )
            ],
            states={
                commands.ADD_LINK: [
                    MessageHandler(Filters.entity("url"), commands.receive_link)
                ]
            },
            fallbacks=[]
    )

    dispatcher.add_handler(CommandHandler("search", commands.search))
    dispatcher.add_handler(conversation)

    updater.start_polling()
    updater.idle()

if __name__ == "__main__":
    main()

And commands are in another file called commands.py:

from telegram.ext import ConversationHandler

ADD_LINK = range(1)

def receive_link(update, context):
    bot = context.bot
    url = update.message.text
    chat_id = update.message.chat.id

    bot.send_message(
            chat_id=chat_id,
            text="The link has been added."
    )
    return ConversationHandler.END

def add_link(update, context):
    bot = context.bot
    uuid = update.message.text.replace("/al_", "")
    chat_id = update.message.chat.id
    bot.send_message(
            chat_id=chat_id,
            text="Send the link as a message."
    )

    return ADD_LINK

Now the problem is that I need to be able to use the uuid variable (that is generated in add_link) in my receive_link function. But I don't know how to pass this variable. How can I do it?


Solution

  • With the help of this article, I solved it like this.

    By using context.user_data in any Handler callback, you have access to a user-specific dict.

    So my code would change as follows:

    from telegram.ext import ConversationHandler
    
    ADD_LINK = range(1)
    
    def receive_link(update, context):
        bot = context.bot
        url = update.message.text
        chat_id = update.message.chat.id
        uuid = context.user_data["uuid"]
    
        bot.send_message(
                chat_id=chat_id,
                text=f"The link has been added to '{uuid}'."
        )
        return ConversationHandler.END
    
    def add_link(update, context):
        bot = context.bot
        uuid = update.message.text.replace("/al_", "")
        context.user_data["uuid"] = uuid
        chat_id = update.message.chat.id
        bot.send_message(
                chat_id=chat_id,
                text=f"Send the link as a message."
        )
    
        return ADD_LINK
    

    I stored the uuid variable like this:

    context.user_data["uuid"] = uuid
    

    And use it like this:

    uuid = context.user_data["uuid"]
    

    Pretty easy and intuitive. Here's the output:

    python-telegram-bot store user data