forked from Galactic/galactic-bot
selfrole
This commit is contained in:
parent
ea1893636f
commit
8d64fdbfc6
87
src/structure/components/commands/utility/Selfrole.js
Normal file
87
src/structure/components/commands/utility/Selfrole.js
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
const { Emojis } = require("../../../../constants");
|
||||||
|
const { EmbedLimits } = require("../../../../constants/Constants");
|
||||||
|
const { SlashCommand } = require("../../../interfaces");
|
||||||
|
|
||||||
|
class SelfroleCommand extends SlashCommand {
|
||||||
|
constructor(client) {
|
||||||
|
super(client, {
|
||||||
|
name: 'selfrole',
|
||||||
|
description: 'Manage your selfroles',
|
||||||
|
module: 'utility',
|
||||||
|
guildOnly: true,
|
||||||
|
options: [{
|
||||||
|
name: ['add', 'remove'],
|
||||||
|
type: 'SUB_COMMAND',
|
||||||
|
options: [{
|
||||||
|
name: 'roles',
|
||||||
|
type: 'ROLES',
|
||||||
|
description: 'Roles to give/take',
|
||||||
|
required: true
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
name: ['list', 'clear'],
|
||||||
|
type: 'SUB_COMMAND'
|
||||||
|
}],
|
||||||
|
clientPermissions: ['MANAGE_ROLES']
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async execute(invoker, { roles }) {
|
||||||
|
|
||||||
|
const { subcommand: { name: subcommand } } = invoker;
|
||||||
|
if (subcommand === 'list') return this._listRoles(invoker);
|
||||||
|
|
||||||
|
const { guild, member } = invoker;
|
||||||
|
const { selfrole } = await guild.settings();
|
||||||
|
if (!selfrole.roles.length) return { index: 'COMMAND_SELFROLE_NONE', emoji: 'failure' };
|
||||||
|
|
||||||
|
const memberRoles = member.roles.cache.map((r) => r.id);
|
||||||
|
const _roles = roles.value.filter((r) => selfrole.roles.includes(r.id));
|
||||||
|
|
||||||
|
if (subcommand === 'add') {
|
||||||
|
await member.roles.set([...new Set([...memberRoles, ..._roles.map((r) => r.id)])]);
|
||||||
|
return { index: 'COMMAND_SELFROLE_ADD_SUCCESS', emoji: 'success', params: { roles: _roles.map((r) => r.name).join('**, **') } };
|
||||||
|
} else if (subcommand === 'remove') {
|
||||||
|
const ids = _roles.map((r) => r.id);
|
||||||
|
const set = memberRoles.filter((r) => !ids.includes(r));
|
||||||
|
await member.roles.set([...new Set(set)]);
|
||||||
|
return { index: 'COMMAND_SELFROLE_REMOVE_SUCCESS', emoji: 'success', params: { roles: _roles.map((r) => r.name).join('**, **') } };
|
||||||
|
} else if (subcommand === 'clear') {
|
||||||
|
const set = memberRoles.filter((r) => !selfrole.roles.includes(r));
|
||||||
|
await member.roles.set([...new Set(set)]);
|
||||||
|
return { index: 'COMMAND_SELFROLE_CLEAR_SUCCESS', emoji: 'success', };
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
async _listRoles(invoker) {
|
||||||
|
|
||||||
|
const { guild, member } = invoker;
|
||||||
|
const { selfrole } = await guild.settings();
|
||||||
|
const memberRoles = member.roles.cache;
|
||||||
|
if (!selfrole.roles.length) return { index: 'COMMAND_SELFROLE_NONE', emoji: 'failure' };
|
||||||
|
|
||||||
|
const fields = [];
|
||||||
|
const roles = selfrole.roles.map((r) => `${memberRoles.has(r) ? Emojis.success : Emojis.failure} <@&${r}>`);
|
||||||
|
let str = '';
|
||||||
|
for (const role of roles) {
|
||||||
|
const tmp = `${str}\n${role}`;
|
||||||
|
if (tmp.length > EmbedLimits.fieldValue) {
|
||||||
|
fields.push({ name: '\u200b', value: str });
|
||||||
|
str = role;
|
||||||
|
} else str = tmp;
|
||||||
|
}
|
||||||
|
fields.push({ name: '\u200b', value: str });
|
||||||
|
|
||||||
|
return {
|
||||||
|
embed: {
|
||||||
|
title: guild.format('COMMAND_SELFROLE_LIST'),
|
||||||
|
fields
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = SelfroleCommand;
|
@ -21,6 +21,7 @@ class UtilityHook extends Observer {
|
|||||||
['inviteCreate', this.inviteCreate.bind(this)],
|
['inviteCreate', this.inviteCreate.bind(this)],
|
||||||
['inviteDelete', this.inviteDelete.bind(this)],
|
['inviteDelete', this.inviteDelete.bind(this)],
|
||||||
// ['messageReactionAdd', this.reactionAdd.bind(this)]
|
// ['messageReactionAdd', this.reactionAdd.bind(this)]
|
||||||
|
['interactionCreate', this.selfrole.bind(this)]
|
||||||
];
|
];
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -163,6 +164,7 @@ class UtilityHook extends Observer {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Code for enforcing single reaction per user for polls, disabled due to rate limit issues
|
||||||
async reactionAdd(reaction, user) {
|
async reactionAdd(reaction, user) {
|
||||||
if (reaction.partial) reaction = await reaction.fetch();
|
if (reaction.partial) reaction = await reaction.fetch();
|
||||||
if (user.partial) user = await user.fetch();
|
if (user.partial) user = await user.fetch();
|
||||||
@ -187,6 +189,37 @@ class UtilityHook extends Observer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async selfrole(interaction) {
|
||||||
|
if (!interaction.isSelectMenu() && !interaction.isButton()) return;
|
||||||
|
const { guild, message, customId, values, channel, member } = interaction;
|
||||||
|
if (!guild || !member || !customId.includes('selfrole')) return;
|
||||||
|
const { selfrole } = await guild.settings();
|
||||||
|
if (!selfrole.message || selfrole.message !== message.id ||
|
||||||
|
!selfrole.channel || selfrole.channel !== channel.id ||
|
||||||
|
!selfrole.roles.length) return;
|
||||||
|
|
||||||
|
const missing = guild.me.permissions.missing(['MANAGE_ROLES']);
|
||||||
|
if (missing.length)
|
||||||
|
return this.client.emit('utilityError', { guild, utility: 'selfrole', reason: 'UTILITY_SELFROLE_PERMS', params: { missing: missing.join(', ') } });
|
||||||
|
|
||||||
|
const memberRoles = member.roles.cache.map((r) => r.id);
|
||||||
|
if (interaction.isButton()) {
|
||||||
|
const assignThese = memberRoles.filter((r) => !selfrole.roles.includes(r));
|
||||||
|
await member.roles.set(assignThese);
|
||||||
|
} else {
|
||||||
|
for (const value of values) {
|
||||||
|
if (!selfrole.roles.includes(value)) continue;
|
||||||
|
const index = memberRoles.indexOf(value);
|
||||||
|
if (index >= 0) memberRoles.splice(index, 1);
|
||||||
|
else memberRoles.push(value);
|
||||||
|
}
|
||||||
|
await member.roles.set(memberRoles);
|
||||||
|
}
|
||||||
|
|
||||||
|
await interaction.update({ components: message.components });
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = UtilityHook;
|
module.exports = UtilityHook;
|
114
src/structure/components/settings/utility/Selfrole.js
Normal file
114
src/structure/components/settings/utility/Selfrole.js
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
const { Emojis } = require("../../../../constants");
|
||||||
|
const { Util } = require("../../../../utilities");
|
||||||
|
const { Setting } = require("../../../interfaces");
|
||||||
|
|
||||||
|
class SelfroleSetting extends Setting {
|
||||||
|
|
||||||
|
constructor(client) {
|
||||||
|
super(client, {
|
||||||
|
name: 'selfrole',
|
||||||
|
description: 'Configure roles that users can assign to themselves',
|
||||||
|
module: 'utility',
|
||||||
|
display: 'Self Role',
|
||||||
|
default: {
|
||||||
|
roles: [],
|
||||||
|
message: null,
|
||||||
|
channel: null,
|
||||||
|
text: null
|
||||||
|
},
|
||||||
|
commandOptions: [{
|
||||||
|
name: 'roles',
|
||||||
|
description: 'Modify roles users can give themselves',
|
||||||
|
choices: [
|
||||||
|
{ name: 'add', value: 'add' },
|
||||||
|
{ name: 'remove', value: 'remove' },
|
||||||
|
{ name: 'set', value: 'set' },
|
||||||
|
{ name: 'reset', value: 'reset' },
|
||||||
|
],
|
||||||
|
}, {
|
||||||
|
name: 'channel',
|
||||||
|
description: 'Optional channel to output message for selecting roles',
|
||||||
|
type: 'TEXT_CHANNEL'
|
||||||
|
}, {
|
||||||
|
name: 'text',
|
||||||
|
description: 'Optional text to display above the select menu'
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async execute(invoker, { roles, channel, text }, setting) {
|
||||||
|
|
||||||
|
if (!roles && !channel && !text) return { error: true, index: 'SETTING_MISSING_ARG' };
|
||||||
|
const { guild } = invoker;
|
||||||
|
|
||||||
|
if (roles) {
|
||||||
|
const response = await this._prompt(invoker, {
|
||||||
|
index: `SETTING_PROMPT_${roles.value.toUpperCase()}`,
|
||||||
|
params: { list: 'roles' }
|
||||||
|
});
|
||||||
|
if (response.error) return response;
|
||||||
|
const params = Util.parseQuotes(response).map(([param]) => param);
|
||||||
|
const values = (await guild.resolveRoles(params)).filter((r) => !r.managed).map((r) => r.id);
|
||||||
|
this[roles.value](setting.roles, values);
|
||||||
|
if(setting.roles.length >= 25 && (setting.channel || channel)) await invoker.channel.send(guild.format('SETTING_SELFROLE_WARNING'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// old channel for deleting old message if one exists
|
||||||
|
const oldChannel = await guild.resolveChannel(setting.channel);
|
||||||
|
const newChannel = channel?.value || oldChannel;
|
||||||
|
if (channel) setting.channel = channel.value.id; // Set the new channel if one is given
|
||||||
|
if (text) setting.text = text.value;
|
||||||
|
|
||||||
|
// If an old channel exists, and a message exists, and either all roles were removed or the channel changed, delete the old message
|
||||||
|
if (oldChannel && setting.message && (!setting.roles.length || newChannel !== oldChannel)) {
|
||||||
|
const message = await oldChannel.messages.fetch(setting.message).catch(() => null);
|
||||||
|
if (message) {
|
||||||
|
await message.delete();
|
||||||
|
setting.message = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setting.roles.length && setting.channel && setting.roles.length <= 25) {
|
||||||
|
const roles = await guild.resolveRoles(setting.roles);
|
||||||
|
const components = [{
|
||||||
|
type: 'ACTION_ROW',
|
||||||
|
components: [{
|
||||||
|
type: 'SELECT_MENU',
|
||||||
|
customId: 'selfrole-select',
|
||||||
|
maxValues: roles.length,
|
||||||
|
options: roles.map((r) => {
|
||||||
|
return { label: r.name, value: r.id };
|
||||||
|
})
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
type: 'ACTION_ROW',
|
||||||
|
components: [{
|
||||||
|
type: 'BUTTON',
|
||||||
|
customId: 'selfrole-clear',
|
||||||
|
label: 'Clear',
|
||||||
|
style: 'PRIMARY',
|
||||||
|
emoji: Emojis.failure
|
||||||
|
}]
|
||||||
|
}];
|
||||||
|
const payload = {
|
||||||
|
content: setting.text || guild.format('SETTING_SELFROLE_SELECT'),
|
||||||
|
components
|
||||||
|
};
|
||||||
|
|
||||||
|
const msg = await oldChannel.messages.fetch(setting.message).catch(() => null);
|
||||||
|
if (msg && newChannel === oldChannel) {
|
||||||
|
await msg.edit(payload);
|
||||||
|
} else {
|
||||||
|
const msg = await newChannel.send(payload);
|
||||||
|
setting.message = msg.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return { index: 'SETTING_SUCCESS_ALT' };
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = SelfroleSetting;
|
Loading…
Reference in New Issue
Block a user