使用Discord.py Cog无法回复斜杠命令,机器人挂起崩溃
Discord.py Cog斜杠命令执行后机器人挂起崩溃问题修复
问题现象
执行/ping斜杠命令后,机器人长时间无响应,最终崩溃。
问题代码
Cog代码片段
import discord from discord import app_commands from discord.ext import commands class Example(commands.Cog): def __init__(self, bot: commands.Bot): self.bot = bot @commands.Cog.listener() async def on_ready(self): print("ChatGPT cog connected.") @commands.command() async def sync(self, ctx) -> None: fmt = await ctx.bot.tree.sync(guild=ctx.guild) await ctx.send(f"Synced {len(fmt)} commands") @app_commands.command(name="ping", description="desc") async def ping(self, ctx): await ctx.reply("pong")
主文件代码片段
import discord from discord.ext import commands import os from tools.config import TOKEN import asyncio client = commands.Bot(command_prefix="!", intents=discord.Intents.all()) @client.event async def on_ready(): print("Success: Bot is connected to Discord") async def load(): for filename in os.listdir("./cogs"): if filename.endswith("py"): await client.load_extension(f"cogs.{filename[:-3]}") async def main(): await load() await client.start(TOKEN) if __name__ == "__main__": asyncio.run(main())
问题原因
app_commands.command装饰的斜杠命令函数,接收的参数是**discord.Interaction对象**,而非传统前缀命令的Context(ctx)对象。原代码中用ctx.reply()调用了不存在的方法,引发未处理的异常,导致机器人挂起并崩溃。
修复方案
将斜杠命令的参数改为interaction,并使用Interaction对象的响应方法发送消息:
修复后的Cog代码
import discord from discord import app_commands from discord.ext import commands class Example(commands.Cog): def __init__(self, bot: commands.Bot): self.bot = bot @commands.Cog.listener() async def on_ready(self): print("ChatGPT cog connected.") @commands.command() async def sync(self, ctx) -> None: fmt = await ctx.bot.tree.sync(guild=ctx.guild) await ctx.send(f"Synced {len(fmt)} commands") @app_commands.command(name="ping", description="回复pong") async def ping(self, interaction: discord.Interaction): # 立即发送响应,必须在3秒内完成 await interaction.response.send_message("pong")
额外说明
- 斜杠命令必须在3秒内调用
interaction.response相关方法,否则Discord会判定命令超时。 - 如果需要后续发送消息(比如处理耗时任务后),可以先调用
await interaction.response.defer()延迟响应,再用await interaction.followup.send()发送后续内容。
内容的提问来源于stack exchange,提问作者syrok
相关产品推荐
相关产品推荐

