如何在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
相关产品推荐
相关产品推荐

