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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 09:33:22