Discord.py bot.command命令无响应无报错问题咨询
故障核心原因
代码存在三个直接导致命令完全无法触发的问题:
- 重复创建客户端实例:同时初始化了
bot = commands.Bot(...)和client = discord.Client()两个独立的客户端对象,所有命令都注册在bot实例上,但最后调用client.run(my_secret)启动的是没有挂载任何命令的空Client实例,注册的rps命令根本不会被加载,自然不会产生任何响应。 - 命令参数逻辑错误:
@bot.command()装饰的命令函数中,ctx之后的参数是用户在命令后通过空格分隔传入的普通字符串,不是Discord原生Message对象,原代码中answer = message.content.lower()属于错误属性调用,就算启动了正确的bot实例,这行也会抛出属性错误导致命令执行失败。 - 原代码胜负判断分支写得过于零散,多组独立if判断没有做分支拦截,存在漏判无输出的隐患,后续修改很容易漏写对应条件。
修复后可直接运行的代码
import os import discord import random from discord.ext import commands my_secret = os.environ['TOKEN'] intents = discord.Intents().all() # 仅保留commands.Bot实例,不需要额外创建discord.Client对象 bot = commands.Bot(command_prefix='!', intents=intents) @bot.command() async def rps(ctx, user_choice): answer = user_choice.lower() choices = ["rock", "paper", "scissors"] computer_answer = random.choice(choices) if answer not in choices: await ctx.send('You have to answer with "rock" "paper" or "scissors", dummy!') return # 平局判断 if computer_answer == answer: await ctx.send('Darn, we tied... Rematch!!') return # 用映射表简化胜负判断,避免零散if分支漏判 win_rule = { "rock": "scissors", "paper": "rock", "scissors": "paper" } if win_rule[answer] == computer_answer: # 用户获胜分支 win_resp = { "paper": 'Aw, no fair! You won...', "rock": 'Arrgh!! Fine, you win.', "scissors": 'Wow. Good for you /s' } await ctx.send(win_resp[answer]) else: # 机器人获胜分支 lose_resp = { "rock": 'Well, looks like I won ;)', "paper": 'Hehehe! I won~', "scissors": 'Hahaha! Take that!! I win~!' } await ctx.send(lose_resp[computer_answer]) # 启动挂载了命令的bot实例,不要调用空client的run方法 bot.run(my_secret)
额外注意事项
- 命令触发格式为在聊天框输入
!rps rock/!rps paper/!rps scissors,选择内容需要和命令用空格分隔,否则会触发缺少参数的错误。 - 确认Discord开发者后台对应机器人的*Message Content Intent(消息内容权限)*已经开启,否则就算代码里设置了
intents.all(),也无法接收普通用户发送的消息内容,导致命令无法识别。 - 如果后续需要添加
on_message事件监听,必须在事件函数的最后添加await bot.process_commands(message),否则命令会被事件拦截无法触发。
内容的提问来源于stack exchange,提问作者Ver
相关产品推荐
相关产品推荐

