@spatulox/simplediscordbot 1.0.2 → 1.0.3
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/dist/manager/handlers/builder/ModalManager.js +113 -0
- package/dist/manager/handlers/interactions/BaseInteractionManager.js +338 -0
- package/dist/manager/handlers/interactions/InteractionManager.js +29 -0
- package/handlers/commands/README.md +11 -0
- package/handlers/commands/example.json +144 -0
- package/handlers/commands/example_v2.json +32 -0
- package/handlers/context_menu/example.json +24 -0
- package/handlers/modals/example.json +51 -0
- package/package.json +1 -1
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ModalManager = void 0;
|
|
4
|
+
const discord_js_1 = require("discord.js");
|
|
5
|
+
const FolderName_1 = require("../../../type/FolderName");
|
|
6
|
+
const FileManager_1 = require("../../FileManager");
|
|
7
|
+
class ModalManager {
|
|
8
|
+
/**
|
|
9
|
+
* Load modal from JSON file and return ModalBuilder
|
|
10
|
+
*/
|
|
11
|
+
static async load(filename) {
|
|
12
|
+
try {
|
|
13
|
+
const file = await FileManager_1.FileManager.readJsonFile(`./handlers/${FolderName_1.FolderName.MODAL}/${filename}`);
|
|
14
|
+
if (!file)
|
|
15
|
+
return false;
|
|
16
|
+
return ModalManager.jsonToBuilder(file);
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* List all modal files
|
|
24
|
+
*/
|
|
25
|
+
static async list() {
|
|
26
|
+
try {
|
|
27
|
+
const files = await FileManager_1.FileManager.listJsonFiles(`./handlers/${FolderName_1.FolderName.MODAL}`);
|
|
28
|
+
return files || [];
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
static jsonToBuilder(json) {
|
|
35
|
+
const modal = new discord_js_1.ModalBuilder()
|
|
36
|
+
.setCustomId(json.customId)
|
|
37
|
+
.setTitle(json.title.slice(0, 45));
|
|
38
|
+
const actionRows = [];
|
|
39
|
+
for (const fieldJson of json.fields) {
|
|
40
|
+
const input = this.fieldJsonToInput(fieldJson);
|
|
41
|
+
const row = new discord_js_1.ActionRowBuilder()
|
|
42
|
+
.addComponents(input);
|
|
43
|
+
actionRows.push(row);
|
|
44
|
+
}
|
|
45
|
+
return modal.addComponents(...actionRows);
|
|
46
|
+
}
|
|
47
|
+
static fieldJsonToInput(fieldJson) {
|
|
48
|
+
const input = new discord_js_1.TextInputBuilder()
|
|
49
|
+
.setCustomId(fieldJson.customId)
|
|
50
|
+
.setLabel(fieldJson.title.slice(0, 45))
|
|
51
|
+
.setPlaceholder(fieldJson.placeholder || 'Enter value...')
|
|
52
|
+
.setRequired(fieldJson.required !== false)
|
|
53
|
+
.setMinLength(fieldJson.minLength || 0)
|
|
54
|
+
.setMaxLength(fieldJson.maxLength || 400);
|
|
55
|
+
// Convertir style JSON (1, 2, "Number") → TextInputStyle
|
|
56
|
+
const style = fieldJson.style;
|
|
57
|
+
if (typeof style === 'number') {
|
|
58
|
+
// 1=Short, 2=Paragraph
|
|
59
|
+
input.setStyle(style);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
// "Number", "Phone", "Date"
|
|
63
|
+
switch (style) {
|
|
64
|
+
case 'Number':
|
|
65
|
+
case 'Phone':
|
|
66
|
+
case 'Date':
|
|
67
|
+
input.setStyle(discord_js_1.TextInputStyle.Short);
|
|
68
|
+
input.setPlaceholder(style === 'Number' ? '123' :
|
|
69
|
+
style === 'Phone' ? '+33 6 12 34 56 78' :
|
|
70
|
+
'2024-02-05');
|
|
71
|
+
break;
|
|
72
|
+
default:
|
|
73
|
+
input.setStyle(discord_js_1.TextInputStyle.Short);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return input;
|
|
77
|
+
}
|
|
78
|
+
static parseNumber(value) {
|
|
79
|
+
if (!/^\d+$/.test(value))
|
|
80
|
+
return null;
|
|
81
|
+
const num = parseInt(value);
|
|
82
|
+
return isNaN(num) ? null : num;
|
|
83
|
+
}
|
|
84
|
+
static parsePhone(value) {
|
|
85
|
+
// 0604050359, +33604050359, 06 40 50 35 59, (06) 40-50-35-59
|
|
86
|
+
const clean = value.replace(/[\s\-\(\)]/g, '');
|
|
87
|
+
// Français : 06/07/09 + 8 chiffres OU +33 + 9 chiffres
|
|
88
|
+
if (/^(06|07|09)\d{8}$/.test(clean) || /^(\+33|0033)?[6-9]\d{8}$/.test(clean)) {
|
|
89
|
+
// Normalise au format international
|
|
90
|
+
if (clean.startsWith('06') || clean.startsWith('07') || clean.startsWith('09')) {
|
|
91
|
+
return '+33' + clean.slice(2);
|
|
92
|
+
}
|
|
93
|
+
return clean.startsWith('0033') ? '+33' + clean.slice(4) : clean;
|
|
94
|
+
}
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
static parseDate(value) {
|
|
98
|
+
// yyyy-mm-dd → Date
|
|
99
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(value)) {
|
|
100
|
+
const [year, month, day] = value.split('-').map(Number);
|
|
101
|
+
const date = new Date(year, month - 1, day);
|
|
102
|
+
return isNaN(date.getTime()) ? null : date;
|
|
103
|
+
}
|
|
104
|
+
// dd/mm/yyyy → Date
|
|
105
|
+
if (/^\d{2}\/\d{2}\/\d{4}$/.test(value)) {
|
|
106
|
+
const [day, month, year] = value.split('/').map(Number);
|
|
107
|
+
const date = new Date(year, month - 1, day);
|
|
108
|
+
return isNaN(date.getTime()) ? null : date;
|
|
109
|
+
}
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
exports.ModalManager = ModalManager;
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.BaseInteractionManager = exports.CommandType = void 0;
|
|
38
|
+
const rest_1 = require("@discordjs/rest");
|
|
39
|
+
const v10_1 = require("discord-api-types/v10");
|
|
40
|
+
const discord_js_1 = require("discord.js");
|
|
41
|
+
const fs = __importStar(require("fs/promises"));
|
|
42
|
+
const FileManager_1 = require("../../FileManager");
|
|
43
|
+
const Log_1 = require("../../../utils/Log");
|
|
44
|
+
var CommandType;
|
|
45
|
+
(function (CommandType) {
|
|
46
|
+
CommandType[CommandType["SLASH"] = 1] = "SLASH";
|
|
47
|
+
CommandType[CommandType["USER_CONTEXT_MENU"] = 2] = "USER_CONTEXT_MENU";
|
|
48
|
+
CommandType[CommandType["MESSAGE_CONTEXT_MENU"] = 3] = "MESSAGE_CONTEXT_MENU";
|
|
49
|
+
})(CommandType || (exports.CommandType = CommandType = {}));
|
|
50
|
+
class BaseInteractionManager {
|
|
51
|
+
constructor(clientId, token) {
|
|
52
|
+
this.clientId = clientId;
|
|
53
|
+
this.token = token;
|
|
54
|
+
this.rest = new rest_1.REST({ version: '10' }).setToken(token);
|
|
55
|
+
}
|
|
56
|
+
async listFromFile() {
|
|
57
|
+
console.log(`Listing Handlers (${this.folderPath}) not deployed on discord`);
|
|
58
|
+
try {
|
|
59
|
+
const files = await FileManager_1.FileManager.listJsonFiles(`./handlers/${this.folderPath}`);
|
|
60
|
+
if (!files || files.length === 0) {
|
|
61
|
+
console.log('No files found');
|
|
62
|
+
return [];
|
|
63
|
+
}
|
|
64
|
+
const commandList = [];
|
|
65
|
+
for (const [index, file] of files.entries()) {
|
|
66
|
+
const cmd = await this.readInteraction(`./handlers/${this.folderPath}/${file}`);
|
|
67
|
+
if (!cmd || cmd.id)
|
|
68
|
+
continue;
|
|
69
|
+
const commandWithIndex = {
|
|
70
|
+
...cmd,
|
|
71
|
+
index: index,
|
|
72
|
+
filename: file
|
|
73
|
+
};
|
|
74
|
+
commandList.push(commandWithIndex);
|
|
75
|
+
}
|
|
76
|
+
console.log(`✅ ${commandList.length} local ${this.folderPath}(s) not deployed\n`);
|
|
77
|
+
console.table(commandList.map((cmd) => ({
|
|
78
|
+
'#': cmd.index,
|
|
79
|
+
Nom: cmd.name,
|
|
80
|
+
Type: cmd.type === CommandType.SLASH ? 'Slash' :
|
|
81
|
+
cmd.type === CommandType.USER_CONTEXT_MENU ? 'User' : 'Message',
|
|
82
|
+
Description: cmd.description,
|
|
83
|
+
Fichier: cmd.filename
|
|
84
|
+
})));
|
|
85
|
+
return commandList;
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
Log_1.Log.error(`${error.message}`);
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async fetchCommands(endpoint, scope, guildId, printResult = true) {
|
|
93
|
+
const scopeLabel = scope === 'global' ? 'global' : `guild ${scope}`;
|
|
94
|
+
console.log(`Handlers ${this.folderPath} on Discord (${scopeLabel})...`);
|
|
95
|
+
try {
|
|
96
|
+
const rawCmds = await this.rest.get(endpoint);
|
|
97
|
+
const commands = rawCmds.filter(cmd => this.commandType.includes(cmd.type));
|
|
98
|
+
const commandList = commands.map((cmd, index) => ({
|
|
99
|
+
index: index,
|
|
100
|
+
name: cmd.name,
|
|
101
|
+
type: cmd.type,
|
|
102
|
+
description: cmd.description || 'N/A',
|
|
103
|
+
default_member_permissions: cmd.default_member_permissions,
|
|
104
|
+
default_member_permissions_string: this.bitfieldToPermissions(cmd.default_member_permissions),
|
|
105
|
+
id: cmd.id,
|
|
106
|
+
...(guildId && { guildID: [guildId] })
|
|
107
|
+
}));
|
|
108
|
+
if (printResult) {
|
|
109
|
+
console.log(`✅ ${commandList.length} ${this.folderPath}(s) found\n`);
|
|
110
|
+
console.table(commandList.map((cmd) => ({
|
|
111
|
+
Nom: cmd.name,
|
|
112
|
+
Type: cmd.type === CommandType.SLASH ? 'Slash' :
|
|
113
|
+
cmd.type === CommandType.USER_CONTEXT_MENU ? 'User Context Menu' : 'Message Context Menu',
|
|
114
|
+
Description: cmd.description,
|
|
115
|
+
Permissions: cmd.default_member_permissions_string?.join(", "),
|
|
116
|
+
ID: cmd.id
|
|
117
|
+
})));
|
|
118
|
+
}
|
|
119
|
+
return commandList;
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
const errorMsg = scope === 'global'
|
|
123
|
+
? `❌ Error: ${error.message}`
|
|
124
|
+
: `❌ Guild error ${scope}: ${error.message}`;
|
|
125
|
+
Log_1.Log.error(errorMsg);
|
|
126
|
+
return [];
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
async list() {
|
|
130
|
+
return this.fetchCommands(v10_1.Routes.applicationCommands(this.clientId), 'global');
|
|
131
|
+
}
|
|
132
|
+
async listGuild(guildID) {
|
|
133
|
+
return this.fetchCommands(v10_1.Routes.applicationGuildCommands(this.clientId, guildID), guildID, guildID);
|
|
134
|
+
}
|
|
135
|
+
async listAllGuilds(guilds) {
|
|
136
|
+
console.log("📡 Getting all guilds...\n");
|
|
137
|
+
console.log(`📋 ${guilds.length} guild(s) found\n`);
|
|
138
|
+
if (!guilds.length)
|
|
139
|
+
return [];
|
|
140
|
+
const guildCommandPromises = guilds.map(async (guild) => {
|
|
141
|
+
try {
|
|
142
|
+
const commands = await this.fetchCommands(v10_1.Routes.applicationGuildCommands(this.clientId, guild.id), guild.id, guild.id, false);
|
|
143
|
+
return {
|
|
144
|
+
guild: `${guild.name} (${guild.id})`,
|
|
145
|
+
guildId: guild.id,
|
|
146
|
+
commands,
|
|
147
|
+
count: commands.length
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
console.error(`⚠️ Guild ${guild.id}: ${error.message}`);
|
|
152
|
+
return {
|
|
153
|
+
guild: `${guild.name} (${guild.id})`,
|
|
154
|
+
guildId: guild.id,
|
|
155
|
+
commands: [],
|
|
156
|
+
count: 0
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
const results = await Promise.all(guildCommandPromises);
|
|
161
|
+
console.log("\n📊 INTERACTION PER GUILD :\n");
|
|
162
|
+
console.table(results.map(r => ({
|
|
163
|
+
"Guild": r.guild,
|
|
164
|
+
"Interactions": r.count,
|
|
165
|
+
"Total": r.commands.length
|
|
166
|
+
})));
|
|
167
|
+
return results.filter(r => r.count > 0);
|
|
168
|
+
}
|
|
169
|
+
async deploy(commands) {
|
|
170
|
+
console.log(`Deploying ${commands.length} ${this.folderPath}(s)...`);
|
|
171
|
+
let updatedCount = 0;
|
|
172
|
+
for (const cmd of commands) {
|
|
173
|
+
const file = cmd.filename;
|
|
174
|
+
if (!file) {
|
|
175
|
+
Log_1.Log.error(`${cmd.name}: Not linked to a file (wtf)`);
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
try {
|
|
179
|
+
await this.deploySingleInteraction(cmd, file);
|
|
180
|
+
updatedCount++;
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
Log_1.Log.error(`Error ${file}: ${error.message}`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
console.log(`✅ ${updatedCount}/${commands.length} deployed`);
|
|
187
|
+
}
|
|
188
|
+
async delete(commands) {
|
|
189
|
+
console.log(`Deleting ${commands.length} ${this.folderPath}(s)...`);
|
|
190
|
+
const IDList = [];
|
|
191
|
+
for (const cmd of commands) {
|
|
192
|
+
if (!cmd.id) {
|
|
193
|
+
Log_1.Log.error(`${cmd.name}: No Discord ID, cannot delete the ${this.folderPath}`);
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
IDList.push(cmd.id);
|
|
197
|
+
try {
|
|
198
|
+
await this.rest.delete(v10_1.Routes.applicationCommand(this.clientId, cmd.id));
|
|
199
|
+
console.log(`${cmd.name} (${cmd.id.slice(-8)}) deleted`);
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
Log_1.Log.error(`${cmd.name} (${cmd.id.slice(-8)}): ${error.message}`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
await this.removeLocalIdFromFile(IDList);
|
|
206
|
+
}
|
|
207
|
+
async update(commands) {
|
|
208
|
+
console.log(`Updating ${commands.length} ${this.folderPath}(s)...`);
|
|
209
|
+
for (const cmd of commands) {
|
|
210
|
+
if (!cmd.id) {
|
|
211
|
+
Log_1.Log.error(`${cmd.name}: No Discord ID, cannot update the ${this.folderPath}`);
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
try {
|
|
215
|
+
await this.rest.patch(v10_1.Routes.applicationCommand(this.clientId, cmd.id), {
|
|
216
|
+
body: { description: `${cmd.description} (Updated ${new Date().toISOString()})` }
|
|
217
|
+
});
|
|
218
|
+
console.log(`${cmd.name} updated`);
|
|
219
|
+
}
|
|
220
|
+
catch (error) {
|
|
221
|
+
Log_1.Log.error(`${cmd.name}: ${error.message}`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
async deploySingleInteraction(cmd, file) {
|
|
226
|
+
const deployToGuilds = cmd.guildID?.length ? cmd.guildID : [];
|
|
227
|
+
const dataToSend = { ...cmd };
|
|
228
|
+
delete dataToSend.guildID;
|
|
229
|
+
if (cmd.default_member_permissions_string && Array.isArray(cmd.default_member_permissions_string)) {
|
|
230
|
+
const bitfield = this.permissionsToBitfield(cmd.default_member_permissions_string);
|
|
231
|
+
if (bitfield !== undefined) {
|
|
232
|
+
dataToSend.default_member_permissions = bitfield;
|
|
233
|
+
cmd.default_member_permissions = bitfield;
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
delete dataToSend.default_member_permissions;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (cmd.type === CommandType.MESSAGE_CONTEXT_MENU || cmd.type === CommandType.USER_CONTEXT_MENU) {
|
|
240
|
+
delete dataToSend.options;
|
|
241
|
+
}
|
|
242
|
+
// Guild deployment
|
|
243
|
+
if (deployToGuilds.length > 0) {
|
|
244
|
+
for (const guildId of deployToGuilds) {
|
|
245
|
+
try {
|
|
246
|
+
const guildCmds = await this.rest.get(v10_1.Routes.applicationGuildCommands(this.clientId, guildId));
|
|
247
|
+
const found = guildCmds.find((c) => c.name === cmd.name);
|
|
248
|
+
if (!cmd.id || !found) {
|
|
249
|
+
const resp = await this.rest.post(v10_1.Routes.applicationGuildCommands(this.clientId, guildId), { body: dataToSend });
|
|
250
|
+
cmd.id = resp.id;
|
|
251
|
+
await this.saveInteraction(file, cmd);
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
await this.rest.patch(v10_1.Routes.applicationGuildCommand(this.clientId, guildId, found.id), { body: dataToSend });
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
catch (error) {
|
|
258
|
+
console.error(`⚠️ Guild ${guildId}: ${error.message}`);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
// Global deployment
|
|
264
|
+
try {
|
|
265
|
+
const globalCmds = await this.rest.get(v10_1.Routes.applicationCommands(this.clientId));
|
|
266
|
+
const found = globalCmds.find((c) => c.name === cmd.name);
|
|
267
|
+
if (!cmd.id || !found) {
|
|
268
|
+
const resp = await this.rest.post(v10_1.Routes.applicationCommands(this.clientId), { body: dataToSend });
|
|
269
|
+
cmd.id = resp.id;
|
|
270
|
+
await this.saveInteraction(file, cmd);
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
await this.rest.patch(v10_1.Routes.applicationCommand(this.clientId, found.id), { body: dataToSend });
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
catch (error) {
|
|
277
|
+
console.error(`⚠️ Global: ${error.message}`);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
async readInteraction(filePath) {
|
|
282
|
+
try {
|
|
283
|
+
const data = await fs.readFile(filePath, 'utf8');
|
|
284
|
+
return JSON.parse(data);
|
|
285
|
+
}
|
|
286
|
+
catch {
|
|
287
|
+
return null;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
async saveInteraction(fileName, cmd) {
|
|
291
|
+
delete cmd.filename;
|
|
292
|
+
const filePath = `./handlers/${this.folderPath}/${fileName}`;
|
|
293
|
+
await fs.writeFile(filePath, JSON.stringify(cmd, null, 2));
|
|
294
|
+
}
|
|
295
|
+
async removeLocalIdFromFile(idListToDelete) {
|
|
296
|
+
const files = await FileManager_1.FileManager.listJsonFiles(`./handlers/${this.folderPath}`);
|
|
297
|
+
if (!files || files.length === 0) {
|
|
298
|
+
console.log('No local files to clean');
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
for (const file of files) {
|
|
302
|
+
const filePath = `./handlers/${this.folderPath}/${file}`;
|
|
303
|
+
const localCmd = await this.readInteraction(filePath);
|
|
304
|
+
if (localCmd && localCmd.id && idListToDelete.includes(localCmd.id)) {
|
|
305
|
+
delete localCmd.id;
|
|
306
|
+
await this.saveInteraction(file, localCmd);
|
|
307
|
+
break;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
permissionsToBitfield(perms) {
|
|
312
|
+
if (!perms || perms.length === 0)
|
|
313
|
+
return undefined;
|
|
314
|
+
let bits = 0n;
|
|
315
|
+
for (const name of perms) {
|
|
316
|
+
const value = discord_js_1.PermissionFlagsBits[name];
|
|
317
|
+
if (!value) {
|
|
318
|
+
console.warn(`Unknow permission in default_member_permissions: ${name}`);
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
bits |= value;
|
|
322
|
+
}
|
|
323
|
+
return bits.toString();
|
|
324
|
+
}
|
|
325
|
+
bitfieldToPermissions(bitfield) {
|
|
326
|
+
if (!bitfield)
|
|
327
|
+
return [];
|
|
328
|
+
const bits = BigInt(bitfield);
|
|
329
|
+
const result = [];
|
|
330
|
+
for (const [name, value] of Object.entries(discord_js_1.PermissionFlagsBits)) {
|
|
331
|
+
if ((bits & value) === value) {
|
|
332
|
+
result.push(name);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
return result;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
exports.BaseInteractionManager = BaseInteractionManager;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AllInteractionManager = exports.ContextMenuManager = exports.CommandManager = void 0;
|
|
4
|
+
const BaseInteractionManager_1 = require("./BaseInteractionManager");
|
|
5
|
+
const FolderName_1 = require("../../../type/FolderName");
|
|
6
|
+
class CommandManager extends BaseInteractionManager_1.BaseInteractionManager {
|
|
7
|
+
constructor() {
|
|
8
|
+
super(...arguments);
|
|
9
|
+
this.commandType = [BaseInteractionManager_1.CommandType.SLASH];
|
|
10
|
+
this.folderPath = FolderName_1.FolderName.SLASH_COMMANDS;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.CommandManager = CommandManager;
|
|
14
|
+
class ContextMenuManager extends BaseInteractionManager_1.BaseInteractionManager {
|
|
15
|
+
constructor() {
|
|
16
|
+
super(...arguments);
|
|
17
|
+
this.commandType = [BaseInteractionManager_1.CommandType.USER_CONTEXT_MENU, BaseInteractionManager_1.CommandType.MESSAGE_CONTEXT_MENU];
|
|
18
|
+
this.folderPath = FolderName_1.FolderName.CONTEXT_MENU;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.ContextMenuManager = ContextMenuManager;
|
|
22
|
+
class AllInteractionManager extends BaseInteractionManager_1.BaseInteractionManager {
|
|
23
|
+
constructor() {
|
|
24
|
+
super(...arguments);
|
|
25
|
+
this.commandType = [BaseInteractionManager_1.CommandType.SLASH, BaseInteractionManager_1.CommandType.USER_CONTEXT_MENU, BaseInteractionManager_1.CommandType.MESSAGE_CONTEXT_MENU];
|
|
26
|
+
this.folderPath = undefined;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.AllInteractionManager = AllInteractionManager;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "server-management",
|
|
3
|
+
"type": 1,
|
|
4
|
+
"description": "Manage various aspects of the server",
|
|
5
|
+
"permissions": ["admin", "manage_role", "manage_users"],
|
|
6
|
+
"permissionsComment": "if undefined, or empty, all user gonna have access to the command",
|
|
7
|
+
"options": [
|
|
8
|
+
{
|
|
9
|
+
"type": 2,
|
|
10
|
+
"name": "user",
|
|
11
|
+
"description": "User management commands",
|
|
12
|
+
"options": [
|
|
13
|
+
{
|
|
14
|
+
"type": 1,
|
|
15
|
+
"name": "info",
|
|
16
|
+
"description": "Get information about a user",
|
|
17
|
+
"options": [
|
|
18
|
+
{
|
|
19
|
+
"type": 6,
|
|
20
|
+
"name": "target",
|
|
21
|
+
"description": "The user to get information about",
|
|
22
|
+
"required": true
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"type": 1,
|
|
28
|
+
"name": "role",
|
|
29
|
+
"description": "Manage user roles",
|
|
30
|
+
"options": [
|
|
31
|
+
{
|
|
32
|
+
"type": 6,
|
|
33
|
+
"name": "user",
|
|
34
|
+
"description": "The user to manage roles for",
|
|
35
|
+
"required": true
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"type": 8,
|
|
39
|
+
"name": "role",
|
|
40
|
+
"description": "The role to add or remove",
|
|
41
|
+
"required": true
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"type": 5,
|
|
45
|
+
"name": "add",
|
|
46
|
+
"description": "Add the role if true, remove if false",
|
|
47
|
+
"required": true
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"type": 1,
|
|
55
|
+
"name": "channel",
|
|
56
|
+
"description": "Manage server channels",
|
|
57
|
+
"options": [
|
|
58
|
+
{
|
|
59
|
+
"type": 7,
|
|
60
|
+
"name": "target",
|
|
61
|
+
"description": "The channel to manage",
|
|
62
|
+
"required": true
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"type": 3,
|
|
66
|
+
"name": "action",
|
|
67
|
+
"description": "The action to perform",
|
|
68
|
+
"required": true,
|
|
69
|
+
"choices": [
|
|
70
|
+
{
|
|
71
|
+
"name": "Rename",
|
|
72
|
+
"value": "rename"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"name": "Delete",
|
|
76
|
+
"value": "delete"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"name": "Archive",
|
|
80
|
+
"value": "archive"
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"type": 3,
|
|
86
|
+
"name": "new_name",
|
|
87
|
+
"description": "New name for the channel (only for rename action)",
|
|
88
|
+
"required": false,
|
|
89
|
+
"min_length": 1,
|
|
90
|
+
"max_length": 100
|
|
91
|
+
}
|
|
92
|
+
]
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"type": 1,
|
|
96
|
+
"name": "server-stats",
|
|
97
|
+
"description": "Get server statistics",
|
|
98
|
+
"options": [
|
|
99
|
+
{
|
|
100
|
+
"type": 4,
|
|
101
|
+
"name": "days",
|
|
102
|
+
"description": "Number of days to get stats for",
|
|
103
|
+
"required": false,
|
|
104
|
+
"min_value": 1,
|
|
105
|
+
"max_value": 30
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"type": 10,
|
|
109
|
+
"name": "activity-threshold",
|
|
110
|
+
"description": "Minimum activity level to consider",
|
|
111
|
+
"required": false,
|
|
112
|
+
"min_value": 0.0,
|
|
113
|
+
"max_value": 1.0
|
|
114
|
+
}
|
|
115
|
+
]
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"type": 1,
|
|
119
|
+
"name": "announcement",
|
|
120
|
+
"description": "Make a server announcement",
|
|
121
|
+
"options": [
|
|
122
|
+
{
|
|
123
|
+
"type": 3,
|
|
124
|
+
"name": "message",
|
|
125
|
+
"description": "The announcement message",
|
|
126
|
+
"required": true
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"type": 7,
|
|
130
|
+
"name": "channel",
|
|
131
|
+
"description": "The channel to post the announcement in",
|
|
132
|
+
"required": true,
|
|
133
|
+
"channel_types": [0, 5]
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"type": 11,
|
|
137
|
+
"name": "attachment",
|
|
138
|
+
"description": "An optional attachment for the announcement",
|
|
139
|
+
"required": false
|
|
140
|
+
}
|
|
141
|
+
]
|
|
142
|
+
}
|
|
143
|
+
]
|
|
144
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "example",
|
|
3
|
+
"description": "Description",
|
|
4
|
+
"defaultMemberPermissions": ["Administrator"],
|
|
5
|
+
"dmPermission": false,
|
|
6
|
+
"integration_types":[0,1],
|
|
7
|
+
"integration_type_comment":{
|
|
8
|
+
"0":"GUILD_INSTALL",
|
|
9
|
+
"1":"USER_INSTALL"
|
|
10
|
+
},
|
|
11
|
+
"contexts": [0,1,2],
|
|
12
|
+
"contexts_comment": {
|
|
13
|
+
"0":"Interaction can be used inside server",
|
|
14
|
+
"1":"Interaction can be used inside DMs with the app's bot user",
|
|
15
|
+
"2":"Interaction can be used inside Groups DMs and DMs other than the app bot user"
|
|
16
|
+
},
|
|
17
|
+
"options": [
|
|
18
|
+
{
|
|
19
|
+
"type": 3,
|
|
20
|
+
"name": "parametre",
|
|
21
|
+
"description": "Description paramètre",
|
|
22
|
+
"required": true,
|
|
23
|
+
"choices": [
|
|
24
|
+
{
|
|
25
|
+
"name": "Option 1",
|
|
26
|
+
"value": "valeur1"
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Example context Menu",
|
|
3
|
+
"type": 3,
|
|
4
|
+
"type_comment": [
|
|
5
|
+
"1 => It's like a Slash command",
|
|
6
|
+
"2 => Context Menu for users",
|
|
7
|
+
"3 => Context Menu for messages"
|
|
8
|
+
],
|
|
9
|
+
"default_member_permissions": ["ModerateMembers", "KickMembers", "BanMembers"],
|
|
10
|
+
"default_member_permissions_comment": "It's the same as the PermissionFlagsBits enum from discordjs",
|
|
11
|
+
"dm_permission": false,
|
|
12
|
+
"integration_types": [0, 1],
|
|
13
|
+
"integration_type_comment":{
|
|
14
|
+
"0":"GUILD_INSTALL",
|
|
15
|
+
"1":"USER_INSTALL"
|
|
16
|
+
},
|
|
17
|
+
"contexts": [0, 1, 2],
|
|
18
|
+
"contexts_comment": {
|
|
19
|
+
"0":"Interaction can be used inside server",
|
|
20
|
+
"1":"Interaction can be used inside DMs with the app's bot user",
|
|
21
|
+
"2":"Interaction can be used inside Groups DMs and DMs other than the app bot user"
|
|
22
|
+
},
|
|
23
|
+
"guildID":["1111160769132896377", "1214320754578165901"]
|
|
24
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Example Modal",
|
|
3
|
+
"customId": "example_modal",
|
|
4
|
+
"label": "example_modal",
|
|
5
|
+
"fields": [
|
|
6
|
+
{
|
|
7
|
+
"title": "Name",
|
|
8
|
+
"customId": "name",
|
|
9
|
+
"placeholder": "Name",
|
|
10
|
+
"required": true,
|
|
11
|
+
"style": 1,
|
|
12
|
+
"minLength": 3,
|
|
13
|
+
"maxLength": 100
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"title": "Description",
|
|
17
|
+
"customId": "description",
|
|
18
|
+
"placeholder": "Description",
|
|
19
|
+
"required": true,
|
|
20
|
+
"style": 2,
|
|
21
|
+
"maxLength": 400
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"title": "Phone",
|
|
25
|
+
"customId": "phone",
|
|
26
|
+
"placeholder": "Phone",
|
|
27
|
+
"required": true,
|
|
28
|
+
"style": "Phone",
|
|
29
|
+
"minLength": 10,
|
|
30
|
+
"maxLength": 10
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"title": "Age",
|
|
34
|
+
"customId": "age",
|
|
35
|
+
"placeholder": "Age",
|
|
36
|
+
"required": true,
|
|
37
|
+
"style": "Number",
|
|
38
|
+
"minLength": 1,
|
|
39
|
+
"maxLength": 2
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"title": "Birthday",
|
|
43
|
+
"customId": "birthday",
|
|
44
|
+
"placeholder": "Birthday",
|
|
45
|
+
"required": true,
|
|
46
|
+
"style": "Date",
|
|
47
|
+
"minLength": 10,
|
|
48
|
+
"maxLength": 10
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
}
|