如何在discord.py中实现Discord服务器脏话拦截?现有拦截代码无响应问题的修复方案
Let's break down why your bot isn't reacting to swear words and fix the issues step by step:
Key Issues in Your Code
1. You're Iterating Over Characters, Not Words
The biggest problem is this line:
for x in msg:
This loops through every single character in the message, not individual words or phrases. So unless your badwords list contains single characters, it will never match anything—that's why your bot doesn't respond.
2. Variable Name Mismatch
You're mixing up exception_counter and exception_handling throughout the code. For example, in on_member_join you initialize exception_handling, but in on_message you check exception_counter—this leads to KeyErrors or broken logic.
3. Broken Ban Logic
- Your condition checks
exception_counter == 1but this variable is never defined (you meantexception_handling[str(message.author.id)]). - Both ban branches send the same DM, so they can be merged.
- You're sending a ban notification but never actually banning the user.
- The logic for when to ban is unclear (you check
>5but don't reset the count or handle escalating warnings).
4. Incorrect process_commands Placement
When the message is from the bot itself, you shouldn't call process_commands—just return early to avoid unnecessary processing.
Fixed Code
First, make sure you load your badwords correctly (add this at the top of your script):
import discord from discord.ext import commands # Initialize bot (replace with your prefix and enable required intents) client = commands.Bot(command_prefix="!", intents=discord.Intents.all()) # Load badwords from file def load_badwords(): try: with open("badwords.txt", "r", encoding="utf-8") as f: # Convert to lowercase to make matching case-insensitive return [word.strip().lower() for word in f.readlines() if word.strip()] except FileNotFoundError: print("Error: badwords.txt not found!") return [] badwords = load_badwords() # Initialize user data dictionaries (do this before the bot starts) swearword_count = {} exception_handling = {} # Tracks if a user has received their first warning @client.event async def on_message(message): # Ignore messages from the bot itself if message.author == client.user: return msg_content = message.content.lower() user_id = str(message.author.id) # Initialize user data if they're not in our dictionaries if user_id not in swearword_count: swearword_count[user_id] = 0 if user_id not in exception_handling: exception_handling[user_id] = 0 # Check if the message contains any bad word contains_badword = any(badword in msg_content for badword in badwords) if contains_badword: swearword_count[user_id] += 1 # First offense: send a DM warning and channel reminder if exception_handling[user_id] == 0: await message.author.send("Warning: Using this word will lead to punishment if repeated.") exception_handling[user_id] = 1 await message.channel.send(f"{message.author.mention}, please do not use that word.") # Subsequent offenses: stricter channel reminder else: await message.channel.send(f"{message.author.mention}, stop using inappropriate language!") # Ban logic: 5+ offenses if swearword_count[user_id] >= 5: try: await message.author.send("You have been banned for repeated use of inappropriate language.") await message.author.ban(reason="Excessive swear words") await message.channel.send(f"{message.author.mention} has been banned for violating our rules.") except discord.Forbidden: await message.channel.send("I don't have permission to ban this user!") # Process commands after handling the swear filter await client.process_commands(message) @client.event async def on_member_join(member): channel = discord.utils.get(member.guild.text_channels, name="welcome") if channel: await channel.send(f"{member.name}, welcome to the server! :)") # Initialize user data for new members user_id = str(member.id) swearword_count[user_id] = 0 exception_handling[user_id] = 0 # Send DM welcome (handle cases where DMs are disabled) try: await member.send(f"Hi {member.name}, welcome to the server! Please follow our rules.") except discord.Forbidden: print(f"Couldn't send DM to {member.name} (they have DMs disabled)") # Run the bot (replace with your token) client.run("YOUR_BOT_TOKEN")
Optimization Suggestions
Avoid Global Variables: Instead of using dictionaries, use a lightweight database like SQLite or
discord.ext.commands.Bot's built-inbot.dataattribute. This way, user data persists across bot restarts.Better Swear Word Matching: Use regular expressions to match whole words (to avoid false positives like "ass" in "assignment"):
import re pattern = re.compile(r'\b(' + '|'.join(re.escape(word) for word in badwords) + r')\b', re.IGNORECASE) contains_badword = pattern.search(message.content) is not NoneEscalating Warnings: Instead of a single warning, implement a tiered system (e.g., 1st = warning, 2nd = mute, 3rd = kick, 5th = ban) for better moderation.
Delete Offensive Messages: Add
await message.delete()to remove the swear word message (make sure your bot has the "Manage Messages" permission).Admin Reload Command: Add a command to reload the badwords list on the fly (for admins only):
@client.command() @commands.has_permissions(administrator=True) async def reload_badwords(ctx): global badwords badwords = load_badwords() await ctx.send("Badwords list reloaded!")
内容的提问来源于stack exchange,提问作者hARASİVa

