Discord Bot权限问题:!sendmessage命令角色限制失效排查修复
问题原因与修正方案
错误点分析
- 参数类型错误:
@commands.has_any_role()装饰器不接受discord.Object类型参数,它仅支持整数角色ID、角色名称字符串或直接的Role对象。你传入discord.Object(id=allowed_role_id),导致装饰器无法正确校验用户角色权限。 - 变量赋值语法错误:
allowed_role_id = (---)是无效Python语法,需替换为实际的整数角色ID,例如allowed_role_id = 123456789012345678。
修改后的完整代码
import discord from discord.ext import commands # 替换为你允许的角色ID(整数) allowed_role_id = 123456789012345678 # 配置必要的意图 intents = discord.Intents.default() intents.members = True # 需开启成员意图才能获取服务器成员列表 intents.message_content = True # 需开启消息内容意图才能处理命令 bot = commands.Bot(command_prefix='!', intents=intents) @bot.event async def on_ready(): print(f'Logged in as {bot.user} (ID: {bot.user.id})') @bot.command(name='sendmessage') # 直接传入角色ID整数即可完成权限校验 @commands.has_any_role(allowed_role_id) async def send_message(ctx, *, message: str): for member in ctx.guild.members: if not member.bot: dm_channel = await member.create_dm() sent_message = await dm_channel.send(message) await sent_message.add_reaction("✅") await sent_message.add_reaction("❌") await sent_message.add_reaction("🟡") @bot.event async def on_raw_reaction_add(payload): member = bot.get_user(payload.user_id) if member == bot.user: return guild = bot.get_guild(1077548297037819985) member = guild.get_member(payload.user_id) if not member: # 增加判断,避免用户退出服务器后报错 return channel = bot.get_channel(payload.channel_id) if not channel: return try: message = await channel.fetch_message(payload.message_id) except discord.NotFound: return # 消息不存在时直接返回 if message.author != bot.user: return log_channel = bot.get_channel(1095793300184764477) if not log_channel: return embed = discord.Embed(title="Reaction Log", color=0x00ff00) embed.add_field(name="User", value=f"{member.mention} ({member.id})", inline=True) embed.add_field(name="Reaction", value=payload.emoji.name, inline=True) embed.add_field(name="Roles", value=" ".join([role.mention for role in member.roles]), inline=False) embed.add_field(name="Nickname", value=member.nick if member.nick else "无昵称", inline=True) embed.add_field(name="Joined At", value=member.joined_at.strftime("%Y-%m-%d %H:%M:%S"), inline=True) await log_channel.send(embed=embed) # 替换为你的Bot Token bot.run('YOUR_BOT_TOKEN_HERE')
额外注意事项
- 需在Discord开发者门户中开启成员意图(Server Members Intent)和消息内容意图(Message Content Intent),否则Bot无法获取服务器成员列表或处理命令。
- 若需支持多个角色,可在
has_any_role中传入多个ID,例如@commands.has_any_role(role_id1, role_id2)。
内容的提问来源于stack exchange,提问作者Technical
相关产品推荐
相关产品推荐

