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

discord.py中Cogs模块下反应角色功能失效求助

问题分析与修复方案

核心问题1:命令类型不匹配

你给rr命令用了@app_commands.command()装饰器,这是Discord斜杠命令的定义方式,只能通过/rr调用,而你用的是前缀>rr,自然没有响应。需要改成前缀命令的装饰器@commands.command()。

核心问题2:监听器参数与调用错误

  • on_raw_reaction_add监听器多了一个ctx参数,该事件只接收payload,多余参数会导致监听器无法触发。
  • 获取频道、公会时错误使用commands.get_channel/commands.get_guild,应该通过self.bot实例调用对应方法。
  • 颜色角色的添加/移除代码缩进错误,导致逻辑混乱。
  • 自定义表情判断可以结合ID更准确,避免重名表情冲突。

其他细节问题

  • 未处理Role为None的情况(比如角色不存在时),会导致隐性报错。
  • on_raw_reaction_remove中获取公会的方式错误,且多余的message变量未使用。

修改后的完整代码

main.py(无需修改,保持原样)

import discord
from discord.ext import commands
from discord import app_commands
import os
import asyncio

intents = discord.Intents.all()
bot = commands.Bot(command_prefix=">",intents=intents)

asta_guild_id = 1030203387423236136

# Cogs Setup
async def load():
    for filename in os.listdir("./Cogs"):
      if filename.endswith(".py"):
        await bot.load_extension(f"Cogs.{filename[:-3]}")

@bot.event
async def on_connect():
    print("Bot has connected!")
    
@bot.event
async def on_ready():
    print("Bot is Ready!")

async def main():
  await load()
  await bot.start("MY_TOKEN", reconnect=True)

asyncio.run(main())

Cogs/ReactionRoles.py(修复后)

import discord
from discord.ext import commands
from discord import app_commands

asta_guild_id = 1030203387423236136
reaction_channel_id = 1039476995324649572
pink_emoji_id = 1041820443692249109

class ReactionRoles(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    # 改成前缀命令装饰器
    @commands.command()
    async def rr(self, ctx):
        if not ctx.author.top_role.permissions.administrator:
            await ctx.reply("Only admins can complete this command.")
            return
        
        await ctx.reply(f"I will DM you once the reaction roles have been created.")
        
        # 发送标题嵌入
        embed = discord.Embed(title="『📜』Reaction Roles!", description=f"React with the corresponding emoji to customise your roles!")
        title_msg = await ctx.send(embed=embed)
        
        # 发送Ping角色嵌入
        embed1 = discord.Embed(title="『📜』Ping Roles:", description=f"React with 🎉 to get pinged for Giveaways\nReact with ⌨️ to get pinged for Chat Revival\nReact with 🎙️ to get pinged for Announcements\nReact with 👮 to get pinged for Staff Notices")
        ping_roles = await ctx.send(embed=embed1)
        await ping_roles.add_reaction("🎉")
        await ping_roles.add_reaction("⌨️")
        await ping_roles.add_reaction("🎙️")
        await ping_roles.add_reaction("👮")
        
        # 发送颜色角色嵌入
        embed2 = discord.Embed(title="『📜』Color Roles:", description=f"React with 🟥 for red colour\nReact with 🟩 for green colour\nReact with 🟦 for blue colour\nReact with <:pink_square:{pink_emoji_id}> for pink colour")
        col_roles = await ctx.send(embed=embed2)
        await col_roles.add_reaction("🟥")
        await col_roles.add_reaction("🟩")
        await col_roles.add_reaction("🟦")
        await col_roles.add_reaction(discord.PartialEmoji(id=pink_emoji_id, name="pink_square"))
        
        # 发送DM通知
        dmembed = discord.Embed(title="", description=f"I have finished setting up the reaction roles in [Reaction Roles]({title_msg.jump_url})")
        await ctx.author.send(embed=dmembed)

    @commands.Cog.listener()
    async def on_raw_reaction_add(self, payload):
        # 过滤非目标频道的反应
        if payload.channel_id != reaction_channel_id:
            return
        # 忽略机器人自身的反应
        if payload.user_id == self.bot.user.id:
            return
        
        guild = self.bot.get_guild(payload.guild_id)
        if not guild:
            guild = await self.bot.fetch_guild(payload.guild_id)
        
        user = guild.get_member(payload.user_id)
        if not user:
            user = await guild.fetch_member(payload.user_id)
        
        # Ping角色处理
        if payload.emoji.name == "🎉":
            role = discord.utils.get(guild.roles, name="Giveaway")
            if role:
                await user.add_roles(role)
        elif payload.emoji.name == "⌨️":
            role = discord.utils.get(guild.roles, name="Chat revival")
            if role:
                await user.add_roles(role)
        elif payload.emoji.name == "🎙️":
            role = discord.utils.get(guild.roles, name="Announcement")
            if role:
                await user.add_roles(role)
        elif payload.emoji.name == "👮":
            role = discord.utils.get(guild.roles, name="Staff Notices")
            if role:
                await user.add_roles(role)
        # 颜色角色处理
        elif payload.emoji.name == "🟥":
            role = discord.utils.get(guild.roles, name="Red")
            if role:
                await user.add_roles(role)
        elif payload.emoji.name == "🟩":
            role = discord.utils.get(guild.roles, name="Green")
            if role:
                await user.add_roles(role)
        elif payload.emoji.name == "🟦":
            role = discord.utils.get(guild.roles, name="Blue")
            if role:
                await user.add_roles(role)
        elif payload.emoji.id == pink_emoji_id:
            role = discord.utils.get(guild.roles, name="Pink")
            if role:
                await user.add_roles(role)

    @commands.Cog.listener()
    async def on_raw_reaction_remove(self, payload):
        # 过滤非目标频道的反应
        if payload.channel_id != reaction_channel_id:
            return
        # 忽略机器人自身的反应
        if payload.user_id == self.bot.user.id:
            return
        
        guild = self.bot.get_guild(asta_guild_id)
        if not guild:
            guild = await self.bot.fetch_guild(asta_guild_id)
        
        user = guild.get_member(payload.user_id)
        if not user:
            user = await guild.fetch_member(payload.user_id)
        
        # Ping角色处理
        if payload.emoji.name == "🎉":
            role = discord.utils.get(guild.roles, name="Giveaway")
            if role:
                await user.remove_roles(role)
        elif payload.emoji.name == "⌨️":
            role = discord.utils.get(guild.roles, name="Chat revival")
            if role:
                await user.remove_roles(role)
        elif payload.emoji.name == "🎙️":
            role = discord.utils.get(guild.roles, name="Announcement")
            if role:
                await user.remove_roles(role)
        elif payload.emoji.name == "👮":
            role = discord.utils.get(guild.roles, name="Staff Notices")
            if role:
                await user.remove_roles(role)
        # 颜色角色处理
        elif payload.emoji.name == "🟥":
            role = discord.utils.get(guild.roles, name="Red")
            if role:
                await user.remove_roles(role)
        elif payload.emoji.name == "🟩":
            role = discord.utils.get(guild.roles, name="Green")
            if role:
                await user.remove_roles(role)
        elif payload.emoji.name == "🟦":
            role = discord.utils.get(guild.roles, name="Blue")
            if role:
                await user.remove_roles(role)
        elif payload.emoji.id == pink_emoji_id:
            role = discord.utils.get(guild.roles, name="Pink")
            if role:
                await user.remove_roles(role)

async def setup(bot):
    await bot.add_cog(ReactionRoles(bot))

内容的提问来源于stack exchange,提问作者DRags

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 05:25:12