py-cord:如何删除用户的最后 n 条消息?

py-cord: How do I delete the last n messages of a user?

我正在用 py-cord 编写一个反垃圾邮件机器人,我想在用户达到压力限制(= 太多垃圾邮件)后自动删除他们最后的 n 条消息。到目前为止,我删除消息的代码是:

95 counter = 0
96 while counter < 10:
97    for channel in message.guild.channels:
98        for msg in channel.messages:
99            if msg.author.id == message.author.id and counter < 10:
100               await msg.delete()
101               counter += 1

我得到的错误是

Ignoring exception in on_message
Traceback (most recent call last):
  File "C:\Users\Username\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\client.py", line 343, in _run_event
    await coro(*args, **kwargs)
  File "c:\Users\Username\OneDrive\Desktop\Dateien\Python\MessageCheck\messagecheck.py", line 98, in on_message
    for msg in channel.messages:
AttributeError: 'CategoryChannel' object has no attribute 'messages'

我尝试在 Whosebug 上搜索类似的问题,但我得到的最接近的是 50301090,这并不能完全回答我的问题,因为我不想为此使用命令,而且看起来像如果 运行 一段时间,它可能会给缓存带来一些压力。

根据这个错误,我会说你缺少一个缩进块,使你的第一个 for 循环实际上什么都不做。

尝试:

95 counter = 0
96 while counter < 10:
97    for channel in message.guild.channels:
98        for msg in channel.messages:
99            if msg.author.id == message.author.id and counter < 10:
100               await msg.delete()
101               counter += 1

或者错误是说您没有正确确定范围。

message.guild.channels 遍历 所有 个频道,包括类别和语音频道。由于您无法在上述任何一种渠道类型中发送消息,因此它们没有 channel.messages 属性,导致您收到错误消息。

您应该改为遍历公会的文本频道:message.guild.text_channels。这样,该属性将始终被设置,您将不会再收到此错误


也就是说,您的代码绝不会删除用户的最后 10 条消息。它将从上到下搜索文本频道。如果用户 2 年前在服务器的第一个文本通道中写了 10 条消息,现在在第二个文本通道中发送了 100 条垃圾邮件,您的机器人将删除 2 年前的消息并保持垃圾邮件不变。

既然您已经在使用 on_message 活动,为什么不跟踪任何用户的最后 10 条消息呢?通过将频道和消息 ID 存储在以公会和用户 ID 为键的字典中,您可以很容易地实现这一点。这样,如果用户超过压力限制,您可以简单地遍历这 10 条消息并将其删除。然后,您的删除代码将如下所示(USER_MESSAGES 是违规用户最后 10 个 channel/message ID 对的占位符,并假设您的机器人客户端名为 bot):

for chl_id, msg_id in USER_MESSAGES:
    msg = await bot.get_channel(chl_id).fetch_message(msg_id)
    await msg.delete()

它只是说您的 CategoryChannel 类型的频道没有 messages 属性,如果您 look in the documentation.

则没有

此外,您要实现的内容已经 built-in 和 discord.py 一起提供,称为 purge(),所以您应该直接使用它。

# Whatever you had here most like an on_message() listener
await channel.purge(limit=10, check=lambda msg: msg.author == person) 
# Here person is a discord.Member object which let's just say you stored from a command function

另外想指出的是,这实际上并没有删除用户的最后10条消息,而是用户在频道的最后10条消息中发送的消息。