mirror of
https://github.com/arthur-pbty/LazyBot.git
synced 2026-06-03 23:36:37 +02:00
add some utilities commands
This commit is contained in:
@@ -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 :
|
||||||
|
|||||||
@@ -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] });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
@@ -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.")]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
@@ -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 });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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 });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 });
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user