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

使用discord.py开发Discord机器人,斜杠命令无法同步至内置命令助手

问题:Discord.py 斜杠命令无法显示在命令提示弹窗中

我正在使用discord.py库开发Python版Discord机器人,希望slash commands(斜杠命令)能在用户开始输入斜杠命令时,显示在Discord的命令提示弹窗中。据我了解,目前有两种实现方式:interactions库或discord.ext.commands包。但现在切换到interactions库有一定难度,且我不确定这能否解决我的问题。除了命令无法显示在提示窗中,以下代码功能正常(尽管不够美观)。请问我缺少什么配置才能让机器人与命令助手正确同步?

## Import statements
import configparser
from discord.ext import commands
import discord
import typing
from dataclasses import dataclass, field

#Load in config file/config settings
config = configparser.RawConfigParser()
try:
    config.read('config.properties')
except:
    print("Failed to read config.properties - Make sure the file exists")
    exit

#Dataclass of a User which we will store in a queue
@dataclass
class User:
    social_name: str = ""
    alt_name: str = ""
    username: str = ""
    discord_user_id: int = 0

@dataclass
class Queue:
    name: str = ""
    rate: int = 1
    vc_optional: bool = True
    vc_id: int = 0
    users_at_bat: list[User] = field(default_factory=list)
    user_list: list[User] = field(default_factory=list)
    locked: bool = False

ACTIVE_QUEUES = list()

def getActiveQueuesList():
    return [q.name for q in ACTIVE_QUEUES]

def getQueuesString():
    queues = "<Type: None>"
    if len(ACTIVE_QUEUES) > 0:
        queues = ACTIVE_QUEUES[0].name
    if len(ACTIVE_QUEUES) > 1:
        for q in ACTIVE_QUEUES[1::]:
            queues.append(", " + q.name)
    return queues

def insertUserIntoQueue(queueName, user):
    success = False
    for q in ACTIVE_QUEUES:
        if q.name == queueName:
            success = True
            q.user_list.append(user)
    return success

#Starting the discord bot
bot = commands.Bot(command_prefix=".", intents=discord.Intents.all())



@bot.listen('on_ready')
async def on_ready():
    print("Hello! Chromes Py-Bot is ready!")
    channel = bot.get_channel(int(config.get('Discord', 'BOT_LOG_ID')))
    await channel.send("Hello! Chromes Py-Bot is ready!")



@bot.command(
        name="ping",
        description="Ping command"
)
async def ping(ctx):
    await ctx.send("pong!")



@bot.command(
        name="helpme",
        description="not gonna help ya btw"
)
async def helpme(ctx):
    await ctx.send("no")



@bot.command(
        name="getQueues",
        description="Get the queues locked or not"
)
async def getQueues(ctx):
    await ctx.send(f"There are {len(ACTIVE_QUEUES)} active queues: {getQueuesString()}")



@bot.command(
        name="createQueue",
        description="it's a little on the nose ik"
)
async def createQueue(ctx, name: str, rate: typing.Optional[int] = 1, vc_id: typing.Optional[int] = 0, vc_optional: typing.Optional[bool] = True):
    if name in getActiveQueuesList():
        await ctx.send(f"Failed to create queue {name} because a queue already exists with that name.")
        return
    queue = Queue(name, rate, vc_optional, vc_id)
    ACTIVE_QUEUES.append(queue)
    await ctx.send(f"Created queue: {queue.name}")



@bot.command(
        name="deleteQueue",
        description="deletes the queue based on the name you put in"
)
async def deleteQueue(ctx, name):
    for q in ACTIVE_QUEUES[::-1]:
        if q.name == name:
            ACTIVE_QUEUES.remove(q)
    await ctx.send(f"There are now {len(ACTIVE_QUEUES)} active queues: {getQueuesString()}")



@bot.command(
        name="joinQueue",
        description="joins the author into the specified queue"
)
async def joinQueue(ctx, queue: str, username: typing.Optional[str] = ""):
    author = ctx.author
    alt_name = ""
    if author.nick is not None:
        alt_name = author.nick
    user = User(author.display_name, alt_name, username, author.id)
    if insertUserIntoQueue(queue, user):
        await ctx.send(str(user) + " added to the queue: " + queue)
    else:
        await ctx.send(str(user) + " failed to be added to the queue: " + queue)


bot.run(config.get('Discord', 'BOT_TOKEN'))

解决方案

你当前用的@bot.command()是前缀触发命令(比如.ping),并非Discord官方的斜杠命令。要让命令出现在斜杠提示弹窗里,需要使用discord.py原生支持的应用命令(Application Commands),步骤如下:

1. 替换命令装饰器与交互逻辑

把所有@bot.command()替换为@bot.tree.command(),同时修改命令的参数与回复方式:

  • 原来的ctx参数要换成discord.Interaction对象
  • 回复消息需用await interaction.response.send_message(),而不是ctx.send()

示例:修改ping命令

@bot.tree.command(name="ping", description="Ping command")
async def ping(interaction: discord.Interaction):
    await interaction.response.send_message("pong!")

2. 同步命令到Discord服务器

必须将命令同步到Discord的命令列表,弹窗才会显示。在on_ready事件中添加同步代码:

  • 服务器同步:即时生效,适合开发测试,需要在配置文件中添加服务器ID
  • 全局同步:生效时间约1小时,适合正式发布,有速率限制

修改后的on_ready示例:

@bot.listen('on_ready')
async def on_ready():
    print("Hello! Chromes Py-Bot is ready!")
    # 同步到指定服务器(替换为你的服务器ID,需在config.properties中添加GUILD_ID字段)
    guild_id = int(config.get('Discord', 'GUILD_ID'))
    guild = discord.Object(id=guild_id)
    # 将全局命令复制到指定服务器
    bot.tree.copy_global_to(guild=guild)
    # 执行同步
    await bot.tree.sync(guild=guild)
    
    # 如果需要全局同步,注释上面三行,使用下面一行
    # await bot.tree.sync()
    
    channel = bot.get_channel(int(config.get('Discord', 'BOT_LOG_ID')))
    await channel.send("Hello! Chromes Py-Bot is ready! 斜杠命令已同步!")

3. 处理带参数的命令

对于带参数的命令(比如createQueue),直接保留参数定义即可,discord.py会自动适配为斜杠命令的选项:

@bot.tree.command(name="createqueue", description="创建一个新队列")
async def create_queue(interaction: discord.Interaction, 
                       name: str, 
                       rate: typing.Optional[int] = 1, 
                       vc_id: typing.Optional[int] = 0, 
                       vc_optional: typing.Optional[bool] = True):
    if name in getActiveQueuesList():
        await interaction.response.send_message(f"创建队列失败:{name} 已存在")
        return
    queue = Queue(name, rate, vc_optional, vc_id)
    ACTIVE_QUEUES.append(queue)
    await interaction.response.send_message(f"已创建队列:{queue.name}")

4. 权限检查

确保机器人在Discord开发者门户的OAuth2设置中,勾选了applications.commands权限,重新邀请机器人到服务器时需要包含该权限。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 16:59:52