开发Discord机器人修改成员角色遇AttributeError报错求助
解决Discord机器人角色修改的AttributeError问题
嘿,我帮你拆解下这个问题——你碰到的AttributeError: 'NoneType' object has no attribute 'roles',核心原因是server变量是None,也就是机器人没成功获取到你的服务器对象。我来帮你修复代码,顺便解决几个潜在的小问题:
为啥会报错?
你在代码最外层直接写了server = client.get_guild(int(server-id)),这时候Discord客户端还没完成初始化和连接,根本没法拿到服务器数据,所以get_guild返回了None。另外还有几个容易踩的坑:
- 没检查发命令的人是不是管理员,普通用户也能触发就麻烦了
- 没跳过管理员成员,不符合你“管理员除外”的需求
- 没处理
newrole不存在的情况,万一角色没创建,代码又会崩
修复后的完整代码
import discord from discord.ext import commands # 初始化客户端,Discord.py新版必须开这两个意图才能拿成员和消息 intents = discord.Intents.default() intents.members = True intents.message_content = True client = commands.Bot(command_prefix="!", intents=intents) @client.event async def on_ready(): print(f'机器人已登录:{client.user}') # 等客户端完全准备好再拿服务器对象,这时候才靠谱 global server server = client.get_guild(123456789) # 直接填你的服务器数字ID,不用转int if server is None: print("找不到目标服务器!检查下ID对不对,或者机器人有没有进服务器") @client.event async def on_message(message): # 先处理命令前缀,避免和其他命令冲突 await client.process_commands(message) if message.content.startswith('change role'): # 先确认发命令的是管理员 if not message.author.guild_permissions.administrator: await message.author.send("抱歉,只有管理员才能执行这个命令哦") return await message.author.send("开始给所有非管理员成员添加newrole角色啦") # 先检查服务器对象有没有拿到 if server is None: await message.author.send("服务器初始化失败,请检查机器人是否在目标服务器里") return # 找newrole角色 role = discord.utils.get(server.roles, name="newrole") if role is None: await message.author.send("服务器里没找到叫newrole的角色!先去创建这个角色再试哦") return # 遍历所有成员,跳过管理员 for member in server.members: if not member.guild_permissions.administrator: # 注意:@everyone是服务器默认角色,所有成员都有,没法移除!你应该是想添加newrole await member.add_roles(role) await message.channel.send(f"已给{member.display_name}添加newrole角色") await message.author.send("所有非管理员成员的角色修改完成啦!") # 替换成你的机器人令牌 client.run('你的机器人令牌')
关键修复点说明
- 开启成员意图:Discord.py 2.0以上版本必须手动开启
members和message_content意图,还要去Discord开发者门户的机器人设置里把这两个开关打开,不然机器人拿不到成员列表和消息内容。 - 延迟获取服务器:把获取服务器的代码移到
on_ready事件里,这时候客户端已经完全连接到Discord了,能正确拿到服务器对象,不会返回None。 - 权限校验:加了两层权限检查——只有管理员能发命令,遍历成员时跳过管理员,完美符合你的需求。
- 错误兜底:加了服务器不存在、角色不存在的判断,不会一出错就崩溃,还能给你发提示消息。
- 关于@everyone:这个是服务器默认角色,所有成员自动拥有,根本没法移除!你的需求应该是给非管理员成员添加
newrole,如果想让newrole的权限覆盖@everyone,去服务器角色设置里调整权限优先级就行。
额外要注意的点
- 机器人必须在目标服务器里,并且拥有管理角色的权限,不然没法改成员角色。
- 服务器ID要正确:开启Discord开发者模式,右键服务器图标就能复制ID。
- 建议把Python升级到3.8以上,Discord.py最新版对3.6的支持不太友好,容易出其他问题。
内容的提问来源于stack exchange,提问作者francesco pivetti




