From c24520dd245b0ecc8a61ab670f4b9155b00ffa9a Mon Sep 17 00:00:00 2001 From: Supositware Date: Mon, 29 Aug 2022 20:56:26 +0200 Subject: [PATCH] Optout of quotation feature --- commands/utility/optout.js | 46 ++++++++++++ events/client/messageCreate.js | 83 +++++++++++----------- migrations/20220829184747-create-optout.js | 27 +++++++ models/optout.js | 23 ++++++ 4 files changed, 139 insertions(+), 40 deletions(-) create mode 100644 commands/utility/optout.js create mode 100644 migrations/20220829184747-create-optout.js create mode 100644 models/optout.js diff --git a/commands/utility/optout.js b/commands/utility/optout.js new file mode 100644 index 0000000..319524c --- /dev/null +++ b/commands/utility/optout.js @@ -0,0 +1,46 @@ +import { SlashCommandBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } from 'discord.js'; +import db from '../../models/index.js'; + +export default { + data: new SlashCommandBuilder() + .setName('optout') + .setDescription('Opt out of the quotation command.'), + category: 'utility', + async execute(interaction, args, client) { + const isOptOut = await db.optout.findOne({ where: { userID: interaction.user.id } }); + + if (!isOptOut) { + const body = { userID: interaction.user.id }; + await db.optout.create(body); + return await interaction.reply({ content: 'You have successfully been opt out.' }); + } + + const row = new ActionRowBuilder() + .addComponents( + new ButtonBuilder() + .setCustomId('yes') + .setLabel('Yes') + .setStyle(ButtonStyle.Primary), + ) + .addComponents( + new ButtonBuilder() + .setCustomId('no') + .setLabel('No') + .setStyle(ButtonStyle.Danger), + ); + + await interaction.reply({ content: 'You are already opt out, do you wish to opt in?', components: [row] }); + + client.once('interactionCreate', async (interactionMenu) => { + if (!interactionMenu.isButton) return; + interactionMenu.update({ components: [] }); + if (interactionMenu.customId === 'yes') { + await db.optout.destroy({ where: { userID: interaction.user.id } }); + return interaction.editReply('You have successfully been opt in'); + } + else { + return interaction.editReply('Nothing has been changed.'); + } + }); + }, +}; diff --git a/events/client/messageCreate.js b/events/client/messageCreate.js index ab6a7fa..a7c0e50 100644 --- a/events/client/messageCreate.js +++ b/events/client/messageCreate.js @@ -205,46 +205,49 @@ export default { * This section will contain the code for the quotation feature, it will detect link for it and send it as embed * */ - const quotationstat = await db.quotationStat.findOne({ where: { serverID: message.guild.id, stat: 'enable' } }); - - if (quotationstat && (message.content.includes('discordapp.com/channels/') || message.content.includes('discord.com/channels/'))) { - const url = message.content.split('/'); - const guildID = url[4]; - const channelID = url[5]; - const messageID = url[6].split(' ')[0]; - - - // Verify if the guild, channel and message exist - const guild = client.guilds.resolve(guildID); - if (!guild) return; - const channel = client.channels.resolve(channelID); - if (!channel) return; - const quote = await channel.messages.fetch(messageID) - .catch(() => { - return; - }); - if (!quote) return; - - const Embed = new EmbedBuilder() - .setAuthor({ name: quote.author.username, iconURL: quote.author.displayAvatarURL() }) - .setColor(message.member ? message.member.displayHexColor : 'NAVY') - .addFields( - { name: 'Jump to', value: `[message](https://discordapp.com/channels/${message.guild.id}/${channelID}/${messageID})`, inline: true }, - { name: 'In channel', value: quote.channel.name.toString(), inline: true }, - { name: 'Quoted by', value: message.author.toString(), inline: true }, - ) - .setDescription(quote.content) - .setTimestamp(quote.createdTimestamp); - - if (quote.member) Embed.setAuthor({ name: `${quote.author.username}#${quote.author.discriminator}`, iconURL: quote.author.displayAvatarURL() }); - - if (quote.author.bot) Embed.setAuthor({ name: `${quote.author.username}#${quote.author.discriminator} (BOT)`, iconURL: quote.author.displayAvatarURL() }); - - if (guild.id != message.guild.id) Embed.addFields({ name: 'In guild', value: guild.name, inline: true }); - const Attachment = Array.from(message.attachments.values()); - if (Attachment[0]) Embed.setImage(Attachment[0].url); - - return message.channel.send({ embeds: [Embed] }); + const isOptOut = await db.optout.findOne({ where: { userID: message.author.id } }); + if (!isOptOut) { + const quotationstat = await db.quotationStat.findOne({ where: { serverID: message.guild.id, stat: 'enable' } }); + + if (quotationstat && (message.content.includes('discordapp.com/channels/') || message.content.includes('discord.com/channels/'))) { + const url = message.content.split('/'); + const guildID = url[4]; + const channelID = url[5]; + const messageID = url[6].split(' ')[0]; + + + // Verify if the guild, channel and message exist + const guild = client.guilds.resolve(guildID); + if (!guild) return; + const channel = client.channels.resolve(channelID); + if (!channel) return; + const quote = await channel.messages.fetch(messageID) + .catch(() => { + return; + }); + if (!quote) return; + + const Embed = new EmbedBuilder() + .setAuthor({ name: quote.author.username, iconURL: quote.author.displayAvatarURL() }) + .setColor(message.member ? message.member.displayHexColor : 'NAVY') + .addFields( + { name: 'Jump to', value: `[message](https://discordapp.com/channels/${message.guild.id}/${channelID}/${messageID})`, inline: true }, + { name: 'In channel', value: quote.channel.name.toString(), inline: true }, + { name: 'Quoted by', value: message.author.toString(), inline: true }, + ) + .setDescription(quote.content) + .setTimestamp(quote.createdTimestamp); + + if (quote.member) Embed.setAuthor({ name: `${quote.author.username}#${quote.author.discriminator}`, iconURL: quote.author.displayAvatarURL() }); + + if (quote.author.bot) Embed.setAuthor({ name: `${quote.author.username}#${quote.author.discriminator} (BOT)`, iconURL: quote.author.displayAvatarURL() }); + + if (guild.id != message.guild.id) Embed.addFields({ name: 'In guild', value: guild.name, inline: true }); + const Attachment = Array.from(message.attachments.values()); + if (Attachment[0]) Embed.setImage(Attachment[0].url); + + return message.channel.send({ embeds: [Embed] }); + } } } diff --git a/migrations/20220829184747-create-optout.js b/migrations/20220829184747-create-optout.js new file mode 100644 index 0000000..1c89ec4 --- /dev/null +++ b/migrations/20220829184747-create-optout.js @@ -0,0 +1,27 @@ +'use strict'; +module.exports = { + async up(queryInterface, Sequelize) { + await queryInterface.createTable('optouts', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + userID: { + type: Sequelize.BIGINT + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }); + }, + async down(queryInterface, Sequelize) { + await queryInterface.dropTable('optouts'); + } +}; \ No newline at end of file diff --git a/models/optout.js b/models/optout.js new file mode 100644 index 0000000..c9afc92 --- /dev/null +++ b/models/optout.js @@ -0,0 +1,23 @@ +'use strict'; +const { + Model +} = require('sequelize'); +module.exports = (sequelize, DataTypes) => { + class optout extends Model { + /** + * Helper method for defining associations. + * This method is not a part of Sequelize lifecycle. + * The `models/index` file will call this method automatically. + */ + static associate(models) { + // define association here + } + } + optout.init({ + userID: DataTypes.BIGINT + }, { + sequelize, + modelName: 'optout', + }); + return optout; +}; \ No newline at end of file