如何判断discord.Message是否为回复消息及优化Discord机器人%pin命令获取用户回复的目标消息
解决Discord机器人%pin命令的两个问题
嘿,很高兴你在做这个趣味编程实践项目!这两个问题在discord.py(假设你用的是这个最常用的Discord机器人库)里都有清晰的解决方案,我一步步给你讲:
一、如何判断一条discord.Message是否是回复消息?
在discord.py中,每条Message对象都自带一个reference属性:
- 如果这条消息不是回复,
message.reference的值是None - 如果这条消息是回复,
message.reference会包含被回复消息的引用信息,你可以通过message.reference.resolved直接获取被回复的那条Message对象(注意:如果被回复的消息已经被删除,resolved会返回None,所以要做异常处理)
举个简单的判断示例:
# 假设msg是你拿到的discord.Message对象 if msg.reference is not None: # 尝试获取被回复的消息 replied_msg = msg.reference.resolved if isinstance(replied_msg, discord.Message): print(f"这条消息是回复:{replied_msg.content}") else: print("被回复的消息已经不存在啦") else: print("这条消息不是回复")
二、修改%pin命令,置顶用户回复的消息
原来的逻辑是取聊天最后一条消息,现在我们改成:当用户发送%pin时,检查这条命令消息是不是在回复某条消息,如果是,就置顶那条被回复的消息;如果不是,给用户提示需要回复消息再执行命令。
给你个完整的命令示例(适配discord.py v2.x版本):
import json import discord from discord.ext import commands bot = commands.Bot(command_prefix='%', intents=discord.Intents.all()) @bot.command(name='pin') async def custom_pin(ctx): # 检查当前命令消息是否是回复 if not ctx.message.reference: await ctx.send("请先回复你想要置顶的消息,再发送%pin命令哦!") return # 获取被回复的消息 try: target_msg = ctx.message.reference.resolved if not isinstance(target_msg, discord.Message): await ctx.send("抱歉,无法获取到你回复的消息(可能已经被删除)") return # 这里写入你的json文件逻辑,比如存储消息ID、内容、频道ID等 pinned_data = { "message_id": target_msg.id, "content": target_msg.content, "channel_id": target_msg.channel.id, "author": target_msg.author.name } # 写入json文件(这里用追加模式,你也可以根据需求改成覆盖或其他方式) with open('pinned_messages.json', 'a', encoding='utf-8') as f: json.dump(pinned_data, f, ensure_ascii=False) f.write('\n') # 每条数据换行,方便后续读取 await ctx.send(f"成功将这条消息写入置顶列表:\n> {target_msg.content[:100]}...") except Exception as e: await ctx.send(f"处理时出错啦:{str(e)}") # 记得替换成你的机器人token bot.run('YOUR_BOT_TOKEN')
如果你用的是discord.py v1.x版本
v1.x里没有resolved属性,需要通过message_id手动获取消息:
# 在custom_pin函数里替换获取target_msg的部分 reference = ctx.message.reference target_msg_id = reference.message_id try: target_msg = await ctx.channel.fetch_message(target_msg_id) # 后续逻辑和上面一样 except discord.NotFound: await ctx.send("被回复的消息不存在啦")
这样修改后,你的%pin命令就可以精准置顶用户回复的消息啦,而且也能正确判断消息是否为回复类型~
内容的提问来源于stack exchange,提问作者simo.
相关产品推荐
相关产品推荐

