python-telegram-bot icon indicating copy to clipboard operation
python-telegram-bot copied to clipboard

CommandHandler helps

Open micheleberardi opened this issue 3 years ago β€’ 3 comments

Issue I am facing

Hi All i started to build a bot that call different API now i have 3 function /start /standings /circuit

if i call standings i got the button and then I click it and i got the response

instead, if i call circuit I got the button and then i click the button but the function call standing function instead circuit function

below my main script and my def

Traceback to the issue

No response

Related part of your code

import logging
from turtle import update

from telegram import Update, Bot, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import ApplicationBuilder, ContextTypes, CommandHandler, CallbackContext, Updater, CallbackQueryHandler
from telegram.ext import Updater, CommandHandler, CallbackQueryHandler,ConversationHandler
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update, ReplyKeyboardMarkup
import requests
from modules import defines, def_driverstandings, def_circuit
import json





async def start(update: Update, context: ContextTypes):
    user = update.message.from_user

    welcome_msg = "Hi  "+str(user.first_name)+"   
                  

    reply_markup = {'keyboard': [[{'text': 'πŸ† Standings'},{'text':'🏁 Results'},{'text':'πŸ—“ Schedule'}],
                                 [{'text': 'πŸ‘±πŸΌ Driver'},{'text':'🏎️ Constructor'},{'text':'🏟️ Circuit'}],
                                 [{'text': '☁️ Weather'}, {'text': 'βš™οΈ Settings'}, {'text': '❌ Exit'}]

                                 ], 'resize_keyboard': True,
                    'one_time_keyboard': False}
    reply_markup = json.dumps(reply_markup)

    await context.bot.send_message(chat_id=update.effective_chat.id, text=welcome_msg ,reply_markup=reply_markup)







if __name__ == '__main__':
    # Stages


    application = ApplicationBuilder().token('token').build()

    start_handler = CommandHandler('start', start)
    application.add_handler(start_handler)

    ####### DRIVER STANDING

    driverstandings_handler = CommandHandler('standings', def_driverstandings.driverstandings_main)
    application.add_handler(driverstandings_handler)
    application.add_handler(CallbackQueryHandler(def_driverstandings.driverstandings_handler_action))
    ####### CIRQUIT PART

    circuit_handler = CommandHandler('circuit', def_circuit.circuit_main)
    application.add_handler(circuit_handler)
    application.add_handler(CallbackQueryHandler(def_circuit.circuit_action))

    # log all errors
    application.add_error_handler(error)
    application.run_polling()
    application.idle()


##### DEF circuit

from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
from telegram.ext import Application, CallbackQueryHandler, CommandHandler, ContextTypes,CallbackContext
from modules import defines

async def circuit_main(update: Update, context: CallbackContext):
    url = "https://api.domain.com""
    r = defines.callApi(url)
    keybrd = []

    for item in r:
        circuitId = item.get('circuitId')
        keybrd.append([InlineKeyboardButton(item['name'], callback_data=circuitId ),])

    reply_markup = InlineKeyboardMarkup(keybrd)

    await update.message.reply_text("Please choose:", reply_markup=reply_markup)
    #await context.bot.send_message("Please choose:", reply_markup=reply_markup)



async def circuit_action(update: Update, context: CallbackContext):
    query = update.callback_query
    query = query.data
    url = "https://api.domain.com"
    r = defines.callApi(url)
    dict = []
    for item in r:
        text = item['circuitId']
        if str(text) == query:
            year = item['year']
            round = item['round']
            circuitId = item['circuitId']
            circuit_name = item['name']
            circuit_country = item['country']
            location = item['location']
            url = item['url']
            fp1_date = item['fp1_date']
            fp2_date = item['fp2_date']
            fp3_date = item['fp3_date']
            quali_date = item['quali_date']
            sprint_date = item['sprint_date']
            lat = item['lat']
            lng = item['lng']
            alt = item['alt']
            r_dict = "🏟️ Circuit information for "+str(circuit_country)+" Year: "+str(year)+"\n\n" \
                             "πŸ“‡ Circuit" + ": " + str(circuit_name) + "\n\n"+\
                             "πŸ“… Round" + ": " + str(round) + "\n\n"+\
                             "πŸ“…FP1"+": "+str(fp1_date)+"\n"+\
                             "πŸ“…FP2"+": "+str(fp2_date)+"\n"+\
                             "πŸ“…FP3"+": "+str(fp3_date)+"\n"+\
                             "πŸ“…Quali"+": "+str(quali_date)+"\n"+\
                             "πŸ“…Sprint"+": "+str(sprint_date)+"\n\n" + \
                             "πŸ”— location" + ": " +str(location) + "\n" \
                             "πŸ”— lng" + ": " +str(lng) + "\n" \
                             "πŸ”— lat" + ": " +str(lat) + "\n" \
                             "πŸ”— alt" + ": " +str(alt) + "\n\n" \
                             "πŸ“Url" + ": " +str(url)+""
            await context.bot.send_message(chat_id=update.effective_chat.id, text=str(r_dict))
            #await update.message.reply_text("Please choose:", reply_markup=reply_markup)
            break
        else:
            continue

