const { Client, GatewayIntentBits, EmbedBuilder, PermissionsBitField, Collection, Partials,ActionRowBuilder, ButtonBuilder, ButtonStyle, ChannelType,SlashCommandBuilder } = require(`discord.js`); const { createTranscript } = require('discord-html-transcripts'); const fs = require('fs'); const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildMembers, GatewayIntentBits.MessageContent, ], partials:[ Partials.Channel, Partials.Message, Partials.User, Partials.GuildMember, Partials.Reaction, ] }); const ticketSchema = require("../src/Models/ticketSchema"); client.on("interactionCreate", async (interaction) => { const { customId, guild, channel } = interaction; if (interaction.isButton()) { if (customId === "ticket") { let data = await ticketSchema.findOne({ GuildID: interaction.guild.id, }); if (!data) return await interaction.reply({ content: "Ticket system is not setup in this server", ephemeral: true }) const role = guild.roles.cache.get(data.Role) const cate = data.Category; await interaction.guild.channels.create({ name: `ticket-${interaction.user.username}`, parent: cate, type: ChannelType.GuildText, permissionOverwrites: [ { id: interaction.guild.id, deny: ["ViewChannel"] }, { id: role.id, allow: ["ViewChannel", "SendMessages", "ReadMessageHistory"] }, { id: interaction.member.id, allow: ["ViewChannel", "SendMessages", "ReadMessageHistory"] }, ], }).then(async (channel) => { const openembed = new EmbedBuilder() .setColor("Red") .setTitle("Ticket Opened") .setDescription(`Welcome to your ticket ${interaction.user.username}\n React with 🔒 to close the ticket`) .setThumbnail(interaction.guild.iconURL()) .setTimestamp() .setFooter({ text: `${interaction.guild.name}'s Tickets` }) const closeButton = new ActionRowBuilder() .addComponents( new ButtonBuilder() .setCustomId('closeticket') .setLabel('Close') .setStyle(ButtonStyle.Danger) .setEmoji('🔒') ) await channel.send({ content: `<@&${role.id}>`, embeds: [openembed], components: [closeButton] }) const openedTicket = new EmbedBuilder() .setDescription(`Ticket created in <#${channel.id}>`) await interaction.reply({ embeds: [openedTicket], ephemeral: true }) }) } if (customId === "closeticket") { const closingEmbed = new EmbedBuilder() .setDescription('🔒 are you sure you want to close this ticket?') .setColor('Red') const buttons = new ActionRowBuilder() .addComponents( new ButtonBuilder() .setCustomId('yesclose') .setLabel('Yes') .setStyle(ButtonStyle.Danger) .setEmoji('✅'), new ButtonBuilder() .setCustomId('nodont') .setLabel('No') .setStyle(ButtonStyle.Secondary) .setEmoji('❌') ) await interaction.reply({ embeds: [closingEmbed], components: [buttons] }) } if (customId === "yesclose") { let data = await ticketSchema.findOne({ GuildID: interaction.guild.id }); const transcript = await createTranscript(channel, { limit: -1, returnBuffer: false, filename: `ticket-${interaction.user.username}.html`, }); const transcriptEmbed = new EmbedBuilder() .setAuthor({ name: `${interaction.guild.name}'s Transcripts`, iconURL: guild.iconURL() }) .addFields( {name: `Closed by`, value: `${interaction.user.tag}`} ) .setColor('Red') .setTimestamp() .setThumbnail(interaction.guild.iconURL()) .setFooter({ text: `${interaction.guild.name}'s Tickets` }) const processEmbed = new EmbedBuilder() .setDescription(` Closing ticket in 10 seconds...`) .setColor('Red') await interaction.reply({ embeds: [processEmbed] }) await guild.channels.cache.get(data.Logs).send({ embeds: [transcriptEmbed], files: [transcript], }); setTimeout(() => { interaction.channel.delete() }, 10000); } if (customId === "nodont") { const noEmbed = new EmbedBuilder() .setDescription('🔒 Ticket close cancelled') .setColor('Red') await interaction.reply({ embeds: [noEmbed], ephemeral: true }) } } }) //suggestion const suggestion = require('../src/Models/suggestionSchema'); const formatResults = require('../src/Utilts/formatResults'); client.on("interactionCreate", async interaction => { if (!interaction.guild) return; if (!interaction.message) return; if (!interaction.isButton) return; const data = await suggestion.findOne({ GuildID: interaction.guild.id, Msg: interaction.message.id }); if (!data) return; const message = await interaction.channel.messages.fetch(data.Msg); if (interaction.customId == 'upv') { if (data.Upmembers.includes(interaction.user.id)) return await interaction.reply({content: `You cannot vote again! You have already sent an upvote on this suggestion.`, ephemeral: true}); let Downvotes = data.downvotes; if (data.Downmembers.includes(interaction.user.id)) { Downvotes = Downvotes - 1; } if (data.Downmembers.includes(interaction.user.id)) { data.downvotes = data.downvotes - 1; } data.Upmembers.push(interaction.user.id); data.Downmembers.pull(interaction.user.id); const newEmbed = EmbedBuilder.from(message.embeds[0]).setFields({name: `Upvotes`, value: `> **${data.upvotes + 1}** Votes`, inline: true}, { name: `Downvotes`, value: `> **${Downvotes}** Votes`, inline: true}, {name: `Author`, value: `> <@${data.AuthorID}>`}, { name: `Votes`, value: formatResults(data.Upmembers, data.Downmembers)}); const button = new ActionRowBuilder() .addComponents( new ButtonBuilder() .setCustomId('upv') .setLabel('Upvotes') .setStyle(ButtonStyle.Primary) .setEmoji('👍'), new ButtonBuilder() .setCustomId('downv') .setEmoji('👎') .setLabel('Downvotes') .setStyle(ButtonStyle.Primary), new ButtonBuilder() .setCustomId('totalvotes') .setEmoji('💭') .setLabel('Votes') .setStyle(ButtonStyle.Secondary) ) const button2 = new ActionRowBuilder() .addComponents( new ButtonBuilder() .setCustomId('appr') .setLabel('Approve') .setEmoji('✔') .setStyle(ButtonStyle.Success), new ButtonBuilder() .setCustomId('rej') .setEmoji('❌') .setLabel('Reject') .setStyle(ButtonStyle.Danger) ) await interaction.update({ embeds: [newEmbed], components: [button, button2] }); data.upvotes++; data.save(); } if (interaction.customId == 'downv') { if (data.Downmembers.includes(interaction.user.id)) return await interaction.reply({ content: `You cannot down vote twice on this suggestion!`, ephemeral: true}); let Upvotes = data.upvotes; if (data.Upmembers.includes(interaction.user.id)) { Upvotes = Upvotes - 1; } if (data.Upmembers.includes(interaction.user.id)) { data.upvotes = data.upvotes - 1; } data.Downmembers.push(interaction.user.id); data.Upmembers.pull(interaction.user.id); const newEmbed = EmbedBuilder.from(message.embeds[0]).setFields({name: `Upvotes`, value: `> **${Upvotes}** Votes`, inline: true}, { name: `Downvotes`, value: `> **${data.downvotes + 1}** Votes`, inline: true}, {name: `Author`, value: `> <@${data.AuthorID}>`}, { name: `Votes`, value: formatResults(data.Upmembers, data.Downmembers)}); const button = new ActionRowBuilder() .addComponents( new ButtonBuilder() .setCustomId('upv') .setLabel('Upvotes') .setStyle(ButtonStyle.Primary) .setEmoji('<:tup:1162598259626352652>'), new ButtonBuilder() .setCustomId('downv') .setEmoji('<:tdown:1162598331390889994>') .setLabel('Downvotes') .setStyle(ButtonStyle.Primary), new ButtonBuilder() .setCustomId('totalvotes') .setEmoji('💭') .setLabel('Votes') .setStyle(ButtonStyle.Secondary) ) const button2 = new ActionRowBuilder() .addComponents( new ButtonBuilder() .setCustomId('appr') .setLabel('Approve') .setEmoji('') .setStyle(ButtonStyle.Success), new ButtonBuilder() .setCustomId('rej') .setEmoji('') .setLabel('Reject') .setStyle(ButtonStyle.Danger) ) await interaction.update({ embeds: [newEmbed], components: [button, button2] }); data.downvotes++; data.save(); } if (interaction.customId == 'totalvotes') { let upvoters = []; await data.Upmembers.forEach(async member => { upvoters.push(`<@${member}`) }); let downvoters = []; await data.Downmembers.forEach(async member => { downvoters.push(`<@${member}>`) }); const embed = new EmbedBuilder() .addFields({ name: `Upvoters (${upvoters.length})`, value: `> ${upvoters.join(', ').slice(0, 1020) || `No upvoters!`}`, inline: true}) .addFields({ name: `Downvoters (${downvoters.length})`, value: `> ${downvoters.join(', ').slice(0, 1020) || `No downvoters!`}`, inline: true}) .setColor('Random') .setTimestamp() .setFooter({ text: `💭 Vote Data`}) .setAuthor({ name: `${interaction.guild.name}'s Suggestion System`}) await interaction.reply({ embeds: [embed], ephemeral: true }); } if (interaction.customId == 'appr') { if (!interaction.member.permissions.has(PermissionsBitField.Flags.ModerateMembers)) return await interaction.reply({ content: `Only Admins & Staffs can use this button.`, ephemeral: true }); const newEmbed = EmbedBuilder.from(message.embeds[0]).setDescription(' Your suggestion has been approved!') await interaction.update({ embeds: [newEmbed], components: [message.components[0]] }); } if (interaction.customId == 'rej') { if (!interaction.member.permissions.has(PermissionsBitField.Flags.ModerateMembers)) return await interaction.reply({ content: `Only Admins & Staffs can use this button.`, ephemeral: true }); const newEmbed = EmbedBuilder.from(message.embeds[0]).setDescription(' Your suggestion has been rejected!') await interaction.update({ embeds: [newEmbed], components: [message.components[0]] }); } }) client.commands = new Collection(); require('dotenv').config(); const functions = fs.readdirSync("./src/functions").filter(file => file.endsWith(".js")); const eventFiles = fs.readdirSync("./src/events").filter(file => file.endsWith(".js")); const commandFolders = fs.readdirSync("./src/commands"); (async () => { for (file of functions) { require(`./functions/${file}`)(client); } client.handleEvents(eventFiles, "./src/events"); client.handleCommands(commandFolders, "./commands"); client.login(process.env.token) })();