Python discord bot属性错误仅在某些消息上

时间:2021-03-04 09:57:33

标签: python discord discord.py

我对这个错误是如何发生感到非常困惑,它只在我在我的机器人中使用 kick/ban 命令而没有其他命令时发生,我查看了 on_message 函数并且它不会导致错误除了 kick/ban 命令之外,我还发送了其他任何消息,但我不知道为什么。我正确地传入了公会并且有一个 id 属性,因为代码仍在工作,但无论如何它都会出现。

错误如下:

    Ignoring exception in on_message
Traceback (most recent call last):
  File ".local/lib/python3.7/site-packages/discord/client.py", line 333, in _run_event
    await coro(*args, **kwargs)
  File "file path", line 1937, in on_message
    await open_automod(guild)
  File "file path", line 1920, in open_automod
    if str(guild.id) in data:
AttributeError: 'NoneType' object has no attribute 'id'

以下是导致此错误的机器人命令示例:

@bot.command(name='testlog')
@commands.has_permissions(kick_members=True)
async def kick (ctx, member:discord.Member, *reason):
    moderator = ctx.message.author.id
    server = ctx.guild.id
    if member == None or member == moderator:
        await ctx.channel.send("You cannot kick yourself")
        return
    if reason == None:
        reason = "no reason stated"
    reason = " ".join(reason)
    message = f"You have been banned from {ctx.guild.name}. Reason: {reason}"
    await member.send(message)
    await ctx.channel.send(f"{member} has been kicked. Reason: {reason}")
    await send_log('test', moderator, member.id, reason, server)

这是 open_automod 函数:

async def open_automod(guild):
    data = await get_automod_data()

    if str(guild.id) in data:
        return False
    else:
        data[str(guild.id)] = {}
        data[str(guild.id)]["automodenabled"] = f'off'
        data[str(guild.id)]["automodlogging"] = f'false'
        data[str(guild.id)]["automodchannel"] = 0

    with open("automoderator.json","w") as f:
        json.dump(data,f)
    return True

这是传入“公会”的代码部分:

@bot.event
async def on_message(message):  
    guild = message.guild
    await open_automod(guild)

我不明白的是为什么这个错误只出现在我使用踢球或禁令的消息中,或者在上述情况下是测试踢球。谁能解释为什么我收到这个错误,为什么它只发生在这条消息上?消息的一个例子是'h/testlog @user reason'

1 个答案:

答案 0 :(得分:1)

  1. 看起来正在运行 on_message 而不是 kick,如错误所示。从您的问题来看,您似乎希望运行 kick。这是因为覆盖了 on_message。请参阅 Why does on_message make my commands stop working? 的 discord.py 文档:
<块引用>

覆盖默认提供的 on_message 禁止运行任何额外的命令。要解决此问题,请在 bot.process_commands(message) 的末尾添加 on_message 行。 或者,您可以将 on_message 逻辑放入侦听器 [使用 @bot.listen('on_message')]

  1. 从错误消息可以清楚地看出 guildNone。 Discord.py 文档确实显示了 Message.guild is optional。所以你应该提防:
@bot.event
async def on_message(message):  
    if (guild := message.guild):
        await open_automod(guild)
  1. 但是,您似乎又希望公会在 kickon_message 中都有一个值,所以您应该弄清楚为什么没有。我的猜测是您将我们的测试日志消息/命令直接发送到机器人而不是在公会频道中 - 因此机器人不知道要针对哪个公会。
    • 如果 kick 只在一个频道内被调用,你应该确保在尝试使用它们之前检查 ctx.guildctx.channel 不是 None而是回复有关如何正确使用机器人的说明。
    • 如果 kick 命令旨在直接发送到机器人而不是在频道中,您应该想出另一种获取 guildchannel 的方法(例如存储它,或作为命令的一部分传递)。