add some utilities commands

This commit is contained in:
Arthur Puechberty
2026-01-17 23:07:54 +01:00
parent 6997254a3f
commit e321e38c19
14 changed files with 1155 additions and 0 deletions
+1
View File
@@ -27,6 +27,7 @@ BOT_TOKEN=VOTRE_TOKEN_BOT
SESSION_SECRET=un_secret_aleatoire_pour_les_sessions SESSION_SECRET=un_secret_aleatoire_pour_les_sessions
DB_PATH=database.sqlite DB_PATH=database.sqlite
OWNER=VOTRE_ID_UTILISATEUR OWNER=VOTRE_ID_UTILISATEUR
URL=https://ton-domaine.com
``` ```
4. Lancer le serveur : 4. Lancer le serveur :
+99
View File
@@ -0,0 +1,99 @@
const addCommand = require("../fonctions/addCommand");
const { EmbedBuilder } = require("discord.js");
module.exports = addCommand({
name: "avatar",
description: "Affiche l'avatar d'un utilisateur.",
aliases: ["av", "pp", "pdp", "pfp"],
permissions: [],
botOwnerOnly: false,
dm: false,
scope: "global",
slashOptions: [
{
type: "USER",
name: "utilisateur",
description: "L'utilisateur dont vous voulez voir l'avatar",
required: false,
},
],
executePrefix: async (client, message, args) => {
const user = message.mentions.users.first() || (args[0] ? await client.users.fetch(args[0]).catch(() => null) : null) || message.author;
const member = message.guild.members.cache.get(user.id);
await sendAvatarEmbed(message, user, member, message.author);
},
executeSlash: async (client, interaction) => {
const user = interaction.options.getUser("utilisateur") || interaction.user;
const member = interaction.guild.members.cache.get(user.id);
await sendAvatarEmbedSlash(interaction, user, member);
},
});
async function sendAvatarEmbed(message, user, member, requestedBy) {
const globalAvatar = user.displayAvatarURL({ dynamic: true, size: 4096 });
const serverAvatar = member?.displayAvatarURL({ dynamic: true, size: 4096 });
const embed = new EmbedBuilder()
.setColor(0x5865F2)
.setTitle(`🖼️ Avatar de ${user.username}`)
.setImage(globalAvatar)
.addFields(
{ name: "🔗 Liens", value: `[PNG](${user.displayAvatarURL({ extension: "png", size: 4096 })}) • [JPG](${user.displayAvatarURL({ extension: "jpg", size: 4096 })}) • [WEBP](${user.displayAvatarURL({ extension: "webp", size: 4096 })})${user.avatar?.startsWith("a_") ? ` • [GIF](${user.displayAvatarURL({ extension: "gif", size: 4096 })})` : ""}`, inline: false }
)
.setFooter({ text: `Demandé par ${requestedBy.username}`, iconURL: requestedBy.displayAvatarURL({ dynamic: true }) })
.setTimestamp();
if (serverAvatar && serverAvatar !== globalAvatar) {
embed.setDescription("**Avatar global** (avatar de serveur ci-dessous)");
}
await message.reply({ embeds: [embed] });
if (serverAvatar && serverAvatar !== globalAvatar) {
const serverEmbed = new EmbedBuilder()
.setColor(0x5865F2)
.setTitle(`🖼️ Avatar serveur de ${user.username}`)
.setImage(serverAvatar)
.addFields(
{ name: "🔗 Liens", value: `[PNG](${member.displayAvatarURL({ extension: "png", size: 4096 })}) • [JPG](${member.displayAvatarURL({ extension: "jpg", size: 4096 })}) • [WEBP](${member.displayAvatarURL({ extension: "webp", size: 4096 })})${member.avatar?.startsWith("a_") ? ` • [GIF](${member.displayAvatarURL({ extension: "gif", size: 4096 })})` : ""}`, inline: false }
);
await message.channel.send({ embeds: [serverEmbed] });
}
}
async function sendAvatarEmbedSlash(interaction, user, member) {
const globalAvatar = user.displayAvatarURL({ dynamic: true, size: 4096 });
const serverAvatar = member?.displayAvatarURL({ dynamic: true, size: 4096 });
const embed = new EmbedBuilder()
.setColor(0x5865F2)
.setTitle(`🖼️ Avatar de ${user.username}`)
.setImage(globalAvatar)
.addFields(
{ name: "🔗 Liens", value: `[PNG](${user.displayAvatarURL({ extension: "png", size: 4096 })}) • [JPG](${user.displayAvatarURL({ extension: "jpg", size: 4096 })}) • [WEBP](${user.displayAvatarURL({ extension: "webp", size: 4096 })})${user.avatar?.startsWith("a_") ? ` • [GIF](${user.displayAvatarURL({ extension: "gif", size: 4096 })})` : ""}`, inline: false }
)
.setFooter({ text: `Demandé par ${interaction.user.username}`, iconURL: interaction.user.displayAvatarURL({ dynamic: true }) })
.setTimestamp();
if (serverAvatar && serverAvatar !== globalAvatar) {
embed.setDescription("**Avatar global** (avatar de serveur ci-dessous)");
}
await interaction.reply({ embeds: [embed] });
if (serverAvatar && serverAvatar !== globalAvatar) {
const serverEmbed = new EmbedBuilder()
.setColor(0x5865F2)
.setTitle(`🖼️ Avatar serveur de ${user.username}`)
.setImage(serverAvatar)
.addFields(
{ name: "🔗 Liens", value: `[PNG](${member.displayAvatarURL({ extension: "png", size: 4096 })}) • [JPG](${member.displayAvatarURL({ extension: "jpg", size: 4096 })}) • [WEBP](${member.displayAvatarURL({ extension: "webp", size: 4096 })})${member.avatar?.startsWith("a_") ? ` • [GIF](${member.displayAvatarURL({ extension: "gif", size: 4096 })})` : ""}`, inline: false }
);
await interaction.followUp({ embeds: [serverEmbed] });
}
}
+118
View File
@@ -0,0 +1,118 @@
const addCommand = require("../fonctions/addCommand");
const { EmbedBuilder, PermissionFlagsBits } = require("discord.js");
module.exports = addCommand({
name: "ban",
description: "Bannit un membre du serveur.",
aliases: ["bannir"],
permissions: [PermissionFlagsBits.BanMembers],
botOwnerOnly: false,
dm: false,
scope: "global",
slashOptions: [
{
type: "USER",
name: "utilisateur",
description: "L'utilisateur à bannir",
required: true,
},
{
type: "STRING",
name: "raison",
description: "La raison du bannissement",
required: false,
},
{
type: "INTEGER",
name: "supprimer_messages",
description: "Nombre de jours de messages à supprimer (0-7)",
required: false,
},
],
executePrefix: async (client, message, args) => {
const user = message.mentions.users.first() || (args[0] ? await client.users.fetch(args[0]).catch(() => null) : null);
if (!user) {
return message.reply({ embeds: [new EmbedBuilder().setColor(0xED4245).setDescription("❌ Veuillez mentionner un utilisateur à bannir.")] });
}
const reason = args.slice(1).join(" ") || "Aucune raison fournie";
const member = message.guild.members.cache.get(user.id);
const error = validateBan(member, message.member, message.guild, user);
if (error) return message.reply({ embeds: [error] });
await executeBan(user, reason, 0, message.author, message.guild, message, member);
},
executeSlash: async (client, interaction) => {
const user = interaction.options.getUser("utilisateur");
const reason = interaction.options.getString("raison") || "Aucune raison fournie";
const deleteMessageDays = interaction.options.getInteger("supprimer_messages") || 0;
const member = interaction.guild.members.cache.get(user.id);
const error = validateBan(member, interaction.member, interaction.guild, user);
if (error) return interaction.reply({ embeds: [error], ephemeral: true });
await executeBan(user, reason, deleteMessageDays, interaction.user, interaction.guild, interaction, member);
},
});
function validateBan(member, executor, guild, user) {
if (user.id === executor.id) {
return new EmbedBuilder().setColor(0xED4245).setDescription("❌ Vous ne pouvez pas vous bannir vous-même.");
}
if (user.id === guild.ownerId) {
return new EmbedBuilder().setColor(0xED4245).setDescription("❌ Vous ne pouvez pas bannir le propriétaire du serveur.");
}
if (member) {
if (!member.bannable) {
return new EmbedBuilder().setColor(0xED4245).setDescription("❌ Je ne peux pas bannir cet utilisateur. Vérifiez que mon rôle est au-dessus du sien.");
}
if (executor.roles.highest.position <= member.roles.highest.position && executor.id !== guild.ownerId) {
return new EmbedBuilder().setColor(0xED4245).setDescription("❌ Vous ne pouvez pas bannir quelqu'un avec un rôle égal ou supérieur au vôtre.");
}
}
return null;
}
async function executeBan(user, reason, deleteMessageDays, moderator, guild, context, member) {
try {
try {
const dmEmbed = new EmbedBuilder()
.setColor(0xED4245)
.setTitle(`🔨 Vous avez été banni de ${guild.name}`)
.addFields(
{ name: "📋 Raison", value: reason },
{ name: "👮 Modérateur", value: moderator.tag }
)
.setTimestamp();
await user.send({ embeds: [dmEmbed] });
} catch (e) {}
await guild.members.ban(user, {
reason: `${reason} | Par ${moderator.tag}`,
deleteMessageSeconds: Math.min(Math.max(deleteMessageDays, 0), 7) * 24 * 60 * 60
});
const embed = new EmbedBuilder()
.setColor(0xED4245)
.setTitle("🔨 Membre banni")
.setThumbnail(user.displayAvatarURL({ dynamic: true }))
.addFields(
{ name: "👤 Utilisateur", value: `${user.tag} (${user.id})`, inline: true },
{ name: "👮 Modérateur", value: moderator.tag, inline: true },
{ name: "📋 Raison", value: reason, inline: false },
{ name: "🗑️ Messages supprimés", value: `${deleteMessageDays} jour(s)`, inline: true }
)
.setFooter({ text: `Banni par ${moderator.username}`, iconURL: moderator.displayAvatarURL({ dynamic: true }) })
.setTimestamp();
await context.reply({ embeds: [embed] });
} catch (error) {
console.error(error);
const errorEmbed = new EmbedBuilder().setColor(0xED4245).setDescription("❌ Une erreur est survenue lors du bannissement.");
await context.reply({ embeds: [errorEmbed], ephemeral: true });
}
}
+69
View File
@@ -0,0 +1,69 @@
const addCommand = require("../fonctions/addCommand");
const { EmbedBuilder } = require("discord.js");
module.exports = addCommand({
name: "banner",
description: "Affiche la bannière d'un utilisateur.",
aliases: ["banniere"],
permissions: [],
botOwnerOnly: false,
dm: false,
scope: "global",
slashOptions: [
{
type: "USER",
name: "utilisateur",
description: "L'utilisateur dont vous voulez voir la bannière",
required: false,
},
],
executePrefix: async (client, message, args) => {
const user = message.mentions.users.first() || (args[0] ? await client.users.fetch(args[0]).catch(() => null) : null) || message.author;
const fetchedUser = await user.fetch();
if (!fetchedUser.banner) {
const embed = new EmbedBuilder()
.setColor(0xED4245)
.setDescription(`❌ **${user.username}** n'a pas de bannière.`)
.setFooter({ text: `Demandé par ${message.author.username}`, iconURL: message.author.displayAvatarURL({ dynamic: true }) });
return message.reply({ embeds: [embed] });
}
const embed = createBannerEmbed(fetchedUser, user, message.author);
await message.reply({ embeds: [embed] });
},
executeSlash: async (client, interaction) => {
const user = interaction.options.getUser("utilisateur") || interaction.user;
const fetchedUser = await user.fetch();
if (!fetchedUser.banner) {
const embed = new EmbedBuilder()
.setColor(0xED4245)
.setDescription(`❌ **${user.username}** n'a pas de bannière.`)
.setFooter({ text: `Demandé par ${interaction.user.username}`, iconURL: interaction.user.displayAvatarURL({ dynamic: true }) });
return interaction.reply({ embeds: [embed], ephemeral: true });
}
const embed = createBannerEmbed(fetchedUser, user, interaction.user);
await interaction.reply({ embeds: [embed] });
},
});
function createBannerEmbed(fetchedUser, user, requestedBy) {
const bannerUrl = fetchedUser.bannerURL({ dynamic: true, size: 4096 });
return new EmbedBuilder()
.setColor(fetchedUser.accentColor || 0x5865F2)
.setTitle(`🎨 Bannière de ${user.username}`)
.setImage(bannerUrl)
.addFields(
{ name: "🔗 Liens", value: `[PNG](${fetchedUser.bannerURL({ extension: "png", size: 4096 })}) • [JPG](${fetchedUser.bannerURL({ extension: "jpg", size: 4096 })}) • [WEBP](${fetchedUser.bannerURL({ extension: "webp", size: 4096 })})${fetchedUser.banner?.startsWith("a_") ? ` • [GIF](${fetchedUser.bannerURL({ extension: "gif", size: 4096 })})` : ""}`, inline: false }
)
.setFooter({ text: `Demandé par ${requestedBy.username}`, iconURL: requestedBy.displayAvatarURL({ dynamic: true }) })
.setTimestamp();
}
+59
View File
@@ -0,0 +1,59 @@
const addCommand = require("../fonctions/addCommand");
const { EmbedBuilder } = require("discord.js");
const os = require("os");
module.exports = addCommand({
name: "botinfo",
description: "Affiche les informations du bot.",
aliases: ["bot", "bi", "stats"],
permissions: [],
botOwnerOnly: false,
dm: true,
scope: "global",
slashOptions: [],
executePrefix: async (client, message, args) => {
const embed = createBotInfoEmbed(client, message.author);
await message.reply({ embeds: [embed] });
},
executeSlash: async (client, interaction) => {
const embed = createBotInfoEmbed(client, interaction.user);
await interaction.reply({ embeds: [embed] });
},
});
function createBotInfoEmbed(client, user) {
const uptime = process.uptime();
const days = Math.floor(uptime / 86400);
const hours = Math.floor((uptime % 86400) / 3600);
const minutes = Math.floor((uptime % 3600) / 60);
const seconds = Math.floor(uptime % 60);
const uptimeString = `${days}j ${hours}h ${minutes}m ${seconds}s`;
const memUsage = process.memoryUsage();
const memUsed = (memUsage.heapUsed / 1024 / 1024).toFixed(2);
const memTotal = (memUsage.heapTotal / 1024 / 1024).toFixed(2);
return new EmbedBuilder()
.setColor(0x5865F2)
.setTitle(`🤖 Informations sur ${client.user.username}`)
.setThumbnail(client.user.displayAvatarURL({ dynamic: true, size: 256 }))
.addFields(
{ name: "📛 Nom", value: client.user.tag, inline: true },
{ name: "🆔 ID", value: client.user.id, inline: true },
{ name: "📅 Créé le", value: `<t:${Math.floor(client.user.createdTimestamp / 1000)}:D>`, inline: true },
{ name: "⏱️ Uptime", value: uptimeString, inline: true },
{ name: "🏓 Latence", value: `${client.ws.ping}ms`, inline: true },
{ name: "💾 Mémoire", value: `${memUsed} / ${memTotal} MB`, inline: true },
{ name: "🖥️ Serveurs", value: `${client.guilds.cache.size}`, inline: true },
{ name: "👥 Utilisateurs", value: `${client.users.cache.size}`, inline: true },
{ name: "📺 Salons", value: `${client.channels.cache.size}`, inline: true },
{ name: "📚 Node.js", value: process.version, inline: true },
{ name: "📦 Discord.js", value: require("discord.js").version, inline: true },
{ name: "💻 OS", value: `${os.type()} ${os.release()}`, inline: true }
)
.setFooter({ text: `Demandé par ${user.username}`, iconURL: user.displayAvatarURL({ dynamic: true }) })
.setTimestamp();
}
+143
View File
@@ -0,0 +1,143 @@
const addCommand = require("../fonctions/addCommand");
const { EmbedBuilder, PermissionFlagsBits } = require("discord.js");
module.exports = addCommand({
name: "clear",
description: "Supprime un nombre de messages dans le salon.",
aliases: ["purge", "supprimer", "delete"],
permissions: [PermissionFlagsBits.ManageMessages],
botOwnerOnly: false,
dm: false,
scope: "global",
slashOptions: [
{
type: "INTEGER",
name: "nombre",
description: "Le nombre de messages à supprimer (1-100)",
required: true,
},
{
type: "USER",
name: "utilisateur",
description: "Supprimer uniquement les messages de cet utilisateur",
required: false,
},
],
executePrefix: async (client, message, args) => {
const amount = parseInt(args[0]);
if (!amount || amount < 1 || amount > 100) {
return message.reply({ embeds: [new EmbedBuilder().setColor(0xED4245).setDescription("❌ Veuillez spécifier un nombre entre 1 et 100.")] });
}
const targetUser = message.mentions.users.first();
// Supprimer le message de commande
await message.delete().catch(() => {});
await executeClear(message.channel, amount, targetUser, message.author);
},
executeSlash: async (client, interaction) => {
const amount = interaction.options.getInteger("nombre");
const targetUser = interaction.options.getUser("utilisateur");
await interaction.deferReply({ ephemeral: true });
await executeClearSlash(interaction, amount, targetUser);
},
});
async function executeClear(channel, amount, targetUser, moderator) {
try {
let messages = await channel.messages.fetch({ limit: 100 });
if (targetUser) {
messages = messages.filter(m => m.author.id === targetUser.id);
}
const twoWeeksAgo = Date.now() - 14 * 24 * 60 * 60 * 1000;
messages = messages.filter(m => m.createdTimestamp > twoWeeksAgo);
const messagesToDelete = [...messages.values()].slice(0, amount);
if (messagesToDelete.length === 0) {
const errorEmbed = new EmbedBuilder()
.setColor(0xED4245)
.setDescription("❌ Aucun message à supprimer.");
const errorMsg = await channel.send({ embeds: [errorEmbed] });
setTimeout(() => errorMsg.delete().catch(() => {}), 5000);
return;
}
const deleted = await channel.bulkDelete(messagesToDelete, true);
const embed = new EmbedBuilder()
.setColor(0x57F287)
.setDescription(`🗑️ **${deleted.size}** message(s) supprimé(s) par ${moderator}.`);
if (targetUser) {
embed.addFields({ name: "👤 Utilisateur ciblé", value: targetUser.tag, inline: true });
}
const confirmMsg = await channel.send({ embeds: [embed] });
setTimeout(() => confirmMsg.delete().catch(() => {}), 5000);
} catch (error) {
console.error(error);
const errorEmbed = new EmbedBuilder().setColor(0xED4245).setDescription("❌ Une erreur est survenue lors de la suppression.");
const errorMsg = await channel.send({ embeds: [errorEmbed] });
setTimeout(() => errorMsg.delete().catch(() => {}), 5000);
}
}
async function executeClearSlash(interaction, amount, targetUser) {
try {
let messages = await interaction.channel.messages.fetch({ limit: 100 });
if (targetUser) {
messages = messages.filter(m => m.author.id === targetUser.id);
}
const twoWeeksAgo = Date.now() - 14 * 24 * 60 * 60 * 1000;
messages = messages.filter(m => m.createdTimestamp > twoWeeksAgo);
const messagesToDelete = [...messages.values()].slice(0, amount);
if (messagesToDelete.length === 0) {
return interaction.editReply({
embeds: [new EmbedBuilder().setColor(0xED4245).setDescription("❌ Aucun message à supprimer (les messages de plus de 14 jours ne peuvent pas être supprimés en masse).")]
});
}
const deleted = await interaction.channel.bulkDelete(messagesToDelete, true);
const embed = new EmbedBuilder()
.setColor(0x57F287)
.setTitle("🗑️ Messages supprimés")
.setDescription(`**${deleted.size}** message(s) supprimé(s) avec succès.`)
.addFields(
{ name: "📺 Salon", value: `<#${interaction.channel.id}>`, inline: true },
{ name: "👮 Modérateur", value: interaction.user.tag, inline: true }
)
.setFooter({ text: `Supprimé par ${interaction.user.username}`, iconURL: interaction.user.displayAvatarURL({ dynamic: true }) })
.setTimestamp();
if (targetUser) {
embed.addFields({ name: "👤 Utilisateur ciblé", value: targetUser.tag, inline: true });
}
await interaction.editReply({ embeds: [embed] });
const confirmEmbed = new EmbedBuilder()
.setColor(0x57F287)
.setDescription(`🗑️ **${deleted.size}** message(s) supprimé(s) par ${interaction.user}.`);
const confirmMsg = await interaction.channel.send({ embeds: [confirmEmbed] });
setTimeout(() => confirmMsg.delete().catch(() => {}), 5000);
} catch (error) {
console.error(error);
await interaction.editReply({
embeds: [new EmbedBuilder().setColor(0xED4245).setDescription("❌ Une erreur est survenue lors de la suppression des messages.")]
});
}
}
+36
View File
@@ -0,0 +1,36 @@
const addCommand = require("../fonctions/addCommand");
const { EmbedBuilder } = require("discord.js");
module.exports = addCommand({
name: "coinflip",
description: "Lance une pièce (pile ou face).",
aliases: ["cf", "flip", "piece"],
permissions: [],
botOwnerOnly: false,
dm: true,
scope: "global",
slashOptions: [],
executePrefix: async (client, message, args) => {
const embed = createCoinflipEmbed(message.author);
await message.reply({ embeds: [embed] });
},
executeSlash: async (client, interaction) => {
const embed = createCoinflipEmbed(interaction.user);
await interaction.reply({ embeds: [embed] });
},
});
function createCoinflipEmbed(user) {
const result = Math.random() < 0.5 ? "pile" : "face";
const emoji = result === "pile" ? "🪙" : "💿";
return new EmbedBuilder()
.setColor(result === "pile" ? 0xFEE75C : 0x5865F2)
.setTitle(`${emoji} Coinflip`)
.setDescription(`La pièce est tombée sur **${result.toUpperCase()}** !`)
.setFooter({ text: `Lancé par ${user.username}`, iconURL: user.displayAvatarURL({ dynamic: true }) })
.setTimestamp();
}
+108
View File
@@ -0,0 +1,108 @@
const addCommand = require("../fonctions/addCommand");
const { EmbedBuilder, PermissionFlagsBits } = require("discord.js");
module.exports = addCommand({
name: "kick",
description: "Expulse un membre du serveur.",
aliases: ["expulser"],
permissions: [PermissionFlagsBits.KickMembers],
botOwnerOnly: false,
dm: false,
scope: "global",
slashOptions: [
{
type: "USER",
name: "utilisateur",
description: "L'utilisateur à expulser",
required: true,
},
{
type: "STRING",
name: "raison",
description: "La raison de l'expulsion",
required: false,
},
],
executePrefix: async (client, message, args) => {
const user = message.mentions.users.first() || (args[0] ? await client.users.fetch(args[0]).catch(() => null) : null);
if (!user) {
return message.reply({ embeds: [new EmbedBuilder().setColor(0xED4245).setDescription("❌ Veuillez mentionner un utilisateur à expulser.")] });
}
const reason = args.slice(1).join(" ") || "Aucune raison fournie";
const member = message.guild.members.cache.get(user.id);
const error = validateKick(member, message.member, message.guild, user);
if (error) return message.reply({ embeds: [error] });
await executeKick(member, user, reason, message.author, message.guild, message);
},
executeSlash: async (client, interaction) => {
const user = interaction.options.getUser("utilisateur");
const reason = interaction.options.getString("raison") || "Aucune raison fournie";
const member = interaction.guild.members.cache.get(user.id);
const error = validateKick(member, interaction.member, interaction.guild, user);
if (error) return interaction.reply({ embeds: [error], ephemeral: true });
await executeKick(member, user, reason, interaction.user, interaction.guild, interaction);
},
});
function validateKick(member, executor, guild, user) {
if (!member) {
return new EmbedBuilder().setColor(0xED4245).setDescription("❌ Cet utilisateur n'est pas sur ce serveur.");
}
if (member.id === executor.id) {
return new EmbedBuilder().setColor(0xED4245).setDescription("❌ Vous ne pouvez pas vous expulser vous-même.");
}
if (member.id === guild.ownerId) {
return new EmbedBuilder().setColor(0xED4245).setDescription("❌ Vous ne pouvez pas expulser le propriétaire du serveur.");
}
if (!member.kickable) {
return new EmbedBuilder().setColor(0xED4245).setDescription("❌ Je ne peux pas expulser cet utilisateur. Vérifiez que mon rôle est au-dessus du sien.");
}
if (executor.roles.highest.position <= member.roles.highest.position && executor.id !== guild.ownerId) {
return new EmbedBuilder().setColor(0xED4245).setDescription("❌ Vous ne pouvez pas expulser quelqu'un avec un rôle égal ou supérieur au vôtre.");
}
return null;
}
async function executeKick(member, user, reason, moderator, guild, context) {
try {
try {
const dmEmbed = new EmbedBuilder()
.setColor(0xFEE75C)
.setTitle(`🚪 Vous avez été expulsé de ${guild.name}`)
.addFields(
{ name: "📋 Raison", value: reason },
{ name: "👮 Modérateur", value: moderator.tag }
)
.setTimestamp();
await user.send({ embeds: [dmEmbed] });
} catch (e) {}
await member.kick(reason);
const embed = new EmbedBuilder()
.setColor(0x57F287)
.setTitle("🚪 Membre expulsé")
.setThumbnail(user.displayAvatarURL({ dynamic: true }))
.addFields(
{ name: "👤 Utilisateur", value: `${user.tag} (${user.id})`, inline: true },
{ name: "👮 Modérateur", value: moderator.tag, inline: true },
{ name: "📋 Raison", value: reason, inline: false }
)
.setFooter({ text: `Expulsé par ${moderator.username}`, iconURL: moderator.displayAvatarURL({ dynamic: true }) })
.setTimestamp();
await context.reply({ embeds: [embed] });
} catch (error) {
console.error(error);
const errorEmbed = new EmbedBuilder().setColor(0xED4245).setDescription("❌ Une erreur est survenue lors de l'expulsion.");
await context.reply({ embeds: [errorEmbed], ephemeral: true });
}
}
+54
View File
@@ -0,0 +1,54 @@
const addCommand = require("../fonctions/addCommand");
const { EmbedBuilder, ButtonBuilder, ButtonStyle, ActionRowBuilder } = require("discord.js");
module.exports = addCommand({
name: "panel",
description: "Affiche le lien vers le dashboard du serveur.",
aliases: ["dashboard", "dash", "web"],
permissions: [],
botOwnerOnly: false,
dm: false,
scope: "global",
slashOptions: [],
executePrefix: async (client, message, args) => {
const embed = createPanelEmbed(message.guild, message.author, client);
const row = createPanelButton(message.guild.id);
await message.reply({ embeds: [embed], components: [row] });
},
executeSlash: async (client, interaction) => {
const embed = createPanelEmbed(interaction.guild, interaction.user, client);
const row = createPanelButton(interaction.guild.id);
await interaction.reply({ embeds: [embed], components: [row] });
},
});
function createPanelEmbed(guild, user, client) {
const dashboardUrl = `${process.env.URL}/guild/${guild.id}`;
return new EmbedBuilder()
.setColor(0x5865F2)
.setTitle("🎛️ Panel de configuration")
.setDescription(`Accédez au dashboard pour configurer **${guild.name}** !`)
.setThumbnail(guild.iconURL({ dynamic: true, size: 256 }))
.addFields(
{ name: "🔗 Lien direct", value: dashboardUrl, inline: false },
{ name: "⚙️ Fonctionnalités", value: "• Système de niveaux\n• Économie\n• Messages de bienvenue/au revoir\n• Auto-rôles\n• Et plus encore !", inline: false }
)
.setFooter({ text: `Demandé par ${user.username}`, iconURL: user.displayAvatarURL({ dynamic: true }) })
.setTimestamp();
}
function createPanelButton(guildId) {
const dashboardUrl = `${process.env.URL}/guild/${guildId}`;
const button = new ButtonBuilder()
.setLabel("Ouvrir le Dashboard")
.setStyle(ButtonStyle.Link)
.setURL(dashboardUrl)
.setEmoji("🌐");
return new ActionRowBuilder().addComponents(button);
}
+72
View File
@@ -0,0 +1,72 @@
const addCommand = require("../fonctions/addCommand");
const { EmbedBuilder, ChannelType } = require("discord.js");
module.exports = addCommand({
name: "serverinfo",
description: "Affiche les informations du serveur.",
aliases: ["server", "si", "serveur"],
permissions: [],
botOwnerOnly: false,
dm: false,
scope: "global",
slashOptions: [],
executePrefix: async (client, message, args) => {
const embed = await createServerInfoEmbed(message.guild, message.author);
await message.reply({ embeds: [embed] });
},
executeSlash: async (client, interaction) => {
const embed = await createServerInfoEmbed(interaction.guild, interaction.user);
await interaction.reply({ embeds: [embed] });
},
});
async function createServerInfoEmbed(guild, user) {
await guild.members.fetch();
const textChannels = guild.channels.cache.filter(c => c.type === ChannelType.GuildText).size;
const voiceChannels = guild.channels.cache.filter(c => c.type === ChannelType.GuildVoice).size;
const categories = guild.channels.cache.filter(c => c.type === ChannelType.GuildCategory).size;
const onlineMembers = guild.members.cache.filter(m => m.presence?.status !== "offline").size;
const botCount = guild.members.cache.filter(m => m.user.bot).size;
const humanCount = guild.memberCount - botCount;
const verificationLevels = {
0: "Aucune",
1: "Faible",
2: "Moyenne",
3: "Haute",
4: "Très haute"
};
const boostLevel = guild.premiumTier ? `Niveau ${guild.premiumTier}` : "Aucun";
const embed = new EmbedBuilder()
.setColor(0x5865F2)
.setTitle(`📊 Informations sur ${guild.name}`)
.setThumbnail(guild.iconURL({ dynamic: true, size: 256 }))
.addFields(
{ name: "📛 Nom", value: guild.name, inline: true },
{ name: "🆔 ID", value: guild.id, inline: true },
{ name: "👑 Propriétaire", value: `<@${guild.ownerId}>`, inline: true },
{ name: "📅 Créé le", value: `<t:${Math.floor(guild.createdTimestamp / 1000)}:D>`, inline: true },
{ name: "🔒 Vérification", value: verificationLevels[guild.verificationLevel], inline: true },
{ name: "🚀 Boost", value: `${boostLevel} (${guild.premiumSubscriptionCount || 0} boosts)`, inline: true },
{ name: "👥 Membres", value: `Total: ${guild.memberCount}\n👤 Humains: ${humanCount}\n🤖 Bots: ${botCount}\n🟢 En ligne: ${onlineMembers}`, inline: true },
{ name: "📺 Salons", value: `💬 Textuels: ${textChannels}\n🔊 Vocaux: ${voiceChannels}\n📁 Catégories: ${categories}`, inline: true },
{ name: "🎭 Rôles", value: `${guild.roles.cache.size}`, inline: true },
{ name: "😀 Emojis", value: `${guild.emojis.cache.size}`, inline: true },
{ name: "🎨 Stickers", value: `${guild.stickers.cache.size}`, inline: true }
)
.setFooter({ text: `Demandé par ${user.username}`, iconURL: user.displayAvatarURL({ dynamic: true }) })
.setTimestamp();
if (guild.bannerURL()) {
embed.setImage(guild.bannerURL({ size: 512 }));
}
return embed;
}
+157
View File
@@ -0,0 +1,157 @@
const addCommand = require("../fonctions/addCommand");
const { EmbedBuilder, PermissionFlagsBits } = require("discord.js");
module.exports = addCommand({
name: "timeout",
description: "Met un membre en timeout (exclusion temporaire).",
aliases: ["mute", "to"],
permissions: [PermissionFlagsBits.ModerateMembers],
botOwnerOnly: false,
dm: false,
scope: "global",
slashOptions: [
{
type: "USER",
name: "utilisateur",
description: "L'utilisateur à mettre en timeout",
required: true,
},
{
type: "STRING",
name: "durée",
description: "La durée du timeout (ex: 10m, 1h, 1d, 1w)",
required: true,
},
{
type: "STRING",
name: "raison",
description: "La raison du timeout",
required: false,
},
],
executePrefix: async (client, message, args) => {
const user = message.mentions.users.first() || (args[0] ? await client.users.fetch(args[0]).catch(() => null) : null);
if (!user) {
return message.reply({ embeds: [new EmbedBuilder().setColor(0xED4245).setDescription("❌ Veuillez mentionner un utilisateur.")] });
}
const durationStr = args[1];
if (!durationStr) {
return message.reply({ embeds: [new EmbedBuilder().setColor(0xED4245).setDescription("❌ Veuillez spécifier une durée (ex: 10m, 1h, 1d).")] });
}
const reason = args.slice(2).join(" ") || "Aucune raison fournie";
const member = message.guild.members.cache.get(user.id);
await executeTimeout(member, user, durationStr, reason, message.member, message.author, message.guild, message);
},
executeSlash: async (client, interaction) => {
const user = interaction.options.getUser("utilisateur");
const durationStr = interaction.options.getString("durée");
const reason = interaction.options.getString("raison") || "Aucune raison fournie";
const member = interaction.guild.members.cache.get(user.id);
await executeTimeout(member, user, durationStr, reason, interaction.member, interaction.user, interaction.guild, interaction);
},
});
function parseDuration(durationStr) {
const durationRegex = /^(\d+)(s|m|h|d|w)$/;
const match = durationStr.match(durationRegex);
if (!match) return null;
const amount = parseInt(match[1]);
const unit = match[2];
const multipliers = {
s: 1000,
m: 60 * 1000,
h: 60 * 60 * 1000,
d: 24 * 60 * 60 * 1000,
w: 7 * 24 * 60 * 60 * 1000
};
return { ms: amount * multipliers[unit], amount, unit };
}
async function executeTimeout(member, user, durationStr, reason, executor, moderator, guild, context) {
const duration = parseDuration(durationStr);
const maxTimeout = 28 * 24 * 60 * 60 * 1000;
const sendError = async (msg) => {
const embed = new EmbedBuilder().setColor(0xED4245).setDescription(msg);
await context.reply({ embeds: [embed], ephemeral: true });
};
if (!duration) {
return sendError("❌ Format de durée invalide. Utilisez: `10s`, `10m`, `1h`, `1d`, `1w`");
}
if (duration.ms > maxTimeout) {
return sendError("❌ La durée maximale du timeout est de 28 jours.");
}
if (!member) {
return sendError("❌ Cet utilisateur n'est pas sur ce serveur.");
}
if (member.id === executor.id) {
return sendError("❌ Vous ne pouvez pas vous mettre en timeout vous-même.");
}
if (member.id === guild.ownerId) {
return sendError("❌ Vous ne pouvez pas mettre le propriétaire en timeout.");
}
if (!member.moderatable) {
return sendError("❌ Je ne peux pas mettre cet utilisateur en timeout. Vérifiez que mon rôle est au-dessus du sien.");
}
if (executor.roles.highest.position <= member.roles.highest.position && executor.id !== guild.ownerId) {
return sendError("❌ Vous ne pouvez pas mettre en timeout quelqu'un avec un rôle égal ou supérieur au vôtre.");
}
try {
try {
const dmEmbed = new EmbedBuilder()
.setColor(0xFEE75C)
.setTitle(`⏰ Vous avez été mis en timeout sur ${guild.name}`)
.addFields(
{ name: "⏱️ Durée", value: durationStr },
{ name: "📋 Raison", value: reason },
{ name: "👮 Modérateur", value: moderator.tag }
)
.setTimestamp();
await user.send({ embeds: [dmEmbed] });
} catch (e) {}
await member.timeout(duration.ms, `${reason} | Par ${moderator.tag}`);
const unitNames = { s: "seconde(s)", m: "minute(s)", h: "heure(s)", d: "jour(s)", w: "semaine(s)" };
const endTimestamp = Math.floor((Date.now() + duration.ms) / 1000);
const embed = new EmbedBuilder()
.setColor(0xFEE75C)
.setTitle("⏰ Membre mis en timeout")
.setThumbnail(user.displayAvatarURL({ dynamic: true }))
.addFields(
{ name: "👤 Utilisateur", value: `${user.tag} (${user.id})`, inline: true },
{ name: "👮 Modérateur", value: moderator.tag, inline: true },
{ name: "⏱️ Durée", value: `${duration.amount} ${unitNames[duration.unit]}`, inline: true },
{ name: "🕐 Expire", value: `<t:${endTimestamp}:F>\n(<t:${endTimestamp}:R>)`, inline: false },
{ name: "📋 Raison", value: reason, inline: false }
)
.setFooter({ text: `Timeout par ${moderator.username}`, iconURL: moderator.displayAvatarURL({ dynamic: true }) })
.setTimestamp();
await context.reply({ embeds: [embed] });
} catch (error) {
console.error(error);
const errorEmbed = new EmbedBuilder().setColor(0xED4245).setDescription("❌ Une erreur est survenue lors du timeout.");
await context.reply({ embeds: [errorEmbed], ephemeral: true });
}
}
+100
View File
@@ -0,0 +1,100 @@
const addCommand = require("../fonctions/addCommand");
const { EmbedBuilder, PermissionFlagsBits } = require("discord.js");
module.exports = addCommand({
name: "untimeout",
description: "Retire le timeout d'un membre.",
aliases: ["unmute", "uto"],
permissions: [PermissionFlagsBits.ModerateMembers],
botOwnerOnly: false,
dm: false,
scope: "global",
slashOptions: [
{
type: "USER",
name: "utilisateur",
description: "L'utilisateur dont vous voulez retirer le timeout",
required: true,
},
{
type: "STRING",
name: "raison",
description: "La raison du retrait du timeout",
required: false,
},
],
executePrefix: async (client, message, args) => {
const user = message.mentions.users.first() || (args[0] ? await client.users.fetch(args[0]).catch(() => null) : null);
if (!user) {
return message.reply({ embeds: [new EmbedBuilder().setColor(0xED4245).setDescription("❌ Veuillez mentionner un utilisateur.")] });
}
const reason = args.slice(1).join(" ") || "Aucune raison fournie";
const member = message.guild.members.cache.get(user.id);
await executeUntimeout(member, user, reason, message.author, message.guild, message);
},
executeSlash: async (client, interaction) => {
const user = interaction.options.getUser("utilisateur");
const reason = interaction.options.getString("raison") || "Aucune raison fournie";
const member = interaction.guild.members.cache.get(user.id);
await executeUntimeout(member, user, reason, interaction.user, interaction.guild, interaction);
},
});
async function executeUntimeout(member, user, reason, moderator, guild, context) {
const sendError = async (msg) => {
const embed = new EmbedBuilder().setColor(0xED4245).setDescription(msg);
await context.reply({ embeds: [embed], ephemeral: true });
};
if (!member) {
return sendError("❌ Cet utilisateur n'est pas sur ce serveur.");
}
if (!member.isCommunicationDisabled()) {
return sendError("❌ Cet utilisateur n'est pas en timeout.");
}
if (!member.moderatable) {
return sendError("❌ Je ne peux pas modifier le timeout de cet utilisateur.");
}
try {
await member.timeout(null, `${reason} | Par ${moderator.tag}`);
try {
const dmEmbed = new EmbedBuilder()
.setColor(0x57F287)
.setTitle(`✅ Votre timeout a été retiré sur ${guild.name}`)
.addFields(
{ name: "📋 Raison", value: reason },
{ name: "👮 Modérateur", value: moderator.tag }
)
.setTimestamp();
await user.send({ embeds: [dmEmbed] });
} catch (e) {}
const embed = new EmbedBuilder()
.setColor(0x57F287)
.setTitle("✅ Timeout retiré")
.setThumbnail(user.displayAvatarURL({ dynamic: true }))
.addFields(
{ name: "👤 Utilisateur", value: `${user.tag} (${user.id})`, inline: true },
{ name: "👮 Modérateur", value: moderator.tag, inline: true },
{ name: "📋 Raison", value: reason, inline: false }
)
.setFooter({ text: `Untimeout par ${moderator.username}`, iconURL: moderator.displayAvatarURL({ dynamic: true }) })
.setTimestamp();
await context.reply({ embeds: [embed] });
} catch (error) {
console.error(error);
const errorEmbed = new EmbedBuilder().setColor(0xED4245).setDescription("❌ Une erreur est survenue lors du retrait du timeout.");
await context.reply({ embeds: [errorEmbed], ephemeral: true });
}
}
+44
View File
@@ -0,0 +1,44 @@
const addCommand = require("../fonctions/addCommand");
const { EmbedBuilder } = require("discord.js");
module.exports = addCommand({
name: "uptime",
description: "Affiche depuis combien de temps le bot est en ligne.",
aliases: ["up", "online"],
permissions: [],
botOwnerOnly: false,
dm: true,
scope: "global",
slashOptions: [],
executePrefix: async (client, message, args) => {
const embed = createUptimeEmbed(message.author);
await message.reply({ embeds: [embed] });
},
executeSlash: async (client, interaction) => {
const embed = createUptimeEmbed(interaction.user);
await interaction.reply({ embeds: [embed] });
},
});
function createUptimeEmbed(user) {
const uptime = process.uptime();
const days = Math.floor(uptime / 86400);
const hours = Math.floor((uptime % 86400) / 3600);
const minutes = Math.floor((uptime % 3600) / 60);
const seconds = Math.floor(uptime % 60);
const startTimestamp = Math.floor((Date.now() - uptime * 1000) / 1000);
return new EmbedBuilder()
.setColor(0x57F287)
.setTitle("⏱️ Uptime")
.setDescription(`Le bot est en ligne depuis **${days}** jours, **${hours}** heures, **${minutes}** minutes et **${seconds}** secondes.`)
.addFields(
{ name: "🚀 Démarré", value: `<t:${startTimestamp}:F>\n(<t:${startTimestamp}:R>)`, inline: true }
)
.setFooter({ text: `Demandé par ${user.username}`, iconURL: user.displayAvatarURL({ dynamic: true }) })
.setTimestamp();
}
+95
View File
@@ -0,0 +1,95 @@
const addCommand = require("../fonctions/addCommand");
const { EmbedBuilder } = require("discord.js");
module.exports = addCommand({
name: "userinfo",
description: "Affiche les informations d'un utilisateur.",
aliases: ["user", "ui", "whois", "membre"],
permissions: [],
botOwnerOnly: false,
dm: false,
scope: "global",
slashOptions: [
{
type: "USER",
name: "utilisateur",
description: "L'utilisateur dont vous voulez voir les informations",
required: false,
},
],
executePrefix: async (client, message, args) => {
const user = message.mentions.users.first() || (args[0] ? await client.users.fetch(args[0]).catch(() => null) : null) || message.author;
const member = message.guild.members.cache.get(user.id);
const embed = createUserInfoEmbed(user, member, message.guild, message.author);
await message.reply({ embeds: [embed] });
},
executeSlash: async (client, interaction) => {
const user = interaction.options.getUser("utilisateur") || interaction.user;
const member = interaction.guild.members.cache.get(user.id);
const embed = createUserInfoEmbed(user, member, interaction.guild, interaction.user);
await interaction.reply({ embeds: [embed] });
},
});
function createUserInfoEmbed(user, member, guild, requestedBy) {
const flags = user.flags?.toArray() || [];
const badges = {
ActiveDeveloper: "👨‍💻 Développeur Actif",
BugHunterLevel1: "🐛 Bug Hunter Niveau 1",
BugHunterLevel2: "🐛 Bug Hunter Niveau 2",
CertifiedModerator: "🛡️ Modérateur Certifié",
HypeSquadOnlineHouse1: "🏠 HypeSquad Bravery",
HypeSquadOnlineHouse2: "🏠 HypeSquad Brilliance",
HypeSquadOnlineHouse3: "🏠 HypeSquad Balance",
Hypesquad: "🎉 HypeSquad Events",
Partner: "👥 Partenaire Discord",
PremiumEarlySupporter: "💎 Early Supporter",
Staff: "⚙️ Staff Discord",
VerifiedBot: "✅ Bot Vérifié",
VerifiedDeveloper: "🔧 Développeur Vérifié"
};
const userBadges = flags.map(flag => badges[flag] || flag).join("\n") || "Aucun";
const status = {
online: "🟢 En ligne",
idle: "🟡 Inactif",
dnd: "🔴 Ne pas déranger",
offline: "⚫ Hors ligne"
};
const embed = new EmbedBuilder()
.setColor(member?.displayHexColor || 0x5865F2)
.setTitle(`👤 Informations sur ${user.username}`)
.setThumbnail(user.displayAvatarURL({ dynamic: true, size: 256 }))
.addFields(
{ name: "📛 Nom", value: user.tag, inline: true },
{ name: "🆔 ID", value: user.id, inline: true },
{ name: "🤖 Bot", value: user.bot ? "Oui" : "Non", inline: true },
{ name: "📅 Compte créé le", value: `<t:${Math.floor(user.createdTimestamp / 1000)}:D>\n(<t:${Math.floor(user.createdTimestamp / 1000)}:R>)`, inline: true }
);
if (member) {
embed.addFields(
{ name: "📥 A rejoint le", value: `<t:${Math.floor(member.joinedTimestamp / 1000)}:D>\n(<t:${Math.floor(member.joinedTimestamp / 1000)}:R>)`, inline: true },
{ name: "📊 Statut", value: status[member.presence?.status || "offline"], inline: true },
{ name: "🎨 Couleur", value: member.displayHexColor, inline: true },
{ name: `🎭 Rôles (${member.roles.cache.size - 1})`, value: member.roles.cache.filter(r => r.id !== guild.id).map(r => r.toString()).slice(0, 10).join(", ") || "Aucun", inline: false }
);
if (member.premiumSinceTimestamp) {
embed.addFields({ name: "🚀 Booster depuis", value: `<t:${Math.floor(member.premiumSinceTimestamp / 1000)}:D>`, inline: true });
}
}
embed.addFields({ name: "🏅 Badges", value: userBadges, inline: false });
embed
.setFooter({ text: `Demandé par ${requestedBy.username}`, iconURL: requestedBy.displayAvatarURL({ dynamic: true }) })
.setTimestamp();
return embed;
}