Skip to content

Commit 4691b7f

Browse files
committed
updated index + README + name of project
changed order of func parameters due to an optional param was in front of a required one and some other things that are too complex. just see the code
1 parent 87f1093 commit 4691b7f

3 files changed

Lines changed: 120 additions & 94 deletions

File tree

README.md

Lines changed: 74 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -64,25 +64,28 @@ module.exports = {
6464
### Deploy the commands
6565

6666
```js
67-
const { Events, GatewayIntentBits } = require("discord.js");
68-
// Name it whatever you want
69-
const Client = require("djs-command-deployer");
70-
const { join: pathJoin } = require("node:path");
71-
require("dotenv").config();
67+
// Don't forget to load all things from discord.js
7268

73-
// Set up your client ; use the guide for example (https://discordjs.guide/creating-your-bot/main-file)
69+
const { deployCommands } = require("djs-command-deployer");
70+
const path = require("node:path");
71+
require("dotenv").config(); // load your token and app's id
7472

75-
// Create a new client instance
76-
let client = new Client({ intents: [GatewayIntentBits.Guilds] });
73+
// Set up your client
74+
// Use the guide as an example if you need help
75+
// https://discordjs.guide/creating-your-bot/main-file
7776

78-
// When the client is ready, run this code (only once).
77+
// When the client is ready, run this code once.
7978
client.once(Events.ClientReady, (readyClient) => {
8079
console.log(`Ready! Logged in as ${readyClient.user.tag}`);
8180

8281
// Call deployCommands to refresh your commands
83-
readyClient.deployCommands(
84-
pathJoin(__dirname, "commands", "utility")
85-
// Optional: logOptions object
82+
deployCommands(
83+
path.join(__dirname, "commands", "utility")
84+
{
85+
appToken: process.env.DISCORD_TOKEN,
86+
appId: process.env.ClientId,
87+
}
88+
// logs are optional
8689
);
8790
});
8891

@@ -92,29 +95,65 @@ client.login(process.env.DISCORD_TOKEN);
9295

9396
### Delete a guild-command
9497

95-
There are two options to do this: Either with the command's ID or his name.
98+
The name of a command of an application is unique, but only in its type.
99+
Make sure that **you** have command's id and not it's name.
96100

97-
In this example we are building a manager-command that has StringOptions for the command and the guild id where one can paste in the ID or the name.\
101+
In this example we are building a manager-command that has StringOptions for the command and the guild id where one can paste in the ID or the name.
98102

99-
Please see [the example code](https://github.com/The-LukeZ/djs-command-deployer-tests/blob/main/commands/command.js) for the command file and the [`index.js`](https://github.com/The-LukeZ/djs-command-deployer-tests/blob/main/index.js) on how to do this in general.
103+
````js
104+
const { SlashCommandBuilder, EmbedBuilder } = require("discord.js");
105+
const { deleteCommand } = require("djs-command-helper");
100106

101-
#### `logOptions`
102-
103-
| Option name | Description / Example | Default |
104-
| ----------- | ------------------------------------------------ | ------- |
105-
| `status` | Logs like `Started refreshing X global commands` | `true` |
106-
| `ignored` | Logs like `Command 'user' ignored` | `true` |
107-
| `created` | Logs like `Created 'user'` | `true` |
108-
| `updated` | Logs like `Updated 'user'` | `true` |
109-
| `deleted` | Logs like `Deleted 'user'` | `true` |
110-
| `noLogs` | No logs at all (besides errors) | `false` |
111-
112-
### TODO
113-
114-
- [ ] L94 | Fix that currentCommands is correct (currently doesn't work and therefore checking for current commands doesn't really work)
115-
116-
- [ ] L166 | Add support for sharding
117-
118-
- [ ] Finish `this.deleteCommand`
119-
120-
Feel free to help me with the TODOs, I will merge any useful pull requests :)
107+
module.exports = {
108+
guildIds: ["1114825999155200101"],
109+
data: new SlashCommandBuilder()
110+
.setName("manage-commands")
111+
.setDescription("Replies with Pong!")
112+
.addStringOption((op) =>
113+
op
114+
.setName("command-id")
115+
.setDescription(
116+
"The ID of the command to be removed"
117+
)
118+
)
119+
.addStringOption((op) =>
120+
op
121+
.setName("server-id")
122+
.setDescription("The ID of the server from which the command is to be removed")
123+
),
124+
125+
// This function is called whenever an interactionCreate event is triggered.
126+
async run(interaction) {
127+
const guildId = interaction.options.getString("server-id");
128+
const command = interaction.options.getString("command-id");
129+
await interaction.deferReply({ ephemeral: true }); // Defer to remove the risk of not responding in time
130+
131+
132+
try {
133+
const response = await deleteCommand(command, {
134+
appToken: interaction.client.token,
135+
appId: interaction.application.id,
136+
guildId: guildId,
137+
});
138+
} catch (err) { // respond with an error if the operation fails in some way
139+
return await interaction.editReply({
140+
embeds: [
141+
new EmbedBuilder()
142+
.setTitle("❌ Command not deleted due to an error")
143+
.setDescription("```" + err + "```")
144+
.setColor(0xee0000),
145+
],
146+
});
147+
}
148+
149+
// Success!
150+
await interaction.editReply({
151+
embeds: [
152+
new EmbedBuilder()
153+
.setTitle("✅ Command deleted")
154+
.setColor(0x44ff44),
155+
],
156+
});
157+
},
158+
};
159+
````

index.js

Lines changed: 45 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -18,28 +18,41 @@ const Routes = {
1818
};
1919

2020
/**
21-
* @typedef {Object} ClientData
22-
* @property {string} token - The token of your Discord bot.
23-
* @property {string} id - The ID of your Discord bot.
21+
* @typedef {Object} deployOptions
22+
* @property {string} appToken - The token of your Discord bot.
23+
* @property {string} appId - The ID of your Discord bot.
24+
* @property {boolean?} logs Whether to log what command was ignored, created, updated or deleted
2425
*/
2526

27+
/**
28+
* @typedef {Object} DeleteOptions
29+
* @property {string} appToken The token of your Discord bot.
30+
* @property {string} appId The ID of your Discord bot.
31+
* @property {string | null} guildId The guild's ID to delete the command in (not needed for a global command)
32+
*/
33+
34+
const DEFAULT_OPTS = {
35+
appToken: "",
36+
appId: "",
37+
logs: true,
38+
};
39+
2640
/**
2741
* Create, update and delete global and guild application commands.
2842
*
2943
* To update guild-specific commands correctly, make sure the bot is logged in.\
3044
* Otherwise the check for a guild ID is omitted, and you could make pointless requests which can also result in an error
3145
*
3246
* @param {string} folderPath The absolute path to your commands folder (the command files have to be directly in it!)
33-
* @param {boolean} logs Whether to log what command was ignored, created, updated or deleted
34-
* @param {ClientData} clientDetails The client's details
47+
* @param {deployOptions} opts the appId, appToken and if the actions should be logged
3548
* @returns {Promise<boolean>} `true` if the operation was successfull. Otherwise `false`.
3649
*/
3750
module.exports.deployCommands = async function deployCommands(
3851
folderPath,
39-
logs = false,
40-
clientDetails
52+
opts = DEFAULT_OPTS
4153
) {
42-
const clientId = clientDetails.id;
54+
opts = Object.assign({}, DEFAULT_OPTS, opts || {});
55+
const clientId = opts.appId;
4356

4457
let commands = [];
4558
let privateCommands = [];
@@ -48,7 +61,8 @@ module.exports.deployCommands = async function deployCommands(
4861
file.endsWith(".js")
4962
);
5063

51-
if (logs) console.log(`🔁 Started refreshing global and guild commands.`);
64+
if (opts.logs)
65+
console.log(`🔁 Started refreshing global and guild commands.`);
5266

5367
try {
5468
const currentCommands = await rest.get(Routes.commands(clientId));
@@ -66,7 +80,7 @@ module.exports.deployCommands = async function deployCommands(
6680
);
6781
continue;
6882
} else if ("data" in command && Boolean(command.ignore ?? false)) {
69-
if (logs)
83+
if (opts.logs)
7084
console.log(`- Command '${command.name}' is ignored!`);
7185
continue;
7286
}
@@ -81,19 +95,20 @@ module.exports.deployCommands = async function deployCommands(
8195
}
8296
}
8397

84-
const rest = new REST().setToken(clientDetails.token);
98+
const rest = new REST().setToken(opts.token);
8599

86100
let data;
87101

88102
data = await rest.put(Routes.commands(clientId), { body: commands });
89-
if (logs) console.log(`✅ Global commands '${data.length}' refreshed`);
103+
if (opts.logs)
104+
console.log(`✅ Global commands '${data.length}' refreshed`);
90105

91106
for (let cmd of privateCommands) {
92107
for (let gid of cmd.guildIds) {
93108
data = await rest.post(Routes.guildCommands(clientId, gid), {
94109
body: cmd.data,
95110
});
96-
if (logs)
111+
if (opts.logs)
97112
console.log(`✅ Guild command '${data.name}' refreshed`);
98113
}
99114
}
@@ -107,51 +122,23 @@ module.exports.deployCommands = async function deployCommands(
107122
/**
108123
* Shortcut method to delete an application command by its name or ID. **The client needs to be logged in!**
109124
*
110-
* @param {string} command The commands's name or ID
111-
* @param {string | null} guildId The guild's ID to delete the command in (not needed for a global command)
112-
* @param {ClientData} clientDetails The client's details
113-
* @returns {Promise<boolean>} `true` if the operation was successfull. Otherwise `false`.
125+
* @param {string} commandId The commands id. Note, that command names can only be unique among their command type.
126+
* @param {DeleteOptions} opts the bot's token, ID and the guildId (if applicable)
127+
* @returns {Promise<void>}
114128
*/
115-
module.exports.deleteCommand = async function deleteCommand(
116-
command,
117-
guildId = null,
118-
clientDetails
119-
) {
120-
const commandPath = (cmdId, guildId = null) => {
121-
if (guildId)
122-
return Routes.guildCommand(clientDetails.id, guildId, cmdId);
123-
return Routes.command(clientDetails.id, cmdId);
124-
};
125-
126-
try {
127-
const rest = new REST().setToken(clientDetails.token);
128-
129-
if (/^\d+$/i.test(command)) {
130-
await rest.delete(commandPath(command, guildId));
131-
} else {
132-
const theCommand =
133-
this.application.commands.cache.get(command) ??
134-
(await this.application.commands.fetch({
135-
guildId: guildId,
136-
cache: true,
137-
}));
138-
139-
if (!theCommand) {
140-
console.error(
141-
`❌ Command '${command}' not found in guild '${guildId}'`
142-
);
143-
return;
144-
}
145-
146-
await rest.delete(commandPath(theCommand.id, guildId));
147-
if (logs) console.log(`✅ Guild command '${data.name}' deleted`);
148-
}
149-
return true;
150-
} catch (err) {
151-
console.error(
152-
`❌ Error while deleting a command in guild '${guildId}':`,
153-
err
154-
);
155-
return false;
129+
module.exports.deleteCommand = async function deleteCommand(commandId, opts) {
130+
const guildId = opts.guildId ?? null;
131+
132+
const commandPath = guildId
133+
? Routes.guildCommand(opts.appId, guildId, commandId)
134+
: Routes.command(opts.appId, commandId);
135+
136+
if (commandId.match(/^\d+$/i)) {
137+
await new REST()
138+
.setToken(opts.appToken)
139+
.delete(commandPath(commandId, guildId));
140+
} else {
141+
throw new Error("command id is not a bigInt!");
156142
}
143+
return;
157144
};

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "djs-command-deployer",
2+
"name": "djs-command-helper",
33
"version": "2.0.0",
44
"description": "",
55
"main": "./index.js",

0 commit comments

Comments
 (0)