###### def standings

from telegram.ext import ApplicationBuilder, ContextTypes, CommandHandler, CallbackContext, Updater, CallbackQueryHandler
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update, ReplyKeyboardMarkup, ReplyKeyboardRemove
from modules import defines
import json



async def driverstandings_main(update: Update, context: CallbackContext):
    keybrd = [
        [InlineKeyboardButton("🏟️ Driver (current)", callback_data="2022"),
         InlineKeyboardButton("🏟️ Contructor(current)", callback_data="2022")],
        [InlineKeyboardButton("🏟️ Driver(by year)", callback_data="2022"),
         InlineKeyboardButton("🏟️ Contructor(by year)", callback_data="2022")],
        [InlineKeyboardButton("❌ Cancel", callback_data="2022")],
    ]

    reply_markup = InlineKeyboardMarkup(keybrd)

    await update.message.reply_text("Get standings from:", reply_markup=reply_markup)

async def driverstandings_handler_action(update: Update, context: CallbackContext):
    query = update.callback_query
    query = query.data
    url = "https://api.domain.com"
    r = defines.callApi(url)
    keybrd = ""
    for r_tot in r:
        pos = r_tot.get('pos')
        forename = r_tot.get('forename')
        points = r_tot.get('points')
        surname = r_tot.get('surname')
        nationality = r_tot.get('nationality')
        result_driver = "\n "+ str(pos)+" 🏎️ "+str(forename)+" "+str(surname)+ " ("+str(points)+")"
        keybrd += str(result_driver)

    result_fina = "πŸ† The "+str(query)+" Formula 1 driver standings:\n\n " +str(keybrd)

    await context.bot.send_message(chat_id=update.effective_chat.id, text=result_fina)
    #await update.message.reply_text(chat_id=update.effective_chat.id, text=result_fina)

Operating System

ubuntu

Version of Python, python-telegram-bot & dependencies

python-telegram-bot 20.0a0
Bot API 6.0
Python 3.9.10 (main, Jan 15 2022, 11:48:04)  [Clang 13.0.0 (clang-1300.0.29.3)]

micheleberardi avatar Aug 09 '22 02:08 micheleberardi

In order for PTB to differentiate which handler should handle the CallbackQuery, you can specify the pattern as an argument. Otherwise only the first CallbackQueryHandler will handle the update, which in your case is for /standings.

P.S. Upgrading to a2 is recommended (pip install python-telegram-bot --pre -U). See the release notes at @pythontelegrambotchannel

harshil21 avatar Aug 09 '22 17:08 harshil21

@harshil21 thanks for your help my problem is that I have the same pattern for both call

```
circuit_handler = CommandHandler('circuit', def_circuit.circuit_main)
application.add_handler(circuit_handler)
application.add_handler(CallbackQueryHandler(def_circuit.circuit_action, pattern=r"^(0|[1-9][0-9]?|100)$"))
driver_handler = CommandHandler('driver', def_driver.driver_main)
application.add_handler(driver_handler)
application.add_handler(CallbackQueryHandler(def_driver.driver_action, pattern=r"^(0|[1-1000][0-1000]?|1000)$"))'

micheleberardi avatar Aug 10 '22 19:08 micheleberardi

in that case you should add a payload to your callback_data like: circuitId + '_circuit', so you can differentiate it in your handler like: CallbackQueryHandler(def_circuit.circuit_action, pattern=r"^(0|[1-9][0-9]?|100)_circuit")).

harshil21 avatar Aug 10 '22 19:08 harshil21

@harshil21 It works Thanks so much

micheleberardi avatar Aug 16 '22 18:08 micheleberardi