使用discord.py开发Discord机器人:消息替换功能报错求助
问题解决与代码修正
直接报错原因
你的on_message事件函数定义错误:discord.py的on_message事件仅接受message一个参数,你额外添加的before参数不存在于事件触发的参数列表中,导致调用时出现TypeError。
完整修正代码
import discord from discord.ext import commands # 初始化全局开关变量 underscored_mode = False bot = commands.Bot(command_prefix='/', intents=discord.Intents.all()) @bot.command() async def underscored(ctx): global underscored_mode # 切换开关状态(支持开启/关闭切换) underscored_mode = not underscored_mode await ctx.send(f"下划线模式已{'开启' if underscored_mode else '关闭'}") @bot.command() async def test(ctx): original_content = "This is a test command." # 根据开关状态直接发送对应格式内容 if underscored_mode: await ctx.send(original_content.replace(' ', '_')) else: await ctx.send(original_content) # 如需统一处理所有机器人发送的消息(含其他命令输出),保留此事件 @bot.event async def on_message(message): # 先处理命令,避免命令逻辑被拦截 await bot.process_commands(message) # 仅处理机器人自身发送的消息,且跳过开关提示消息(防止循环编辑) if message.author == bot.user and "下划线模式" not in message.content: if underscored_mode and ' ' in message.content: await message.edit(content=message.content.replace(' ', '_')) bot.run("你的机器人Token")
关键修正点说明
- 修正事件参数:移除
on_message中多余的before参数,仅保留官方定义的message参数。 - 修复变量赋值逻辑:在
underscored命令中用global声明全局变量,用=完成赋值(原代码==是比较运算符,不会改变变量状态),同时改为切换模式的逻辑更实用。 - 避免错误与循环:在
on_message中先处理命令,再判断消息是否来自机器人本身,跳过开关提示消息,防止重复编辑触发循环,也避免尝试编辑用户消息引发权限错误。 - 两种实现思路:
- 直接在命令内根据开关生成对应格式内容(更高效,无需编辑消息)。
- 通过
on_message统一拦截处理所有机器人消息(适用于全命令输出格式统一修改)。
原代码的其他隐性问题
- 未声明全局变量,函数内的
underscored会被视为局部变量,无法影响全局开关状态。 on_message未过滤消息来源,会尝试编辑所有用户的消息,大概率触发权限报错。
内容的提问来源于stack exchange,提问作者waw
相关产品推荐
相关产品推荐

