You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Discord.py反垃圾消息Bot忽略通道功能异常排查求助

Discord.py反垃圾Bot问题排查与修复

核心问题

  1. 提前return导致反垃圾逻辑完全失效
    在on_message的try代码块中,读取完忽略频道列表后直接执行return all_channels,这会让函数立即终止,后续的垃圾消息计数、踢人逻辑根本不会运行。无论消息在哪个频道,都不会触发反垃圾操作,看起来就像所有频道都被忽略了。

  2. 缺少“判断当前频道是否在忽略列表”的逻辑
    代码没有检查当前消息所在频道是否属于channels.json中的忽略频道,正确逻辑应该是:如果频道在忽略列表内,就跳过垃圾检测;不在列表内才执行后续的反垃圾判断。

次要问题(顺带优化)

  • spam-bank.txt的计数逻辑不合理:每次读取整个文件统计用户ID出现次数,然后追加ID,会导致文件无限膨胀,且没有时间窗口限制(比如1分钟内发送N条才算垃圾),容易出现误判或性能问题。
  • ignore命令的add_channel函数重复打开文件,可优化为一次读取修改后写入,同时缺少重复添加频道的判断。

修复后的完整代码

import json
import asyncio
from discord.ext import commands

@client.listen()
async def on_message(message):
    # 跳过机器人自身消息,避免自触发
    if message.author.bot:
        return

    # 读取忽略频道列表并判断是否跳过当前频道
    try:
        with open("channels.json", "r") as r:
            channel_data = json.load(r)
            ignored_channels = channel_data["channels"]
            # 检查当前频道ID是否在忽略列表中
            if str(message.channel.id) in ignored_channels:
                return
    except FileNotFoundError:
        # 若文件不存在,默认不忽略任何频道
        pass

    # 垃圾消息计数处理(建议后续添加时间窗口限制)
    counter = 0
    user_records = []
    with open("spam-bank.txt", "r+") as file:
        records = file.readlines()
        for record in records:
            user_id = record.strip()
            user_records.append(user_id)
            if user_id == str(message.author.id):
                counter += 1
        # 追加当前用户ID记录
        user_records.append(str(message.author.id))
        # 重置文件内容并写入更新后的记录
        file.seek(0)
        file.writelines([f"{uid}\n" for uid in user_records])
        file.truncate()

    # 达到垃圾阈值则执行踢人操作
    if counter > 3:
        await message.channel.send(f'{message.author} 因发送垃圾消息被踢出服务器')
        await message.guild.kick(message.author, reason="反垃圾Bot检测到垃圾消息行为")
        print(f'{message.author} 已被踢出')
        await asyncio.sleep(2)

@client.command()
async def ignore(ctx, channel_id: str):
    def add_ignored_channel(target_id, file_path="channels.json"):
        # 读取或初始化忽略频道数据
        try:
            with open(file_path, "r") as f:
                data = json.load(f)
        except FileNotFoundError:
            data = {"channels": []}
        
        # 避免重复添加同一频道
        if target_id not in data["channels"]:
            data["channels"].append(target_id)
            with open(file_path, "w") as f:
                json.dump(data, f, indent=4)

    add_ignored_channel(channel_id)
    await ctx.send("该频道已添加到反垃圾忽略列表!")

修复说明

  1. 移除了on_message中提前return的错误代码,改为判断当前频道是否在忽略列表,符合预期的“仅忽略指定频道”逻辑。
  2. 优化了spam-bank.txt的读写方式,避免文件无限增大(后续可进一步添加时间窗口,比如只保留最近5分钟的记录)。
  3. 修复了ignore命令的文件操作逻辑,添加了重复频道判断,防止无效重复添加。
  4. 增加了排除机器人消息的判断,避免Bot自身触发反垃圾机制。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 09:30:51