You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Telegram Bot内联按钮无响应问题求助

Python Telegram Bot 内联按钮点击无响应问题

我开发Python Telegram Bot时遇到了一个问题:已经实现了用于审批/拒绝请求的内联按钮,按钮能正常显示,但点击后完全没反应。我用Telegram Bot API开发,内联按钮已经配置了回调数据,怀疑问题出在回调处理逻辑或者消息数据提取环节,以下是处理内联按钮的简化代码:

import os
import json
from datetime import datetime, timedelta
from telegram import InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import CallbackQueryHandler

# 假设admins、bot、generate_invoice_id、show_main_menu等已定义

def process_id_input(message, user_id, product_info, product_price):
    user_folder_path = os.path.join("users_data", str(user_id))
    user_file_path = os.path.join(user_folder_path, "user_data.json")
    with open(user_file_path, "r", encoding="utf-8") as user_file:
        user_data = json.load(user_file)

    target_user_id = message.text
    invoice_id = generate_invoice_id()

    server_time = datetime.now()
    adjusted_time = server_time + timedelta(hours=3)

    purchase_record = {
        "product_name": product_info["name"],
        "price": product_price,
        "invoice_id": invoice_id,
        "purchase_time": adjusted_time.strftime("%Y-%m-%d %H:%M:%S"),
        "target_user_id": target_user_id,
        "order_status": "قيد التنفيذ"
    }

    purchases_file_path = os.path.join(user_folder_path, "purchases.json")
    if os.path.exists(purchases_file_path):
        with open(purchases_file_path, "r", encoding="utf-8") as purchases_file:
            user_purchases = json.load(purchases_file)
    else:
        user_purchases = []

    user_purchases.append(purchase_record)

    with open(purchases_file_path, "w", encoding="utf-8") as purchases_file:
        json.dump(user_purchases, purchases_file)

    for admin_chat_id in admins:
        admin_message = (
            "استخدم الأمر /ss لتعيين حالة الطلب\n"
            "🛒 طلب جديد!\n\n"
            f"المستخدم: {user_data['name']}\n"
            f"المنتج: {product_info['name']}\n"
            f"السعر: {product_price} SYP\n"
            f"رقم الفاتورة: `{invoice_id}`\n"
            f"الايدي المراد التحويل اليه: `{target_user_id}`\n"
            "حالة الطلب: قيد التنفيذ"
        )

        approve_button = InlineKeyboardButton("موافق", callback_data=f"approve_{invoice_id}")
        reject_button = InlineKeyboardButton("رفض", callback_data=f"reject_{invoice_id}")

        keyboard = InlineKeyboardMarkup([[approve_button, reject_button]])

        try:
            bot.send_message(admin_chat_id, admin_message, parse_mode='Markdown', reply_markup=keyboard)
        except Exception as e:
            print(f"Failed to send admin message: {e}")

    thank_message = f"""شكرًا لك على شراء {product_info['name']}!

رقم الفاتورة: `{invoice_id}`

يتم الآن معالجة طلبك من قبل الإدارة."""

    try:
        bot.send_message(user_id, thank_message, parse_mode='Markdown')
        show_main_menu(user_id)
    except Exception as e:
        print(f"Failed to send thank you message to the user: {e}")
      
def handle_inline_buttons(update, context):
    query = update.callback_query
    data = query.data
    user_id = query.from_user.id

    try:
        invoice_id = query.message.text.split("رقم الفاتورة: `")[1].split("`")[0]

        if data.startswith("approve_"):
            update_purchase_status(user_id, invoice_id, "مكتملة")
        elif data.startswith("reject_"):
            update_purchase_status(user_id, invoice_id, "مرفوضة")

        query.answer(text="تم تحديث حالة الطلب بنجاح.")
    except Exception as e:
        print(f"An error occurred while handling inline buttons: {e}")

def update_purchase_status(user_id, invoice_id, status):
    user_folder_path = os.path.join("users_data", str(user_id))
    purchases_file_path = os.path.join(user_folder_path, "purchases.json")

    if os.path.exists(purchases_file_path):
        with open(purchases_file_path, "r", encoding="utf-8") as purchases_file:
            user_purchases = json.load(purchases_file)

        for purchase in user_purchases:
            if purchase["invoice_id"] == invoice_id:
                purchase["order_status"] = status

        with open(purchases_file_path, "w", encoding="utf-8") as purchases_file:
            json.dump(user_purchases, purchases_file)

问题排查与修复方案

  • 回调处理器未注册:必须确保handle_inline_buttons已注册到Bot的Dispatcher中,否则点击按钮不会触发任何逻辑。添加以下代码完成注册:

    # 假设dp是你的Dispatcher实例
    dp.add_handler(CallbackQueryHandler(handle_inline_buttons))
    
  • 发票ID提取逻辑脆弱:原代码依赖解析消息文本提取发票ID,一旦消息格式变动就会抛出异常。直接从回调数据中提取更可靠:

    def handle_inline_buttons(update, context):
        query = update.callback_query
        data = query.data
        
        try:
            parts = data.split("_")
            action = parts[0]
            invoice_id = parts[1]
            # 后续需要提取原用户ID,见下一点
            
            if action == "approve":
                # 这里要替换成原订单用户的ID,不是管理员ID
                update_purchase_status(original_user_id, invoice_id, "مكتملة")
            elif action == "reject":
                update_purchase_status(original_user_id, invoice_id, "مرفوضة")
            
            query.answer(text="تم تحديث حالة الطلب بنجاح.")
        except Exception as e:
            error_msg = f"处理请求时出错: {str(e)}"
            print(error_msg)
            query.answer(text=error_msg, show_alert=True)
    
  • 订单所属用户ID错误:原代码把管理员的ID当成订单所属用户的ID,导致找不到对应订单文件。修改按钮的回调数据,加入原订单用户的ID:

    # 在process_id_input函数中修改按钮回调数据
    approve_button = InlineKeyboardButton("موافق", callback_data=f"approve_{user_id}_{invoice_id}")
    reject_button = InlineKeyboardButton("رفض", callback_data=f"reject_{user_id}_{invoice_id}")
    

    然后在处理回调时提取原用户ID:

    parts = data.split("_")
    action = parts[0]
    original_user_id = parts[1]
    invoice_id = parts[2]
    
  • 异常处理优化:原代码仅打印错误,管理员无法感知问题。修改异常处理逻辑,给管理员弹出错误提示:

    except Exception as e:
        error_msg = f"处理请求时出错: {str(e)}"
        print(error_msg)
        query.answer(text=error_msg, show_alert=True)
    

内容的提问来源于stack exchange,提问作者Mohammed Alhaji

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 11:44:52