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, anonChannelID, 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 => { // Gestione comandi slash if (interaction.isCommand()) { const command = client.commands.get(interaction.commandName); if (!command) return; try { await command.execute(interaction); } catch (error) { console.error('Errore durante l\'esecuzione del comando:', error); if (!interaction.replied) { await interaction.reply({ content: 'Si è verificato un errore durante l\'esecuzione del comando.', ephemeral: true }); } } } // Gestione dei menu a tendina (StringSelectMenu) if (interaction.isStringSelectMenu()) { const { customId, values, member } = interaction; if (customId === 'etaSelect') { // Gestione del menu "età" const selectedRoleID = values[0]; const etaRoles = [tredquatRolelID, quindiciaRolelID, diciottoRolelID]; try { const rolesToRemove = member.roles.cache.filter(role => etaRoles.includes(role.id)); await member.roles.remove(rolesToRemove); await member.roles.add(selectedRoleID); await interaction.reply({ content: `Ruolo età assegnato: <@&${selectedRoleID}>`, ephemeral: true }); } catch (error) { console.error('Errore durante la gestione del ruolo età:', error); await interaction.reply({ content: 'Si è verificato un errore durante l\'assegnazione del ruolo.', ephemeral: true }); } } else if (customId === 'localitaSelect') { // Gestione del menu "località" const selectedRoleID = values[0]; const localitaRoles = [nordRolelID, centroRolelID, sudRolelID, esteroRoleID]; try { const rolesToRemove = member.roles.cache.filter(role => localitaRoles.includes(role.id)); await member.roles.remove(rolesToRemove); await member.roles.add(selectedRoleID); await interaction.reply({ content: `Ruolo località assegnato: <@&${selectedRoleID}>`, ephemeral: true }); } catch (error) { console.error('Errore durante la gestione del ruolo località:', error); await interaction.reply({ content: 'Si è verificato un errore durante l\'assegnazione del ruolo.', ephemeral: true }); } } else if (customId === 'genereSelect') { // Gestione del menu "genere" const selectedRoleID = values[0]; const genereRoles = [maschioRolelID, femminaRolelID, altroRolelID]; try { const rolesToRemove = member.roles.cache.filter(role => genereRoles.includes(role.id)); await member.roles.remove(rolesToRemove); await member.roles.add(selectedRoleID); await interaction.reply({ content: `Ruolo genere assegnato: <@&${selectedRoleID}>`, ephemeral: true }); } catch (error) { console.error('Errore durante la gestione del ruolo genere:', error); await interaction.reply({ content: 'Si è verificato un errore durante l\'assegnazione del ruolo.', ephemeral: true }); } } else if (customId === 'ticketType') { // Gestione del menu per la creazione del ticket const ticketType = values[0]; // "tech_support", "report", ecc. const ticketUser = interaction.user; const ticketChannel = await client.channels.fetch(ticketChannelID); 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] }, { id: staffRoleID, 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 }); } } } // Gestione dei pulsanti if (interaction.isButton() && interaction.customId === 'close_ticket') { const ticketChannel = interaction.channel; try { await interaction.reply({ content: 'Ticket chiuso con successo.', ephemeral: true }); await ticketChannel.delete(); delete activeTickets[interaction.user.id]; } catch (error) { console.error('Errore durante la chiusura del ticket:', error); if (!interaction.replied) { await interaction.reply({ content: 'Si è verificato un errore durante la chiusura 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); } if (interaction.isModalSubmit()) { if (interaction.customId === 'anonModal') { // Usa lo stesso customId di anonCommand.js const messageContent = interaction.fields.getTextInputValue('anonMessage'); // Allineato con anonCommand.js try { const channel = client.channels.cache.get(anonChannelID); // Usa l'ID del canale dal config.js if (!channel) { return interaction.reply({ content: 'Canale per i messaggi anonimi non trovato.', ephemeral: true }); } // Invia il messaggio anonimo nel canale await channel.send(`Messaggio anonimo: ${messageContent}`); // Risponde al Modal informando che il messaggio è stato inviato con successo await interaction.reply({ content: 'Il tuo messaggio anonimo è stato inviato con successo!', ephemeral: true }); } catch (error) { console.error('Errore durante l\'invio del messaggio anonimo:', error); await interaction.reply({ content: 'Si è verificato un errore durante l\'invio del tuo messaggio.', ephemeral: true }); } } }}); 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);