4

I'm trying to develop my own bot with the python-telegram-bot library.

I have a problem with ConversationHandler, that may come from the fact that I haven't understand very well how to use it. I would like to put a /settings command to my bot that, when it gets called, it triggers a ConversationHandler.
This is a fragment of code, inspired from their official example, that enables the ConversationHandler to the /settings command.

CHOOSING = range(1)
reply_keyboard = [[' Breaking News', ' News'], ['✅ Done']]
markup = ReplyKeyboardMarkup(reply_keyboard,one_time_keyboard=True)



settings_handler = ConversationHandler(
    entry_points = [CommandHandler('settings', settings)],

    states = {
        CHOOSING: [MessageHandler(Filters.regex('^( Breaking News)$'), modificaBreakingNews),
        MessageHandler(Filters.regex('^( News)$'),modificaLatestNews)]
    },

    fallbacks = [MessageHandler(Filters.regex('^✅ Done$'), save)]
)

Then, the user gets several options to set and choose the one to set.

def modificaBreakingNews(update, context):
    locale = update.message.from_user.language_code
    keyboard = [
        [InlineKeyboardButton("✅ Attiva", callback_data="modBreakingNews - True"),
        InlineKeyboardButton("❌ Disattiva", callback_data="modBreakingNews - False")
        ]
    ]
    reply_markup = InlineKeyboardMarkup(keyboard)

    update.message.reply_text(translation['opzioniBreakingNews']['it'] if locale == 'it' else translation['opzioniBreakingNews']['en'], reply_markup=reply_markup)


def modificaLatestNews(update, coontext):
    locale = update.message.from_user.language_code
    keyboard = [
        [InlineKeyboardButton(" " + translation['primaSquadra']['it'] if locale == 'it' else translation['primaSquadra']['en'], callback_data="modLatestNews - First Team"),
        InlineKeyboardButton(" " + translation['settGiovanile']['it'] if locale == 'it' else translation['settGiovanile']['en'], callback_data="modLatestNews - Youngsters"),
        InlineKeyboardButton(" " + translation['tutteNews']['it'] if locale == 'it' else translation['tutteNews']['en'] , callback_data="modLatestNews - All")]
    ]
    reply_markup = InlineKeyboardMarkup(keyboard)

    update.message.reply_text(translation['opzioniLatestNews']['it'] if locale == 'it' else translation['opzioniLatestNews']['en'], reply_markup=reply_markup)


def save(update,context):
    locale = update.effective_user.language_code
    update.effective_message.reply_text(translation['modificheOK']['it'] if locale == 'it' else translation['modificheOK']['en'])
    return ConversationHandler.END


def gestore_callback(update, context):
    data = update.callback_query.data.split(" - ")
    dataToSend = {"idTelegram":update.effective_user.id, "intent":"", "confidenza": 0, "command": True}
    print(dataToSend)
    if data[0] == "modBreakingNews":
        dataToSend["newPreference"]  =  data[1]  == 'True'
        print(dataToSend)
        result = requests.post("http://localhost:8000/user/preferences/breaking", data=dataToSend)
    elif data[0] == "modLatestNews":
        dataToSend["newPreference"]  =  data[1]
        result = requests.post("http://localhost:8000/user/preferences/news", data=dataToSend)
    return save(update,context)

After that, the modified setting gets saved on my back-end and, ideally, I'd like the ReplyKeyboard to disappear until the /setting command gets triggered again. This doesn't happen, as when I want to summon again /settings, the command is not triggered anymore

What am I missing? Of course, both the ConversationHandler and the callbackhandler are initialized and assigned to the dispatcher object.

Gianmarco F.
  • 780
  • 2
  • 12
  • 36
  • You left out the most important part of the code, how is your STATE-logic defined? In the official example there is only one STATE (choosing) it seems yours has more. – Fnguyen Sep 09 '19 at 11:50
  • I only handle the choosing state – Gianmarco F. Sep 09 '19 at 11:52
  • Did you check whether ```save```is always called? Because that is the only function that returns ConversationHandler.END. If that is not called then your conversation never stopped. – Fnguyen Sep 09 '19 at 11:59
  • Yes it gets called and then that’s what exactly stops every flow. Apprently, by putting allow_reuse=True (or something like that) in the ConversationHandler initializer fixes the issue – Gianmarco F. Sep 09 '19 at 11:59
  • I'm glad you found a fix, however allow_reuse should not be necessary. Normally conversation_handler enables repeated use out of the box, so somewhere in your code there is still a trip up in the conversation logic. – Fnguyen Sep 09 '19 at 12:03

0 Answers0