Discord机器人在线无报错但不响应命令求助
问题诊断与修复方案
核心问题:错误启动了Client而非Bot实例
你同时创建了discord.Client和commands.Bot两个实例,但最终调用的是client.run(TOKEN)启动普通客户端,而非bot.run(TOKEN)启动命令机器人。commands.Bot是Client的子类,内置了命令处理逻辑,只有启动Bot实例,你的@bot.command装饰的指令才会被触发。
其他代码问题与修正
除了核心启动问题,代码里还有几处逻辑或语法错误需要修复:
- 多余的
bot.process_commands(ctx)调用:命令函数内部无需手动调用该方法,Bot会自动处理消息并触发对应命令,手动调用可能导致逻辑混乱。 - 参数解析错误:
characters命令中手动拆分消息内容获取页码的方式不规范,且ctx没有content属性,应使用commands内置的参数解析功能。 - 字符串拼接语法错误:
embed.add_field的name参数拼接方式有误,会触发语法错误。 - 冒险槽逻辑颠倒:初始槽状态和占用判断逻辑相反,导致一开始就提示槽位已满。
- 私信内容错误:返回的
character是数据库元组,直接拼接会显示不友好的格式,应取具体字段。
修正后的完整代码
import discord from discord.ui import Button, View from discord.ext import commands import database from dotenv import load_dotenv import asyncio import os load_dotenv('tokens.env') TOKEN = os.getenv("DISCORD_TOKEN") intents = discord.Intents().all() # 只需要创建Bot实例,无需单独创建Client bot = commands.Bot(command_prefix='?', intents=intents) # 修正槽位初始状态:False表示空,True表示已占用 adventure_slots = [False, False, False] adventurers = {} @bot.command(aliases=["c"]) # 使用内置参数解析,默认页码为1 async def characters(ctx, page: int = 1): print(ctx) username = ctx.author.display_name offset = (page - 1) * 10 characters = database.get_characters(offset) embed = discord.Embed(title="Character List", color=0x0eebeb) character_list = "" total_characters = 0 for character in characters: character_list += f"• {character[1]} | {character[3]}\n" total_characters += 1 # 修正字符串拼接为正确的f-string embed.add_field( name=f"{username} has a total of {total_characters} characters:", value=character_list, inline=False ) footer_text = "" if page > 1: footer_text += "<< Prev" if len(characters) == 10: footer_text += " | Next >>" embed.set_footer(text=footer_text) await ctx.channel.send(embed=embed) print(ctx) @bot.command(aliases=["a"]) async def adventure(ctx): print(ctx) # 修正槽位满的判断逻辑:所有槽都为True时才满 if all(slot for slot in adventure_slots): await ctx.send("All adventure slots are currently full. Please try again later.") return message = await ctx.send("Please pick the character you would like to send by typing `r!'character_name'`") def check(m): return m.author == ctx.author and m.content.startswith("r!'") and len(m.content.split()) == 2 try: character_message = await bot.wait_for("message", check=check, timeout=60.0) except asyncio.TimeoutError: await ctx.send("Timed out waiting for character name. Please try the `?adventure` command again.") return character_name = character_message.content.split()[1].strip("'") # 去掉多余的引号 character = database.get_character(character_name) if not character: await ctx.send(f"Character `{character_name}` not found.") return # 找到空槽并标记为已占用 for i, slot in enumerate(adventure_slots): if not slot: adventure_slots[i] = True break else: return await ctx.send(f"{character_name} has been sent on an adventure! They will return in 3 hours.") await asyncio.sleep(3 * 3600) # 3 hours in seconds # 使用character的名字字段而非整个元组 await ctx.author.send(f"{character[1]}'s adventure is complete! You can collect your loot now.") # 启动Bot实例而非Client bot.run(TOKEN)
验证步骤
- 确保Discord开发者门户中,你的机器人已开启所有必要的intents(你代码里用了
Intents().all(),所以门户里要对应开启)。 - 替换修正后的代码,重新启动机器人。
- 使用
?characters或?c、?adventure或?a指令测试是否正常响应。
内容的提问来源于stack exchange,提问作者Yanaize
相关产品推荐
相关产品推荐

