Add slash commands support #20

Merged
Anri merged 5 commits from commands into main 2022-07-03 21:09:58 +02:00
7 changed files with 186 additions and 12 deletions

106
package-lock.json generated
View file

@ -9,6 +9,8 @@
"version": "0.0.1", "version": "0.0.1",
"license": "GPL-3.0-only", "license": "GPL-3.0-only",
"dependencies": { "dependencies": {
"@discordjs/rest": "^0.5.0",
"discord-api-types": "^0.36.0",
"discord.js": "^13.8.1" "discord.js": "^13.8.1"
}, },
"devDependencies": { "devDependencies": {
@ -33,6 +35,11 @@
"node": ">=16.9.0" "node": ">=16.9.0"
} }
}, },
"node_modules/@discordjs/builders/node_modules/discord-api-types": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.33.5.tgz",
"integrity": "sha512-dvO5M52v7m7Dy96+XUnzXNsQ/0npsYpU6dL205kAtEDueswoz3aU3bh1UMoK4cQmcGtB1YRyLKqp+DXi05lzFg=="
},
"node_modules/@discordjs/collection": { "node_modules/@discordjs/collection": {
"version": "0.7.0", "version": "0.7.0",
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.7.0.tgz", "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.7.0.tgz",
@ -41,6 +48,27 @@
"node": ">=16.9.0" "node": ">=16.9.0"
} }
}, },
"node_modules/@discordjs/rest": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-0.5.0.tgz",
"integrity": "sha512-S4E1YNz1UxgUfMPpMeqzPPkCfXE877zOsvKM5WEmwIhcpz1PQV7lzqlEOuz194UuwOJLLjQFBgQELnQfCX9UfA==",
"dependencies": {
"@discordjs/collection": "^0.7.0",
"@sapphire/async-queue": "^1.3.1",
"@sapphire/snowflake": "^3.2.2",
"discord-api-types": "^0.33.3",
"tslib": "^2.4.0",
"undici": "^5.4.0"
},
"engines": {
"node": ">=16.9.0"
}
},
"node_modules/@discordjs/rest/node_modules/discord-api-types": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.33.5.tgz",
"integrity": "sha512-dvO5M52v7m7Dy96+XUnzXNsQ/0npsYpU6dL205kAtEDueswoz3aU3bh1UMoK4cQmcGtB1YRyLKqp+DXi05lzFg=="
},
"node_modules/@eslint/eslintrc": { "node_modules/@eslint/eslintrc": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz",
@ -99,6 +127,15 @@
"npm": ">=7.0.0" "npm": ">=7.0.0"
} }
}, },
"node_modules/@sapphire/snowflake": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.2.2.tgz",
"integrity": "sha512-ula2O0kpSZtX9rKXNeQMrHwNd7E4jPDJYUXmEGTFdMRfyfMw+FPyh04oKMjAiDuOi64bYgVkOV3MjK+loImFhQ==",
"engines": {
"node": ">=v14.0.0",
"npm": ">=7.0.0"
}
},
"node_modules/@sindresorhus/is": { "node_modules/@sindresorhus/is": {
"version": "4.6.0", "version": "4.6.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
@ -595,9 +632,9 @@
} }
}, },
"node_modules/discord-api-types": { "node_modules/discord-api-types": {
"version": "0.33.5", "version": "0.36.0",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.33.5.tgz", "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.36.0.tgz",
"integrity": "sha512-dvO5M52v7m7Dy96+XUnzXNsQ/0npsYpU6dL205kAtEDueswoz3aU3bh1UMoK4cQmcGtB1YRyLKqp+DXi05lzFg==" "integrity": "sha512-bazR7FWko6JY4xwoa4Ds4SCRTKGvbzq2ivAuZxiR79RJipU+IXYNvy4tiUt8ixcs2bI04JOQwgHvz491lruBaw=="
}, },
"node_modules/discord.js": { "node_modules/discord.js": {
"version": "13.8.1", "version": "13.8.1",
@ -619,6 +656,11 @@
"npm": ">=7.0.0" "npm": ">=7.0.0"
} }
}, },
"node_modules/discord.js/node_modules/discord-api-types": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.33.5.tgz",
"integrity": "sha512-dvO5M52v7m7Dy96+XUnzXNsQ/0npsYpU6dL205kAtEDueswoz3aU3bh1UMoK4cQmcGtB1YRyLKqp+DXi05lzFg=="
},
"node_modules/doctrine": { "node_modules/doctrine": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
@ -2037,6 +2079,14 @@
"integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
"dev": true "dev": true
}, },
"node_modules/undici": {
"version": "5.6.0",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.6.0.tgz",
"integrity": "sha512-mc+8SY1fXubTrdx4CXDkeFFGV8lI3Tq4I/70U1V8Z6g4iscGII0uLO7CPnDt56bXEbvaKwo2T2+VrteWbZiXiQ==",
"engines": {
"node": ">=12.18"
}
},
"node_modules/unique-string": { "node_modules/unique-string": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",
@ -2252,6 +2302,13 @@
"fast-deep-equal": "^3.1.3", "fast-deep-equal": "^3.1.3",
"ts-mixer": "^6.0.1", "ts-mixer": "^6.0.1",
"tslib": "^2.4.0" "tslib": "^2.4.0"
},
"dependencies": {
"discord-api-types": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.33.5.tgz",
"integrity": "sha512-dvO5M52v7m7Dy96+XUnzXNsQ/0npsYpU6dL205kAtEDueswoz3aU3bh1UMoK4cQmcGtB1YRyLKqp+DXi05lzFg=="
}
} }
}, },
"@discordjs/collection": { "@discordjs/collection": {
@ -2259,6 +2316,26 @@
"resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.7.0.tgz", "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.7.0.tgz",
"integrity": "sha512-R5i8Wb8kIcBAFEPLLf7LVBQKBDYUL+ekb23sOgpkpyGT+V4P7V83wTxcsqmX+PbqHt4cEHn053uMWfRqh/Z/nA==" "integrity": "sha512-R5i8Wb8kIcBAFEPLLf7LVBQKBDYUL+ekb23sOgpkpyGT+V4P7V83wTxcsqmX+PbqHt4cEHn053uMWfRqh/Z/nA=="
}, },
"@discordjs/rest": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-0.5.0.tgz",
"integrity": "sha512-S4E1YNz1UxgUfMPpMeqzPPkCfXE877zOsvKM5WEmwIhcpz1PQV7lzqlEOuz194UuwOJLLjQFBgQELnQfCX9UfA==",
"requires": {
"@discordjs/collection": "^0.7.0",
"@sapphire/async-queue": "^1.3.1",
"@sapphire/snowflake": "^3.2.2",
"discord-api-types": "^0.33.3",
"tslib": "^2.4.0",
"undici": "^5.4.0"
},
"dependencies": {
"discord-api-types": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.33.5.tgz",
"integrity": "sha512-dvO5M52v7m7Dy96+XUnzXNsQ/0npsYpU6dL205kAtEDueswoz3aU3bh1UMoK4cQmcGtB1YRyLKqp+DXi05lzFg=="
}
}
},
"@eslint/eslintrc": { "@eslint/eslintrc": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz",
@ -2303,6 +2380,11 @@
"resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.4.0.tgz", "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-3.4.0.tgz",
"integrity": "sha512-uV+vErdfbxCgnjgcwkPDADlyS40I20L57YPy254LKbRNfLCg4/ymy510aNSGhLhq/dpNU0s1fQnTbI2YAetzsA==" "integrity": "sha512-uV+vErdfbxCgnjgcwkPDADlyS40I20L57YPy254LKbRNfLCg4/ymy510aNSGhLhq/dpNU0s1fQnTbI2YAetzsA=="
}, },
"@sapphire/snowflake": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.2.2.tgz",
"integrity": "sha512-ula2O0kpSZtX9rKXNeQMrHwNd7E4jPDJYUXmEGTFdMRfyfMw+FPyh04oKMjAiDuOi64bYgVkOV3MjK+loImFhQ=="
},
"@sindresorhus/is": { "@sindresorhus/is": {
"version": "4.6.0", "version": "4.6.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
@ -2678,9 +2760,9 @@
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
}, },
"discord-api-types": { "discord-api-types": {
"version": "0.33.5", "version": "0.36.0",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.33.5.tgz", "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.36.0.tgz",
"integrity": "sha512-dvO5M52v7m7Dy96+XUnzXNsQ/0npsYpU6dL205kAtEDueswoz3aU3bh1UMoK4cQmcGtB1YRyLKqp+DXi05lzFg==" "integrity": "sha512-bazR7FWko6JY4xwoa4Ds4SCRTKGvbzq2ivAuZxiR79RJipU+IXYNvy4tiUt8ixcs2bI04JOQwgHvz491lruBaw=="
}, },
"discord.js": { "discord.js": {
"version": "13.8.1", "version": "13.8.1",
@ -2696,6 +2778,13 @@
"form-data": "^4.0.0", "form-data": "^4.0.0",
"node-fetch": "^2.6.1", "node-fetch": "^2.6.1",
"ws": "^8.7.0" "ws": "^8.7.0"
},
"dependencies": {
"discord-api-types": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.33.5.tgz",
"integrity": "sha512-dvO5M52v7m7Dy96+XUnzXNsQ/0npsYpU6dL205kAtEDueswoz3aU3bh1UMoK4cQmcGtB1YRyLKqp+DXi05lzFg=="
}
} }
}, },
"doctrine": { "doctrine": {
@ -3768,6 +3857,11 @@
"integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
"dev": true "dev": true
}, },
"undici": {
"version": "5.6.0",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.6.0.tgz",
"integrity": "sha512-mc+8SY1fXubTrdx4CXDkeFFGV8lI3Tq4I/70U1V8Z6g4iscGII0uLO7CPnDt56bXEbvaKwo2T2+VrteWbZiXiQ=="
},
"unique-string": { "unique-string": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",

View file

@ -15,6 +15,8 @@
"author": "La confrérie du Kassoulait", "author": "La confrérie du Kassoulait",
"license": "GPL-3.0-only", "license": "GPL-3.0-only",
"dependencies": { "dependencies": {
"@discordjs/rest": "^0.5.0",
"discord-api-types": "^0.36.0",
"discord.js": "^13.8.1" "discord.js": "^13.8.1"
}, },
"devDependencies": { "devDependencies": {

37
src/commands/loader.js Normal file
View file

@ -0,0 +1,37 @@
import { REST } from '@discordjs/rest';
import { Routes } from 'discord-api-types/v9';
import { readdir } from 'fs/promises';
export default async client => {
const rest = new REST({ version: '9' }).setToken(client.token);
const command_categories = (await readdir('./src/commands'))
.filter(element => !element.endsWith('.js'));
const commands = (
await Promise.all(
// For each categorie
command_categories.map(async command_category => {
// Retrieve all the commands
const command_files = await readdir(`./src/commands/${command_category}`);
// Add the command
return Promise.all(
command_files.map(async command_file => {
const command = (
await import(`../commands/${command_category}/${command_file}`)
).default;
client.commands.set(command.data.name, command);
return command.data.toJSON();
}),
);
}),
)
).flat(2);
return await rest.put(Routes.applicationCommands(client.user.id), {
body: commands,
});
};

17
src/commands/misc/ping.js Normal file
View file

@ -0,0 +1,17 @@
import { SlashCommandBuilder } from '@discordjs/builders';
export default {
data: new SlashCommandBuilder()
.setName('ping')
.setDescription('Pong!'),
interaction: async (interaction, client) => {
const sent = await interaction.reply({ content: 'Pinging...', fetchReply: true });
interaction.editReply(
`Roundtrip latency: \
${sent.createdTimestamp - interaction.createdTimestamp}ms
Websocket heartbeat: ${client.ws.ping}ms.`);
},
};

View file

@ -0,0 +1,13 @@
export default (interaction, client) => {
if (interaction.isCommand()) {
const command = client.commands.get(interaction.commandName);
if (!command) {
return interaction.reply({
content: 'Désolé la commande n\'existe probablement plus...',
ephemeral: true,
});
}
return command.interaction(interaction, client);
}
};

View file

@ -1,5 +1,6 @@
import loadClient from './utils/client.js'; import loadClient from './utils/client.js';
import loadEvents from './events/loader.js'; import loadEvents from './events/loader.js';
import loadCommands from './commands/loader.js';
const run = async () => { const run = async () => {
console.log('Starting Botanique...'); console.log('Starting Botanique...');
@ -14,19 +15,25 @@ const run = async () => {
.catch(() => { .catch(() => {
throw 'Client ❌'; throw 'Client ❌';
}); });
if (client) {
console.log('Client ✅'); console.log('Client ✅');
}
await loadEvents(client) await loadEvents(client)
.then(() => console.log('Events ✅')) .then(console.log('Events ✅'))
.catch(() => { .catch(() => {
throw 'Events ❌'; throw 'Events ❌';
}); });
await client.login(client.config.token_discord); await client.login(client.config.token_discord);
console.log( await loadCommands(client)
`Botanique "${client.user.username}" ${client.config.version} started!` .then(console.log('Commands ✅'))
); .catch(() => {
throw 'Commands ❌';
});
console.log(`Botanique "${client.user.username}" ${client.config.version} started!`);
}; };
run().catch(error => console.error(error)); run().catch(error => console.error(error));

View file

@ -1,4 +1,4 @@
import { Client, Intents } from 'discord.js'; import { Client, Collection, Intents } from 'discord.js';
import { readFileSync } from 'fs'; import { readFileSync } from 'fs';
const { version } = JSON.parse(readFileSync('./package.json')); const { version } = JSON.parse(readFileSync('./package.json'));
@ -11,10 +11,14 @@ export default async () => {
], ],
}); });
// Store the client configuration
client.config = { client.config = {
version: version, version: version,
token_discord: process.env.TOKEN_DISCORD, token_discord: process.env.TOKEN_DISCORD,
}; };
// Store the commands available
client.commands = new Collection();
return client; return client;
}; };