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

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)

验证步骤

  1. 确保Discord开发者门户中,你的机器人已开启所有必要的intents(你代码里用了Intents().all(),所以门户里要对应开启)。
  2. 替换修正后的代码,重新启动机器人。
  3. 使用?characters或?c、?adventure或?a指令测试是否正常响应。

内容的提问来源于stack exchange,提问作者Yanaize

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 09:31:43