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

如何在Python中将Discord机器人last_message命令转为Slash命令?

解决Discord机器人last_message命令转Slash命令的问题

你遇到的问题是直接替换装饰器后Slash命令无法在Replit上正常工作,核心原因是Slash命令需要正确的参数定义、Discord端的命令注册,以及适配ApplicationContext的回复方式。以下是修改后的完整可行代码:

import discord
from discord.ext import commands
from datetime import timedelta, datetime
import pytz
from webserver import keep_alive

# 必须开启message_content意图才能读取消息内容
intents = discord.Intents.all()
intents.message_content = True

bot = commands.Bot(command_prefix='/', intents=intents)

# 替换为Slash命令装饰器,指定命令名称和描述
@bot.slash_command(name="last_message", description="查询指定用户的最新消息")
async def last_message(ctx: discord.ApplicationContext, user: discord.Member):
    newest_message = None
    newest_channel = None
    # 遍历机器人可见的所有文本频道
    for channel in bot.get_all_channels():
        if isinstance(channel, discord.TextChannel):
            # 检查机器人是否有读取频道历史的权限
            if not channel.permissions_for(ctx.guild.me).read_message_history:
                continue
            async for message in channel.history(limit=300):
                if message.author == user:
                    if newest_message is None or message.created_at > newest_message.created_at:
                        newest_message = message
                        newest_channel = channel

    if newest_message is not None:
        now = datetime.now(pytz.utc)
        message_age = now - newest_message.created_at
        days_old = message_age.days
        # 保持原逻辑的UTC+1时间转换
        response_time = newest_message.created_at + timedelta(hours=1)
        response = (
            f"{user.mention}的最新消息:\n\n"
            f"{newest_message.content}\n\n"
            f"由{user.display_name}发送于{newest_channel.mention},时间:{response_time.strftime('%b %d, %Y %I:%M %p')}\n\n"
            f"距离现在已过去{days_old}天。"
        )
    else:
        response = f"未找到用户{user.display_name}({user.name})的任何消息。"

    # Slash命令必须用respond方法回复,而非send
    await ctx.respond(response)

@bot.event
async def on_ready():
    print(f"已登录为{bot.user}")
    # 可选:将命令同步到指定服务器(测试用,同步后立即生效)
    # 替换为你的服务器ID
    # guild = discord.Object(id=1234567890)
    # bot.tree.copy_global_to(guild=guild)
    # await bot.tree.sync(guild=guild)
    # print("已同步命令到指定服务器")

keep_alive()
bot.run('你的机器人TOKEN')

关键修改说明:

  • 装饰器替换:用@bot.slash_command()替代@bot.command(),补充命令描述以符合Discord Slash命令规范。
  • 参数定义:保留discord.Member类型注解,Discord会自动生成@用户选择器,支持直接@目标用户传参。
  • 回复方式:Slash命令必须使用ctx.respond()而非ctx.send(),否则会触发API错误。
  • 权限检查:新增频道历史读取权限校验,避免机器人因权限不足抛出异常。
  • 意图配置:显式开启message_content意图,这是Discord当前读取消息内容必须开启的权限。
  • 命令同步:若需快速测试,可取消on_ready中的注释并替换服务器ID,服务器级命令同步后立即生效,全局命令同步需约1小时。

在Replit环境中,确保机器人TOKEN正确,且Discord开发者后台已开启对应intents(服务器成员意图、消息内容意图)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 08:54:59