You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何优化discord.py机器人的反垃圾(Anti-spam)功能?

Optimized Anti-Spam Discord Bot Implementation

Let's tackle your anti-spam bot optimizations step by step. Below is a polished solution that addresses all three of your requirements, with clear explanations for each change:

Key Requirements Addressed

  • Exempt Specific Roles: Skip anti-spam checks for admins/moderators (supports both administrator permissions and custom role names)
  • Exempt Spam Channel: Disable all spam checks in a dedicated spam channel
  • Delete Duplicate Messages: Track recent message content to remove repeats, alongside the existing rate-limiting logic

Full Optimized Code

import os
import discord
from discord.ext import commands
import datetime

intents = discord.Intents.all()
bot = commands.Bot(command_prefix='$', intents=intents)

# Configuration - tweak these values to match your server needs
TIME_WINDOW_MS = 5000
MAX_MSG_PER_WINDOW = 5
# Replace with your spam channel's ID (right-click channel -> Copy ID)
SPAM_CHANNEL_ID = 123456789012345678
# Replace with role names you want to exempt (e.g., ["Admin", "Moderator"])
EXEMPT_ROLE_NAMES = ["Admin", "Moderator"]

# Track message timestamps for rate limiting
author_msg_times = {}
# Track recent message content for duplicate detection
author_recent_messages = {}

@bot.event
async def on_message(message):
    # Ignore bot messages to prevent loops or false positives
    if message.author.bot:
        return

    # 1. Check if user is exempt from anti-spam checks
    is_exempt = False
    # First check if user has administrator permissions
    if message.author.guild_permissions.administrator:
        is_exempt = True
    # Then check if user has any of the specified exempt roles
    else:
        for role in message.author.roles:
            if role.name in EXEMPT_ROLE_NAMES:
                is_exempt = True
                break

    # 2. Check if message is sent in the spam-exempt channel
    if message.channel.id == SPAM_CHANNEL_ID:
        is_exempt = True

    # Skip all checks if user or channel is exempt
    if is_exempt:
        await bot.process_commands(message)
        return

    # --- Rate Limiting (Refactored Original Logic) ---
    author_id = message.author.id
    curr_time = datetime.datetime.now().timestamp() * 1000

    # Initialize entry for new users
    if author_id not in author_msg_times:
        author_msg_times[author_id] = []
    
    author_msg_times[author_id].append(curr_time)
    # Remove expired timestamps using list comprehension for cleaner code
    expr_time = curr_time - TIME_WINDOW_MS
    author_msg_times[author_id] = [t for t in author_msg_times[author_id] if t >= expr_time]

    # --- Duplicate Message Detection ---
    if author_id not in author_recent_messages:
        author_recent_messages[author_id] = []
    
    # Normalize message content to catch minor variations (extra spaces, capitalization)
    message_content = message.content.strip().lower()
    is_duplicate = message_content in author_recent_messages[author_id]

    # Keep only the last 3 messages to check for repeats (adjust this number as needed)
    author_recent_messages[author_id].append(message_content)
    if len(author_recent_messages[author_id]) > 3:
        author_recent_messages[author_id].pop(0)

    # Take action if spam or duplicate is detected
    if len(author_msg_times[author_id]) > MAX_MSG_PER_WINDOW or is_duplicate:
        try:
            await message.delete()
            # Send a temporary warning that auto-deletes after 5 seconds
            await message.channel.send(f"{message.author.mention}, please stop spamming or sending duplicate messages!", delete_after=5)
        except discord.errors.Forbidden:
            # Handle cases where the bot lacks permission to delete messages
            await message.channel.send("I don't have permission to delete spam messages! Please update my permissions.", delete_after=5)
    else:
        print(f"Compliant message from {message.author.display_name}")

    # Don't forget to process bot commands at the end
    await bot.process_commands(message)

bot.run(os.getenv('token'))

Key Improvements Explained

  • Role/Channel Exemption:
    • Uses both administrator permissions and custom role names to cover different server setups
    • Targets the spam channel by ID (more reliable than channel names, which can be changed)
  • Duplicate Detection:
    • Normalizes message content (stripped and lowercase) to catch subtle repeats like "Hello" vs "hello "
    • Tracks the last 3 messages per user (adjustable) to avoid overloading memory
  • Error Handling:
    • Adds a try/except block to gracefully handle missing permissions
    • Ignores bot messages to prevent self-triggering
    • Uses delete_after=5 for warnings to keep channels uncluttered
  • Code Cleanup:
    • Renamed variables for better readability (e.g., TIME_WINDOW_MS instead of time_window_milliseconds)
    • Replaced manual list removal with list comprehensions for cleaner expired timestamp handling
    • Added a dedicated configuration section for easy adjustments

Before deploying, make sure to:

  1. Replace SPAM_CHANNEL_ID with your actual spam channel's ID
  2. Update EXEMPT_ROLE_NAMES to match your server's admin/moderator role names
  3. Ensure your bot has the necessary permissions (Manage Messages, Read Message History, etc.) in your server

内容的提问来源于stack exchange,提问作者Dweller

火山引擎 最新活动