@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.
- package/.env.example +2 -0
- package/LICENSE.md +21 -0
- package/README.md +1 -0
- package/dist/bot/Bot.js +107 -0
- package/dist/bot/BotEnv.js +29 -0
- package/dist/bot/BotLog.js +90 -0
- package/dist/bot/BotMessage.js +79 -0
- package/dist/cli/BaseCLI.js +165 -0
- package/dist/cli/GenerationCLI/ContextMenuGeneratorCLI.js +109 -0
- package/dist/cli/GenerationCLI/GenerationCLI.js +25 -0
- package/dist/cli/GenerationCLI/InteractionGeneratorCLI.js +20 -0
- package/dist/cli/GenerationCLI/ModalGeneratorCLI.js +166 -0
- package/dist/cli/GenerationCLI/SlashCommandsGeneratorCLI.js +221 -0
- package/dist/cli/GenerationCLI.js +36 -0
- package/dist/cli/GuildListManager.js +61 -0
- package/dist/cli/InputCLI.js +25 -0
- package/dist/cli/InteractionCLI/InteractionCLI.js +30 -0
- package/dist/cli/InteractionCLI/InteractionCLIManager.js +80 -0
- package/dist/cli/InteractionCLI.js +109 -0
- package/dist/cli/MainCLI.js +32 -0
- package/dist/cli/type/ContextMenuConfig.js +2 -0
- package/dist/cli/type/InteractionType.js +14 -0
- package/dist/cli/type/SlashCommandConfig.js +2 -0
- package/dist/index.js +31 -0
- package/dist/manager/FileManager.js +136 -0
- package/dist/manager/direct/UserManager.js +76 -0
- package/dist/manager/discord/ChannelManager.js +48 -0
- package/dist/manager/discord/DiscordRegex.js +114 -0
- package/dist/manager/discord/GuildManager.js +67 -0
- package/dist/manager/discord/InviteManager.js +89 -0
- package/dist/manager/discord/RoleManager.js +83 -0
- package/dist/manager/discord/UserManager.js +69 -0
- package/dist/manager/guild/ChannelManager/ForumChannelManager.js +33 -0
- package/dist/manager/guild/ChannelManager/GuildChannelList.js +20 -0
- package/dist/manager/guild/ChannelManager/GuildChannelManager.js +91 -0
- package/dist/manager/guild/ChannelManager/GuildMessageManager.js +85 -0
- package/dist/manager/guild/ChannelManager/GuildTextChannelManager.js +33 -0
- package/dist/manager/guild/ChannelManager/GuildVoiceChannelManager.js +33 -0
- package/dist/manager/guild/ChannelManager/NewsChannelManager.js +33 -0
- package/dist/manager/guild/ChannelManager/StageChannelManager.js +33 -0
- package/dist/manager/guild/ChannelManager/ThreadChannelManager.js +34 -0
- package/dist/manager/guild/GuildManager.js +134 -0
- package/dist/manager/guild/GuildUserManager.js +212 -0
- package/dist/manager/guild/InviteManager.js +68 -0
- package/dist/manager/guild/InviteManager_old.js +89 -0
- package/dist/manager/guild/RoleManager.js +83 -0
- package/dist/manager/hadlers_old/builder/ModalManager.js +111 -0
- package/dist/manager/hadlers_old/builder/delete.js +49 -0
- package/dist/manager/hadlers_old/builder/deploy.js +225 -0
- package/dist/manager/hadlers_old/builder/interactions/CommandManager.js +14 -0
- package/dist/manager/hadlers_old/builder/interactions/ContextMenuManager.js +14 -0
- package/dist/manager/hadlers_old/builder/interactions/InteractionBase.js +341 -0
- package/dist/manager/hadlers_old/builder/interactions/InteractionManager.js +65 -0
- package/dist/manager/hadlers_old/builder/list.js +166 -0
- package/dist/manager/messages/EmbedManager.js +131 -0
- package/dist/manager/messages/ReactionManager.js +99 -0
- package/dist/manager/messages/WebhookManager.js +105 -0
- package/dist/type/FolderName.js +9 -0
- package/dist/utils/DiscordRegex.js +116 -0
- package/dist/utils/Log.js +28 -0
- package/dist/utils/SimpleMutex.js +39 -0
- package/dist/utils/network/InternetChecker.js +54 -0
- package/dist/utils/times/UnitTime.js +85 -0
- package/package.json +40 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const rest_1 = require("@discordjs/rest");
|
|
4
|
+
const v10_1 = require("discord-api-types/v10");
|
|
5
|
+
const Log_1 = require("../../../utils/Log");
|
|
6
|
+
const BotEnv_1 = require("../../../bot/BotEnv");
|
|
7
|
+
const Bot_1 = require("../../../bot/Bot");
|
|
8
|
+
async function deleteAllCommandsAndMenus() {
|
|
9
|
+
const rest = new rest_1.REST({ version: '10' }).setToken(BotEnv_1.BotEnv.token);
|
|
10
|
+
const guildIDs = ["1111160769132896377", "1214320754578165901"]; // Liste des guildes à vérifier
|
|
11
|
+
try {
|
|
12
|
+
// 1. Suppression des commandes/menus globaux
|
|
13
|
+
Log_1.Log.info('INFO : Suppression des commandes et menus contextuels globaux...');
|
|
14
|
+
const globalCommands = await rest.get(v10_1.Routes.applicationCommands(Bot_1.Bot.config.clientId));
|
|
15
|
+
for (const command of globalCommands) {
|
|
16
|
+
try {
|
|
17
|
+
await rest.delete(v10_1.Routes.applicationCommand(Bot_1.Bot.config.clientId, command.id));
|
|
18
|
+
Log_1.Log.info(`Commande/menu contextuel global "${command.name}" supprimé.`);
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
Log_1.Log.error(`Impossible de supprimer la commande/menu contextuel global "${command.name}" : ${err.message}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
// 2. Suppression des commandes/menus spécifiques aux guildes
|
|
25
|
+
Log_1.Log.info('Suppression des commandes et menus contextuels spécifiques aux guildes...');
|
|
26
|
+
for (const guildId of guildIDs) {
|
|
27
|
+
try {
|
|
28
|
+
const guildCommands = await rest.get(v10_1.Routes.applicationGuildCommands(Bot_1.Bot.config.clientId, guildId));
|
|
29
|
+
for (const command of guildCommands) {
|
|
30
|
+
try {
|
|
31
|
+
await rest.delete(v10_1.Routes.applicationGuildCommand(Bot_1.Bot.config.clientId, guildId, command.id));
|
|
32
|
+
Log_1.Log.info(`Commande/menu contextuel "${command.name}" supprimé sur la guilde ${guildId}.`);
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
Log_1.Log.error(`Impossible de supprimer la commande/menu contextuel "${command.name}" sur la guilde ${guildId} : ${err.message}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
Log_1.Log.error(`Impossible de récupérer ou supprimer les commandes/menus contextuels pour le serveur ${guildId} : ${err.message}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
Log_1.Log.info('Toutes les commandes et menus contextuels ont été supprimés.');
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
Log_1.Log.error(`Impossible de récupérer ou supprimer les commandes/menus contextuels : ${err.message}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
deleteAllCommandsAndMenus();
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/*import { PermissionFlagsBits } from 'discord-api-types/v10';
|
|
4
|
+
import { REST } from '@discordjs/rest';
|
|
5
|
+
import { Routes } from 'discord-api-types/v10';
|
|
6
|
+
import { setTimeout } from "timers/promises";
|
|
7
|
+
import { client } from '../utils/client.js';
|
|
8
|
+
import { Time } from '../utils/times/UnitTime.js';
|
|
9
|
+
import { log } from '../utils/log.js';
|
|
10
|
+
import { listJsonFile, readJsonFile, writeJsonFileRework } from '../utils/server/files.js';
|
|
11
|
+
import { loginBot } from '../utils/login.js';
|
|
12
|
+
import config from '../config.js';
|
|
13
|
+
import {Events} from "discord.js";
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
export interface Command {
|
|
17
|
+
name: string;
|
|
18
|
+
description: string;
|
|
19
|
+
options?: any[];
|
|
20
|
+
default_member_permissions?: string | bigint | number;
|
|
21
|
+
guildID?: string[];
|
|
22
|
+
type: 1 | 2 | 3; // 1 = slash, 2 = user context, 3 = message context
|
|
23
|
+
id?: string; // Discord API Command ID
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Initialisation du REST
|
|
27
|
+
client.rest = new REST({ version: '10' }).setToken(config.token);
|
|
28
|
+
|
|
29
|
+
export async function deployCommand(commandPath: string[]): Promise<void> {
|
|
30
|
+
if (!(await loginBot(client))) {
|
|
31
|
+
log("Erreur : Impossible de connecter le bot");
|
|
32
|
+
process.exit()
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
client.once(Events.ClientReady, async () => {
|
|
36
|
+
log('INFO : Déploiement des commandes slash');
|
|
37
|
+
|
|
38
|
+
for (const path of commandPath){
|
|
39
|
+
const slashFiles = await listJsonFile(`./handlers/${path}/`);
|
|
40
|
+
if (!slashFiles) {
|
|
41
|
+
log('ERREUR : Impossible de lire les fichiers de commandes');
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
console.log(`${slashFiles.length} ${path}`)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Récupère toutes les commandes actuelles sur Discord
|
|
48
|
+
const globalDiscordCmds: any[] = await client.rest.get(
|
|
49
|
+
Routes.applicationCommands(client.user!.id)
|
|
50
|
+
) as any[];
|
|
51
|
+
|
|
52
|
+
const allLocalCommands: Command[] = [];
|
|
53
|
+
const guildDiscordCmds = {} as Record<string, any[]>;
|
|
54
|
+
|
|
55
|
+
for(const path of commandPath){
|
|
56
|
+
const slashFiles = await listJsonFile(`./${path}/`);
|
|
57
|
+
if (!slashFiles) {
|
|
58
|
+
log('ERREUR : Impossible de lire les fichiers de commandes');
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
// Pour chaque guilde utilisée dans tes JSONs
|
|
64
|
+
const allGuildIds = new Set<string>();
|
|
65
|
+
for (const filename of slashFiles) {
|
|
66
|
+
const cmdData = await readJsonFile(`./${path}/${filename}`);
|
|
67
|
+
if (cmdData?.guildID) {
|
|
68
|
+
for (const gid of cmdData.guildID) allGuildIds.add(gid);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
for (const guildId of allGuildIds) {
|
|
73
|
+
try {
|
|
74
|
+
guildDiscordCmds[guildId] = await client.rest.get(
|
|
75
|
+
Routes.applicationGuildCommands(config.clientId, guildId)
|
|
76
|
+
) as any[];
|
|
77
|
+
} catch (error) {
|
|
78
|
+
console.error()
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// ---------------------- Déploiement attendue ---------------------------
|
|
83
|
+
|
|
84
|
+
for (const file of slashFiles.filter((n: string | string[])=>!n.includes('example'))) {
|
|
85
|
+
let updated = false;
|
|
86
|
+
const cmd: Command | false = await readJsonFile(`./${path}/${file}`);
|
|
87
|
+
if(!cmd) continue;
|
|
88
|
+
|
|
89
|
+
// Traitement permissions
|
|
90
|
+
if (cmd.default_member_permissions && Array.isArray(cmd.default_member_permissions)) {
|
|
91
|
+
const bitfield = cmd.default_member_permissions
|
|
92
|
+
.map(perm => {
|
|
93
|
+
const flag = PermissionFlagsBits[perm as keyof typeof PermissionFlagsBits];
|
|
94
|
+
if (flag === undefined) throw new Error(`Permission inconnue : "${perm}"`);
|
|
95
|
+
return flag;
|
|
96
|
+
})
|
|
97
|
+
.reduce((acc, val) => acc | val, BigInt(0));
|
|
98
|
+
cmd.default_member_permissions = Number(bitfield)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Déploiement Guild vs Global
|
|
102
|
+
const deployToGuilds = (cmd.guildID && cmd.guildID.length > 0) ? cmd.guildID : [];
|
|
103
|
+
if (deployToGuilds.length > 0) {
|
|
104
|
+
for (const guildId of deployToGuilds) {
|
|
105
|
+
// Cherche la commande existante sur Discord
|
|
106
|
+
const found = guildDiscordCmds[guildId]?.find(e => e.id === cmd.id || e.name === cmd.name);
|
|
107
|
+
const dataToSend = { ...cmd };
|
|
108
|
+
delete dataToSend.guildID;
|
|
109
|
+
|
|
110
|
+
if (cmd.type === 2 || cmd.type === 3) {
|
|
111
|
+
// Les context menus ne doivent **pas** utiliser `options`
|
|
112
|
+
console.log("on delete options")
|
|
113
|
+
delete dataToSend.options;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
try {
|
|
117
|
+
if (!cmd.id || !found) {
|
|
118
|
+
// Pas d'ID ou pas trouvée, on crée la commande
|
|
119
|
+
console.log("Pas d'ID ou pas trouvée, on crée la commande : " + dataToSend.name)
|
|
120
|
+
const resp = await client.rest.post(
|
|
121
|
+
Routes.applicationGuildCommands(config.clientId, guildId),
|
|
122
|
+
{ body: dataToSend }
|
|
123
|
+
) as any;
|
|
124
|
+
cmd.id = resp.id;
|
|
125
|
+
updated = true;
|
|
126
|
+
log(`SUCCÈS : Commande "${cmd.name}" déployée/guild ${guildId}, id = ${cmd.id}`);
|
|
127
|
+
} else {
|
|
128
|
+
// Si déjà existante, on la met à jour
|
|
129
|
+
console.log("Si déjà existante, on la met à jour : " + dataToSend.name)
|
|
130
|
+
await client.rest.patch(
|
|
131
|
+
Routes.applicationGuildCommand(config.clientId, guildId, found.id),
|
|
132
|
+
{ body: dataToSend }
|
|
133
|
+
);
|
|
134
|
+
cmd.id = found.id;
|
|
135
|
+
log(`MAJ : Commande "${cmd.name}" mise à jour/guild ${guildId}, id = ${cmd.id}`);
|
|
136
|
+
}
|
|
137
|
+
await setTimeout(Time.second.SEC_01.toMilliseconds());
|
|
138
|
+
} catch (error) {
|
|
139
|
+
console.log(error)
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
} else {
|
|
143
|
+
// Commande globale
|
|
144
|
+
const found = globalDiscordCmds.find(e => e.id === cmd.id || e.name === cmd.name);
|
|
145
|
+
const dataToSend = { ...cmd };
|
|
146
|
+
delete dataToSend.guildID;
|
|
147
|
+
if (cmd.type === 2 || cmd.type === 3) {
|
|
148
|
+
// Les context menus ne doivent **pas** utiliser `options`
|
|
149
|
+
delete dataToSend.options;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
try {
|
|
153
|
+
if (!cmd.id || !found) {
|
|
154
|
+
const resp = await client.rest.post(
|
|
155
|
+
Routes.applicationCommands(client.user!.id),
|
|
156
|
+
{ body: dataToSend }
|
|
157
|
+
) as any;
|
|
158
|
+
cmd.id = resp.id;
|
|
159
|
+
updated = true;
|
|
160
|
+
log(`SUCCÈS : Commande globale "${cmd.name}" déployée, id = ${cmd.id}`);
|
|
161
|
+
} else {
|
|
162
|
+
await client.rest.patch(
|
|
163
|
+
Routes.applicationCommand(client.user!.id, found.id),
|
|
164
|
+
{ body: dataToSend }
|
|
165
|
+
);
|
|
166
|
+
cmd.id = found.id;
|
|
167
|
+
log(`MAJ : Commande globale "${cmd.name}" mise à jour, id = ${cmd.id}`);
|
|
168
|
+
}
|
|
169
|
+
} catch (error) {
|
|
170
|
+
console.log(error)
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
//if (updated) await writeJsonFileRework(`./${path}/`, `${file}`, cmd); // Sauvegarde l'id Discord
|
|
174
|
+
if (updated) {
|
|
175
|
+
allLocalCommands.push(cmd); // Ajoute ici la version à jour de la commande
|
|
176
|
+
await writeJsonFileRework(`./${path}/`, `${file}`, cmd);
|
|
177
|
+
} else {
|
|
178
|
+
allLocalCommands.push(cmd); // Même si elle n’a pas été modifiée, on veut la conserver
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// ---------------------- SUPPRESSION COMMANDES ---------------------------
|
|
186
|
+
|
|
187
|
+
const localNames = allLocalCommands.map(c => c.name); // Regroupe toutes les commandes locales
|
|
188
|
+
|
|
189
|
+
// Supprime les commandes globales non déclarées
|
|
190
|
+
for (const apiCmd of globalDiscordCmds) {
|
|
191
|
+
try {
|
|
192
|
+
if (!localNames.includes(apiCmd.name)) {
|
|
193
|
+
await client.rest.delete(
|
|
194
|
+
Routes.applicationCommand(client.user!.id, apiCmd.id)
|
|
195
|
+
);
|
|
196
|
+
log(`SUPPR : Commande globale "${apiCmd.name}" supprimée, id = ${apiCmd.id}`);
|
|
197
|
+
}
|
|
198
|
+
} catch (error) {
|
|
199
|
+
console.log(error);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Supprime les commandes guild non déclarées
|
|
204
|
+
for (const gid of Object.keys(guildDiscordCmds)) {
|
|
205
|
+
const current = guildDiscordCmds[gid];
|
|
206
|
+
if (!current) continue;
|
|
207
|
+
for (const apiCmd of current) {
|
|
208
|
+
try {
|
|
209
|
+
if (!localNames.includes(apiCmd.name)) {
|
|
210
|
+
await client.rest.delete(
|
|
211
|
+
Routes.applicationGuildCommand(config.clientId, gid, apiCmd.id)
|
|
212
|
+
);
|
|
213
|
+
log(`SUPPR : Commande "${apiCmd.name}" supprimée de guild ${gid}`);
|
|
214
|
+
}
|
|
215
|
+
} catch (error) {
|
|
216
|
+
console.log(error);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
process.exit();
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
deployCommand(["context_menu", "commands"]);*/
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CommandManager = void 0;
|
|
4
|
+
// src/discord/CommandManager.ts
|
|
5
|
+
const InteractionBase_1 = require("./InteractionBase");
|
|
6
|
+
class CommandManager extends InteractionBase_1.InteractionBase {
|
|
7
|
+
get name() {
|
|
8
|
+
return "📋 SLASH COMMAND MANAGER";
|
|
9
|
+
}
|
|
10
|
+
get interactionHandlerFolder() {
|
|
11
|
+
return "commands";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.CommandManager = CommandManager;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ContextMenuManager = void 0;
|
|
4
|
+
// src/discord/ContextMenuManager.ts
|
|
5
|
+
const InteractionBase_1 = require("./InteractionBase");
|
|
6
|
+
class ContextMenuManager extends InteractionBase_1.InteractionBase {
|
|
7
|
+
get name() {
|
|
8
|
+
return `📋 CONTEXT MENU MANAGER`;
|
|
9
|
+
}
|
|
10
|
+
get interactionHandlerFolder() {
|
|
11
|
+
return "context_menu";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.ContextMenuManager = ContextMenuManager;
|
|
@@ -0,0 +1,341 @@
|
|
|
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
|
+
exports.InteractionBase = void 0;
|
|
7
|
+
const discord_js_1 = require("discord.js");
|
|
8
|
+
const readline_1 = __importDefault(require("readline"));
|
|
9
|
+
const FileManager_1 = require("../../../FileManager");
|
|
10
|
+
const Bot_1 = require("../../../../bot/Bot");
|
|
11
|
+
const BotEnv_1 = require("../../../../bot/BotEnv");
|
|
12
|
+
const Log_1 = require("../../../../utils/Log");
|
|
13
|
+
class InteractionBase {
|
|
14
|
+
constructor() {
|
|
15
|
+
this.currentState = 'menu';
|
|
16
|
+
this.deployFiles = [];
|
|
17
|
+
this.rest = new discord_js_1.REST({ version: '10' }).setToken(BotEnv_1.BotEnv.token);
|
|
18
|
+
this.rl = readline_1.default.createInterface({
|
|
19
|
+
input: process.stdin,
|
|
20
|
+
output: process.stdout
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
/** 🚀 START INTERACTIF (100% automatique) */
|
|
24
|
+
async startInteractive() {
|
|
25
|
+
Log_1.Log.info('================================');
|
|
26
|
+
console.clear();
|
|
27
|
+
Log_1.Log.info(`${this.name}`);
|
|
28
|
+
await this.showMenu();
|
|
29
|
+
this.rl.prompt();
|
|
30
|
+
this.rl.on('line', async (input) => {
|
|
31
|
+
await this.handleInput(input.trim().toLowerCase());
|
|
32
|
+
});
|
|
33
|
+
this.rl.on('close', () => {
|
|
34
|
+
Log_1.Log.info('👋 Au revoir !');
|
|
35
|
+
process.exit(0);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
/** 🎛️ SINGLE INPUT HANDLER */
|
|
39
|
+
async handleInput(input) {
|
|
40
|
+
switch (this.currentState) {
|
|
41
|
+
case 'menu':
|
|
42
|
+
await this.handleMenuInput(input);
|
|
43
|
+
break;
|
|
44
|
+
case 'deploy_select':
|
|
45
|
+
await this.handleDeploySelect(input);
|
|
46
|
+
break;
|
|
47
|
+
case 'delete_name':
|
|
48
|
+
await this.handleDeleteName(input);
|
|
49
|
+
break;
|
|
50
|
+
case 'delete_all_confirm':
|
|
51
|
+
await this.handleDeleteAllConfirm(input);
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
this.rl?.prompt();
|
|
55
|
+
}
|
|
56
|
+
/** 🎛️ MENU PRINCIPAL */
|
|
57
|
+
async handleMenuInput(input) {
|
|
58
|
+
const [action, arg] = input.split(' ');
|
|
59
|
+
switch (action) {
|
|
60
|
+
case 'deploy':
|
|
61
|
+
await this.startDeployInteractive();
|
|
62
|
+
break;
|
|
63
|
+
case 'deploy-all':
|
|
64
|
+
await this.deployAll();
|
|
65
|
+
break;
|
|
66
|
+
case 'list':
|
|
67
|
+
await this.listAll();
|
|
68
|
+
break;
|
|
69
|
+
case 'list-guild':
|
|
70
|
+
await this.listGuild(arg || '');
|
|
71
|
+
break;
|
|
72
|
+
case 'delete':
|
|
73
|
+
this.startDeleteInteractive();
|
|
74
|
+
break;
|
|
75
|
+
case 'delete-all':
|
|
76
|
+
this.startDeleteAllConfirm();
|
|
77
|
+
break;
|
|
78
|
+
case 'help':
|
|
79
|
+
await this.showMenu();
|
|
80
|
+
break;
|
|
81
|
+
case 'exit':
|
|
82
|
+
this.rl?.close();
|
|
83
|
+
break;
|
|
84
|
+
default:
|
|
85
|
+
Log_1.Log.error('❌ Commande inconnue. Tapez "help"');
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/** 📁 START DEPLOY INTERACTIF */
|
|
89
|
+
async startDeployInteractive() {
|
|
90
|
+
const files = await FileManager_1.FileManager.listJsonFiles(`./handlers/${this.interactionHandlerFolder}`);
|
|
91
|
+
if (!files) {
|
|
92
|
+
Log_1.Log.error("Files not found!");
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
this.deployFiles = files;
|
|
96
|
+
if (!this.deployFiles || this.deployFiles.length <= 0) {
|
|
97
|
+
Log_1.Log.error("Files not found");
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
console.log(`\n📁 ${this.name} (${this.deployFiles.length} fichiers):`);
|
|
101
|
+
console.log(' 0. ALL → Tout déployer');
|
|
102
|
+
this.deployFiles.forEach((file, index) => {
|
|
103
|
+
console.log(` ${index + 1}. ${file.replace('.json', '')}`);
|
|
104
|
+
});
|
|
105
|
+
console.log('');
|
|
106
|
+
this.currentState = 'deploy_select';
|
|
107
|
+
console.log('Choisir (numéro ou 0 pour tout): ');
|
|
108
|
+
}
|
|
109
|
+
/** 🔢 HANDLE DEPLOY CHOICE */
|
|
110
|
+
async handleDeploySelect(input) {
|
|
111
|
+
const num = parseInt(input);
|
|
112
|
+
if (isNaN(num)) {
|
|
113
|
+
Log_1.Log.error("❌ Numéro invalide");
|
|
114
|
+
this.currentState = 'menu';
|
|
115
|
+
await this.showMenu();
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (num === 0) {
|
|
119
|
+
await this.deployAll();
|
|
120
|
+
}
|
|
121
|
+
else if (num > 0 && num <= this.deployFiles.length) {
|
|
122
|
+
const selectedFile = this.deployFiles[num - 1];
|
|
123
|
+
Log_1.Log.info(`🚀 Déploiement ${selectedFile}...`);
|
|
124
|
+
const cmd = await FileManager_1.FileManager.readJsonFile(`./handlers/${this.interactionHandlerFolder}/${selectedFile}`);
|
|
125
|
+
if (cmd) {
|
|
126
|
+
const processed = await this.processPermissions(cmd);
|
|
127
|
+
const globalCmds = await this.getGlobalCommands();
|
|
128
|
+
await this.deploySingle(processed);
|
|
129
|
+
await this.cleanup(globalCmds, [processed]);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
Log_1.Log.error(`❌ Choix ${num} invalide (1-${this.deployFiles.length} ou 0)`);
|
|
134
|
+
this.currentState = 'menu';
|
|
135
|
+
await this.showMenu();
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
this.currentState = 'menu';
|
|
139
|
+
await this.showMenu();
|
|
140
|
+
}
|
|
141
|
+
/** 🗑️ START DELETE INTERACTIF */
|
|
142
|
+
startDeleteInteractive() {
|
|
143
|
+
console.log('\nNom de la commande: ');
|
|
144
|
+
this.currentState = 'delete_name';
|
|
145
|
+
}
|
|
146
|
+
/** 🗑️ HANDLE DELETE NAME */
|
|
147
|
+
async handleDeleteName(input) {
|
|
148
|
+
await this.deleteCommand(input);
|
|
149
|
+
this.currentState = 'menu';
|
|
150
|
+
await this.showMenu();
|
|
151
|
+
}
|
|
152
|
+
/** 💥 START DELETE ALL CONFIRM */
|
|
153
|
+
startDeleteAllConfirm() {
|
|
154
|
+
console.log('\n⚠️ SUPPRIMER TOUT ? (yes/no): ');
|
|
155
|
+
this.currentState = 'delete_all_confirm';
|
|
156
|
+
}
|
|
157
|
+
/** 💥 HANDLE DELETE ALL CONFIRM */
|
|
158
|
+
async handleDeleteAllConfirm(input) {
|
|
159
|
+
if (input.toLowerCase() === 'yes') {
|
|
160
|
+
await this.deleteAllCommands();
|
|
161
|
+
}
|
|
162
|
+
this.currentState = 'menu';
|
|
163
|
+
await this.showMenu();
|
|
164
|
+
}
|
|
165
|
+
/** 🚀 DÉPLOIER TOUT */
|
|
166
|
+
async deployAll() {
|
|
167
|
+
Log_1.Log.info(`🚀 Déploiement ${this.name}...`);
|
|
168
|
+
await this.deployCommands([this.interactionHandlerFolder]);
|
|
169
|
+
this.currentState = 'menu';
|
|
170
|
+
await this.showMenu();
|
|
171
|
+
}
|
|
172
|
+
/** 📦 DÉPLOIEMENT BATCH */
|
|
173
|
+
async deployCommands(paths) {
|
|
174
|
+
const globalCmds = await this.getGlobalCommands();
|
|
175
|
+
const localCommands = [];
|
|
176
|
+
for (const path of paths) {
|
|
177
|
+
const files = await FileManager_1.FileManager.listJsonFiles(`./handlers/${path}`);
|
|
178
|
+
if (files == false || files.length <= 0) {
|
|
179
|
+
Log_1.Log.error(`Aucun fichier dans ${path}`);
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
for (const file of files.filter(f => !f.includes('example'))) {
|
|
183
|
+
const cmd = await FileManager_1.FileManager.readJsonFile(`./handlers/${path}/${file}`);
|
|
184
|
+
if (!cmd)
|
|
185
|
+
continue;
|
|
186
|
+
const processed = await this.processPermissions(cmd);
|
|
187
|
+
localCommands.push(processed);
|
|
188
|
+
await this.deploySingle(processed);
|
|
189
|
+
await this.delay(100);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
await this.cleanup(globalCmds, localCommands);
|
|
193
|
+
}
|
|
194
|
+
/** ⚡ DÉPLOYER UNE SEULE */
|
|
195
|
+
async deploySingle(cmd) {
|
|
196
|
+
const data = { ...cmd, guildID: undefined };
|
|
197
|
+
if (cmd.type === 2 || cmd.type === 3)
|
|
198
|
+
delete data.options;
|
|
199
|
+
try {
|
|
200
|
+
if (cmd.guildID?.length) {
|
|
201
|
+
for (const guildId of cmd.guildID) {
|
|
202
|
+
const guildCmds = await this.getGuildCommands(guildId);
|
|
203
|
+
const existing = guildCmds.find(c => c.name === cmd.name && c.type === cmd.type);
|
|
204
|
+
if (existing) {
|
|
205
|
+
await this.rest.patch(discord_js_1.Routes.applicationGuildCommand(Bot_1.Bot.config.clientId, guildId, existing.id), { body: data });
|
|
206
|
+
Log_1.Log.info(`🔄 MAJ ${cmd.name} → ${guildId.slice(-4)}`);
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
await this.rest.post(discord_js_1.Routes.applicationGuildCommands(Bot_1.Bot.config.clientId, guildId), { body: data });
|
|
210
|
+
Log_1.Log.info(`✅ NEW ${cmd.name} → ${guildId.slice(-4)}`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
const globalCmds = await this.getGlobalCommands();
|
|
216
|
+
const existing = globalCmds.find(c => c.name === cmd.name && c.type === cmd.type);
|
|
217
|
+
if (existing) {
|
|
218
|
+
await this.rest.patch(discord_js_1.Routes.applicationCommand(Bot_1.Bot.config.clientId, existing.id), { body: data });
|
|
219
|
+
Log_1.Log.info(`🔄 MAJ ${cmd.name} → GLOBAL`);
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
await this.rest.post(discord_js_1.Routes.applicationCommands(Bot_1.Bot.config.clientId), { body: data });
|
|
223
|
+
Log_1.Log.info(`✅ NEW ${cmd.name} → GLOBAL`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
Log_1.Log.error(`❌ ${cmd.name}: ${error}`);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
/** 📊 LISTE TOUT */
|
|
232
|
+
async listAll() {
|
|
233
|
+
const globalCmds = await this.getGlobalCommands();
|
|
234
|
+
Log_1.Log.table([{ Type: `${this.name} GLOBAL`, Nombre: globalCmds.length }]);
|
|
235
|
+
this.currentState = 'menu';
|
|
236
|
+
await this.showMenu();
|
|
237
|
+
}
|
|
238
|
+
/** 📊 LISTE GUILDE */
|
|
239
|
+
async listGuild(guildId) {
|
|
240
|
+
if (!guildId) {
|
|
241
|
+
Log_1.Log.error('ID guilde requis');
|
|
242
|
+
this.currentState = 'menu';
|
|
243
|
+
await this.showMenu();
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
const guildCmds = await this.getGuildCommands(guildId);
|
|
247
|
+
Log_1.Log.table([{ Guilde: guildId.slice(-8), [`${this.name}`]: guildCmds.length }]);
|
|
248
|
+
this.currentState = 'menu';
|
|
249
|
+
await this.showMenu();
|
|
250
|
+
}
|
|
251
|
+
/** 📋 MENU PRINCIPAL */
|
|
252
|
+
async showMenu() {
|
|
253
|
+
console.log(`\n${this.name}:`);
|
|
254
|
+
console.log(' deploy → Déployer spécifique');
|
|
255
|
+
console.log(' deploy-all → Tout déployer/MAJ');
|
|
256
|
+
console.log(' list → Lister toutes');
|
|
257
|
+
console.log(' list-guild <id> → Lister guilde');
|
|
258
|
+
console.log(' delete → Supprimer une');
|
|
259
|
+
console.log(' delete-all → Tout supprimer');
|
|
260
|
+
console.log(' help → Cette aide');
|
|
261
|
+
console.log(' exit → Quitter\n');
|
|
262
|
+
}
|
|
263
|
+
// ... [Toutes les autres méthodes restent EXACTEMENT identiques] ...
|
|
264
|
+
/** ⏱️ DELAY */
|
|
265
|
+
async delay(ms) {
|
|
266
|
+
return new Promise(r => setTimeout(r, ms));
|
|
267
|
+
}
|
|
268
|
+
/** 🌍 GLOBAL CMDS */
|
|
269
|
+
async getGlobalCommands() {
|
|
270
|
+
return this.rest.get(discord_js_1.Routes.applicationCommands(Bot_1.Bot.config.clientId));
|
|
271
|
+
}
|
|
272
|
+
/** 🏛️ GUILD CMDS */
|
|
273
|
+
async getGuildCommands(guildId) {
|
|
274
|
+
return this.rest.get(discord_js_1.Routes.applicationGuildCommands(Bot_1.Bot.config.clientId, guildId));
|
|
275
|
+
}
|
|
276
|
+
/** 🔐 PERMISSIONS */
|
|
277
|
+
async processPermissions(cmd) {
|
|
278
|
+
const processed = { ...cmd };
|
|
279
|
+
if (cmd.default_member_permissions && Array.isArray(cmd.default_member_permissions)) {
|
|
280
|
+
const bitfield = cmd.default_member_permissions
|
|
281
|
+
.map(perm => BigInt(discord_js_1.PermissionFlagsBits[perm] || 0))
|
|
282
|
+
.reduce((acc, val) => acc | val, BigInt(0));
|
|
283
|
+
processed.default_member_permissions = Number(bitfield);
|
|
284
|
+
}
|
|
285
|
+
return processed;
|
|
286
|
+
}
|
|
287
|
+
/** 🗑️ DELETE UNE COMMANDE */
|
|
288
|
+
async deleteCommand(name) {
|
|
289
|
+
const globalCmds = await this.getGlobalCommands();
|
|
290
|
+
const globalMatch = globalCmds.find(c => c.name === name);
|
|
291
|
+
if (globalMatch) {
|
|
292
|
+
await this.rest.delete(discord_js_1.Routes.applicationCommand(Bot_1.Bot.config.clientId, globalMatch.id));
|
|
293
|
+
Log_1.Log.info(`✅ SUPPR GLOBAL ${name}`);
|
|
294
|
+
}
|
|
295
|
+
const botGuilds = Bot_1.Bot.client.guilds.cache.map(g => g.id);
|
|
296
|
+
for (const guildId of botGuilds) {
|
|
297
|
+
try {
|
|
298
|
+
const guildCmds = await this.getGuildCommands(guildId);
|
|
299
|
+
const guildMatch = guildCmds.find(c => c.name === name);
|
|
300
|
+
if (guildMatch) {
|
|
301
|
+
await this.rest.delete(discord_js_1.Routes.applicationGuildCommand(Bot_1.Bot.config.clientId, guildId, guildMatch.id));
|
|
302
|
+
Log_1.Log.info(`✅ SUPPR ${name} → ${guildId.slice(-4)}`);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
catch {
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
/** 💥 DELETE TOUS */
|
|
310
|
+
async deleteAllCommands() {
|
|
311
|
+
const globalCmds = await this.getGlobalCommands();
|
|
312
|
+
for (const cmd of globalCmds) {
|
|
313
|
+
await this.rest.delete(discord_js_1.Routes.applicationCommand(Bot_1.Bot.config.clientId, cmd.id));
|
|
314
|
+
Log_1.Log.info(`🗑️ SUPPR GLOBAL ${cmd.name}`);
|
|
315
|
+
await this.delay(100);
|
|
316
|
+
}
|
|
317
|
+
const botGuilds = Bot_1.Bot.client.guilds.cache.map(g => g.id);
|
|
318
|
+
for (const guildId of botGuilds) {
|
|
319
|
+
try {
|
|
320
|
+
const guildCmds = await this.getGuildCommands(guildId);
|
|
321
|
+
for (const cmd of guildCmds) {
|
|
322
|
+
await this.rest.delete(discord_js_1.Routes.applicationGuildCommand(Bot_1.Bot.config.clientId, guildId, cmd.id));
|
|
323
|
+
Log_1.Log.info(`🗑️ SUPPR ${cmd.name} → ${guildId.slice(-4)}`);
|
|
324
|
+
await this.delay(100);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
catch {
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
Log_1.Log.info('✅ TOUT SUPPRIMÉ !');
|
|
331
|
+
}
|
|
332
|
+
/** 🧹 NETTOYAGE */
|
|
333
|
+
async cleanup(globalCmds, localCmds) {
|
|
334
|
+
const localNames = localCmds.map(c => `${c.name}_${c.type}`);
|
|
335
|
+
for (const cmd of globalCmds.filter(c => !localNames.includes(`${c.name}_${c.type}`))) {
|
|
336
|
+
await this.rest.delete(discord_js_1.Routes.applicationCommand(Bot_1.Bot.config.clientId, cmd.id));
|
|
337
|
+
Log_1.Log.info(`🗑️ SUPPR ${cmd.name}`);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
exports.InteractionBase = InteractionBase;
|