You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

discord.py跨服务器复制频道权限时InvalidArgument错误的修复方法

解决跨服务器复制Discord频道权限的问题

你遇到的错误原因很直接:InvalidArgument: Expected PermissionOverwrite received str——你在第二个命令里把打印出来的对象字符串表示直接当成了实际对象使用,但Discord.py的create_text_channel方法要求overwrites参数的键必须是Role/Member对象(或对应ID整数),值必须是PermissionOverwrite对象,不是字符串。

下面是一步步的修复方案:

1. 正确保存原频道的权限信息

直接保存ctx.channel.overwrites里的对象行不通——这些对象和当前服务器绑定,跨服务器无法复用。我们需要把权限转换成可序列化的格式(比如包含角色ID、权限的allow/deny数值):

@bot.command()
async def copychannel(ctx):
    chan_perm = ctx.channel.overwrites
    saved_permissions = {}
    
    for target, overwrite in chan_perm.items():
        # 处理角色权限(包括@everyone)
        if isinstance(target, discord.Role):
            if target.is_default():
                # 单独标记@everyone,因为每个服务器的@everyone ID不同
                saved_permissions["@everyone"] = {
                    "allow": overwrite.allow.value,
                    "deny": overwrite.deny.value,
                    "type": "default_role"
                }
            else:
                saved_permissions[target.id] = {
                    "allow": overwrite.allow.value,
                    "deny": overwrite.deny.value,
                    "type": "role"
                }
        # 如果需要处理成员权限,可添加类似逻辑
        elif isinstance(target, discord.Member):
            saved_permissions[target.id] = {
                "allow": overwrite.allow.value,
                "deny": overwrite.deny.value,
                "type": "member"
            }
    
    print("保存的权限信息:", saved_permissions)
    # 你可以把这个saved_permissions存到文件、数据库,或者暂存到变量供后续使用

2. 在目标服务器重构权限并创建频道

拿到保存的权限信息后,我们需要在目标服务器找到对应的角色/成员,重新构建PermissionOverwrite对象,再传入create_text_channel:

@bot.command()
async def createcopiedchannel(ctx):
    # 替换成你从copychannel命令得到的saved_permissions内容
    saved_permissions = {
        "@everyone": {
            "allow": 0,
            "deny": 1024,
            "type": "default_role"
        }
        # 如果有其他角色,示例如下:
        # 123456789012345678: {
        #     "allow": 8192,
        #     "deny": 0,
        #     "type": "role"
        # }
    }
    
    target_guild = ctx.guild
    final_overwrites = {}
    
    for key, perm_data in saved_permissions.items():
        target = None
        # 处理@everyone角色
        if perm_data["type"] == "default_role":
            target = target_guild.default_role
        # 处理普通角色
        elif perm_data["type"] == "role":
            target = target_guild.get_role(key)
            if not target:
                print(f"警告:目标服务器中找不到ID为{key}的角色")
                continue
        # 处理成员(如果需要的话)
        elif perm_data["type"] == "member":
            target = target_guild.get_member(key)
            if not target:
                print(f"警告:目标服务器中找不到ID为{key}的成员")
                continue
        
        # 构建合法的PermissionOverwrite对象
        overwrite = discord.PermissionOverwrite(
            allow=discord.Permissions(perm_data["allow"]),
            deny=discord.Permissions(perm_data["deny"])
        )
        final_overwrites[target] = overwrite
    
    # 创建带有指定权限的文本频道
    await target_guild.create_text_channel(name="test", overwrites=final_overwrites)
    await ctx.send("频道已创建,权限已应用!")

关键注意点

  • @everyone角色的特殊性:每个服务器的@everyone角色ID就是服务器本身的ID,所以不能直接复制原服务器的角色ID,必须用guild.default_role获取目标服务器的@everyone。
  • 权限数值的含义:allow.value和deny.value是权限的整数表示,Discord.py会自动把它们转换成Permissions对象。
  • 角色/成员存在性检查:跨服务器复制时,目标服务器可能没有原服务器的角色/成员,所以要加存在性判断,避免报错。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 08:52:28