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

Python新手求助:Discord.py传统Echo命令转Slash Command失败

把Discord.py传统Echo命令转成斜杠命令的完整实现

先上适合Python初学者的完整可运行代码:

import discord
from discord import app_commands
from datetime import timedelta
import asyncio

# 用Bot类更适配斜杠命令生态,自带命令树管理
class MyBot(discord.Client):
    def __init__(self, *, intents: discord.Intents):
        super().__init__(intents=intents)
        self.tree = app_commands.CommandTree(self)

    async def setup_hook(self):
        # 开发阶段用服务器专属同步(立即生效),替换成你的服务器ID
        guild = discord.Object(id=123456789012345678)
        self.tree.copy_global_to(guild=guild)
        await self.tree.sync(guild=guild)

# 开启必要的意图,消息内容意图必须手动开启
intents = discord.Intents.default()
intents.message_content = True
bot = MyBot(intents=intents)

@app_commands.command(name="echo", description="将文本发送到指定频道,支持延迟发送")
@app_commands.describe(
    message="要发送的文本内容(必填)",
    channel="目标频道(留空则用当前频道)",
    delay="延迟时间,格式为数字+h/m,比如1h或30m(留空则立即发送)"
)
async def echo(interaction: discord.Interaction, message: str, channel: discord.TextChannel = None, delay: str = None):
    # 处理目标频道逻辑
    target_channel = channel or interaction.channel
    if not target_channel:
        await interaction.response.send_message("无法定位目标频道", ephemeral=True)
        return

    # 处理延迟发送逻辑
    if delay:
        try:
            num = int(delay[:-1])
            unit = delay[-1].lower()
            if unit == "h":
                time_delta = timedelta(hours=num)
            elif unit == "m":
                time_delta = timedelta(minutes=num)
            else:
                raise ValueError("时间单位只能是h(小时)或m(分钟)")
            
            # 斜杠命令必须3秒内响应,先给用户发送提示
            await interaction.response.send_message(f"将在{time_delta}后发送消息", ephemeral=True)
            await asyncio.sleep(time_delta.total_seconds())
        except (ValueError, IndexError):
            await interaction.response.send_message("延迟格式错误,请输入类似1h或30m的格式", ephemeral=True)
            return
    else:
        # 无延迟时直接回复确认
        await interaction.response.send_message("已发送消息", ephemeral=True)

    # 执行最终的echo发送
    await target_channel.send(message)

@bot.event
async def on_ready():
    print(f"已登录为 {bot.user} (ID: {bot.user.id})")
    print("------")

# 替换成你的机器人令牌
bot.run("YOUR_BOT_TOKEN")

关键逻辑对比&说明(对应你原来的传统命令)

  1. 参数处理大幅简化:

    • 原来需要手动解析args里的频道提及格式(<#123>),现在直接用discord.TextChannel类型参数,用户在Discord界面直接选择频道,机器人自动拿到频道对象,无需手动提取ID。
    • 消息内容设为必填参数,Discord会自动拦截无内容的命令调用,省去你原来的空参数判断逻辑。
  2. 斜杠命令核心规则:

    • 斜杠命令必须在3秒内给用户返回响应,所以用interaction.response.send_message处理用户提示,加ephemeral=True让回复仅用户可见,避免刷屏。
    • 延迟发送时必须先回复用户,再执行sleep,否则Discord会判定命令超时。
  3. 命令同步机制:

    • 新的斜杠命令需要同步到Discord服务器才能被用户看到,setup_hook里的代码是开发阶段的快速同步方式,指定服务器ID后重启机器人即可立即生效;如果要全局同步,去掉guild参数即可,但生效需要1小时左右。
  4. 错误处理优化:

    • 新增延迟格式的错误捕获,用户输入错误格式时会收到明确提示,比原来的静默失败更友好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 10:26:04