如何检查我的机器人是不是可以在 discord.js v12 中添加角色?

Posted

技术标签:

【中文标题】如何检查我的机器人是不是可以在 discord.js v12 中添加角色?【英文标题】:How to check if my bot can add a role in discord.js v12?如何检查我的机器人是否可以在 discord.js v12 中添加角色? 【发布时间】:2021-02-11 18:48:22 【问题描述】:

我创建了一个警告命令,为上述用户提供警告角色,但我遇到了问题。有时服务器所有者可能会忘记将机器人的角色移动到警告角色之上,这将导致机器人无法将角色授予用户。我试过使用 role.editable,但即使角色低于机器人的角色,它也会返回 false。要警告的用户的角色也低于机器人。这是我的代码:

const  DiscordAPIError  = require("discord.js");
const Discord = require('discord.js');
const fs = require("fs");
const ms = require("ms")
//let warnedRoleList = JSON.parse(fs.readFileSync("./roleIDs/warnedRole.json", "utf-8"));
var mongoPath = '../../mongo.js' //path.join(__dirname, '..', 'mongo.js');
const mongo = require(mongoPath)
const setWarnedSchema = require('../../schemas/setwarned-schema.js')
const mongoose = require('mongoose');
const cache = 
const setup = require('../../util/setup')
const moderation = require('../../util/moderation')
const index = require('../../index.js')
//const commands = require("./commands");

module.exports = 
    commands: ['warn'],
    expectedArgs: ['user ping/user ID [reason]'],
    permissionError: ['you are missing the manage messages permissions'],
    minArgs: 1,
    maxArgs: null,
    permissions: ['MANAGE_MESSAGES'],
    requiredRoles: [],
    description: "The bot will warn the mentioned user",
    callback: async (message, args, text) => 
        const guild = message.guild
        let guildID = message.guild.id;
        var warnedRoleID = null
        warnedRoleID = await setup.getWarnedRoles(guildID)

        warnedRoleID = warnedRoleID.toString()
        var UserID = args[0]
        var member = index.getMention(args[0], message)

        var warnReason = args
        warnReason.shift()
        warnReason = warnReason.toString()
        warnReason = warnReason.replace(/,/g, ' ')
        if(!member) 
            return message.reply('please specify the user that should be warned')
        ;

        if (!warnReason) 
            warnReason = 'no reason given'
        ;
        var warnedRole = message.guild.roles.cache.get(warnedRoleID);
        var warnedOneHighestRoleID = member.roles.highest.id;
        var warningOneHighestRoleID = message.member.roles.highest.id;

        if(!warnedRole) 
            return message.reply('there is not a role set as the warned role, set it by doing &setwarnedrole (that requires manage server permissions)')
        ;

        //let warnReason = args.join(" ").slice(18);
        if(member.id === message.author.id) 
            return message.reply('can not allow self-harm')
        
        if (message.member.roles.highest.comparePositionTo(member.roles.highest) <= 0)  //warnedOneHighestRoleID === warningOneHighestRoleID
            return message.reply('you can not warn a user with the same (or higher) permissions as you')
        
        if(!message.member.permissions.has('MANAGE_MESSAGES'))
            return message.reply(`you don't have manage messages permissions that are required to execute this command.`);
        

        if (member.roles.cache.has(`$warnedRoleID`)) 
            const logEmbed = new Discord.MessageEmbed()
            .setColor('#FF0000')
            .setTitle(`An attempt to warn an already warned member happened`)
            //.setAuthor(`$userinfoget.user.tag`, userinfoget.user.displayAvatarURL())
            .setDescription(`**Warned member:** <@$member.user.id>\n**Warned by:** <@$message.author.id>\n**Warn reason:** $warnReason`)
            .setTimestamp()
    
            index.modLog(guildID, logEmbed)
            message.reply('this user is already warned!')
            return
        ;
        console.log(warnedRole.editable)
        if(!warnedRole.editable) 
            message.reply(`failed to warn <@$member.id> as the warned role is above my highest role. Try moving at least one of my roles above other ones`)
            return
        ;
        member.roles.add(warnedRoleID)
        .then(memberAdded => 
         message.reply(`you have succesfully warned <@$member.id> with the reason **$warnReason**`);
        )
        .catch(error => 
        //console.log(error);
            if(message.member.permissions.has('ADMINISTRATOR'))
                message.reply('there is no role set as the warned role. Set it by doing `&setwarnedrole add role ID`')
             else message.reply('there is no role set as the warned role. Ask an admin to set it by doing `&setwarnedrole add role ID`')
        );
        const embed = new Discord.MessageEmbed()

        .setColor('#FF0000')
        .setTitle(`You hev been warned in $message.guild.name`)
        //.setAuthor(`$userinfoget.user.tag`, userinfoget.user.displayAvatarURL())
        .setDescription(`**Warned by:** <@$message.author.id>\n**Warn reason:** $warnReason`)
        .setTimestamp()

        member.user.send(embed).catch(error => 
            message.channel.send(`Failed to DM <@$member.id> the info about this action`)
            console.log(error)
        )

        const logEmbed = new Discord.MessageEmbed()
        .setColor('#FF0000')
        .setTitle(`A member has been warned`)
        //.setAuthor(`$userinfoget.user.tag`, userinfoget.user.displayAvatarURL())
        .setDescription(`**Warned member:** <@$member.user.id>\n**Warned by:** <@$message.author.id>\n**Warn reason:** $warnReason`)
        .setTimestamp()

        index.modLog(guildID, logEmbed)
    

有没有办法检查机器人是否可以将角色添加给用户?提前致谢。

【问题讨论】:

【参考方案1】:

角色层次结构并不是确定角色是否可编辑的唯一因素。例如,如果你的bot没有MANAGE_ROLES权限,那么无论你的bot的最高角色有多高,Role#editable仍然会返回false。

您要做的是首先检查 GuildMember 是否可管理(通过GuildMember#manageable)。如果它们不是,您就不能真正期望能够向它们添加角色。 然后,您要检查您的机器人是否具有MANAGE_ROLES 权限。 最后,您要检查所说的“警告角色”的位置是否高于机器人的最高角色。

最后两个步骤应由Role#editable 在内部完成(参见https://github.com/discordjs/discord.js/blob/master/src/structures/Role.js#L128)

所以你可以做的是

if(!member.manageable || !warnedRole.editable) return console.log("Nope, cannot add role to that member")

【讨论】:

以上是关于如何检查我的机器人是不是可以在 discord.js v12 中添加角色?的主要内容,如果未能解决你的问题,请参考以下文章

Discord.JS 用户信息命令

如何让我的 Python Discord 机器人检查消息是不是由机器人本身发送?

有没有办法使用 quick.db 制作 discord.js 日志系统

SyntaxError:意外的令牌'?'在 repl.it 中,因为我更新到 discord.js V13

如何检查不和谐机器人是不是在语音或已连接

我的 discord.py 机器人有啥方法可以检查用户是不是具有使用命令的特定权限?