Discord.py自定义命令角色绑定功能失效求助
修复Discord.py服务器专属命令角色分配问题
我帮你梳理下代码里的几个关键问题,这些问题导致功能失效但无报错,咱们一步步来修复:
1. get_repeatrole函数的变量名错误
函数里读取JSON到了prefixes变量,但返回时误用了未定义的roles,而且直接用索引会导致未配置服务器的KeyError。修正后的函数:
def get_repeatrole(client, message): with open('repeatrole.json', 'r') as c: roles = json.load(c) # 修正变量名,和返回的字典统一 return roles.get(str(message.guild.id)) # 用get方法避免未配置服务器的报错
2. changerepeatrole命令的多处逻辑错误
这个命令里有变量混乱、写入JSON逻辑错误、缺少await等问题,修正后:
@client.command(aliases=['crr', 'repeatchange', 'changerr']) @commands.has_permissions(administrator=True) async def changerepeatrole(ctx, role: discord.Role): # 用类型注解自动转换为Role对象 with open('repeatrole.json', 'r') as c: roles = json.load(c) roles[str(ctx.guild.id)] = role.id # 存储角色ID更可靠(避免角色改名失效) with open('repeatrole.json', 'w') as c: json.dump(roles, c, indent=4) # 写入整个roles字典,而非单个角色 await ctx.send(f'{role.mention} can now use the repeat command') # 加await才能发送消息,用mention更直观
3. repeat命令的检查装饰器用法错误
@commands.has_role()不能直接传入函数,咱们需要自定义检查逻辑来判断用户是否拥有对应角色:
# 自定义检查函数 def has_repeat_role(ctx): role_id = get_repeatrole(client, ctx.message) if not role_id: return False # 未配置角色时默认禁用命令 target_role = ctx.guild.get_role(role_id) return target_role in ctx.author.roles @client.command() @commands.check(has_repeat_role) # 使用自定义检查 async def repeat(ctx, times: int, content='repeating...'): for i in range(times): await ctx.send(content)
4. 错误处理的类型匹配错误
你当前捕获的是NotOwner错误,但实际触发的是检查失败的CheckFailure,修正后:
@repeat.error async def repeat_error(ctx, error): if isinstance(error, discord.ext.commands.errors.CheckFailure): await ctx.send("You don't have the required role to use this command.") elif isinstance(error, discord.ext.commands.errors.BadArgument): await ctx.send("Please enter a valid number of times and content.") else: await ctx.send("An error occurred while executing the command.")
5. 初始化JSON文件(可选但重要)
第一次运行时如果repeatrole.json不存在会报错,建议在启动时添加初始化逻辑:
import os import json # 在client初始化前执行 if not os.path.exists('repeatrole.json'): with open('repeatrole.json', 'w') as c: json.dump({}, c)
这些修改解决了变量名混乱、JSON写入逻辑错误、检查装饰器误用、缺少await等核心问题,现在应该能正常存储指定角色并限制repeat命令的使用了。
内容的提问来源于stack exchange,提问作者Bagle




