// my index.js require('dotenv').config(); const { Client, GatewayIntentBits, EmbedBuilder, ActionRowBuilder, REST, Routes, PermissionsBitField, StringSelectMenuBuilder, ChannelType, Collection, ButtonBuilder, ButtonStyle } = require('discord.js'); const config = require('./config.js'); const { prefix, guildID, botID, ticketChannelID, staffRoleID, logChannelID, welcomeChannelID, logstaffChannelID, ticketCategoryID, leaveChannelID, boostChannelID, chisonoChannelID, tredquatRolelID, quindiciaRolelID, diciottoRolelID, nordRolelID, centroRolelID, sudRolelID, esteroRoleID, maschioRolelID, femminaRolelID, altroRolelID } = config; const client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers, GatewayIntentBits.GuildVoiceStates, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent ] }); const activeTickets = {}; // Definizione dell'oggetto per tenere traccia dei ticket attivi client.commands = new Collection(); const clearCommand = require('./clearCommand.js'); client.commands.set(clearCommand.data.name, clearCommand); const pingCommand = require('./pingCommand.js'); client.commands.set(pingCommand.data.name, pingCommand); const anonCommand = require('./anonCommand.js'); client.commands.set(anonCommand.data.name, anonCommand); client.on('ready', () => { console.log(`Il bot è online come ${client.user.tag}`); updateCommands(); }); client.on('guildMemberAdd', async (member) => { const welcomeChannel = await client.channels.fetch(welcomeChannelID); const roleID = '991387929563910165'; // Sostituisci con l'ID del ruolo base nel server await member.roles.add(roleID); if (welcomeChannel) { const welcomeEmbed = new EmbedBuilder() .setColor('#1010CB') .setTitle('Benvenuto/a!') .setDescription(`Benvenuto/a su ${member.guild.name}, ${member}!`) .setThumbnail(member.user.displayAvatarURL()) .addFields( { name: '*Questo è* ', value: '*un server senza topic specifico, aperto a tutti e tutte, con poche ed essenziali regole basate sul buon senso.*' }, ) .setImage('https://i.pinimg.com/originals/27/1f/9e/271f9e3efbc58dbb075903c7096ba99c.gif') .setTimestamp() .setFooter({ text: 'L U N A R®'}); await welcomeChannel.send({ embeds: [welcomeEmbed] }); } }); client.on('guildMemberRemove', async (member) => { const leaveChannel = await client.channels.fetch(leaveChannelID); if (leaveChannel) { const leaveEmbed = new EmbedBuilder() .setColor('#1010CB') .setTitle('Membro uscito') .setDescription(`${member.user.tag} ha lasciato il server, a presto!`) .setThumbnail(member.user.displayAvatarURL()) .setTimestamp() .setFooter({ text: 'L U N A R®'}); await leaveChannel.send({ embeds: [leaveEmbed] }); } }); client.on('guildMemberUpdate', async (oldMember, newMember) => { const oldBoosting = oldMember.premiumSince; const newBoosting = newMember.premiumSince; if (!oldBoosting && newBoosting) { const boostChannel = await client.channels.fetch(boostChannelID); if (boostChannel) { const boostEmbed = new EmbedBuilder() .setColor('#FF73FA') .setTitle('Grazie per il boost!') .setDescription(`Grazie mille ${newMember.user.tag} per aver boostato il server! 🎉`) .setThumbnail('https://i.pinimg.com/originals/7d/c0/c9/7dc0c919ef58d2514ddb524d7b3ff373.gif') .setTimestamp() .setFooter({ text: 'L U N A R®'}); await boostChannel.send({ embeds: [boostEmbed] }); } } }); const updateCommands = async () => { const commands = [ clearCommand.data.toJSON(), pingCommand.data.toJSON(), anonCommand.data.toJSON(), ]; const rest = new REST({ version: '10' }).setToken(process.env.TOKEN); try { console.log('Inizio il refresh dei comandi dell\'applicazione (/).'); await rest.put( Routes.applicationGuildCommands(botID, guildID), { body: commands }, ); console.log('Comandi dell\'applicazione (/) ricaricati con successo.'); } catch (error) { console.error('Errore durante il refresh dei comandi dell\'applicazione:', error); } }; client.on('interactionCreate', async interaction => { // Controlla se l'interazione avviene nel canale "chisono" if (interaction.channelId === chisonoChannelID && interaction.isStringSelectMenu()) { // Gestione delle selezioni del menu a tendina per i ruoli const { customId, values, member } = interaction; const selectedRoleID = values[0]; // Definisci i gruppi di ruoli const etaRoles = [tredquatRolelID, quindiciaRolelID, diciottoRolelID]; const localitaRoles = [nordRolelID, centroRolelID, sudRolelID, esteroRoleID]; const genereRoles = [maschioRolelID, femminaRolelID, altroRolelID]; let roleGroup = []; // Determina a quale gruppo di ruoli appartiene l'opzione selezionata if (etaRoles.includes(selectedRoleID)) { roleGroup = etaRoles; } else if (localitaRoles.includes(selectedRoleID)) { roleGroup = localitaRoles; } else if (genereRoles.includes(selectedRoleID)) { roleGroup = genereRoles; } try { // Rimuove i ruoli esistenti nel gruppo selezionato const rolesToRemove = member.roles.cache.filter(role => roleGroup.includes(role.id)); await member.roles.remove(rolesToRemove); // Assegna il nuovo ruolo selezionato if (!rolesToRemove.has(selectedRoleID)) { await member.roles.add(selectedRoleID); await interaction.reply({ content: `Ruolo assegnato: <@&${selectedRoleID}>`, ephemeral: true }); } else { await interaction.reply({ content: `Il ruolo è già stato rimosso: <@&${selectedRoleID}>`, ephemeral: true }); } } catch (error) { console.error('Errore durante la gestione dell\'interazione:', error); await interaction.reply({ content: 'Si è verificato un errore durante la gestione della tua selezione.', ephemeral: true }); } } // Controlla se l'interazione riguarda l'apertura di un ticket else if (interaction.isStringSelectMenu()) { // Gestione della selezione del tipo di ticket const ticketType = interaction.values[0]; const ticketUser = interaction.user; const ticketChannel = await client.channels.fetch(ticketChannelID); const logChannel = await client.channels.fetch(logChannelID); // Controlla se l'utente ha già un ticket aperto if (activeTickets[ticketUser.id]) { await interaction.reply({ content: 'Hai già un ticket aperto!', ephemeral: true }); return; } const ticketChannelName = `${ticketType}-${ticketUser.username}`; try { const createdChannel = await ticketChannel.guild.channels.create({ name: ticketChannelName, type: ChannelType.GuildText, parent: ticketCategoryID, permissionOverwrites: [ { id: ticketChannel.guild.id, deny: [PermissionsBitField.Flags.ViewChannel], }, { id: ticketUser.id, allow: [PermissionsBitField.Flags.ViewChannel], }, ], }); activeTickets[ticketUser.id] = createdChannel.id; const embed = new EmbedBuilder() .setColor(0x0099FF) .setTitle('Ticket Aperto') .setDescription(`Ciao ${ticketUser.username}, attendi che uno <@&${staffRoleID}> risponda al tuo ticket. Per chiudere il ticket premi il pulsante qui sotto.`); const button = new ButtonBuilder() .setCustomId('close_ticket') .setLabel('🔒 Chiudi') .setStyle(ButtonStyle.Danger); const row = new ActionRowBuilder().addComponents(button); await createdChannel.send({ embeds: [embed], components: [row] }); await interaction.reply({ content: `Ticket ${ticketType} aperto con successo nel canale ${createdChannel}`, ephemeral: true }); } catch (error) { console.error('Errore durante la creazione del ticket:', error); await interaction.reply({ content: 'Si è verificato un errore durante la creazione del ticket.', ephemeral: true }); } } }); client.once('ready', async () => { try { const ticketChannel = await client.channels.fetch(ticketChannelID); const messages = await ticketChannel.messages.fetch(); messages.forEach(message => message.delete()); const ticketEmbed = new EmbedBuilder() .setTitle('Apri un Ticket') .setDescription('Seleziona il tipo di ticket che vuoi aprire dalla lista qui sotto:') .addFields( { name: '*NOTA*', value: '*[Aprire un Ticket e non fornire alcuna risposta in esso per un tempo maggiore di 24h comporterà la chiusura automatica dello stesso.]*' } ) .setColor('#e7eb88'); const row = new ActionRowBuilder() .addComponents( new StringSelectMenuBuilder() .setCustomId('ticketType') .setPlaceholder('Seleziona il tipo di ticket') .addOptions([ { label: '🔧Assistenza Tecnica', description: 'Richiedi assistenza tecnica', value: 'tech_support' }, { label: '🥊Segnalazione', description: 'Segnalaci un problema, bug o altro', value: 'report' }, { label: '🧨Rimuovi Sanzione', description: 'Richiedi la rimozione di una sanzione', value: 'remove_punishment' }, { label: '🌺PartnerShip', description: 'Richiedi una Partnership', value: 'partnership' }, { label: '🥥Altro', description: 'Richiedi assistenza per altro', value: 'other' } ]) ); await ticketChannel.send({ embeds: [ticketEmbed], components: [row] }); console.log('Messaggio dei ticket inviato con successo.'); updateCommands(); // Assicurati di chiamare updateCommands quando il bot è pronto } catch (error) { console.error('Errore durante la configurazione iniziale:', error); } }); client.once('ready', async () => { try { const chisonoChannel = await client.channels.fetch(chisonoChannelID); // Elimina tutti i messaggi esistenti nel canale const messages = await chisonoChannel.messages.fetch(); messages.forEach(message => message.delete()); // Creazione degli embed const etaEmbed = new EmbedBuilder() .setImage('https://s10.gifyu.com/images/Sohqi.gif') .setColor('#ffdd00'); const localitaEmbed = new EmbedBuilder() .setImage('https://s12.gifyu.com/images/SohqU.gif') .setColor('#00ffdd'); const genereEmbed = new EmbedBuilder() .setImage('https://s10.gifyu.com/images/Sohq0.gif') .setColor('#dd00ff'); // Creazione dei menu a tendina const etaMenu = new StringSelectMenuBuilder() .setCustomId('etaSelect') .setPlaceholder('Seleziona la tua età') .addOptions([ { label: '🎗13-14', value: tredquatRolelID }, { label: '🧦15-17', value: quindiciaRolelID }, { label: '📿18+', value: diciottoRolelID } ]); const localitaMenu = new StringSelectMenuBuilder() .setCustomId('localitaSelect') .setPlaceholder('Seleziona la tua località') .addOptions([ { label: '🗻Nord', value: nordRolelID }, { label: '🕍Centro', value: centroRolelID }, { label: '🌊Sud', value: sudRolelID }, { label: '🛴Estero', value: esteroRoleID } ]); const genereMenu = new StringSelectMenuBuilder() .setCustomId('genereSelect') .setPlaceholder('Seleziona il tuo genere') .addOptions([ { label: '📘Maschio', value: maschioRolelID }, { label: '📕Femmina', value: femminaRolelID }, { label: '📙Altro', value: altroRolelID } ]); // Invio dei messaggi con gli embed e i menu await chisonoChannel.send({ embeds: [etaEmbed], components: [new ActionRowBuilder().addComponents(etaMenu)] }); await chisonoChannel.send({ embeds: [localitaEmbed], components: [new ActionRowBuilder().addComponents(localitaMenu)] }); await chisonoChannel.send({ embeds: [genereEmbed], components: [new ActionRowBuilder().addComponents(genereMenu)] }); console.log('Embed e menu inviati con successo nel canale chisono.'); } catch (error) { console.error('Errore durante la configurazione iniziale:', error); } }); function logBan(member, executor, reason) { const logstaffChannel = client.channels.cache.get(config.logstaffChannelID); if (logstaffChannel) { const banEmbed = new EmbedBuilder() .setColor('#FF0000') .setTitle('Utente Bannato') .addFields( { name: 'Utente:', value: `${member.user.tag}`, inline: true }, { name: 'Eseguito da:', value: `${executor.tag}`, inline: true } ) .setTimestamp(); logstaffChannel.send({ embeds: [banEmbed] }); } } function logKick(member, executor, reason) { const logstaffChannel = client.channels.cache.get(config.logstaffChannelID); if (logstaffChannel) { const kickEmbed = new EmbedBuilder() .setColor('#FFA500') .setTitle('Utente Espulso') .addFields( { name: 'Utente:', value: `${member.user.tag}`, inline: true }, { name: 'Eseguito da:', value: `${executor.tag}`, inline: true } ) .setTimestamp(); logstaffChannel.send({ embeds: [kickEmbed] }); } } client.on('guildMemberUpdate', (oldMember, newMember) => { const oldTimeout = oldMember.communicationDisabledUntil; const newTimeout = newMember.communicationDisabledUntil; if (!oldTimeout && newTimeout) { const logstaffChannel = client.channels.cache.get(config.logstaffChannelID); const timeoutEmbed = new EmbedBuilder() .setColor('#800080') .setTitle('Utente in Timeout') .addFields( { name: 'Utente:', value: `${newMember.user.tag}`, inline: true }, { name: 'Timeout fino a:', value: newTimeout.toUTCString(), inline: true } ) .setTimestamp(); logstaffChannel.send({ embeds: [timeoutEmbed] }); } }); client.on('messageDelete', async message => { if (message.partial) return; // If the message was not cached, ignore it const logChannel = await client.channels.fetch(logChannelID); if (logChannel) { const embed = new EmbedBuilder() .setColor('#FF0000') .setTitle('Messaggio Eliminato') .setDescription(`Un messaggio è stato eliminato in <#${message.channel.id}>`) .addFields( { name: 'Autore:', value: `${message.author.tag}`, inline: true }, { name: 'Contenuto:', value: message.content || 'Nessun contenuto disponibile' } ) .setTimestamp(); logChannel.send({ embeds: [embed] }); } }); client.on('messageUpdate', async (oldMessage, newMessage) => { if (oldMessage.partial || newMessage.partial) return; // If the message was not cached, ignore it if (oldMessage.content === newMessage.content) return; // Ignore if the content is the same const logChannel = await client.channels.fetch(logChannelID); if (logChannel) { const embed = new EmbedBuilder() .setColor('#FFA500') .setTitle('Messaggio Modificato') .setDescription(`Un messaggio è stato modificato in <#${oldMessage.channel.id}>`) .addFields( { name: 'Autore:', value: `${oldMessage.author.tag}`, inline: true }, { name: 'Prima:', value: oldMessage.content || 'Nessun contenuto disponibile' }, { name: 'Dopo:', value: newMessage.content || 'Nessun contenuto disponibile' } ) .setTimestamp(); logChannel.send({ embeds: [embed] }); } }); client.on('channelUpdate', async (oldChannel, newChannel) => { const logChannel = await client.channels.fetch(logChannelID); if (oldChannel.name !== newChannel.name) { if (logChannel) { const embed = new EmbedBuilder() .setColor('#8A2BE2') .setTitle('Canale Aggiornato') .setDescription(`Un canale è stato aggiornato: <#${newChannel.id}>`) .addFields( { name: 'Nome Precedente:', value: oldChannel.name }, { name: 'Nuovo Nome:', value: newChannel.name } ) .setTimestamp(); logChannel.send({ embeds: [embed] }); } } }); client.on('guildMemberUpdate', async (oldMember, newMember) => { const logChannel = await client.channels.fetch(logChannelID); if (!oldMember.roles.cache.equals(newMember.roles.cache)) { const oldRoles = oldMember.roles.cache.map(role => role.name).join(', ') || 'Nessun ruolo'; const newRoles = newMember.roles.cache.map(role => role.name).join(', ') || 'Nessun ruolo'; if (logChannel) { const embed = new EmbedBuilder() .setColor('#0000FF') .setTitle('Ruoli Aggiornati') .setDescription(`I ruoli di ${newMember.user.tag} sono stati aggiornati`) .addFields( { name: 'Prima:', value: oldRoles }, { name: 'Dopo:', value: newRoles } ) .setTimestamp(); logChannel.send({ embeds: [embed] }); } } }); client.login(process.env.TOKEN); // my clearCommand.js const { PermissionFlagsBits, SlashCommandBuilder } = require('discord.js'); const config = require('./config.js'); const { staffRoleID } = config; async function expensiveOperation() { // Simula un'operazione lunga await new Promise(resolve => setTimeout(resolve, 3000)); } module.exports = { data: new SlashCommandBuilder() .setName('clear') .setDescription('Cancella una quantità di messaggi') .addIntegerOption(option => option.setName('quantita') // Nome dell'opzione .setDescription('Numero di messaggi da cancellare') .setRequired(true)), async execute(interaction) { const amount = interaction.options.getInteger('quantita'); // Ottiene il valore di "quantita" // Controlla se l'utente ha il ruolo staff if (!interaction.member.roles.cache.has(staffRoleID)) { return interaction.reply({ content: "Non hai il permesso di usare questo comando!", ephemeral: true }); } // Controlla se l'utente ha il permesso di gestire i messaggi if (!interaction.member.permissions.has(PermissionFlagsBits.ManageMessages)) { return interaction.reply({ content: "Non hai il permesso di cancellare i messaggi!", ephemeral: true }); } // Verifica che l'importo sia tra 1 e 20 if (amount < 1 || amount > 20) { return interaction.reply({ content: 'Specifica un numero compreso tra 1 e 20 di messaggi da cancellare.', ephemeral: true }); } try { // Deferisce la risposta per gestire operazioni lunghe await interaction.deferReply({ ephemeral: true }); // Simula un'operazione lunga (ad es. elaborazione o attesa di una risorsa esterna) await expensiveOperation(); // Cancella i messaggi specificati const deletedMessages = await interaction.channel.bulkDelete(amount, true); // Se nessun messaggio è stato cancellato, solleva un errore if (deletedMessages.size === 0) { throw new Error('Nessun messaggio da cancellare.'); } // Modifica la risposta originale per confermare l'operazione await interaction.editReply({ content: `Operazione completata. Cancellati ${deletedMessages.size} messaggi.`, ephemeral: true }); } catch (error) { console.error('Errore durante l\'esecuzione del comando:', error); let errorMessage = 'Si è verificato un errore durante l\'esecuzione dell\'operazione.'; if (error.message === 'Nessun messaggio da cancellare.') { errorMessage = 'Non ci sono messaggi da cancellare o i messaggi sono più vecchi di 14 giorni.'; } // Verifica se l'interazione è già stata risolta (replied o deferred) if (interaction.replied || interaction.deferred) { try { await interaction.editReply({ content: errorMessage, ephemeral: true }); } catch (err) { console.error('Errore durante l\'edit della risposta:', err); } } else { try { await interaction.reply({ content: errorMessage, ephemeral: true }); } catch (err) { console.error('Errore durante la risposta:', err); } } } } }; // my anonCommand.js const { SlashCommandBuilder, EmbedBuilder, ModalBuilder, TextInputBuilder, TextInputStyle, ActionRowBuilder } = require('discord.js'); const config = require('./config.js'); const { roleID, anonChannelID } = config; module.exports = { data: new SlashCommandBuilder() .setName('anon') .setDescription('Invia un messaggio anonimo tramite un modulo'), async execute(interaction) { // Controlla se l'utente ha il ruolo richiesto if (!interaction.member.roles.cache.has(roleID)) { return interaction.reply({ content: 'Non hai il permesso di eseguire questo comando!', ephemeral: true }); } // Crea un modulo per inserire il messaggio anonimo const modal = new ModalBuilder() .setCustomId('anonModal') .setTitle('Invia un messaggio anonimo'); const messageInput = new TextInputBuilder() .setCustomId('anonMessage') .setLabel('Inserisci il tuo messaggio anonimo') .setStyle(TextInputStyle.Paragraph) // Stile di input per testo lungo .setRequired(true); const firstActionRow = new ActionRowBuilder().addComponents(messageInput); modal.addComponents(firstActionRow); // Mostra il modulo all'utente await interaction.showModal(modal); }, async handleModalSubmit(interaction) { if (interaction.customId === 'anonModal') { const messaggio = interaction.fields.getTextInputValue('anonMessage'); // Invia il messaggio anonimo nel canale designato const anonChannel = await interaction.guild.channels.fetch(anonChannelID); const embed = new EmbedBuilder() .setTitle('Messaggio Anonimo') .setDescription(messaggio) .setTimestamp() .setFooter({ text: 'L U N A R®' }) .setColor(`#${Math.floor(Math.random() * 16777215).toString(16).padStart(6, '0')}`); await anonChannel.send({ embeds: [embed] }); // Notifica l'utente che il messaggio è stato inviato await interaction.reply({ content: 'Il tuo messaggio anonimo è stato inviato con successo!', ephemeral: true }); } } }; // my pingCommand.js const { SlashCommandBuilder } = require('discord.js'); const config = require('./config.js'); const { roleID } = config; module.exports = { data: new SlashCommandBuilder() .setName('ping') .setDescription('Calcola la latenza di rete di un utente menzionato') .addMentionableOption(option => option.setName('utente') .setDescription('Seleziona un utente per vedere il suo ping') .setRequired(true)), async execute(interaction) { // Controlla se l'utente ha il ruolo richiesto if (!interaction.member.roles.cache.has(roleID)) { return interaction.reply({ content: 'Non hai il permesso di eseguire questo comando!', ephemeral: true }); } // Ottieni l'utente menzionato const mention = interaction.options.getMentionable('utente'); // Verifica se l'opzione è valida e se si riferisce a un utente if (!mention || !mention.user) { return interaction.reply({ content: 'Devi menzionare un utente valido per calcolare il suo ping.', ephemeral: true }); } try { // Calcolo del ping: differenza tra il timestamp corrente e quello di creazione dell'interazione const ping = Date.now() - interaction.createdTimestamp; // Risposta con il risultato del ping await interaction.reply(`Pong! 🏓 La latenza di ${mention.user.username} è di ${ping} ms.`); } catch (error) { console.error('Errore durante l\'esecuzione del comando ping:', error); await interaction.reply({ content: 'Errore durante l\'esecuzione del comando ping.', ephemeral: true }); } }, };