diff --git a/src/Nullinside.Api.TwitchBot.Tests/ChatRules/NezhnaTests.cs b/src/Nullinside.Api.TwitchBot.Tests/ChatRules/NezhnaTests.cs new file mode 100644 index 0000000..c5906f1 --- /dev/null +++ b/src/Nullinside.Api.TwitchBot.Tests/ChatRules/NezhnaTests.cs @@ -0,0 +1,27 @@ +using Moq; + +using Nullinside.Api.Common.Twitch; +using Nullinside.Api.TwitchBot.ChatRules; + +namespace Nullinside.Api.TwitchBot.Tests.ChatRules; + +/// +/// Tests the class. +/// +public class NezhnaTests : AChatRuleUnitTestBase { + /// + /// Tests the strings typed in chats. + /// + /// The string that should fail. + [Test] + [TestCase("Visit nezhna dot com com to boost your viewers and climb the Twitch rankings. Join thousands of successful streamers now! @7xgkq3EK")] + public async Task TestKnownStrings(string badString) { + var rule = new Nezhna(); + var botProxy = new Mock(); + var chat = new TwitchChatMessage(true, badString, "123", "456"); + + // Process the message and assert that we fail the message. + bool result = await rule.Handle("123", botProxy.Object, chat, _db); + Assert.That(result, Is.False); + } +} \ No newline at end of file diff --git a/src/Nullinside.Api.TwitchBot/ChatRules/Nezhna.cs b/src/Nullinside.Api.TwitchBot/ChatRules/Nezhna.cs new file mode 100644 index 0000000..4ac302a --- /dev/null +++ b/src/Nullinside.Api.TwitchBot/ChatRules/Nezhna.cs @@ -0,0 +1,39 @@ +using Nullinside.Api.Common.Twitch; +using Nullinside.Api.Model; +using Nullinside.Api.Model.Ddl; + +using TwitchLib.Client.Models; + +namespace Nullinside.Api.TwitchBot.ChatRules; + +/// +/// Handles the "nezhna dot com" bots. +/// +public class Nezhna : AChatRule { + private const string SPAM = "Visit nezhna dot com com to boost your viewers and climb the Twitch rankings. Join thousands of successful streamers now!"; + + /// + public override bool ShouldRun(TwitchUserConfig config) { + return config is { Enabled: true, BanKnownBots: true }; + } + + /// + public override async Task Handle(string channelId, ITwitchApiProxy botProxy, TwitchChatMessage message, + INullinsideContext db, CancellationToken stoppingToken = new()) { + if (!message.IsFirstMessage) { + return true; + } + + // The number of spaces per message may chance, so normalize that and lowercase it for comparison. + string normalized = string.Join(' ', message.Message.Split(" ").Where(s => !string.IsNullOrWhiteSpace(s))) + .ToLowerInvariant(); + + if (normalized.StartsWith(SPAM, StringComparison.InvariantCultureIgnoreCase)) { + await BanAndLog(channelId, botProxy, new[] { (message.UserId, message.Username) }, + "[Bot] Spam (Nezhna)", db, stoppingToken); + return false; + } + + return true; + } +} \ No newline at end of file