Discord.py 2.2.3中/react app_command报错,如何实现自定义表情选择?
解决Discord.py 2.2.3中/react斜杠命令的TypeError及需求实现
错误根源
直接用discord.Emoji作为斜杠命令的参数类型会触发TypeError——Discord API传递表情参数时采用PartialEmoji格式,而app_commands不支持直接解析为discord.Emoji对象。
完整解决方案
要实现「显示服务器自定义表情列表+可选message_id」的需求,需结合discord.PartialEmoji参数类型与自动补全功能,同时修正原代码中的异步操作错误:
import discord from discord import app_commands from typing import Optional, List import asyncio class ReactionCog(app_commands.GroupCog, name="reaction"): def __init__(self, bot: discord.Bot): self.bot = bot # 生成服务器自定义表情的自动补全列表 async def emoji_autocomplete(self, interaction: discord.Interaction, current: str) -> List[app_commands.Choice[discord.PartialEmoji]]: # 过滤匹配输入关键词的表情,限制最多25个(Discord补全选项上限) matched_emojis = [ app_commands.Choice(name=emoji.name, value=emoji) for emoji in interaction.guild.emojis if current.lower() in emoji.name.lower() ] return matched_emojis[:25] @app_commands.command(name="react", description="给消息添加表情反应") @app_commands.describe( emoji="选择服务器自定义表情", message_id="目标消息ID(可选,默认给频道最新消息添加)" ) @app_commands.autocomplete(emoji=emoji_autocomplete) async def react(self, interaction: discord.Interaction, emoji: discord.PartialEmoji, message_id: Optional[int] = None): # 处理目标消息获取逻辑 try: if message_id is None: # 修复原代码漏写await的问题 message = await interaction.channel.fetch_message(interaction.channel.last_message_id) else: message = await interaction.channel.fetch_message(message_id) except discord.NotFound: await interaction.response.send_message("未找到指定消息", ephemeral=True) return except discord.Forbidden: await interaction.response.send_message("我没有查看该消息的权限", ephemeral=True) return # 执行添加反应逻辑 try: await message.add_reaction(emoji) await interaction.response.send_message("已添加表情反应!请自行添加反应以保留", ephemeral=True) # 替换同步sleep为异步await,避免阻塞事件循环 await asyncio.sleep(7) # 修复原代码漏传表情参数的问题 await message.clear_reaction(emoji) except discord.Forbidden: await interaction.response.send_message("我没有给该消息添加反应的权限", ephemeral=True) except discord.HTTPException as e: await interaction.response.send_message(f"添加反应失败:{str(e)}", ephemeral=True) async def setup(bot: discord.Bot): await bot.add_cog(ReactionCog(bot))
核心修正与优化点
- 参数类型适配:用
discord.PartialEmoji替代discord.Emoji,匹配Discord API的参数格式,解决TypeError。 - 表情选择列表:通过
@app_commands.autocomplete绑定自定义补全函数,实现类似角色选择的服务器表情列表效果。 - 异步操作修复:补全
await关键字、替换同步sleep为异步版本,避免事件循环阻塞;给clear_reaction补传表情参数。 - 异常处理完善:补充消息获取阶段的权限异常捕获,覆盖更多场景。
最终效果
- 输入
/react后,emoji选项将弹出服务器所有自定义表情的选择列表,支持关键词搜索。 - 不填
message_id时自动给频道最新消息加反应,填写ID则给对应消息加反应。 - 7秒后自动清除机器人添加的反应,符合原逻辑需求。
内容的提问来源于stack exchange,提问作者Fakemaster
相关产品推荐
相关产品推荐

