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

开发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以上版本必须手动开启membersmessage_content意图,还要去Discord开发者门户的机器人设置里把这两个开关打开,不然机器人拿不到成员列表和消息内容。
  • 延迟获取服务器:把获取服务器的代码移到on_ready事件里,这时候客户端已经完全连接到Discord了,能正确拿到服务器对象,不会返回None
  • 权限校验:加了两层权限检查——只有管理员能发命令,遍历成员时跳过管理员,完美符合你的需求。
  • 错误兜底:加了服务器不存在、角色不存在的判断,不会一出错就崩溃,还能给你发提示消息。
  • 关于@everyone:这个是服务器默认角色,所有成员自动拥有,根本没法移除!你的需求应该是给非管理员成员添加newrole,如果想让newrole的权限覆盖@everyone,去服务器角色设置里调整权限优先级就行。

额外要注意的点

  • 机器人必须在目标服务器里,并且拥有管理角色的权限,不然没法改成员角色。
  • 服务器ID要正确:开启Discord开发者模式,右键服务器图标就能复制ID。
  • 建议把Python升级到3.8以上,Discord.py最新版对3.6的支持不太友好,容易出其他问题。

内容的提问来源于stack exchange,提问作者francesco pivetti

火山引擎 最新活动