如何使用discord.PartialEmoji/discord.Emoji对象解决反应角色表情报错问题
问题核心原因
discord.Emoji转换器仅支持识别当前服务器上传的自定义表情,无法识别系统默认的Unicode表情,传入Unicode表情就会抛出EmojiNotFound错误PartialEmoji转换失败通常是输入表情格式异常、discord.py版本过旧导致,另外直接把Emoji/PartialEmoji对象存入数据库、后续查询时类型不匹配也是核心问题
修复步骤
1. 替换命令参数的表情转换器
使用Union[discord.Emoji, discord.PartialEmoji]作为参数类型,同时兼容自定义表情和Unicode表情:
# 先导入Union from typing import Union @commands.command() async def test(self,ctx,emoji: Union[discord.Emoji, discord.PartialEmoji] = None): await ctx.send(str(emoji))
2. 修正数据库存储逻辑
不要直接存表情对象,统一转成字符串格式存入数据库:
- 自定义表情转成字符串后是
<:表情名:表情ID>格式,可直接用来添加反应 - Unicode表情转成字符串就是本身的emoji字符
同时建议角色也存储ID而非字符串,后续查找更准确,修改reactionrole命令里的存储逻辑:
# 原来的val = (msgid,emoji,str(role))替换为 val = (msgid, str(emoji), role.id)
3. 修复反应事件的匹配逻辑
用户触发反应时拿到的emoji对象,同样转成字符串再去数据库匹配,同时修复SQL注入风险,使用参数化查询:
async def reaction_roles_role(msgid, emoji): db = sqlite3.connect("db.sqlite") cursor = db.cursor() cursor.execute("SELECT role FROM reaction_role WHERE message_id = ? and emoji = ?", (msgid, str(emoji))) result = cursor.fetchone() cursor.close() db.close() return result
4. 兜底兼容处理
如果仍出现PartialEmoji转换失败,可以新增手动转换逻辑兜底:
def get_emoji(raw_emoji: str): try: return discord.PartialEmoji.from_str(raw_emoji) except: # 兜底返回原始字符串,对应Unicode表情场景 return raw_emoji
可选优化
将msgid参数改为discord.Message类型,discord.py会自动根据传入的消息链接/ID提取消息对象,无需手动fetch:
async def reactionrole(self,ctx,msg: discord.Message = None,emoji: Union[discord.Emoji, discord.PartialEmoji] = None , role: discord.Role = None ): # 后续直接使用msg对象即可,无需调用fetch_message await msg.add_reaction(emoji) val = (msg.id, str(emoji), role.id)
内容的提问来源于stack exchange,提问作者tr3x
相关产品推荐
相关产品推荐

