@spatulox/simplediscordbot 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/.env.example +2 -0
  2. package/LICENSE.md +21 -0
  3. package/README.md +1 -0
  4. package/dist/bot/Bot.js +107 -0
  5. package/dist/bot/BotEnv.js +29 -0
  6. package/dist/bot/BotLog.js +90 -0
  7. package/dist/bot/BotMessage.js +79 -0
  8. package/dist/cli/BaseCLI.js +165 -0
  9. package/dist/cli/GenerationCLI/ContextMenuGeneratorCLI.js +109 -0
  10. package/dist/cli/GenerationCLI/GenerationCLI.js +25 -0
  11. package/dist/cli/GenerationCLI/InteractionGeneratorCLI.js +20 -0
  12. package/dist/cli/GenerationCLI/ModalGeneratorCLI.js +166 -0
  13. package/dist/cli/GenerationCLI/SlashCommandsGeneratorCLI.js +221 -0
  14. package/dist/cli/GenerationCLI.js +36 -0
  15. package/dist/cli/GuildListManager.js +61 -0
  16. package/dist/cli/InputCLI.js +25 -0
  17. package/dist/cli/InteractionCLI/InteractionCLI.js +30 -0
  18. package/dist/cli/InteractionCLI/InteractionCLIManager.js +80 -0
  19. package/dist/cli/InteractionCLI.js +109 -0
  20. package/dist/cli/MainCLI.js +32 -0
  21. package/dist/cli/type/ContextMenuConfig.js +2 -0
  22. package/dist/cli/type/InteractionType.js +14 -0
  23. package/dist/cli/type/SlashCommandConfig.js +2 -0
  24. package/dist/index.js +31 -0
  25. package/dist/manager/FileManager.js +136 -0
  26. package/dist/manager/direct/UserManager.js +76 -0
  27. package/dist/manager/discord/ChannelManager.js +48 -0
  28. package/dist/manager/discord/DiscordRegex.js +114 -0
  29. package/dist/manager/discord/GuildManager.js +67 -0
  30. package/dist/manager/discord/InviteManager.js +89 -0
  31. package/dist/manager/discord/RoleManager.js +83 -0
  32. package/dist/manager/discord/UserManager.js +69 -0
  33. package/dist/manager/guild/ChannelManager/ForumChannelManager.js +33 -0
  34. package/dist/manager/guild/ChannelManager/GuildChannelList.js +20 -0
  35. package/dist/manager/guild/ChannelManager/GuildChannelManager.js +91 -0
  36. package/dist/manager/guild/ChannelManager/GuildMessageManager.js +85 -0
  37. package/dist/manager/guild/ChannelManager/GuildTextChannelManager.js +33 -0
  38. package/dist/manager/guild/ChannelManager/GuildVoiceChannelManager.js +33 -0
  39. package/dist/manager/guild/ChannelManager/NewsChannelManager.js +33 -0
  40. package/dist/manager/guild/ChannelManager/StageChannelManager.js +33 -0
  41. package/dist/manager/guild/ChannelManager/ThreadChannelManager.js +34 -0
  42. package/dist/manager/guild/GuildManager.js +134 -0
  43. package/dist/manager/guild/GuildUserManager.js +212 -0
  44. package/dist/manager/guild/InviteManager.js +68 -0
  45. package/dist/manager/guild/InviteManager_old.js +89 -0
  46. package/dist/manager/guild/RoleManager.js +83 -0
  47. package/dist/manager/hadlers_old/builder/ModalManager.js +111 -0
  48. package/dist/manager/hadlers_old/builder/delete.js +49 -0
  49. package/dist/manager/hadlers_old/builder/deploy.js +225 -0
  50. package/dist/manager/hadlers_old/builder/interactions/CommandManager.js +14 -0
  51. package/dist/manager/hadlers_old/builder/interactions/ContextMenuManager.js +14 -0
  52. package/dist/manager/hadlers_old/builder/interactions/InteractionBase.js +341 -0
  53. package/dist/manager/hadlers_old/builder/interactions/InteractionManager.js +65 -0
  54. package/dist/manager/hadlers_old/builder/list.js +166 -0
  55. package/dist/manager/messages/EmbedManager.js +131 -0
  56. package/dist/manager/messages/ReactionManager.js +99 -0
  57. package/dist/manager/messages/WebhookManager.js +105 -0
  58. package/dist/type/FolderName.js +9 -0
  59. package/dist/utils/DiscordRegex.js +116 -0
  60. package/dist/utils/Log.js +28 -0
  61. package/dist/utils/SimpleMutex.js +39 -0
  62. package/dist/utils/network/InternetChecker.js +54 -0
  63. package/dist/utils/times/UnitTime.js +85 -0
  64. package/package.json +40 -0
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ // src/discord/InteractionManager.ts
7
+ const readline_1 = __importDefault(require("readline"));
8
+ const CommandManager_1 = require("./CommandManager");
9
+ const ContextMenuManager_1 = require("./ContextMenuManager");
10
+ const Log_1 = require("../../../../utils/Log");
11
+ class InteractionManager {
12
+ static async start() {
13
+ console.clear();
14
+ Log_1.Log.info('🎛️ INTERACTION MANAGER');
15
+ Log_1.Log.info('=====================');
16
+ const rl = readline_1.default.createInterface({
17
+ input: process.stdin,
18
+ output: process.stdout
19
+ });
20
+ await this.showMainMenu(rl);
21
+ rl.on('line', async (input) => {
22
+ await this.handleMainMenu(input.trim().toLowerCase(), rl);
23
+ });
24
+ }
25
+ static async showMainMenu(rl) {
26
+ console.log('\n🎯 QUE VOULEZ-VOUS FAIRE ?');
27
+ console.log(' 1. Slash Commands → npm run deploy:slash');
28
+ console.log(' 2. Context Menus → npm run deploy:context');
29
+ console.log(' 3. Tout déployer → npm run deploy:all');
30
+ console.log(' help → Aide');
31
+ console.log(' exit → Quitter\n');
32
+ rl.prompt();
33
+ }
34
+ static async handleMainMenu(input, rl) {
35
+ switch (input) {
36
+ case '1':
37
+ case 'slash':
38
+ await new CommandManager_1.CommandManager().startInteractive();
39
+ break;
40
+ case '2':
41
+ case 'context':
42
+ await new ContextMenuManager_1.ContextMenuManager().startInteractive();
43
+ break;
44
+ case '3':
45
+ case 'all':
46
+ Log_1.Log.info('🚀 Déploiement complet...');
47
+ await Promise.all([
48
+ //new CommandManager().deployAll(),
49
+ //new ContextMenuManager().deployAll()
50
+ ]);
51
+ break;
52
+ case 'help':
53
+ await this.showMainMenu(rl);
54
+ break;
55
+ case 'exit':
56
+ Log_1.Log.info('👋 Au revoir !');
57
+ rl.close();
58
+ process.exit(0);
59
+ default:
60
+ Log_1.Log.error('❌ Choix invalide');
61
+ rl.prompt();
62
+ }
63
+ }
64
+ }
65
+ InteractionManager.start();
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /*import { Routes } from 'discord-api-types/v10';
4
+ import {Events} from "discord.js";
5
+ import {Log} from "../../../utils/Log";
6
+ import {client} from "../../../../src_example/client";
7
+
8
+ export interface Command {
9
+ name: string;
10
+ description: string;
11
+ options?: any[];
12
+ default_member_permissions?: string | bigint | number;
13
+ guildID?: string[];
14
+ type: 1 | 2 | 3; // 1 = slash, 2 = user context, 3 = message context
15
+ id?: string; // Discord API Command ID
16
+ }
17
+
18
+ export interface DiscordCommand extends Command {
19
+ discordData?: any; // Données complètes depuis Discord API
20
+ deployedGuilds: string[]; // Serveurs où la commande est déployée
21
+ }
22
+
23
+ export async function analyzeRegisteredCommands(): Promise<DiscordCommand[]> {
24
+ if (!(await loginBot(client))) {
25
+ Log.error("Impossible de connecter le bot");
26
+ process.exit();
27
+ }
28
+
29
+ const allRegisteredCommands: DiscordCommand[] = [];
30
+
31
+ client.once(Events.ClientReady, async () => {
32
+ Log.info('Analyse des commandes enregistrées sur Discord');
33
+
34
+ // 1. Récupérer TOUTES les commandes Discord du bot
35
+ const globalDiscordCmds: any[] = await client.rest.get(
36
+ Routes.applicationCommands(client.user!.id)
37
+ ) as any[];
38
+
39
+ // 2. Récupérer les commandes de TOUS les serveurs où le bot est présent
40
+ const botGuilds = client.guilds.cache.map(guild => guild.id);
41
+ const guildDiscordCmds: Record<string, any[]> = {};
42
+
43
+ Log.info(`Analyse des ${botGuilds.length} serveurs où le bot est présent...`);
44
+
45
+ for (const guildId of botGuilds) {
46
+ try {
47
+ const guildCmds = await client.rest.get(
48
+ Routes.applicationGuildCommands(config.clientId, guildId)
49
+ ) as any[];
50
+ guildDiscordCmds[guildId] = guildCmds;
51
+ Log.info((`Serveur ${guildId}: ${guildCmds.length} commandes guild`);
52
+ } catch (error) {
53
+ // Le bot n'a peut-être pas les permissions ou n'est pas dans ce serveur
54
+ guildDiscordCmds[guildId] = [];
55
+ }
56
+ }
57
+
58
+ // 3. Classer les commandes par nom et type
59
+ const commandMap = new Map<string, DiscordCommand>();
60
+
61
+ // Commandes globales
62
+ for (const cmd of globalDiscordCmds) {
63
+ const key = `${cmd.name}_${cmd.type}`;
64
+ if (!commandMap.has(key)) {
65
+ commandMap.set(key, {
66
+ name: cmd.name,
67
+ description: cmd.description || '',
68
+ type: cmd.type,
69
+ id: cmd.id,
70
+ deployedGuilds: ['GLOBAL'],
71
+ discordData: cmd
72
+ });
73
+ } else {
74
+ const existing = commandMap.get(key)!;
75
+ existing.deployedGuilds.push('GLOBAL');
76
+ }
77
+ }
78
+
79
+ // Commandes par serveur
80
+ for (const [guildId, guildCmds] of Object.entries(guildDiscordCmds)) {
81
+ for (const cmd of guildCmds) {
82
+ const key = `${cmd.name}_${cmd.type}`;
83
+ if (!commandMap.has(key)) {
84
+ commandMap.set(key, {
85
+ name: cmd.name,
86
+ description: cmd.description || '',
87
+ type: cmd.type,
88
+ id: cmd.id,
89
+ deployedGuilds: [guildId],
90
+ discordData: cmd
91
+ });
92
+ } else {
93
+ const existing = commandMap.get(key)!;
94
+ if (!existing.deployedGuilds.includes(guildId)) {
95
+ existing.deployedGuilds.push(guildId);
96
+ }
97
+ }
98
+ }
99
+ } // ← Fermeture de la boucle for guildId
100
+
101
+ // 4. Conversion en tableau et tri ← ✅ DÉPLACÉ ICI (CORRIGÉ)
102
+ for (const [_key, cmd] of commandMap) {
103
+ allRegisteredCommands.push(cmd);
104
+ }
105
+
106
+ allRegisteredCommands.sort((a, b) => {
107
+ if (a.deployedGuilds.includes('GLOBAL') && !b.deployedGuilds.includes('GLOBAL')) return -1;
108
+ if (!a.deployedGuilds.includes('GLOBAL') && b.deployedGuilds.includes('GLOBAL')) return 1;
109
+ return a.name.localeCompare(b.name);
110
+ });
111
+
112
+ // 5. Affichage du classement
113
+ console.log('\n' + '='.repeat(80));
114
+ console.log('📋 CLASSEMENT DES COMMANDES ENREGISTRÉES SUR DISCORD');
115
+ console.log('='.repeat(80));
116
+
117
+ const globalCmds = allRegisteredCommands.filter(cmd => cmd.deployedGuilds.includes('GLOBAL'));
118
+ const guildOnlyCmds = allRegisteredCommands.filter(cmd => !cmd.deployedGuilds.includes('GLOBAL'));
119
+
120
+ console.log(`🌍 ${globalCmds.length} commandes GLOBALES`);
121
+ console.log(`🏛️ ${guildOnlyCmds.length} commandes SERVEUR-SEUL`);
122
+
123
+ // Tableau récapitulatif
124
+ console.table(
125
+ allRegisteredCommands.map(cmd => ({
126
+ Nom: cmd.name,
127
+ Type: cmd.type === 1 ? 'Slash' : cmd.type === 2 ? 'User Context' : 'Message Context',
128
+ Serveurs: cmd.deployedGuilds.length > 3
129
+ ? `${cmd.deployedGuilds.slice(0, 3).join(', ')}... (+${cmd.deployedGuilds.length - 3})`
130
+ : cmd.deployedGuilds.join(', '),
131
+ ID: cmd.id?.slice(-8) || 'N/A'
132
+ }))
133
+ );
134
+
135
+ // Détails par catégorie
136
+ if (globalCmds.length > 0) {
137
+ console.log('\n🌍 COMMANDES GLOBALES:');
138
+ globalCmds.forEach(cmd => {
139
+ console.log(` • ${cmd.name} (ID: ${cmd.id?.slice(-8)}) - ${cmd.description}`);
140
+ });
141
+ }
142
+
143
+ if (guildOnlyCmds.length > 0) {
144
+ console.log('\n🏛️ COMMANDES SERVEUR-SEULEMENT:');
145
+ const groupedByGuild = guildOnlyCmds.reduce((acc, cmd) => {
146
+ for (const guildId of cmd.deployedGuilds) {
147
+ if (!acc[guildId]) acc[guildId] = [];
148
+ acc[guildId].push(cmd.name);
149
+ }
150
+ return acc;
151
+ }, {} as Record<string, string[]>);
152
+
153
+ for (const [guildId, cmds] of Object.entries(groupedByGuild)) {
154
+ console.log(` 📂 Serveur ${guildId.slice(-8)}: ${cmds.join(', ')}`);
155
+ }
156
+ }
157
+
158
+ console.log('\n✅ Analyse terminée!');
159
+ process.exit();
160
+ });
161
+
162
+ return allRegisteredCommands;
163
+ }
164
+
165
+ // Utilisation
166
+ analyzeRegisteredCommands();*/
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EmbedManager = exports.EmbedColor = void 0;
4
+ const discord_js_1 = require("discord.js");
5
+ const Bot_1 = require("../../bot/Bot");
6
+ var EmbedColor;
7
+ (function (EmbedColor) {
8
+ EmbedColor[EmbedColor["error"] = 8912917] = "error";
9
+ EmbedColor[EmbedColor["success"] = 65280] = "success";
10
+ EmbedColor[EmbedColor["black"] = 0] = "black";
11
+ EmbedColor[EmbedColor["white"] = 16777215] = "white";
12
+ EmbedColor[EmbedColor["red"] = 16711680] = "red";
13
+ EmbedColor[EmbedColor["green"] = 65280] = "green";
14
+ EmbedColor[EmbedColor["blue"] = 255] = "blue";
15
+ EmbedColor[EmbedColor["yellow"] = 16776960] = "yellow";
16
+ EmbedColor[EmbedColor["cyan"] = 65535] = "cyan";
17
+ EmbedColor[EmbedColor["magenta"] = 16711935] = "magenta";
18
+ EmbedColor[EmbedColor["gray"] = 8421504] = "gray";
19
+ EmbedColor[EmbedColor["lightgray"] = 13882323] = "lightgray";
20
+ EmbedColor[EmbedColor["darkgray"] = 11119017] = "darkgray";
21
+ EmbedColor[EmbedColor["orange"] = 16753920] = "orange";
22
+ EmbedColor[EmbedColor["purple"] = 8388736] = "purple";
23
+ EmbedColor[EmbedColor["pink"] = 16761035] = "pink";
24
+ EmbedColor[EmbedColor["brown"] = 10824234] = "brown";
25
+ EmbedColor[EmbedColor["lime"] = 65280] = "lime";
26
+ EmbedColor[EmbedColor["navy"] = 128] = "navy";
27
+ EmbedColor[EmbedColor["teal"] = 32896] = "teal";
28
+ EmbedColor[EmbedColor["olive"] = 8421376] = "olive";
29
+ EmbedColor[EmbedColor["gold"] = 16766720] = "gold";
30
+ EmbedColor[EmbedColor["silver"] = 12632256] = "silver";
31
+ EmbedColor[EmbedColor["coral"] = 16744272] = "coral";
32
+ EmbedColor[EmbedColor["salmon"] = 16416882] = "salmon";
33
+ EmbedColor[EmbedColor["khaki"] = 15787660] = "khaki";
34
+ EmbedColor[EmbedColor["plum"] = 14524637] = "plum";
35
+ EmbedColor[EmbedColor["lavender"] = 15132410] = "lavender";
36
+ EmbedColor[EmbedColor["beige"] = 16119260] = "beige";
37
+ EmbedColor[EmbedColor["mint"] = 10026904] = "mint";
38
+ EmbedColor[EmbedColor["peach"] = 16767673] = "peach";
39
+ EmbedColor[EmbedColor["chocolate"] = 13789470] = "chocolate";
40
+ EmbedColor[EmbedColor["crimson"] = 14423100] = "crimson";
41
+ EmbedColor[EmbedColor["youtube"] = 16718362] = "youtube";
42
+ EmbedColor[EmbedColor["default"] = 6064856] = "default";
43
+ EmbedColor[EmbedColor["minecraft"] = 25600] = "minecraft";
44
+ })(EmbedColor || (exports.EmbedColor = EmbedColor = {}));
45
+ class EmbedManager {
46
+ static get BOT_ICON() {
47
+ return Bot_1.Bot.config.botIconUrl || "";
48
+ }
49
+ static get DEFAULT_COLOR() {
50
+ return Bot_1.Bot.config.defaultEmbedColor || EmbedColor.default;
51
+ }
52
+ /**
53
+ * Creates base embed - SAME SIMPLE API !
54
+ */
55
+ static create(color = null) {
56
+ return new discord_js_1.EmbedBuilder()
57
+ .setColor(color ?? this.DEFAULT_COLOR)
58
+ .setTitle('Title')
59
+ .setDescription('')
60
+ .setThumbnail('')
61
+ .setFooter({
62
+ text: Bot_1.Bot.config.botName || "",
63
+ iconURL: this.BOT_ICON
64
+ })
65
+ .setTimestamp(new Date());
66
+ }
67
+ /**
68
+ * Creates simple embed with just description
69
+ */
70
+ static simple(description, color = null) {
71
+ return this.create(color)
72
+ .setTitle('')
73
+ .setDescription(description)
74
+ .setTimestamp(null);
75
+ }
76
+ /**
77
+ * Creates error embed
78
+ */
79
+ static error(description) {
80
+ return this.create(EmbedColor.error)
81
+ .setTitle('Something went Wrong')
82
+ .setDescription(description);
83
+ }
84
+ /**
85
+ * Creates success embed
86
+ */
87
+ static success(description) {
88
+ return this.create(EmbedColor.minecraft)
89
+ .setTitle('Success')
90
+ .setDescription(description);
91
+ }
92
+ /**
93
+ * Creates debug embed
94
+ */
95
+ static debug(description) {
96
+ return this.create(EmbedColor.green)
97
+ .setTitle('Debug')
98
+ .setDescription(description);
99
+ }
100
+ /**
101
+ * Defer ephemeral reply
102
+ */
103
+ static deferEphemeral() {
104
+ return { flags: discord_js_1.MessageFlags.Ephemeral };
105
+ }
106
+ /**
107
+ * Quick field adder
108
+ */
109
+ static field(embed, name, value, inline = false) {
110
+ return embed.addFields({ name, value, inline });
111
+ }
112
+ /**
113
+ * Fluent API shortcuts
114
+ */
115
+ static title(embed, title) {
116
+ return embed.setTitle(title);
117
+ }
118
+ static desc(embed, description) {
119
+ return embed.setDescription(description);
120
+ }
121
+ static thumb(embed, url) {
122
+ return embed.setThumbnail(url);
123
+ }
124
+ static image(embed, url) {
125
+ return embed.setImage(url);
126
+ }
127
+ static footer(embed, text) {
128
+ return embed.setFooter({ text, iconURL: this.BOT_ICON });
129
+ }
130
+ }
131
+ exports.EmbedManager = EmbedManager;
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ReactionManager = void 0;
4
+ const Log_1 = require("../../utils/Log");
5
+ const Bot_1 = require("../../bot/Bot");
6
+ const GuildTextChannelManager_1 = require("../guild/ChannelManager/GuildTextChannelManager");
7
+ class ReactionManager {
8
+ /**
9
+ * Add a reaction to a message
10
+ */
11
+ static async add(channelId, messageId, emoji) {
12
+ try {
13
+ const channel = await GuildTextChannelManager_1.GuildTextChannelManager.find(channelId);
14
+ if (!channel) {
15
+ throw new Error(`Channel ${channelId} not found`);
16
+ }
17
+ if (!channel.isTextBased()) {
18
+ throw new Error(`Channel ${channelId} is not text based`);
19
+ }
20
+ const message = await channel.messages.fetch(messageId);
21
+ await message.react(emoji);
22
+ Log_1.Log.info(`Added reaction ${emoji} to message ${messageId}`);
23
+ }
24
+ catch (error) {
25
+ Log_1.Log.error(`Failed to add reaction to ${messageId}: ${error}`);
26
+ throw error;
27
+ }
28
+ }
29
+ /**
30
+ * Delete a reaction from a user
31
+ */
32
+ static async remove(channelId, messageId, emoji, userId) {
33
+ try {
34
+ const channel = await GuildTextChannelManager_1.GuildTextChannelManager.find(channelId);
35
+ if (!channel) {
36
+ throw new Error(`Channel ${channelId} not found`);
37
+ }
38
+ const message = await channel.messages.fetch(messageId);
39
+ const reaction = message.reactions.resolve(emoji);
40
+ if (!reaction) {
41
+ throw new Error(`Reaction ${emoji} not found on message ${messageId}`);
42
+ }
43
+ const user = await Bot_1.Bot.client.users.fetch(userId);
44
+ await reaction.users.remove(user);
45
+ Log_1.Log.info(`Removed reaction ${emoji} from user ${userId} on message ${messageId}`);
46
+ }
47
+ catch (error) {
48
+ Log_1.Log.error(`Failed to remove reaction from ${messageId}: ${error}`);
49
+ throw error;
50
+ }
51
+ }
52
+ /**
53
+ * Get all reaction of a message
54
+ */
55
+ static async getAll(channelId, messageId) {
56
+ try {
57
+ const channel = await GuildTextChannelManager_1.GuildTextChannelManager.find(channelId);
58
+ if (!channel) {
59
+ throw new Error(`Channel ${channelId} not found`);
60
+ }
61
+ const message = await channel.messages.fetch(messageId);
62
+ const reactions = message.reactions.cache;
63
+ const reactionList = [];
64
+ for (const reaction of reactions.values()) {
65
+ const users = await reaction.users.fetch();
66
+ reactionList.push({
67
+ emoji: reaction.emoji,
68
+ count: reaction.count,
69
+ users: Array.from(users.values())
70
+ });
71
+ }
72
+ Log_1.Log.info(`Fetched ${reactionList.length} reactions for message ${messageId}`);
73
+ return reactionList;
74
+ }
75
+ catch (error) {
76
+ Log_1.Log.error(`Failed to fetch reactions for ${messageId}: ${error}`);
77
+ throw error;
78
+ }
79
+ }
80
+ /**
81
+ * Delete all reaction
82
+ */
83
+ static async clear(channelId, messageId) {
84
+ try {
85
+ const channel = await GuildTextChannelManager_1.GuildTextChannelManager.find(channelId);
86
+ if (!channel) {
87
+ throw new Error(`Channel ${channelId} not found`);
88
+ }
89
+ const message = await channel.messages.fetch(messageId);
90
+ await message.reactions.removeAll();
91
+ Log_1.Log.info(`Cleared all reactions from message ${messageId}`);
92
+ }
93
+ catch (error) {
94
+ Log_1.Log.error(`Failed to clear reactions from ${messageId}: ${error}`);
95
+ throw error;
96
+ }
97
+ }
98
+ }
99
+ exports.ReactionManager = ReactionManager;
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebhookManager = void 0;
4
+ const discord_js_1 = require("discord.js");
5
+ const EmbedManager_1 = require("./EmbedManager");
6
+ const Log_1 = require("../../utils/Log");
7
+ const Bot_1 = require("../../bot/Bot");
8
+ class WebhookManager {
9
+ constructor(channel, name = Bot_1.Bot.config.botName || "", avatarURL) {
10
+ this.channel = channel;
11
+ this.name = name;
12
+ this.avatarURL = avatarURL;
13
+ this.webhook = null;
14
+ }
15
+ get textChannel() {
16
+ return this.channel instanceof discord_js_1.ThreadChannel
17
+ ? this.channel.parent
18
+ : this.channel;
19
+ }
20
+ /**
21
+ * Get or create webhook (lazy initialization)
22
+ */
23
+ async getWebhook() {
24
+ if (this.webhook)
25
+ return this.webhook;
26
+ try {
27
+ const webhooks = await this.textChannel.fetchWebhooks();
28
+ this.webhook = webhooks.find(h => h.name === this.name) ??
29
+ await this.textChannel.createWebhook({
30
+ name: this.name,
31
+ avatar: this.avatarURL,
32
+ reason: 'Auto-created by WebhookManager'
33
+ });
34
+ Log_1.Log.info(`Webhook ${this.webhook.id} ready for ${this.textChannel.id}`);
35
+ return this.webhook;
36
+ }
37
+ catch (error) {
38
+ Log_1.Log.error(`Failed to setup webhook: ${error}`);
39
+ throw error;
40
+ }
41
+ }
42
+ /**
43
+ * Send message/text/embed - EmbedBuilder NATIVE !
44
+ */
45
+ async send(content) {
46
+ const webhook = await this.getWebhook();
47
+ const options = {};
48
+ if (content instanceof discord_js_1.EmbedBuilder) {
49
+ options.embeds = [content];
50
+ }
51
+ else if (typeof content === 'object') {
52
+ Object.assign(options, content);
53
+ }
54
+ else {
55
+ options.content = content;
56
+ }
57
+ if (this.channel instanceof discord_js_1.ThreadChannel) {
58
+ options.threadId = this.channel.id;
59
+ }
60
+ try {
61
+ const message = await webhook.send(options);
62
+ Log_1.Log.info(`Webhook sent to ${this.channel.id}: ${content}`);
63
+ return message;
64
+ }
65
+ catch (error) {
66
+ Log_1.Log.error(`Webhook send failed ${this.channel.id}: ${error}`);
67
+ return null;
68
+ }
69
+ }
70
+ /**
71
+ * Quick success embed
72
+ */
73
+ async success(message) {
74
+ return await this.send(EmbedManager_1.EmbedManager.success(message));
75
+ }
76
+ /**
77
+ * Quick error embed
78
+ */
79
+ async error(message) {
80
+ return await this.send(EmbedManager_1.EmbedManager.error(message));
81
+ }
82
+ /**
83
+ * Delete webhook
84
+ */
85
+ async delete(reason) {
86
+ if (!this.webhook)
87
+ return;
88
+ try {
89
+ await this.webhook.delete(reason ?? 'Deleted by WebhookManager');
90
+ Log_1.Log.info(`Webhook ${this.webhook.id} deleted`);
91
+ }
92
+ catch (error) {
93
+ if (error.message.includes('Unknown Webhook')) {
94
+ Log_1.Log.warn('Webhook already deleted');
95
+ }
96
+ else {
97
+ Log_1.Log.error(`Failed to delete webhook: ${error}`);
98
+ }
99
+ }
100
+ finally {
101
+ this.webhook = null;
102
+ }
103
+ }
104
+ }
105
+ exports.WebhookManager = WebhookManager;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FolderName = void 0;
4
+ var FolderName;
5
+ (function (FolderName) {
6
+ FolderName["SLASH_COMMANDS"] = "commands";
7
+ FolderName["CONTEXT_MENU"] = "context_menu";
8
+ FolderName["MODAL"] = "modals";
9
+ })(FolderName || (exports.FolderName = FolderName = {}));
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.DiscordRegex = void 0;
5
+ /**
6
+ * Classe utilitaire pour valider tous les formats Discord avec regex
7
+ */
8
+ class DiscordRegex {
9
+ /**
10
+ * Validate Discord ID Discord (18)
11
+ */
12
+ static isDiscordId(id) {
13
+ return this.USER_ID.test(id) || this.GUILD_ID.test(id) || this.CHANNEL_ID.test(id);
14
+ }
15
+ /**
16
+ * Validate a bot ID (19)
17
+ */
18
+ static isBotMention(mention) {
19
+ return this.BOT_REGEX.test(mention);
20
+ }
21
+ /**
22
+ * Validate a User ping
23
+ */
24
+ static isUserMention(mention) {
25
+ return this.USER_REGEX.test(mention);
26
+ }
27
+ /**
28
+ * Validate a Discord username
29
+ */
30
+ static isUsername(username) {
31
+ return this.USERNAME.test(username);
32
+ }
33
+ /**
34
+ * Type guard for Discord ID
35
+ */
36
+ static isDiscordIdType(id) {
37
+ return this.isDiscordId(id);
38
+ }
39
+ /**
40
+ * Any Discord URL
41
+ */
42
+ static isDiscordUrl(url) {
43
+ return this.URL_REGEX.test(url) || this.INVITE.test(url);
44
+ }
45
+ /**
46
+ * Any discord mention
47
+ */
48
+ static isAnyMention(text) {
49
+ return this.DISCORD_MENTION_REGEX.test(text);
50
+ }
51
+ /**
52
+ * List all regex
53
+ */
54
+ static listAll() {
55
+ return {
56
+ SPACE: this.SPACE,
57
+ URL_REGEX: this.URL_REGEX,
58
+ USER_REGEX: this.USER_REGEX,
59
+ BOT_REGEX: this.BOT_REGEX,
60
+ CHANNEL_REGEX: this.CHANNEL_REGEX,
61
+ ROLE_REGEX: this.ROLE_REGEX,
62
+ DISCORD_PING_REGEX: this.DISCORD_PING_REGEX,
63
+ DISCORD_MENTION_REGEX: this.DISCORD_MENTION_REGEX,
64
+ USER_ID: this.USER_ID,
65
+ CHANNEL_ID: this.CHANNEL_ID,
66
+ GUILD_ID: this.GUILD_ID,
67
+ USERNAME: this.USERNAME,
68
+ USERNAME_DISCRIM: this.USERNAME_DISCRIM,
69
+ CHANNEL_MENTION: this.CHANNEL_MENTION,
70
+ USER_MENTION: this.USER_MENTION,
71
+ ROLE_MENTION: this.ROLE_MENTION,
72
+ INVITE: this.INVITE,
73
+ EMOJI: this.EMOJI
74
+ };
75
+ }
76
+ }
77
+ exports.DiscordRegex = DiscordRegex;
78
+ _a = DiscordRegex;
79
+ // Caractères spéciaux
80
+ DiscordRegex.SPACE = "\u200B";
81
+ // URLs basiques
82
+ DiscordRegex.URL_REGEX = /(https?:\/\/[^s]+)/;
83
+ /* DISCORD REGEX */
84
+ DiscordRegex.USER_REGEX = /<@\d{18}>/;
85
+ DiscordRegex.BOT_REGEX = /<@\d{19}>/;
86
+ DiscordRegex.CHANNEL_REGEX = /(<#\d{19}>)|(<id:(browse|customize|guide)>)/;
87
+ DiscordRegex.ROLE_REGEX = /<@&\d{19}>/;
88
+ /**
89
+ * Mention a User
90
+ * Mention a Role
91
+ */
92
+ DiscordRegex.DISCORD_PING_REGEX = new RegExp(`(${_a.USER_REGEX.source})|(${_a.BOT_REGEX.source})|(${_a.ROLE_REGEX.source})`);
93
+ /**
94
+ * Mention a User
95
+ * Mention a Role
96
+ * Mention a Channel
97
+ */
98
+ DiscordRegex.DISCORD_MENTION_REGEX = new RegExp(`(${_a.DISCORD_PING_REGEX.source})|(${_a.CHANNEL_REGEX.source})`);
99
+ // ID Discord (user, channel guild)
100
+ DiscordRegex.USER_ID = /^[0-9]{18}$/;
101
+ DiscordRegex.CHANNEL_ID = /^[0-9]{18}$/;
102
+ DiscordRegex.GUILD_ID = /^[0-9]{19}$/;
103
+ // Username Discord (2-32 caractères alphanumériques + _ .)
104
+ DiscordRegex.USERNAME = /^[a-zA-Z0-9_]{2,32}$/;
105
+ // Username + discrim (ancien format)
106
+ DiscordRegex.USERNAME_DISCRIM = /^[a-zA-Z0-9_]{2,32}#\d{4}$/;
107
+ // Channel mention <#123456789012345678>
108
+ DiscordRegex.CHANNEL_MENTION = /^<#([0-9]{18})>$/;
109
+ // User mention <@123456789012345678> ou <@!123456789012345678>
110
+ DiscordRegex.USER_MENTION = /^<@!?([0-9]{18})>$/;
111
+ // Role mention <@&123456789012345678>
112
+ DiscordRegex.ROLE_MENTION = /^<@&([0-9]{18})>$/;
113
+ // URL Invite Discord
114
+ DiscordRegex.INVITE = /^discord(?:app\.com\/invite|gg)\/[a-zA-Z0-9]+$/;
115
+ // Emoji Discord (custom or unicode)
116
+ DiscordRegex.EMOJI = /^<a?:[a-zA-Z0-9_]{2,32}:[0-9]{18}>$|^[\u{1F300}-\u{1F5FF}\u{1F600}-\u{1F64F}\u{1F680}-\u{1F6FF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}]+$/u;