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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 17:07:32