Discord单词挑战Bot接收错误DM后无响应 该如何修复
Discord单词挑战Bot不响应后续消息的修复方案
根因定位
- 核心错误:你在
on_message监听器的全局位置(未做任何前置判断)直接执行了ab = await disableChallenge(),这行代码会直接将所有活跃的单词挑战的active字段置为0、done字段置为1。只要Bot收到任意一条非Bot用户的消息,不管内容对错、不管是否凑齐3名中奖者,活动会被直接关闭,后续所有消息自然无法匹配到活跃活动,不会被处理。 - 次要逻辑漏洞:
- 所有判断逻辑使用平级
if而非互斥的if-elif,会出现重复判断冲突 - 第三名中奖者的更新逻辑错误调用了
setWinnerTwo而非setWinnerThree getActiveWord无活跃活动时返回字符串,和正常返回的数值1判断逻辑容易混淆- 3人满额的分支中调用
disableChallenge时未加await,无法真正执行 - 未添加
process_commands调用,会导致正常前缀命令失效
- 所有判断逻辑使用平级
修复步骤
1. 移除提前关闭活动的代码
删除on_message开头的ab = await disableChallenge()行,仅在3名中奖者全部产生的分支中调用该方法。
2. 重构on_message的逻辑判断
将平级if改为互斥的if-elif结构,修正各分支逻辑漏洞:
@Cog.listener("on_message") async def greet(self, message): if message.author.bot: await self.bot.process_commands(message) return # 仅处理DM消息 if not isinstance(message.channel, discord.DMChannel): await self.bot.process_commands(message) return try: getTheWord = await getActiveWord() # 无活跃活动直接返回 if getTheWord != 1: await message.author.send("当前没有正在进行的单词挑战,请等待下一轮活动开启。") await self.bot.process_commands(message) return getAnswer = await getFreshAnswer() getWinOne = await getWinnerOne() getWinTwo = await getWinnerTwo() getWinThree = await getWinnerThree() user_input = message.content.lower() user_id = str(message.author.id) # 口令错误分支 if user_input != getAnswer.lower(): await message.author.send("Wrong answer, please try again.") # 口令正确分支 else: # 已中过奖的判断 if (getWinOne[0] != 'winner1' and user_id == getWinOne[0]) or (getWinTwo[0] != 'winner2' and user_id == getWinTwo[0]): await message.author.send(f"{message.author.mention} You already won this challenge, wait for the next one.") # 第一名中奖 elif getWinOne[0] == 'winner1': await message.author.send(f"Check in main chat if you was a winner {message.author.mention}") await setWinnerOne(user_id) db.commit() # 第二名中奖 elif getWinTwo[0] == 'winner2': await message.author.send(f"Check in main chat if you was a winner {message.author.mention}") await setWinnerTwo(user_id) db.commit() # 第三名中奖 elif getWinThree[0] == 'winner3': await message.author.send(f"Check in main chat if you was a winner {message.author.mention}") await setWinnerThree(user_id) db.commit() # 3人满额,关闭活动 await disableChallenge() db.commit() # 可添加向主频道发送活动结束的通知逻辑 # 所有名额已满 else: await message.author.send(f"{message.author.mention} All winners have been selected, wait for the next one.") except Exception as e: print(e) finally: await self.bot.process_commands(message)
3. 修正辅助函数返回值
修改getActiveWord函数,无活跃活动时统一返回None,避免类型判断冲突:
async def getActiveWord(): try: active = db.record(f'SELECT * FROM wordschallenge WHERE active = 1 AND done = 0') if not active: return None else: return active[1] except Exception as e: print(e) return None
4. 修正setword命令的数据库插入语法
原代码中参数传递格式错误,修改为:
db.execute("INSERT INTO wordschallenge (active, question, answer, winner1, winner2, winner3, done) VALUES (?, ?, ?, ?, ?, ?, ?)", (active, question, answer, winner1, winner2, winner3, done))
内容的提问来源于stack exchange,提问作者Leandro Machado
相关产品推荐
相关产品推荐

