I’m developing a moderation bot for Discord and I’m having trouble identifying offensive words. Users are managing to evade the filter by inserting spaces, dots, and other characters among the letters. Currently, my bot can only detect exact matches from my list of banned words.
import discord
from discord.ext import commands
client = commands.Bot(command_prefix='!', intents=discord.Intents.all())
automod_enabled = True
with open('bad_words.txt', 'r') as file:
disallowed_words = file.read().splitlines()
@client.event
async def on_message(message):
await client.process_commands(message)
if message.author.bot or message.author == client.user:
return
if automod_enabled:
for bad in disallowed_words:
if bad in message.content.lower():
await message.delete()
await message.channel.send(f'{message.author.mention}, please refrain from using inappropriate language.')
break
@client.command()
async def toggle_mod(ctx):
global automod_enabled
if ctx.author.guild_permissions.manage_messages:
automod_enabled = not automod_enabled
status = 'enabled' if automod_enabled else 'disabled'
await ctx.send(f'Moderation is now {status}')
My current method doesn’t account for variations like ‘b.a.d’, ‘b a d’, or ‘b_a_d’. I’ve attempted to add spaced-out versions in my bad words file, but it’s unfeasible due to numerous combinations. How can I better handle these evasive tactics?
regex works gr8 for this! use re.sub(r'[^a-z]', '', message.content.lower()) to strip evrything except letters b4 checking ur wordlist. catches most evasion attempts without making ur filter file huge.
Here’s what works well - preprocess your messages by normalizing them first. Strip out non-alphabetic characters and convert everything to lowercase before you compare. I use cleaned_text = ''.join(char for char in message.content.lower() if char.isalpha()) and it’s solid. Been running this on my server for months and it catches most workarounds - leetspeak, unicode tricks, you name it. Just make sure you clean both your banned words list and the incoming messages the same way. Watch out though - aggressive cleaning sometimes flags legit words that happen to contain your banned terms. You might need word boundary checks depending on what you’re doing.
I encountered a similar issue while developing my moderation system. A useful approach is to create a preprocessing function that cleans the input text before checking it against the filter. You can utilize string.translate() in combination with str.maketrans() to remove separator characters such as dots, underscores, and spaces. For example, using text.translate(str.maketrans('', '', ' ._-*')) can help streamline the detection process and is generally more efficient than regex. Also, consider implementing a similarity threshold with the difflib library for handling minor variations in words, but be cautious not to set it too sensitive to avoid excessive false positives.
This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.