You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何限制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

火山引擎 最新活动