Merge pull request #1003 from 13xforever/vnext

Some anti-spam enhancements
This commit is contained in:
Ilya
2025-07-17 19:08:30 +05:00
committed by GitHub
4 changed files with 83 additions and 1 deletions

View File

@@ -42,6 +42,16 @@ internal static partial class CommandErroredHandler
{
Config.Log.Warn(e, "Failed to remove message with unknown text command");
}
try
{
var dm = await tctx.CreateDmAsync().ConfigureAwait(false);
await dm.SendMessageAsync("""
You have tried to use an outdated bot command, please use Discord Application Command instead.
You can access them through `` > `Use Apps` on desktop, or the gamepad button on mobile.
Alternately you can open the list of App Commands by typing `/` prefix.
"""
).ConfigureAwait(false);
} catch {}
}
else
{

View File

@@ -260,9 +260,14 @@ internal static class ContentFilter
{
try
{
if (await client.GetMemberAsync(message.Channel.Guild, message.Author).ConfigureAwait(false) is DiscordMember mem
if (await client.GetMemberAsync(message.Channel?.Guild, message.Author).ConfigureAwait(false) is DiscordMember mem
&& !mem.Roles.Any())
{
try
{
await mem.SendMessageAsync("You have been kicked from the server for posting undesirable content. Please do not post it again.").ConfigureAwait(false);
}
catch {}
await mem.RemoveAsync("Filter action for trigger " + trigger.String).ConfigureAwait(false);
completedActions.Add(FilterAction.Kick);
}

View File

@@ -0,0 +1,66 @@
using CompatBot.Utils.Extensions;
using Microsoft.Extensions.Caching.Memory;
namespace CompatBot.EventHandlers;
public static class AntiSpamMessageHandler
{
private static readonly MemoryCache MessageCache = new(new MemoryCacheOptions{ ExpirationScanFrequency = TimeSpan.FromMinutes(1) });
private static readonly TimeSpan DefaultExpiration = TimeSpan.FromSeconds(10);
public static async Task<bool> OnMessageCreated(DiscordClient client, MessageCreatedEventArgs args)
{
var author = args.Author;
if (author.IsBotSafeCheck())
return true;
#if !DEBUG
if (await author.IsSmartlistedAsync(client, args.Guild).ConfigureAwait(false)
|| await author.IsWhitelistedAsync(client, args.Guild).ConfigureAwait(false))
return true;
#endif
var msg = args.Message;
if (msg.Content is not { Length: > 0 })
return true;
if (MessageCache.TryGetValue(author.Id, out var item)
&& item is (DiscordMessage { Content.Length: >0 } lastMessage, bool isWarned)
&& lastMessage.Content == msg.Content
&& lastMessage.ChannelId != msg.ChannelId)
{
var removedSpam = false;
try
{
await msg.DeleteAsync("spam").ConfigureAwait(false);
Config.Log.Debug($"""
Removed spam message from user {author.Username} ({author.Id}) in #{msg.Channel?.Name}:
{msg.Content.Trim()}
"""
);
removedSpam = true;
}
catch (Exception e)
{
Config.Log.Warn(e, $"Faled to delete spam message from user {author.Username} ({author.Id}) in #{msg.Channel?.Name} {msg.JumpLink}");
}
try
{
if (!isWarned)
{
await author.SendMessageAsync("Please do not spam the same message in multiple channels. Thank you.").ConfigureAwait(false);
isWarned = true;
}
}
catch (Exception e)
{
Config.Log.Warn(e, $"Faled to send DM to user {author.Username} ({author.Id})");
}
MessageCache.Set(author.Id, (lastMessage, isWarned), DefaultExpiration);
return !removedSpam; // couldn't remove, need to check with filters etc
}
MessageCache.Set(author.Id, (msg, false), DefaultExpiration);
return true;
}
}

View File

@@ -236,6 +236,7 @@ internal static class Program
]));
config.HandleMessageCreated(new MultiEventHandlerWrapper<MessageCreatedEventArgs>(
[
AntiSpamMessageHandler.OnMessageCreated,
ContentFilterMonitor.OnMessageCreated, // should be first
DiscordInviteFilter.OnMessageCreated,
],