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

discord.py创建文本频道出现AttributeError: 'str'对象无id属性问题求助

问题修复方案

错误根因

discord.py中Guild.create_text_channel方法的overwrites参数要求字典的键必须是discord.Role、discord.Member这类服务器实体对象,你当前代码在循环构建overwrites时,错误使用了role.name字符串作为键,底层逻辑尝试读取键的id属性时触发了AttributeError。

冗余逻辑优化说明

你当前遍历所有角色给非管理角色设禁止查看的逻辑完全多余:你已经给guild.default_role(即@everyone 所有人)设置了view_channel=False,默认所有成员、角色都看不到频道,只需要单独给管理员组和发起工单的用户开放查看权限即可,不需要遍历所有角色重复设置。

修复后代码

@commands.Cog.listener()
async def on_message(self, message):
    # 先过滤掉指令回复、机器人自身消息
    if message.content.lower() in ["yes", "y", "ya", "yee", "ye", "no", "n", "nope"]:
        return
    if message.author == self.client.user:
        return
    # 仅处理DM频道消息
    if isinstance(message.channel, discord.channel.DMChannel):
        await message.channel.send("Create ticket to modmail in Veemo's Kingdom? Yes or no.")
        def check(msg):
            return msg.content.lower() in ["yes", "y", "ya", "yee", "ye", "no", "n", "nope"] and msg.author == message.author
        response = await self.client.wait_for("message", check=check)
        # 处理用户回复
        if response.content.lower() in ["yes", "y", "ya", "yee", "ye"]:
            guild = discord.utils.get(self.client.guilds, id=834666434042658816)
            text_channel_name = f"{message.author.name}-{message.author.discriminator}"
            # 初始权限:所有人不可见
            overwrites = {
                guild.default_role: discord.PermissionOverwrite(view_channel=False),
                # 单独给发消息的用户开放频道权限
                message.author: discord.PermissionOverwrite(view_channel=True, send_messages=True, read_message_history=True)
            }
            # 给所有管理组开放权限
            for role in guild.roles:
                if role.name in mod_roles_list:
                    overwrites[role] = discord.PermissionOverwrite(view_channel=True, send_messages=True, read_message_history=True)
            # 创建频道
            channel = await guild.create_text_channel(name=text_channel_name, overwrites=overwrites)
            await message.channel.send("工单已创建,管理员会尽快回复你")
        else:
            await message.channel.send("Ticket not created.")

额外说明

  • 原代码的check函数只匹配了同意的回复,用户发拒绝内容会一直卡在等待状态,修复后的check同时包含了同意和拒绝的关键词
  • 原逻辑未给发起工单的用户开放频道权限,修复后的代码单独添加了用户权限,避免用户自己也看不到生成的工单频道

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 23:54:01