求助:discord.py机器人关停命令密码校验功能实现及代码修正
原草稿核心问题梳理
- 语法结构混乱:所有密码校验、关停逻辑没有嵌套在
offline命令的函数作用域内,缩进完全错位,还存在if:无判断条件的语法错误,代码运行直接报错 - 事件监听错误:
wait_for不存在'password'监听类型,discord.py中接收用户输入消息需要使用'message'事件类型 - 校验逻辑完全错位:
check函数写反了校验逻辑,没有判断“当前收到的消息是否来自触发命令的管理员、是否发送在私信频道”,反而拿未初始化的空列表比对密码,永远无法通过校验 - 变量引用错误:没有使用
wait_for返回的用户消息对象,反而试图读取提前定义的空消息变量拿用户输入内容,逻辑完全不闭环 - 客户端指代不统一:代码中同时出现
client和bot两个指代,没有统一变量名会触发未定义错误 - 权限校验缺失:没有防止其他用户伪造输入触发密码校验,存在安全隐患
修正后可直接运行的参考代码
import asyncio import discord from discord.ext import commands # 初始化客户端,按照需求配置权限意图 intents = discord.Intents.default() intents.message_content = True # 必须开启消息内容读取权限,否则无法获取私信内的密码输入 client = commands.Bot(command_prefix="!", intents=intents) @client.event async def on_ready(): print(f"机器人已登录,当前账号:{client.user}") @client.command() @commands.has_permissions(administrator=True) async def offline(ctx: commands.Context): # 删除触发命令的公开消息,避免频道刷屏 await ctx.message.delete() # 在原频道发送操作提示 public_msg = await ctx.send("关停命令已触发,请前往机器人私信输入密码完成验证,验证超时时间为10秒") # 尝试给用户发送私信提示,处理用户关闭私信权限的场景 try: dm_prompt = await ctx.author.send("请输入关停密码,输入内容不会被公开展示,10秒未输入将自动取消本次操作") except discord.Forbidden: await public_msg.edit(content="无法向你发送私信,请开启私信权限后重试") return # 定义消息校验规则:收到的消息必须来自私信频道,且发送者是触发命令的管理员 def check(message: discord.Message): return isinstance(message.channel, discord.DMChannel) and message.author == ctx.author try: # 10秒内监听符合规则的用户输入 user_input = await client.wait_for("message", timeout=10, check=check) except asyncio.TimeoutError: await dm_prompt.edit(content="验证超时,本次关停操作已取消") await public_msg.edit(content="关停操作已超时取消") return # 校验密码,正式使用时替换为自定义的强密码 correct_password = "testo" if user_input.content.strip() != correct_password: await dm_prompt.edit(content="密码错误,本次关停操作已终止") await public_msg.edit(content="密码验证失败,已拒绝执行关停") return # 密码校验通过,执行关停流程 await dm_prompt.edit(content="密码验证通过,机器人将在3秒后关机") await public_msg.edit(content="密码验证通过,机器人即将关停") await asyncio.sleep(3) await public_msg.edit(content="机器人已完成关停") await client.close() # 启动机器人,替换为自身的机器人Token client.run("你的机器人Token")
代码使用说明
- 必须在Discord开发者后台开启对应的消息内容读取Intent,否则机器人无法读取私信内的密码输入内容
- 密码不要硬编码在公开的代码仓库中,正式使用可以存放在环境变量或者本地加密配置文件中,避免密码泄露
- 逻辑已经做了多层防护:仅服务器管理员可触发offline命令、必须能接收机器人私信、输入正确密码才会执行关停,不会被普通用户恶意触发
内容的提问来源于stack exchange,提问作者Shiqi Wang
相关产品推荐
相关产品推荐

