Python编写Discord机器人实现!dm随机私信功能出现控制台报错问题
问题原因
- 报错触发的核心是你第二版代码新增了两个属性读取逻辑:
message.channel.name和message.guild.name,第一版代码没有这两行,所以不会触发报错。 - Discord的频道分为两类:服务器内的公开文字频道(
TextChannel类型)、用户和机器人的一对一私信频道(DMChannel类型)。DMChannel类型没有name属性,且私信场景下message.guild会返回None,没有name属性,读取这两个属性就会抛出你看到的AttributeError。 - 功能正常运行是因为Discord框架会自动捕获
on_message事件内的异常,仅打印到控制台不中断运行,只要指令是在服务器频道触发,属性读取逻辑就能正常执行,只有用户在私信频道发消息时才会触发报错。
解决方法
方案1:过滤私信消息(推荐)
大部分机器人不需要响应私信内的指令,直接在on_message开头加过滤逻辑即可,同时顺便过滤机器人自身发送的消息,避免死循环,还可以简化你的随机输出代码:
@client.event async def on_message(message): # 私信消息、机器人自身发送的消息直接跳过处理 if message.guild is None or message.author.bot: return # 以下为原有逻辑 username = str(message.author).split("#")[0] user_message = str(message.content) channel = str(message.channel.name) server = str(message.guild.name) if user_message.lower() == "!dm": await message.channel.send(f"Sent you a dm {username}") outputs = ["Output 0", "Output 1", "Output 2", "Output 3", "Output 4"] random_output = random.choice(outputs) print(f"({server}) >> {username} ran !dm in {channel} and got output {random_output}") await message.author.send(random_output) return client.run("Token")
方案2:兼容私信场景
如果需要支持用户在私信内触发!dm指令,只需要对属性读取做兼容判断即可:
@client.event async def on_message(message): if message.author.bot: return username = str(message.author).split("#")[0] user_message = str(message.content) # 兼容私信频道属性 channel = message.channel.name if hasattr(message.channel, 'name') else '私信频道' server = message.guild.name if message.guild is not None else '无所属服务器' if user_message.lower() == "!dm": # 只有在服务器频道才发公开提示,私信场景不需要 if message.guild is not None: await message.channel.send(f"Sent you a dm {username}") outputs = ["Output 0", "Output 1", "Output 2", "Output 3", "Output 4"] random_output = random.choice(outputs) print(f"({server}) >> {username} ran !dm in {channel} and got output {random_output}") await message.author.send(random_output) return
内容的提问来源于stack exchange,提问作者Immortal
相关产品推荐
相关产品推荐

