Есть ли хороший способ найти человека, который удалил сообщение в событии on_message_delete?

#python #discord.py #audit-logging

Вопрос:

Хейо, так что я пытаюсь создать регистратор удаления, который просто, по сути, отправляет сообщение в заранее определенном канале со словами «пользователь x удалил сообщение от лица x», однако у меня проблема.

Итак, в настоящее время я получаю имя того, кто удалил сообщение, путем проверки самого последнего журнала аудита. Однако, поскольку удаление ваших собственных сообщений не отображается в журнале аудита, оно прерывается, если вы удаляете свое собственное сообщение. И по этой причине я проверяю, был ли создан журнал аудита Но тогда возникает еще одна проблема. Таким образом, если вы удалите несколько сообщений, и все они отправлены одним и тем же человеком (пример: человек 1 удаляет 3 сообщения от человека 2), это сведет журнал аудита в одну запись (показывает «пользователь x удалил x сообщений от пользователя x», вместо «пользователь x удалил сообщение от пользователя x», повторенное x раз). Но я не думаю, что он обновляет время создания журнала аудита.

Так что теперь я не совсем уверен, как это исправить. На самом деле ничего не приходит в голову. Вот мой текущий код для события on_message_delete.

 @client.event
async def on_message_delete(message):
pst = pytz.timezone('US/Pacific')
psttime = datetime.datetime.now(pst)
current_pst_date = psttime.strftime('%Y/%m/%d, %I:%M %p PST.')
delete_channel = message.channel.mention
nsfw_tag = ''
spoiler_tag = ''
in_nsfw = False
channel = client.get_channel(863957409293664266)
message_author = message.author

if message.content.startswith("^"):
    return

delete_author = None
delta = datetime.datetime.utcnow() - datetime.timedelta(seconds=1)
print(delta)
async for entry in message.guild.audit_logs(action=discord.AuditLogAction.message_delete, limit=1):
    print(entry.created_at)
    if entry.created_at > delta:
        delete_author = "{0.user}".format(entry)
    else:
        delete_author = message.author
if delete_author is None:
    await ctx.send("Test: Some random error ocurred.")
    return

if 'nsfw=True' in str(message):
    nsfw_tag = '**:warning: NSFW :warning:**'
    in_nsfw = True
    spoiler_tag = '||'

e = discord.Embed(title='',
                  description=f"{nsfw_tag}n{delete_author.mention} Deleted a Message by {message_author.name} in {spoiler_tag}{delete_channel}{spoiler_tag}n||n||")
if in_nsfw is True:
    e.color = Color.red()
else:
    e.color = Color.gold()
e.set_author(name=f"{message_author}", icon_url=f"{message_author.avatar_url}")
e.set_footer(text=f"• {current_pst_date}")
await channel.send(embed=e)
 

Комментарии:

1. У discord.Message объекта нет никаких атрибутов о том, кто его удалил. Удаленные сообщения рассматриваются как discord.DeletedReferencedMessage объекты, но имеют только channel_id guild_id атрибуты, id , и. Итак, поскольку я не знаю вашего ответа, я поддержал ваш ответ, и я назначу награду за него, если никто не ответит раньше, чем через 2 дня.

2. API discord не возвращает пользователя, удалившего сообщение, поэтому лучший способ-это то, что вы уже используете, получив последнее действие журнала аудита, проверив, находится ли оно в том же канале, а если нет, предположите, что удалитель был автором сообщения. Это может привести к некоторым ошибкам, например, если P1 удалит сообщение P2 в канале A, а затем P3 удалит свое собственное сообщение в канале A, бот подумает, что P1 удалил сообщение P3.

Ответ №1:

Невозможно


…потому что API Discord не возвращает пользователя, который удалил сообщение.
Как сказал @Chuaat, вы можете попробовать сделать это другими способами, но это может привести к некоторым ошибкам.

Discord.py


Discord.py развитие закончилось, поэтому никто не сможет делать то, что вы хотите.

Редактировать


Можно получить удалитель сообщения, но это невозможно сделать, используя только discord.Message атрибуты.
Вы можете использовать журнал аудита гильдии для этой области, например:

 async for entry in message.guild.audit_logs(limit=1):
    deleter = entry.user
await message.channel.send(embed = discord.Embed(title="Message deleted", description=f"{deleter.mention} deleted a message"))
 

Ответ №2:

Итак, вы пытаетесь узнать автора сообщения из удаленного сообщения и пользователя, который его удалил. Я думаю, что это должно сработать:

 @client.event
async def on_message_delete(message, member):
    async for entry in message.guild.audit_logs(limit=1,action=discord.AuditLogAction.message_delete):
        deleter = entry.user
    print(f"{deleter.name} deleted message by {message.author.name}")
 

выход:
введите описание изображения здесь

Комментарии:

1. Пожалуйста, сохраняйте свой язык.

2. Пожалуйста, не публикуйте текст в виде изображения. Это делает недоступными для поисковых систем некоторых пользователей с ограниченными возможностями, в то же время делая невозможным для нас копирование и вставку, просто чтобы назвать некоторые из многих недостатков. Спасибо!

3. Я не думаю, что это сработало бы, если бы soneone удалил свое собственное сообщение. К сожалению, это не отображается в журнале аудита.

4. @Der Pruefer Это не должно сработать. Я уверен, что по большей части это должно сработать, но вы пробовали удалить свое собственное сообщение и посмотреть, появится ли оно? Потому что, если я правильно смотрю на это, это только захват имени из журнала аудита, и поэтому, если вы удалите свое собственное сообщение, поскольку оно не отображается в журнале аудита, оно ошибочно отметит другого пользователя как удаляющего. Если это действительно работает в полной мере, то я очень удивлен, мне придется попробовать это позже. Спасибо вам за помощь.

5. @Broso56 да, конечно, я пробовал это, и это работает просто идеально. В любом случае, я бы не сказал, что это сработает.