Telegram bot inline keyboard callbacks not working with pyrogram library

I’m building a telegram bot using pyrogram that fetches educational content through an API. The bot works fine when I send the /courses command and displays the inline keyboard buttons properly. However, when users click on any button, nothing happens at all.

import json
import requests
from pyrogram import Client, filters
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from app import BotApp

@BotApp.on_message(filters.command('courses'))
async def show_courses(bot_client, msg):
    # Build inline keyboard for course selection
    course_buttons = [
        [
            InlineKeyboardButton("Biology", callback_data="course_biology"),
            InlineKeyboardButton("Chemistry", callback_data="course_chemistry"),
        ],
        [
            InlineKeyboardButton("English", callback_data="course_english"),
            InlineKeyboardButton("History", callback_data="course_history"),
        ]
    ]
    markup = InlineKeyboardMarkup(course_buttons)
    await msg.reply_text("Select your course:", reply_markup=markup)

@BotApp.on_callback_query(filters.regex(r'^course_.*'))
async def handle_course_selection(_, callback):
    print('callback received')
    selected_course = callback.data.split("_")[1]
    
    # Get instructors from API
    api_response = requests.get(f"https://MY-API-URL/instructors?course={selected_course}")
    if api_response.status_code == 200:
        instructor_data = api_response.json()
        instructor_buttons = [InlineKeyboardButton(name, callback_data=f"instructor_{selected_course}_{name}") for name in instructor_data["instructors"]]
        markup = InlineKeyboardMarkup([instructor_buttons])
        await callback.message.edit_text(f"Pick an instructor for {selected_course}:", reply_markup=markup)
    else:
        await callback.message.edit_text("API request failed. Try again.")

I added print statements to debug but they never execute. The logs show no errors either. I suspect my regex pattern might be wrong but I’m not sure what the issue is.

Your regex looks right, but pyrogram’s callback handling can be weird. Add some debug logging before the handler to see if it’s actually registering - I’ve had handlers silently fail during registration before. Also check if you’ve got other callback handlers above this one that might be grabbing your queries first. Pyrogram runs handlers in order, so a broader handler could eat the callback before yours runs. Try testing with simpler callback_data like just ‘biology’ instead of ‘course_biology’ to rule out string matching problems.

check if your BotApp is runnning the event loop correctly. I had the same issue - callbacks weren’t firing cause I forgot to call BotApp.run() or didn’t start the client propa. Also, throw in await callback.answer() at the start of your handler. Pyrogram gets wonky without it sometimes.

Had the exact same issue when I started with pyrogram callbacks. Your callback handler decorator probably isn’t registering right. Replace @BotApp.on_callback_query(filters.regex(r'^course_.*')) with just @BotApp.on_callback_query() and filter inside the function instead - use an if statement to check callback.data.startswith('course_'). Also, make sure you’re calling callback.answer() at the end of your handler. Pyrogram needs this to acknowledge the callback query. Without it, that loading spinner keeps spinning forever and your next callbacks might break even if the handler runs.