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

Python开发Discord机器人:服务器内创建的自定义命令无法触发问题求助

Python开发Discord机器人:服务器内创建的自定义命令无法触发问题求助

我正在用Python开发一个Discord机器人,想要实现服务器内创建自定义命令的功能——也就是通过机器人自带的命令来生成新的自定义指令,指令触发后机器人会回复预设内容。根据查到的资料,我需要用字典来存储这些自定义命令的映射关系,于是参考了一份旧教程写出了下面的代码(感谢原作者Furas):

import discord
from discord.ext import commands

new_dict = {}


bot = commands.Bot(command_prefix='>', intents=discord.Intents.all())

@bot.command('create')
async def create(ctx, *args):
print("Hey it works")
    print('[create] ctx:', ctx)
    print('[create] args:', args)
    
     if len(args) >= 2:
        key = '!' + args[0]
        val = args[1]
        new_dict[key] = val
    
async def on_message(msg, *args):
    
    if msg.author.bot:
        return

    cmd, *args = msg.content.split(' ')
    
    if cmd in new_dict:
        answer = new_dict[cmd]
        await msg.reply(answer) 
    else:
        # send to other commands
        await bot.process_commands(msg)

    cmd, *args = msg.content.split(' ')
    
    if cmd in new_dict:
        answer = new_dict[cmd]
        await msg.reply(answer) 
    else:
        # send to other commands - like `!create`
        await bot.process_commands(msg)

bot.run('THE TOKEN')

预期功能

当我输入>create并跟上参数时,希望机器人生成一个自定义命令:第一个参数作为命令名,第二个参数(或后续所有内容)作为机器人的回复内容。

举个例子:

输入:>create cat meow
期望效果:之后输入>cat,机器人回复meow

目前遇到的问题

执行>create命令时,终端能打印出Hey it works和参数内容,说明create命令本身能被触发,但自定义命令创建完成后,输入触发词会提示CommandNotFound错误,完全无法触发预设的回复。机器人已经正常上线,消息意图也已开启,终端日志如下:

2025-03-18 23:21:38 INFO     discord.client logging in using static token
2025-03-18 23:21:39 INFO     discord.gateway Shard ID None has connected to Gateway (Session ID: 996c857e3c3c141b35d24977f6a9e025).
Hey it works
[create] ctx: <discord.ext.commands.context.Context object at 0x000001B2BDA1F6E0>
[create] args: ()
Hey it works
[create] ctx: <discord.ext.commands.context.Context object at 0x000001B2BC4DBB30>
[create] args: ('cat', 'meow')
2025-03-18 23:22:01 ERROR    discord.ext.commands.bot Ignoring exception in command None
discord.ext.commands.errors.CommandNotFound: Command "cat" is not found

问题分析与修复方案

你的代码里有几个关键问题导致自定义命令无法正常触发,我来逐一说明并给出修复后的完整代码:

  • on_message未注册为事件监听器:你定义了on_message函数,但没有用@bot.event装饰器标记,机器人根本不会执行这个函数里的逻辑!
  • 自定义命令的键名前缀错误:你在create命令里把键设为! + args[0],但机器人默认前缀是>,这导致字典里存的是!cat,但你实际输入的是>cat,自然匹配不到。
  • on_message存在重复逻辑:你写了两遍完全一样的命令匹配代码,不仅冗余还可能引发逻辑冲突。
  • 回复内容只能支持单单词:原始代码仅取第二个参数作为回复,无法处理多单词的回复内容。

修复后的完整代码

import discord
from discord.ext import commands

# 存储自定义命令:键是完整触发命令(比如">cat"),值是回复内容
custom_commands = {}

# 初始化机器人,前缀为">",开启所有必要意图
bot = commands.Bot(command_prefix='>', intents=discord.Intents.all())

@bot.command(name='create')
async def create_custom_command(ctx, cmd_name: str, *, response: str):
    """创建自定义命令:用法 >create 命令名 回复内容(回复内容支持多单词)"""
    print(f"[create] 收到创建请求:命令名={cmd_name},回复内容={response}")
    # 拼接完整的命令触发词(带上机器人的前缀)
    full_cmd = f"{bot.command_prefix}{cmd_name}"
    custom_commands[full_cmd] = response
    await ctx.reply(f"自定义命令`{full_cmd}`已创建完成!触发后我会回复:{response}")

@bot.event
async def on_message(msg):
    # 忽略机器人自己的消息,避免循环
    if msg.author.bot:
        return

    # 先提取完整的触发命令(比如">cat")
    full_cmd = msg.content.split(' ')[0]
    # 检查是否是自定义命令
    if full_cmd in custom_commands:
        await msg.reply(custom_commands[full_cmd])
    else:
        # 交给机器人处理自带命令(比如>create)
        await bot.process_commands(msg)

# 运行机器人
bot.run('你的机器人TOKEN')

改动说明

  1. 注册事件监听器:给on_message加上@bot.event装饰器,确保机器人执行该逻辑。
  2. 修正命令前缀:用bot.command_prefix拼接命令名,保证存储的键和实际输入的触发命令完全一致。
  3. 支持多单词回复:用*, response: str作为参数,能接收命令名之后的所有内容作为回复(比如>create greet 欢迎来到服务器!)。
  4. 简化逻辑:删除重复的命令匹配代码,让逻辑更清晰。
  5. 语义化命名:把new_dict改成custom_commands,提升代码可读性。

测试效果

  1. 输入>create cat meow,机器人会回复确认消息;
  2. 之后输入>cat,机器人会立刻回复meow;
  3. 还能创建多单词回复的命令,比如>create greet 欢迎来到服务器!有问题随时找管理~,输入>greet就能收到完整回复。

备注:内容来源于stack exchange,提问作者Soopah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 19:14:29