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

Discord.py中on_message无法识别ctx、member参数,如何实现违禁词自动禁言功能

Discord.py 违禁词自动禁言功能正确实现

你原有代码的核心错误点如下:

  • on_message事件仅接收message参数,你用到的ctx、member均属于未定义变量,所需的服务器、发信用户对象都可以从message的内置属性获取
  • 直接使用asyncio.sleep(3600)逻辑不可靠,若机器人中途重启,将永远不会触发解除禁言的操作
  • 未过滤机器人自身发送的消息,可能出现机器人自己触发规则的问题
  • 仅检测消息开头是否匹配违禁词,会漏掉消息中后部包含违禁词的情况

推荐实现(使用Discord原生超时功能,无需自定义Muted角色,Discord.py v2.0+支持)

这是最稳定的实现方案,超时逻辑由Discord服务端维护,即使机器人重启也不会影响到期自动解除:

import discord
from discord.ext import commands

# 初始化时需要开启成员意图
intents = discord.Intents.default()
intents.message_content = True
intents.members = True

client = commands.Bot(command_prefix='!', intents=intents)

# 违禁词列表,可自行扩充
BANNED_WORDS = ["坏词1", "坏词2", "坏词3"]

@client.event
async def on_message(message):
    # 跳过机器人自己发的消息
    if message.author.bot:
        return
    
    # 检测消息内容是否包含违禁词
    if any(bad_word in message.content.lower() for bad_word in BANNED_WORDS):
        # 从message对象获取服务器和发信成员
        guild = message.guild
        member = message.author
        
        # 先发送提示
        await message.channel.send(f"{member.mention}, 你发送了违禁内容,已被自动禁言1小时。")
        # 删除违禁消息
        await message.delete()
        # 执行超时禁言,时间单位为秒,3600秒即1小时
        await member.timeout(discord.utils.utcnow() + discord.timedelta(seconds=3600), reason="发送违禁内容")
    
    # 如果你同时写了指令功能,需要加这行保证指令正常触发
    await client.process_commands(message)

兼容旧版本实现(使用自定义Muted角色)

如果你使用的Discord.py版本低于2.0,不支持原生超时功能,可以用自定义角色的方式实现,注意该方案下机器人重启会导致未执行的解除禁言失效:

import discord
import asyncio
from discord.ext import commands

intents = discord.Intents.default()
intents.message_content = True
intents.members = True

client = commands.Bot(command_prefix='!', intents=intents)

BANNED_WORDS = ["坏词1", "坏词2", "坏词3"]

@client.event
async def on_message(message):
    if message.author.bot:
        return
    
    if any(bad_word in message.content.lower() for bad_word in BANNED_WORDS):
        guild = message.guild
        member = message.author
        
        await message.channel.send(f"{member.mention}, 你发送了违禁内容,已被自动禁言1小时。")
        await message.delete()
        
        # 获取Muted角色
        muted_role = discord.utils.get(guild.roles, name="Muted")
        if not muted_role:
            # 可以加自动创建Muted角色的逻辑,也可以手动提前创建
            await message.channel.send("未找到Muted角色,请先手动创建禁言角色")
            return
        
        await member.add_roles(muted_role, reason="发送违禁内容")
        # 等待1小时后解除
        await asyncio.sleep(3600)
        # 解除前先判断用户是否还在服务器、是否还有禁言角色
        if muted_role in member.roles:
            await member.remove_roles(muted_role, reason="禁言到期自动解除")
    
    await client.process_commands(message)

注意事项

  • 需要提前在Discord开发者门户的机器人设置页面开启Server Members Intent和Message Content Intent两个权限开关,否则无法读取消息内容和获取成员信息
  • 机器人的角色排序需要高于普通用户角色,且拥有「管理成员」权限,才能正常执行禁言操作
  • 可以自行扩充BANNED_WORDS列表里的违禁词,支持任意数量的关键词匹配

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 21:45:05