Telegram Referral Bot频道订阅校验400错误问题排查求助
问题排查与修复方案
核心错误1:传参错误,获取的不是用户ID
你调用check_sub()时传入的第二个参数是call.message.chat.id,这个值是当前bot与用户对话的聊天会话ID,并不是触发回调的用户ID。正确的用户ID取值应该是call.from_user.id。
这是导致你始终无法正确校验订阅状态的最主要原因,你一直在把聊天ID当作用户ID传给Telegram API,自然匹配不到对应用户,才会持续返回user not found错误。
核心错误2:not_subscribed变量未初始化
你代码里的not_subscribed变量只有在check_sub()返回False的时候才会被赋值,如果用户已订阅,该变量不存在,运行时会直接抛出NameError异常,导致逻辑中断。
核心错误3:校验逻辑覆盖不全
你修改后的check_sub()逻辑只处理了「用户不存在」的异常,但没有校验接口返回的用户成员状态:哪怕用户已经退出频道,只要用户账号存在,get_chat_member不会报错,你会直接返回True,导致退订用户也能通过校验。
原代码的逻辑本身是对的,只是没有做异常捕获处理,遇到用户从未和频道产生交互、或者账号不存在的情况就会抛出你遇到的400错误。
核心错误4:权限不足前置问题
请先确认你的Telegram Bot已经加入@interaliex频道成为管理员,并且开启了「读取成员列表」权限,否则无论如何调用get_chat_member接口都会报错。
修复后的代码示例
修正后的check_sub逻辑
def check_sub(chat_id, user_id): try: member_info = bot.get_chat_member(chat_id, user_id) # 只有成员状态不是left才算订阅成功(包括成员、管理员、创建者等所有状态) return member_info.status != 'left' except ApiTelegramException as e: # 捕获用户不存在、用户从未加入过频道等异常情况 if 'Bad Request: user not found' in str(e): return False # 其他异常可以根据需求打印日志排查 return False
修正后的callback_worker逻辑
def callback_worker(call): if call.data == "start_reg": # pressed button start bot.send_message(call.message.chat.id, const.START_REG, reply_markup=kbrd_sub) if call.data == "check_sub": # pressed button "check sub" not_subscribed = False # 先初始化变量 sub_to_text = "Sorry, you haven't subscribed to " # 传入正确的用户ID:call.from_user.id if not check_sub('@interaliex', call.from_user.id): sub_to_text = sub_to_text + "@interaliex" not_subscribed = True if not_subscribed: bot.send_message(call.message.chat.id, sub_to_text, reply_markup=kbrd_sub) else: bot.send_message(call.message.chat.id, const.FINISH_REG, parse_mode="Markdown", reply_markup=kbrd_final)
内容的提问来源于stack exchange,提问作者Asaf Hekimoglu
相关产品推荐
相关产品推荐

