Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exit from conversation when a new command is sent #1447

Closed
davidegori opened this issue Jul 16, 2019 · 6 comments
Closed

Exit from conversation when a new command is sent #1447

davidegori opened this issue Jul 16, 2019 · 6 comments

Comments

@davidegori
Copy link

davidegori commented Jul 16, 2019

What I need:

Define two conversation handler, conv1 and conv2, with entry points /command1 and /command2: each conversation with multiple states. It should work in this way:
a. I enter in conv1 conversation, typing /command1, and I start to follow the normal conversation. Then, in the middle of conversation, I send /command2 and the first conversation end (Like ConversationHandler.END).
And viceversa:
b. I enter in conv2 conversation, typing /command2, and I start to follow the normal conversation. Then, in the middle of conversation, I send /command1 and the first conversation end (Like ConversationHandler.END).
I need that when I start a conversation with the bot I can interrupt it sending a command: in this case the bot end the conversation and answer the new command.

Expected behaviour:

There should be a way to define the conversation handler such that it will handle all the messages sent while the conversation is open.

Actual behaviour:

I've found #1365, so I've try to add to conversation handler the following fallbacks:

def cancel(bot, update):
	update.message.reply_text('Operation canceled', reply_markup=markup)
	return ConversationHandler.END
conv_handler = ConversationHandler(
	entry_points=[CommandHandler('command', conv0)],
	states={
		CONV: [MessageHandler(Filters.text, conv1)],
	},
	fallbacks=[MessageHandler(Filters.command, cancel)],
)

In this way it close conversation if there aren't ConversationHandler/CommandHandler that handle the command send before the ConversationHandler of /command.

Configuration:

Version of Python: 3.6.7
Version of python-telegram-bot: 11.1.0

@hameda169
Copy link

You have MessageHandler(Filters.command, cancel) in your fallbacks of ConversationHandler.
It means that if you entered that conversation, every command should ends that conversation.
That MessageHandler in fallbacks is waste and should be removed

@davidegori
Copy link
Author

I don't understand, do you mean that CommandHandler('cancel', cancel) is unnecessary in conv_handler ?
If you mean that it's better to write fallbacks in this way fallbacks=[MessageHandler(Filters.command, cancel)] I agree wit you, I've just edited it.
Your second sentence is what I would do, every command should ends the conversation but it doesn't work. If there is a conversationhandler or commandhandler in the code that triggers the command before the conv_handler, when I sent a command during the conversation it doesn't exit and it execute the command.

@Bibo-Joshi
Copy link
Member

Could you provide a full minimal working example?

@hameda169
Copy link

First, I apologize of my english:(
Is mean your conversation must be like this and MessageHandler(Filters.command, cancel) is unnecessary

conv_handler = ConversationHandler(
	entry_points=[CommandHandler('command', conv0)],
	states={
		CONV: [MessageHandler(Filters.text, conv1)],
	},
	fallbacks=[CommandHandler('cancel', cancel)],
)

@Bibo-Joshi
Copy link
Member

As far as I understand, MessageHandler(Filters.command, cancel) is the behaviour @dirompante wants, ie every command that is not handled by the ConversationHandler (and thus passed to the fallback) will end the conversation.

However, I think to have found the problem: The Handlers are organized in groups (see docs of Dispatcher) and onlye one Handler is executed per group. Thus a setup like

dispatcher.add_handler(CommandHandler('foo',foo))
dispatcher.add_handler(conv_handler)

would result in the following conversation:

/command # starts the conversation, since only conv_handler gives a match
/foo # executes foo since the CommandHandler gives a match. No other handler is executed since both the foo handler and conv_handler are in the same default group.

To change this, behaviour, simply assign different groups:

dispatcher.add_handler(CommandHandler('foo',foo),2)
dispatcher.add_handler(conv_handler,1)

For both group 1 and 2 one handler may be executed. Thus:

/command # starts the conversation, since only conv_handler gives a match
/foo     # 1. ends the conversation (group 1 is executed first)
         # 2. executes foo since the CommandHandler gives a match.

If /foo is the starting point of another conversation, that one will be started ofter the first has ended.

@davidegori
Copy link
Author

davidegori commented Aug 17, 2019

Thank you @Bibo-Joshi, that's what I was looking for.
Thank also to you @hameda169.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants