Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ commands/reload.js
commands/removeAlt.js
commands/removePending.js
commands/request.js
commands/roleAssignment.js
commands/russianRoulette.js
commands/script.js
commands/setStatus.js
Expand All @@ -66,7 +65,6 @@ commands/updateIP.js
commands/verification.js
commands/vetBan.js
commands/vetVerification.js
commands/vibotChannels.js
commands/warnRemove.js
commands/warns.js
jobs/runner.js
Expand Down
2 changes: 0 additions & 2 deletions botSetup.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ const ErrorLogger = require('./lib/logError');
// Commands
const emoji = require('./commands/emoji.js');
const afkCheck = require('./commands/afkCheck.js');
const vibotChannels = require('./commands/vibotChannels');
const vetVerification = require('./commands/vetVerification');
const verification = require('./commands/verification');
// Specific Jobs
Expand Down Expand Up @@ -128,7 +127,6 @@ async function setup(bot) {
// initialize components (eg. modmail, verification)
iterServers(bot, (bot, g) => {
const db = dbSetup.getDB(g.id);
vibotChannels.update(g, bot, db).catch(er => { });
afkCheck.loadBotAfkChecks(g, bot, db);
if (bot.settings[g.id].backend.verification) verification.init(g, bot, db).catch(er => { ErrorLogger.log(er, bot, g); });
if (bot.settings[g.id].backend.vetverification) vetVerification.init(g, bot, db).catch(er => { ErrorLogger.log(er, bot, g); });
Expand Down
2 changes: 1 addition & 1 deletion commands/pop.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ module.exports = {
);

const reply = await message.reply({ embeds: [confirmEmbed], components: [buttons], ephemeral: true });
createReactionRow(reply, module.exports.name, 'handleButtons', buttons, message.author, { memberId: member.id, keyInfo, count });
createReactionRow(reply, module.exports.name, 'handleButtons', [buttons], message.author, { memberId: member.id, keyInfo, count });
},
async handleButtons(bot, confirmMessage, db, choice, state) {
const member = confirmMessage.interaction.guild.members.cache.get(state.memberId);
Expand Down
272 changes: 139 additions & 133 deletions commands/roleAssignment.js
Original file line number Diff line number Diff line change
@@ -1,148 +1,154 @@
const ErrorLogger = require('../lib/logError')
const Discord = require('discord.js');

//add this to settings eventually:registered:
const reacts = require('../data/roleAssignment.json')

module.exports = {
addInteractionButtons,
name: 'roleassignment',
args: 'send/init',
role: 'moderator',
async execute(message, args, bot, db) {
let settings = bot.settings[message.guild.id]
if (!settings || !settings.backend.roleassignment) return message.channel.send('roleassignment has been turned off in this server');

let guildReacts = reacts[message.guild.id]
if (!guildReacts) return message.channel.send('Reactions not setup for this guild')

//make embed
let embed = getEmbed(guildReacts)

//get channel
let channel = message.guild.channels.cache.get(settings.channels.roleassignment)
if (!channel) return message.channel.send('Could not find channel: ' + settings.channels.roleassignment)

//get arg
if (args.length == 0) return message.channel.send('Inavlid arguements: ``;roleassignment <send/init>``')
switch (args[0].toLowerCase()) {
case 'send':

let message = await channel.send({ embeds: [embed] })

setTimeout(async () => {
await addInteractionButtons(message, bot)
}, 1000);

break;
}
}
}

async function addInteractionButtons(message, bot) {
if (!bot.settings[message.guild.id].backend.roleassignment) return;
let guildReacts = reacts[message.guild.id]
if (!guildReacts) return

const giveAllRolesButton = new Discord.ButtonBuilder()
const reacts = require('../data/roleAssignment.json');
const SlashArgType = require('discord-api-types/v10').ApplicationCommandOptionType;
const { slashArg, slashChoices, slashCommandJSON } = require('../utils.js');
const { createReactionRow } = require('../redis.js');

function addInteractionComponents(bot, guildReacts) {
const components = [];
components.push(new Discord.ButtonBuilder()
.setCustomId('giveAllRoles')
.setLabel('✅ Give All')
.setStyle(3);
const takeAllRolesButton = new Discord.ButtonBuilder()
.setStyle(Discord.ButtonStyle.Success));
guildReacts.map(reaction =>
components.push(new Discord.ButtonBuilder()
.setCustomId(reaction.emote)
.setEmoji(bot.storedEmojis[reaction.emote].id)
.setStyle(Discord.ButtonStyle.Secondary))
);
components.push(new Discord.ButtonBuilder()
.setCustomId('takeAllRoles')
.setLabel('❌ Take All')
.setStyle(4);

let buttons = [];
buttons.push(giveAllRolesButton)
const actionRows = new Array;
for (let i in guildReacts) {
reaction = guildReacts[i]
const buttonToAdd = new Discord.ButtonBuilder()
.setCustomId(reaction.emojiId)
.setEmoji(reaction.emojiId)
.setStyle(Discord.ButtonStyle.Secondary);
buttons.push(buttonToAdd);
if (buttons.length >= 5) {
actionRows.push(new Discord.ActionRowBuilder().addComponents(buttons));
buttons = [];
}
}
if (buttons.length == 5) {
actionRows.push(new Discord.ActionRowBuilder().addComponents(buttons));
actionRows.push(new Discord.ActionRowBuilder().addComponents(takeAllRolesButton));
} else {
buttons.push(takeAllRolesButton)
actionRows.push(new Discord.ActionRowBuilder().addComponents(buttons));
}

message = await message.edit({ components: actionRows })
roleAssignmentInteractionCollector = new Discord.InteractionCollector(bot, { message: message, interactionType: Discord.InteractionType.MessageComponent, componentType: Discord.ComponentType.Button })
roleAssignmentInteractionCollector.on('collect', (interaction) => interactionHandler(interaction, bot))
.setStyle(Discord.ButtonStyle.Danger));
return components.reduce((rows, btn, idx) => {
if (idx % 5 == 0) rows.push(new Discord.ActionRowBuilder());
rows[rows.length - 1].addComponents(btn);
return rows;
}, []);
}

async function interactionHandler(interaction, bot) {
if (!bot.settings[interaction.guild.id].backend.roleassignment) return;
if (!interaction.isButton()) return;

failedEmbed = new Discord.EmbedBuilder()
.setColor('#FF0000')
.setDescription(`Something went wrong, please try again or contact any Head Raid Leader+ to fix this`)
.setFooter({ text: `${interaction.customId}` })

settings = bot.settings[interaction.guild.id]
let guildReacts = reacts[interaction.guild.id]
if (!guildReacts) return await interaction.reply({ embeds: [failedEmbed], ephemeral: true })

if (interaction.customId === "giveAllRoles") {
for (let i in guildReacts) {
reaction = guildReacts[i]
role = interaction.guild.roles.cache.get(settings.roles[reaction.role])
if (!interaction.member.roles.cache.has(role.id)) {
// The user does not have the reactable role, and therefor we will add it
interaction.member.roles.add(role)
module.exports = {
name: 'roleassignment',
description: 'Creates or updates role assignment',
requiredArgs: 1,
args: [
slashArg(SlashArgType.String, 'type', {
description: 'Type of role assignment function to use',
choices: slashChoices(['Send', 'Update'])
})
],
role: 'moderator',
getSlashCommandData(guild) { return slashCommandJSON(this, guild); },
/**
* @param {Discord.Message} message
* @param {string[]} args
* @param {Discord.Client} bot
*/
async execute(message, args, bot) { await this.processRoleAssignment(message, bot); },
/**
* @param {Discord.CommandInteraction} interaction
* @param {Discord.Client} bot
*/
async slashCommandExecute(interaction, bot) { await this.processRoleAssignment(interaction, bot); },
/**
* @param {Discord.Message | Discord.CommandInteraction} interaction
* @param {Discord.Client} bot
*/
async processRoleAssignment(interaction, bot) {
const botSettings = bot.settings[interaction.guild.id];
if (!botSettings || !botSettings.backend.roleassignment) return interaction.reply(`Role Assignment not setup for guild ${interaction.guild.name}`);
const guildReacts = reacts[interaction.guild.id];
if (!guildReacts) return interaction.reply(`Reactions not setup for guild ${interaction.guild.name}`);
const channel = interaction.guild.channels.cache.get(botSettings.channels.roleassignment);
if (!channel) return interaction.reply(`Role Assignment channel not setup for guild ${interaction.guild.name}`);
const type = interaction.options.getString('type');
switch (type.toLowerCase()) {
case 'send': {
const embed = new Discord.EmbedBuilder()
.setTitle('Assign Roles')
.setColor(Discord.Colors.Blue)
.setDescription('Press the buttons with one of the following emojis to get pinged for specific runs\nCan be disabled by pressing the same button after recieving your role')
.setFooter({ text: interaction.guild.name, iconURL: interaction.guild.iconURL() })
.setTimestamp();
guildReacts.map(reaction => embed.addFields([{ name: reaction.name, value: bot.storedEmojis[reaction.emote].text, inline: true }]));
const message = await channel.send({ embeds: [embed], components: addInteractionComponents(bot, guildReacts) });
createReactionRow(message, module.exports.name, 'interactionHandler', addInteractionComponents(bot, guildReacts), null, guildReacts);
interaction.reply(`Role Assignment message has been successfully sent ${message.url}`);
break;
}
}
await interaction.reply({ content: `You now have ${guildReacts.map(role => interaction.guild.roles.cache.get(settings.roles[role.role])).join(', ')}\nand will recieve pings for ${guildReacts.map(name => name.name).join(', ')}`, ephemeral: true })
}
else if (interaction.customId === "takeAllRoles") {
for (let i in guildReacts) {
reaction = guildReacts[i]
role = interaction.guild.roles.cache.get(settings.roles[reaction.role])
if (interaction.member.roles.cache.has(role.id)) {
// The user has the reactable role, and therefor we will remove it
interaction.member.roles.remove(role)
case 'update': {
await this.updateRoleAssignmentListeners(interaction.guild, bot);
interaction.reply(`Role Assignment message has been successfully updated ${channel.url}`);
break;
}
default: {
return interaction.reply('Invalid type of role assignment function, please try again.');
}
}
await interaction.reply({ content: `You no longer have ${guildReacts.map(role => interaction.guild.roles.cache.get(settings.roles[role.role])).join(', ')}\nand will not recieve pings for ${guildReacts.map(name => name.name).join(', ')}`, ephemeral: true })
}
else {
for (let i in guildReacts) {
reaction = guildReacts[i]
if (interaction.customId === reaction.emojiId) {
role = interaction.guild.roles.cache.get(settings.roles[reaction.role])

if (interaction.member.roles.cache.has(role.id)) {
// The user has the reactable role, and therefor we will remove it
interaction.member.roles.remove(role)
await interaction.reply({ content: `You no longer have ${role} and will no longer recieve pings for ${reaction.name}`, ephemeral: true })
},
/**
* @param {Discord.Guild} guild
* @param {Discord.Client} bot
*/
async updateRoleAssignmentListeners(guild, bot) {
const botSettings = bot.settings[guild.id];
if (!botSettings) return; // If roleassignment is not setup for the guild it will not continue
const guildReacts = reacts[guild.id];
if (!guildReacts) return; // If there are no reacts for the guild it will not continue
const roleAssignmentChannel = guild.channels.cache.get(botSettings.channels.roleassignment);
if (!roleAssignmentChannel) return; // If there is no roleassignment channel it will not continue

const roleAssignmentChannelMessages = await roleAssignmentChannel.messages.fetch(); // This fetches all the messages in the roleassignment channel
Promise.all(roleAssignmentChannelMessages.map(async message => { // This will loop through the roleassignment channel messages
if (message.author.id !== bot.user.id) return; // If the roleassignment message author is not the same id as ViBot it will not continue with this message
if (message.embeds.length == 0) return; // If the message has no embeds it will not continue
if (message.components == 0) return; // If the message has no components it will not continue
// Anything below this code inside this function is for roleassignment messages, and we need to reset them
await message.edit({ components: addInteractionComponents(bot, guildReacts) }); // This will add a roleassignment button listeners to the message
createReactionRow(message, module.exports.name, 'interactionHandler', addInteractionComponents(bot, guildReacts), null, guildReacts);
}));
},
async interactionHandler(bot, message, db, choice, guildReacts) {
const interaction = message.interaction; // eslint-disable-line prefer-destructuring
const guild = interaction.guild; // eslint-disable-line prefer-destructuring
const member = interaction.member; // eslint-disable-line prefer-destructuring
const botSettings = bot.settings[interaction.guild.id];
const embed = new Discord.EmbedBuilder()
.setColor(Discord.Colors.Green)
.setFooter({ text: guild.name, iconURL: guild.iconURL() })
.setTimestamp();

switch (choice) {
case 'giveAllRoles': {
const guildReactsToAdd = guildReacts.filter(reaction => !member.roles.cache.has(botSettings.roles[reaction.role]));
const rolesToAdd = guildReactsToAdd.map(reaction => guild.roles.cache.get(botSettings.roles[reaction.role]));
await member.roles.add(rolesToAdd);
if (rolesToAdd.length == 0) embed.setDescription('You already **have** all the roles to receive pings');
else embed.setDescription(`You now **have** the roles to receive pings for the following dungeons:\n${rolesToAdd.map((role, i) => `- ${bot.storedEmojis[guildReactsToAdd[i].emote].text} ${guildReactsToAdd[i].name}: ${role}`).join('\n')} `);
await interaction.reply({ embeds: [embed], ephemeral: true });
break;
}
case 'takeAllRoles': {
const guildReactsToRemove = guildReacts.filter(reaction => member.roles.cache.has(botSettings.roles[reaction.role]));
const rolesToRemove = guildReactsToRemove.map(reaction => guild.roles.cache.get(botSettings.roles[reaction.role]));
await member.roles.remove(rolesToRemove);
if (rolesToRemove.length == 0) embed.setDescription('You already **no longer** have any of the roles to receive pings');
else embed.setDescription(`You now **no longer have** the roles to receive pings for the following dungeons:\n${rolesToRemove.map((role, i) => `- ${bot.storedEmojis[guildReactsToRemove[i].emote].text} ${guildReactsToRemove[i].name}: ${role}`).join('\n')} `);
await interaction.reply({ embeds: [embed], ephemeral: true });
break;
}
default: {
const guildReact = guildReacts.find(reaction => reaction.emote === choice);
const role = guild.roles.cache.get(botSettings.roles[guildReact.role]);
if (member.roles.cache.has(role.id)) {
await member.roles.remove(role);
embed.setDescription(`You now **no longer have** the role to receive pings for ${bot.storedEmojis[guildReact.emote].text} ${guildReact.name}: ${role}`);
} else {
// The user does not have the reactable role, and therefor we will add it
interaction.member.roles.add(role)
await interaction.reply({ content: `You now have ${role} and will recieve pings for ${reaction.name}`, ephemeral: true })
await member.roles.add(role);
embed.setDescription(`You now **have** the role to receive pings for ${bot.storedEmojis[guildReact.emote].text} ${guildReact.name}: ${role}`);
}
await interaction.reply({ embeds: [embed], ephemeral: true });
}
}
}
}

function getEmbed(guildReacts) {
let embed = new Discord.EmbedBuilder()
.setTitle('Assign Roles')
.setColor('#6fa8dc')
.setDescription('Press the buttons with one of the following emojis to get pinged for specific runs\nCan be disabled by pressing the same button after recieving your role')
for (let i of guildReacts) {
embed.addFields([{name: i.name, value: i.emoji, inline: true}])
}
return embed
}
};
Loading