From a41e602036c2fea320b87a847b1140de2131dbfa Mon Sep 17 00:00:00 2001 From: ION606 Date: Mon, 19 Dec 2022 17:20:04 -0500 Subject: [PATCH] Added the 'reactionrole' command and removed some redundancies in code --- commands/admin/reactionrole.js | 182 +++++++++++++++++++++++++++++++ commands/dev only/setPresence.js | 2 +- commands/interactionhandler.js | 5 + commands/misc/scraper.js | 13 +-- commands/premium/icsToEvents.js | 11 +- 5 files changed, 191 insertions(+), 22 deletions(-) create mode 100644 commands/admin/reactionrole.js diff --git a/commands/admin/reactionrole.js b/commands/admin/reactionrole.js new file mode 100644 index 0000000..232d8c4 --- /dev/null +++ b/commands/admin/reactionrole.js @@ -0,0 +1,182 @@ +const {Interaction, Constants, Modal, TextInputComponent, MessageActionRow, MessageEmbed, MessageButton, Message} = require('discord.js'); +const { checkRole } = require('./verify.js'); +const { isValidUrl } = require('../dev only/setPresence.js'); +const embdList = [{name: 'Title'}, {name: 'Image', desc: 'The image url'}, {name: 'Thumbnail', desc: 'The thumbnail url'}, {name: 'URL'}, {name: 'Description', desc: 'Use {ROLE} to insert the role'}]; + + +async function postForm(interaction, role, useEmoji, txt) { + // Create the modal + const modal = new Modal(); + + modal.setTitle('Create a new reaction role!') + .setCustomId(`reactionModal|${role.id}|${useEmoji}|${txt}`); + + for (let i = 0; i < 5; i++) { + const tempInp = new TextInputComponent() + .setCustomId(embdList[i].name.toLowerCase()) + .setLabel(embdList[i].name); + + if (embdList[i].name != 'Description') { + tempInp.setStyle('SHORT'); + } else { + tempInp.setStyle('PARAGRAPH'); + } + + if (embdList[i].desc) { + tempInp.setPlaceholder(embdList[i].desc); + } + + modal.addComponents(new MessageActionRow().addComponents(tempInp)); + } + + // Show the modal to the user + interaction.showModal(modal); +} + +/** + * @param {Interaction} interaction + */ +function postNotif(interaction, roleId, guild, user) { + const role = guild.roles.cache.get(roleId); + + const embd = new MessageEmbed() + .setTitle("You got a new role!") + .setDescription(`You were given the *${role.name}* role in **${guild}**\n_You did this by reacting to [this message](${interaction.message.url})_`) + .setTimestamp() + .setThumbnail(guild.iconURL()); + user.send({embeds: [embd]}); +} + +/** + * @param {Interaction} interaction + */ +function processForm(interaction, bot) { + const roleId = interaction.customId.split('|')[1]; + const title = interaction.fields.getTextInputValue('title'); + const img = interaction.fields.getTextInputValue('image'); + const thumb = interaction.fields.getTextInputValue('thumbnail'); + const url = interaction.fields.getTextInputValue('url'); + var desc = interaction.fields.getTextInputValue('description'); + + const useEmoji = (interaction.customId.split('|')[2] == 'true'); + var txt = interaction.customId.split('|')[3]; + var emoji = undefined; + + //Emoji? + + if (Number.isInteger(Number(txt))) { + emoji = interaction.guild.emojis.cache.get(txt); + } + + if (desc.indexOf("{ROLE}") != -1) { + desc = desc.replaceAll("{ROLE}", `<@&${roleId}>`); + } + + const embd = new MessageEmbed() + .setTitle(title) + .setDescription(desc || ""); + + if (img && isValidUrl(img)) embd.setImage(img); + if (thumb && isValidUrl(thumb)) embd.setThumbnail(thumb); + if (url && isValidUrl(url)) embd.setURL(url); + + if (useEmoji) { + interaction.channel.send({embeds: [embd]}).then((msg) => { + try { + msg.react(emoji || txt); + + const filter = (reaction, user) => { + return (!user.bot && (reaction.emoji.id == txt || reaction.emoji.name == txt)); + }; + + const collector = msg.createReactionCollector({ filter }); + + collector.on('collect', (reaction, user) => { + const guildUser = reaction.message.guild.members.cache.get(user.id); + + if (guildUser.roles.cache.has(roleId)) { + return guildUser.send("You already have this role!"); + } + + guildUser.roles.add(roleId); + postNotif(reaction, roleId, reaction.message.guild, guildUser); + }); + } catch (err) { + console.error(err); + } + }); + } else { + const btn = new MessageButton() + .setCustomId(`addRole|${roleId}`) + .setStyle('PRIMARY'); + + if (emoji) btn.setEmoji(emoji); + else btn.setLabel(txt); + + const row = new MessageActionRow() + .addComponents([btn]); + + interaction.channel.send({embeds: [embd], components: [row]}) + } + + interaction.reply({content: "Reaction role added!", ephemeral: true}); +} + + +/** + * @param {Interaction} interaction + * @returns + */ +function handleBtn(interaction) { + const roleId = interaction.customId.split('|')[1]; + const user = interaction.guild.members.cache.get(interaction.user.id); + if (user.roles.cache.has(roleId)) { + return interaction.reply({content: "You already have this role!", ephemeral: true}); + } + + user.roles.add(roleId); + const role = interaction.guild.roles.cache.get(roleId); + postNotif(interaction, role.id, interaction.guild, interaction.user); +} + + +module.exports = { + name: "reactionrole", + description: "Give someone a role when they react to a message", + /** + * @param {Interaction} interaction + */ + execute(interaction, Discord, Client, bot) { + const user = interaction.user; + + checkRole(bot, interaction.guild, user.id).then((isAdmin) => { + if (isAdmin) { + const role = interaction.options.data.filter((opt) => { return(opt.name == "role"); })[0].role; + const useEmoji = interaction.options.data.filter((opt) => { return(opt.name == "useemoji"); })[0].value; + var txt = interaction.options.data.filter((opt) => { return(opt.name == "text"); })[0].value; + + if (txt.startsWith('<:') && txt.endsWith(">")) { + const emoji = interaction.guild.emojis.cache.get(txt.split(":")[2].split(">")[0]); + + if (!emoji) { return interaction.reply("Please use a valid emoji"); } + + txt = txt.split(":")[2].split(">")[0]; + } + + if (role.position >= interaction.guild.me.roles.highest.position ||!interaction.guild.me.permissions.has("MANAGE_ROLES")) { + return interaction.reply({ + content: "I'm not high enough in the role hierarchy to do that!\n_To raise my place, go to **Server Settings -> Roles** then drag me up!_", + ephemeral: true + }); + } + + postForm(interaction, role, useEmoji, txt); + } + }); + }, processForm, handleBtn, + options: [ + {name: "role", description: "The role to assign", type: Constants.ApplicationCommandOptionTypes.ROLE, required: true}, + {name: "useemoji", description: 'React using a button or emoji', type: Constants.ApplicationCommandOptionTypes.BOOLEAN, required: true}, + {name: 'text', description: 'The reaction emoji or button text', type: Constants.ApplicationCommandOptionTypes.STRING, required: true} + ] +} \ No newline at end of file diff --git a/commands/dev only/setPresence.js b/commands/dev only/setPresence.js index 47cb299..810d731 100644 --- a/commands/dev only/setPresence.js +++ b/commands/dev only/setPresence.js @@ -81,4 +81,4 @@ async function setPresence(bot, interaction) { } -module.exports = { setPresence } \ No newline at end of file +module.exports = { setPresence, isValidUrl } \ No newline at end of file diff --git a/commands/interactionhandler.js b/commands/interactionhandler.js index 847f4a6..0b5c8f1 100644 --- a/commands/interactionhandler.js +++ b/commands/interactionhandler.js @@ -3,6 +3,7 @@ const { pause_start_stop, playNext, showQueue } = require('./audio/audioMain.js' const { resolveComplaint } = require('./dev only/submitcomplaint.js'); const { RSSInteractionHandler } = require('../side projects/RSSHandlers/rssFeed.js'); const reminders = require('./premium/reminders.js'); +const reactionrole = require('./admin/reactionrole.js'); const tuto = require('./Selmer Specific/tuto'); const mswpr = require('./games/minesweeper.js'); const giveaway = require('./misc/giveaway.js'); @@ -98,6 +99,8 @@ async function handle_interaction(interaction, mongouri, turnManager, bot, STATE bot.commands.get('game').execute(bot, interaction, {name: 'accept'}, Discord, mongouri, items, xp_collection); } else if (interaction.customId.indexOf("setupBtn") != -1) { setup.handle(bot, interaction); + } else if (interaction.customId.indexOf('addRole') != -1) { + reactionrole.handleBtn(interaction); } //Button else ifs here }); } @@ -167,6 +170,8 @@ async function handle_interaction(interaction, mongouri, turnManager, bot, STATE reminders.modalHandle(bot, interaction); } else if (interaction.customId.indexOf('giveawayModal') != -1) { giveaway.processForm(interaction, bot); + } else if (interaction.customId.indexOf('reactionModal') != -1) { + reactionrole.processForm(interaction, bot); } } //other selection types here } diff --git a/commands/misc/scraper.js b/commands/misc/scraper.js index 1dd35f6..c8ff33f 100644 --- a/commands/misc/scraper.js +++ b/commands/misc/scraper.js @@ -2,23 +2,14 @@ const hastebin = require("hastebin-gen"); const { addComplaintButton } = require('../dev only/submitcomplaint'); const { Constants } = require('discord.js'); const { URL } = require("url"); - - -function isValidUrl(s) { - try { - new URL(s); - return true; - } catch (err) { - return false; - } -}; +const axios = require('axios'); +const { isValidUrl } = require('../dev only/setPresence.js'); module.exports ={ name: "scrape", description: "Scrapes a website, then puts the result into a hastebin", async execute(interaction, Discord, Client, bot) { - const axios = require('axios'); // const cheerio = require('cheerio'); const url = interaction.options.data[0].value; diff --git a/commands/premium/icsToEvents.js b/commands/premium/icsToEvents.js index ef62631..9097999 100644 --- a/commands/premium/icsToEvents.js +++ b/commands/premium/icsToEvents.js @@ -3,6 +3,7 @@ const { URL } = require('url'); const { Constants } = require('discord.js'); const request = require('request'); const { verPremium } = require('../premium/verifyPremium.js'); +const { isValidUrl } = require('../dev only/setPresence.js'); //#region SET REMINDERS @@ -70,16 +71,6 @@ function addReminder(interaction, bot, obj, Id) { //#region SETUP AND PARSING -function isValidUrl(s) { - try { - new URL(s); - return true; - } catch (err) { - return false; - } -}; - - class calClass { constructor(vevent) { const model = vevent.model;