如何限制python-telegram-bot开发的Telegram机器人仅对指定用户可用?
实现python-telegram-bot私人授权用户访问的方案
嘿,我懂你想做个仅限自己和家里人用的Telegram机器人,不想被陌生人蹭用对吧?你的思路完全没问题,用授权用户ID列表来过滤是最直接有效的办法,我给你一步步讲清楚,再附上能直接跑的示例代码,新手也能轻松上手~
核心思路
本质就是在处理每一条用户消息前,先检查发送者的用户ID是否在咱们预先设定的授权列表里:如果不在,就直接忽略或者回复权限提示;如果在,就正常执行后续的指令逻辑。
具体实现步骤
1. 先获取授权用户的ID
首先你得拿到自己和亲属的Telegram用户ID,最简便的方法是先写个临时小脚本,让用户给机器人发指令就能拿到ID:
from telegram import Update from telegram.ext import ApplicationBuilder, ContextTypes, CommandHandler async def get_id(update: Update, context: ContextTypes.DEFAULT_TYPE): await update.message.reply_text(f"你的用户ID是:{update.effective_user.id}") if __name__ == '__main__': # 替换成@BotFather给你的机器人Token application = ApplicationBuilder().token("你的机器人Token").build() application.add_handler(CommandHandler("getid", get_id)) application.run_polling()
运行这个脚本后,在Telegram里给机器人发/getid,就能拿到自己的ID了,让亲属也这么操作,把所有收集到的ID存起来备用。
2. 实现授权验证逻辑
这里给你两种方案,一种更优雅(装饰器),一种更直观(直接在函数内判断),你可以根据自己的熟悉程度选:
方案一:用装饰器(推荐,减少重复代码)
先写一个专门做权限验证的装饰器,之后每个需要授权的命令函数都能直接套用:
from functools import wraps from telegram import Update from telegram.ext import ContextTypes # 替换成你收集到的真实授权用户ID列表 AUTHORIZED_USER_IDS = [123456789, 987654321] # 示例ID,记得替换 def authorized_only(func): @wraps(func) async def wrapper(update: Update, context: ContextTypes.DEFAULT_TYPE, *args, **kwargs): user_id = update.effective_user.id if user_id not in AUTHORIZED_USER_IDS: # 可以选择回复提示,或者直接return不做任何响应 await update.message.reply_text("抱歉,你没有权限使用这个机器人。") return # 终止后续逻辑执行 return await func(update, context, *args, **kwargs) return wrapper
然后给你的命令处理函数加上这个装饰器就行:
@authorized_only async def start(update: Update, context: ContextTypes.DEFAULT_TYPE): await update.message.reply_text("欢迎使用我的私人机器人!") @authorized_only async def family_news(update: Update, context: ContextTypes.DEFAULT_TYPE): await update.message.reply_text("这是咱们家族的专属消息哦~")
方案二:函数内直接判断(适合新手,更直观)
如果觉得装饰器不好理解,也可以直接在每个处理函数开头加权限判断:
AUTHORIZED_USER_IDS = [123456789, 987654321] async def start(update: Update, context: ContextTypes.DEFAULT_TYPE): user_id = update.effective_user.id if user_id not in AUTHORIZED_USER_IDS: await update.message.reply_text("抱歉,你没有权限使用这个机器人。") return await update.message.reply_text("欢迎使用我的私人机器人!") async def family_news(update: Update, context: ContextTypes.DEFAULT_TYPE): user_id = update.effective_user.id if user_id not in AUTHORIZED_USER_IDS: await update.message.reply_text("抱歉,你没有权限使用这个机器人。") return await update.message.reply_text("这是咱们家族的专属消息哦~")
3. 完整可运行的示例代码
把上面的内容整合起来,完整的机器人代码如下:
from telegram import Update from telegram.ext import ApplicationBuilder, ContextTypes, CommandHandler from functools import wraps # 替换成你的授权用户ID列表 AUTHORIZED_USER_IDS = [123456789, 987654321] # 替换成@BotFather给你的机器人Token BOT_TOKEN = "你的机器人Token" def authorized_only(func): @wraps(func) async def wrapper(update: Update, context: ContextTypes.DEFAULT_TYPE, *args, **kwargs): user_id = update.effective_user.id if user_id not in AUTHORIZED_USER_IDS: await update.message.reply_text("抱歉,你没有权限使用这个机器人。") return return await func(update, context, *args, **kwargs) return wrapper @authorized_only async def start(update: Update, context: ContextTypes.DEFAULT_TYPE): await update.message.reply_text("欢迎来到咱们的私人机器人!") @authorized_only async def family_plan(update: Update, context: ContextTypes.DEFAULT_TYPE): await update.message.reply_text("周末家庭聚餐地点定在XX餐厅啦~") # 临时获取用户ID的命令,不需要授权 async def get_id(update: Update, context: ContextTypes.DEFAULT_TYPE): await update.message.reply_text(f"你的用户ID是:{update.effective_user.id}") if __name__ == '__main__': application = ApplicationBuilder().token(BOT_TOKEN).build() # 添加命令处理器 application.add_handler(CommandHandler("start", start)) application.add_handler(CommandHandler("familyplan", family_plan)) application.add_handler(CommandHandler("getid", get_id)) # 启动机器人 application.run_polling()
小提示
- 要是不想给未授权用户任何回复,直接删掉
await update.message.reply_text(...)那一行就行,机器人会完全忽略他们的消息。 - 以后要新增授权用户,只需要把新的ID加到
AUTHORIZED_USER_IDS列表里,重启机器人就生效啦。
内容的提问来源于stack exchange,提问作者Ntakwetet




