import { Client, GatewayIntentBits, WebhookClient, AuditLogEvent, OAuth2Scopes, Options } from 'discord.js'; import commands from './commands.js'; import firstDetector from './detectors/allDetector.js'; // On importe la chaine de détecteurs const webhookClient = process.env.LOGS_WEBHOOK ? new WebhookClient({ url: process.env.LOGS_WEBHOOK }) : null; const client = new Client({ makeCache: Options.cacheWithLimits({ MessageManager: 0, // le bot ne se souviendra pas des anciens messages (pas de cache) }), intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent, ] }); // Gestion des Logs Guild (Join/Leave) client.on('guildCreate', async (guild) => { const logs = await guild.fetchAuditLogs().catch(() => null); const inviter = logs?.entries .find((l) => l.action === AuditLogEvent.BotAdd && l.targetId === client.user?.id)?.executor; webhookClient?.send({ content: `Joined guild: \`\`\` name: ${guild.name} (${guild.id}) inviter: ${inviter != null ? ` invited by ${inviter.tag} (${inviter.id})` : ' (unknown inviter)'} member count: ${guild.memberCount} \`\`\`` }); }); client.on('guildDelete', async (guild) => { webhookClient?.send({ content: `Left guild ${guild.name} (${guild.id})` }); }); // Démarrage client.on('ready', async () => { console.log(`Logged in as ${client.user?.tag ?? 'unknown'}`); webhookClient?.send({ content: `Logged in as ${client.user?.tag ?? 'unknown'}` }); await client.guilds.fetch(); console.log('Bot is ready!'); console.log(client.generateInvite({ scopes: [OAuth2Scopes.Bot], permissions: [ 'SendMessages', 'ViewAuditLog', 'ViewChannel', 'UseApplicationCommands', 'EmbedLinks', 'ReadMessageHistory' ] })); // Enregistrement des commandes slash if (client.application) { await client.application.commands.set([ commands['channel-ignore'].command, commands['retire-role'].command, commands['get-config'].command, commands['set-config'].command, ]); console.log('Commandes Slash enregistrées.'); } }); // Gestion des Commandes (/slash) client.on('interactionCreate', async (interaction) => { if (!interaction.guild || !interaction.member || !interaction.isChatInputCommand()) { return; } const command = commands[interaction.commandName]; if (command) { try { await command.run(interaction); } catch (error) { console.error('Erreur commande:', error); const replyObj = { content: 'Une erreur est survenue.', ephemeral: true }; if (interaction.replied || interaction.deferred) { await interaction.followUp(replyObj); } else { await interaction.reply(replyObj); } } } }); // Gestion des Messages (Listeners) // Fonction locale pour traiter un message (remplace newMessageListener) async function handleMessage(message) { try { const reply = await firstDetector.createReply(message); if (reply) { await message.reply(reply); } } catch (e) { console.error('Erreur dans le détecteur:', e); } } client.on('messageCreate', async (message) => { if (message.author.bot) return; await handleMessage(message); }); client.on('messageUpdate', async (oldMessage, newMessage) => { let message = newMessage; if (message.partial) { try { message = await message.fetch(); } catch (e) { console.error('Error while fetching message', e); return; } } if (!message.author || message.author.bot) return; if (oldMessage.content === message.content) return; // Pas de changement de texte if (!message.content) return; // Si l'ancien message déclenchait déjà un "quoi" (regex simple), on évite de spammer if (oldMessage.content && oldMessage.content.match(/(\b|^)quoi(\b|$)/i)) { return; } await handleMessage(message); }); client.login(process.env.DISCORD_TOKEN);