Discord.py基于SQLite3实现违禁词系统无报错不生效问题排查
问题排查
以下是你代码中存在的所有可运行性问题:
1. on_message事件相关问题
- 参数定义错误:
on_message事件接收的唯一参数是消息对象,你错误定义为member,导致后续调用的message全局变量不存在,代码触发未定义变量异常直接终止运行。 - 匹配逻辑缺失:查询到违禁词列表后没有做任何关键词匹配判断,直接执行删除和通知操作,逻辑完全不成立。
- 操作语法错误:
- 删除违规消息的方法是
await message.delete(),你写的message.author.delete()是非法操作,不存在删除用户的接口。 - 发送通知需要调用消息所在频道的发送方法:
await message.channel.send(),不存在message.send()接口。
- 删除违规消息的方法是
- 冗余查询:第一次查询
bannedwords表后又额外查询了完全无关的main表,属于无效代码。 - 安全隐患:查询语句使用f字符串拼接参数,存在SQL注入风险,应该统一使用参数化查询。
2. add word命令相关问题
- 参数类型错误:你要接收的输入是违禁词字符串,不是文本频道对象,需要把参数替换为
*, word: str,前缀*支持接收带空格的多词违禁短语。 - 变量未定义:SQL语句中使用的
msg变量完全没有定义,应该替换为传入的违禁词参数。 - 存储逻辑缺陷:现有逻辑每个服务器只能存储1个违禁词,每次添加新违禁词会覆盖旧的,要支持多违禁词需要按行存储,不需要走UPDATE分支,直接新增行即可。
修复后代码示例
import sqlite3 import discord from discord.ext import commands # 初始化Cog的时候就创建数据库连接,避免重复连接 class BannedWordsCog(commands.Cog): def __init__(self, bot): self.bot = bot self.db = sqlite3.connect('.//SQL//bannedwords.sqlite') self.cursor = self.db.cursor() # 初始化表结构,避免表不存在报错 self.cursor.execute(''' CREATE TABLE IF NOT EXISTS bannedwords( guild_id INTEGER, msg TEXT, PRIMARY KEY (guild_id, msg) ) ''') self.db.commit() @commands.Cog.listener() async def on_message(self, message): # 过滤机器人自己发的消息,避免死循环 if message.author.bot: return # 参数化查询当前服务器所有违禁词 self.cursor.execute('SELECT msg FROM bannedwords WHERE guild_id = ?', (message.guild.id,)) banned_words = self.cursor.fetchall() if not banned_words: return # 提取违禁词列表,匹配消息内容 word_list = [word[0] for word in banned_words] for word in word_list: if word in message.content: # 命中违禁词,删除消息+发通知 await message.delete() embed = discord.Embed(title="Blacklisted Word", description="你发送的内容包含违禁词,已被删除") await message.channel.send(embed=embed, delete_after=7.0) return @commands.group(invoke_without_command=True) async def add(self, ctx): return @add.command() async def word(self, ctx, *, word: str): if not ctx.author.guild_permissions.administrator: await ctx.send("你没有管理员权限,无法添加违禁词", delete_after=5.0) return # 先查询违禁词是否已存在,避免重复插入 self.cursor.execute('SELECT msg FROM bannedwords WHERE guild_id = ? AND msg = ?', (ctx.guild.id, word)) exists = self.cursor.fetchone() if exists: await ctx.send(f"违禁词 `{word}` 已存在", delete_after=5.0) return # 插入新违禁词 self.cursor.execute('INSERT INTO bannedwords(guild_id, msg) VALUES(?, ?)', (ctx.guild.id, word)) self.db.commit() await ctx.send(f"已成功添加违禁词 `{word}`", delete_after=5.0) # 注意:启动Bot时需要开启message_content权限,否则无法读取消息内容 # intents = discord.Intents.default() # intents.message_content = True # bot = commands.Bot(command_prefix='!', intents=intents)
额外注意事项
- Discord.py 2.0及以上版本必须在Discord开发者后台开启
Message Content Intent,同时代码中声明启用对应的权限,否则无法获取消息内容,on_message事件不会触发。 - 生产环境建议给数据库操作加异常捕获,避免SQL执行错误导致整个功能崩溃。
内容的提问来源于stack exchange,提问作者somerandomguyhi
相关产品推荐
相关产品推荐

