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

Telegram Bot管理员点击按钮后用户未收到响应问题

问题排查与修复方案

核心问题分析

  1. 全局变量user_id的竞态冲突:当多个用户提交付款截图时,全局user_id会被最后提交的用户ID覆盖,导致管理员处理早期用户的请求时,反馈消息会发给错误的用户。
  2. 回调处理器的优先级问题:两个@bot.callback_query_handler(func=lambda call: True)装饰器的函数按注册顺序执行,第一个处理器会先捕获所有回调请求(包括管理员的「Подтвердить/Отклонить」操作),未处理的请求无法正确传递到第二个处理器。
  3. 冗余代码干扰:handler_photo函数中重复判断content_type == 'photo',属于无效代码。

修复后的完整代码

from telebot import types
import telebot

token = 'token'
bot = telebot.TeleBot(token)

admin_id = 12345678


@bot.message_handler(commands=['start'])
def start(message):
    if message.chat.id == admin_id:
        bot.send_message(message.chat.id, "Привет, администратор!")
    else:
        m1 = f'Привет, {message.from_user.first_name}. В этом боте можно оплатить участие в викторине. Нажми кнопку, чтобы получить реквизиты.'
        markup = types.InlineKeyboardMarkup()
        markup.add(types.InlineKeyboardButton('Получить реквизиты', callback_data='yes'))
        bot.send_message(message.chat.id, m1, reply_markup=markup)

# 仅处理「Получить реквизиты」的回调请求
@bot.callback_query_handler(func=lambda call: call.data == 'yes')
def callback_query_handler(call):
    chat_id = call.message.chat.id
    m2 = 'Реквизиты для оплаты: 5555 5555 4444 4444. ' \
         'После оплаты прикрепите скриншот оплаты для проверки.'
    bot.send_message(chat_id, m2)

@bot.message_handler(content_types=['text', 'photo', 'audio', 'video', 'document', 'location', 'contact', 'sticker', 'poll'])
def handler_photo(message):
    content_type = message.content_type
    chat_id = message.chat.id
    if message.from_user.id != admin_id:
        if content_type == 'photo':
            m3 = 'Спасибо, фотография получена. Нам необходимо немного времени, чтобы проверить оплату'
            bot.send_message(chat_id, m3)
            user_id = message.from_user.id
            photo_file_id = message.photo[-1].file_id
            markup = types.InlineKeyboardMarkup(row_width=2)
            # 将用户ID嵌入回调数据,避免全局变量冲突
            approve_button = types.InlineKeyboardButton('Подтвердить', callback_data=f'approve_{user_id}')
            reject_button = types.InlineKeyboardButton('Отклонить', callback_data=f'reject_{user_id}')
            markup.add(approve_button, reject_button)
            bot.send_photo(chat_id=admin_id, photo=photo_file_id, reply_markup=markup)
        else:
            m4 = 'Пожалуйста, прикрепите скриншот оплаты в виде фотографии. Спасибо!'
            bot.send_message(chat_id, m4)

# 仅处理管理员的审批/驳回回调
@bot.callback_query_handler(func=lambda call: call.data.startswith('approve_') or call.data.startswith('reject_'))
def handle_callback_query(call):
    # 从回调数据中解析目标用户ID
    action, user_id = call.data.split('_')
    user_id = int(user_id)
    
    if action == 'approve':
        m5 = 'Ваша оплата принята! Ссылка на канал: https://t.me/'
        bot.send_message(chat_id=user_id, text=m5)
    elif action == 'reject':
        m6 = 'Оплата не была подтверджена. Отправьте квитанцию повторно или свяжитесь с поддержкой.'
        bot.send_message(chat_id=user_id, text=m6)
    
    bot.answer_callback_query(callback_query_id=call.id)


bot.polling(none_stop=True, interval=0)

关键修改说明

  1. 移除全局user_id:将用户ID直接嵌入按钮的callback_data中(格式为approve_用户ID/reject_用户ID),确保管理员处理请求时能精准定位到提交截图的用户。
  2. 拆分回调处理器:
    • 第一个回调处理器仅响应用户点击「Получить реквизиты」的操作,避免拦截管理员的审批回调。
    • 第二个回调处理器仅处理包含approve_或reject_前缀的请求,逻辑边界清晰。
  3. 清理冗余代码:删除handler_photo中重复的content_type == 'photo'判断,简化逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 01:57:38