#node.js #discord.js
#node.js #discord.js
Вопрос:
Я сделал команду warn, которая дает указанному пользователю роль с предупреждением, но я столкнулся с проблемой. Иногда владельцы серверов могут забыть о перемещении роли бота выше предупрежденной роли, и это приведет к тому, что бот не сможет предоставить роль пользователю. Я пробовал использовать 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 amp;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 `amp;setwarnedrole add {role ID}`')
} else message.reply('there is no role set as the warned role. Ask an admin to set it by doing `amp;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:
Иерархия ролей — не единственный фактор, определяющий, доступна ли роль для редактирования. Например, если у вашего бота нет MANAGE_ROLES
разрешения, то независимо от того, насколько высока самая высокая роль вашего бота, Role#editable
он все равно вернет false.
Что вы хотите сделать, это сначала проверить, является ли член гильдии управляемым (через GuildMember#manageable
). Если это не так, вы не можете ожидать, что сможете добавлять к ним роли. Затем вы хотите проверить, есть ли у вашего бота MANAGE_ROLES
разрешение. Наконец, вы хотите проверить, находится ли позиция указанной «роли предупреждения» выше, чем позиция самой высокой роли бота.
Последние 2 шага должны быть выполнены внутри 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")