Skip to content

Commit 566207e

Browse files
committed
complete command, event, and validation mdx
1 parent dfb0cf0 commit 566207e

File tree

10 files changed

+320
-18
lines changed

10 files changed

+320
-18
lines changed

apps/nextra-docs/pages/_meta.json

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,7 @@
33
"title": "Home",
44
"type": "page"
55
},
6-
"docs": {
7-
"title": "Documentation",
8-
"type": "page"
9-
},
10-
"typedef": {
11-
"title": "Typedefs",
12-
"type": "page"
13-
}
6+
"docs": "Documentation",
7+
"typedef": "Typedefs",
8+
"enums": "Enums"
149
}

apps/nextra-docs/pages/docs/command-file-setup.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Tabs } from 'nextra/components';
44

55
CommandKit supports both slash commands and context menu commands. Since both have the same triggers (interactions) and similar command structure, they are both stored and handled from the same commands directory.
66

7-
### Slash Command
7+
## Slash Command
88

99
Here's an example `/ping` slash command which replies with "Pong!"
1010

@@ -76,7 +76,7 @@ Here's an example `/ping` slash command which replies with "Pong!"
7676

7777
</Tabs>
7878

79-
### Context Menu Command
79+
## Context Menu Command
8080

8181
Here's an example `content` command which replies with the content of the target message.
8282

apps/nextra-docs/pages/docs/commandkit-setup.mdx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,7 @@ This is a simple overview of how to set up CommandKit with all the available opt
9696
9797
</Tabs>
9898
99-
<Callout>
100-
**Note:** Some Discord.js properties are only accessible using the correct intents.
101-
</Callout>
99+
<Callout>Some Discord.js properties are only accessible using the correct intents.</Callout>
102100
103101
## CommandKit options
104102
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,163 @@
11
# Events Setup
2+
3+
import { Tabs } from 'nextra/components';
4+
5+
This is a simple overview of how to set up a simple function that is called when the "ready" event is triggered. All this code does is log to the console when the bot is ready.
6+
7+
<Tabs items={['CommonJS', 'ESM', 'TypeScript']}>
8+
<Tabs.Tab>
9+
```js filename="events/ready/console-log.js" copy
10+
module.exports = (c, client, handler) => {
11+
console.log(`${c.user.username} is ready!`);
12+
};
13+
```
14+
</Tabs.Tab>
15+
16+
<Tabs.Tab>
17+
```js filename="events/ready/console-log.js" copy
18+
export default function (c, client, handler) {
19+
console.log(`${c.user.username} is ready!`);
20+
};
21+
```
22+
</Tabs.Tab>
23+
24+
<Tabs.Tab>
25+
```ts filename="events/ready/console-log.ts" copy
26+
import type { Client } from 'discord.js';
27+
import type { CommandKit } from 'commandkit';
28+
29+
export default function (c: Client<true>, client: Client<true>, handler: CommandKit) {
30+
console.log(`${c.user.username} is ready!`);
31+
};
32+
```
33+
</Tabs.Tab>
34+
35+
</Tabs>
36+
37+
## Parameters explained
38+
39+
The parameters might look a bit confusing at first, but they're actually quite simple. The first parameter `c` is the client object that was returned as a parameter when the "ready" event was triggered. The second parameter `client` is the Discord.js client that was instantiated in your main entry point file. Finally, the `handler` parameter is the current CommandKit instance.
40+
41+
To better understand how the parameters work, here's another example but with the "messageCreate" event listener.
42+
43+
<Tabs items={['CommonJS', 'ESM', 'TypeScript']}>
44+
<Tabs.Tab label="CommonJS">
45+
```js filename="events/messageCreate/say-hi.js" copy
46+
module.exports = (message, client) => {
47+
if (message.content === 'hey') {
48+
message.reply('Hi!');
49+
}
50+
};
51+
```
52+
</Tabs.Tab>
53+
54+
<Tabs.Tab label="ESM">
55+
```js filename="events/messageCreate/say-hi.js" copy
56+
export default function (message, client, handler) {
57+
if (message.content === 'hey') {
58+
message.reply('Hi!');
59+
}
60+
};
61+
```
62+
</Tabs.Tab>
63+
64+
<Tabs.Tab label="TypeScript">
65+
```ts filename="events/messageCreate/say-hi.ts" copy
66+
import type { Message, Client } from 'discord.js';
67+
import type { CommandKit } from 'commandkit';
68+
69+
export default function (message: Message<true>, client: Client<true>, handler: CommandKit) {
70+
if (message.content === 'hey') {
71+
message.reply('Hi!');
72+
}
73+
};
74+
```
75+
</Tabs.Tab>
76+
77+
</Tabs>
78+
79+
In this example you can see that the first parameter is the `message` object that was returned as a parameter when the "messageCreate" event was triggered. The `client` parameter is the same as the previous example.
80+
81+
## Multiple parameters explained
82+
83+
But what if an event returns multiple parameters? Let's take for example the "messageUpdate" event. This event returns two parameters, `oldMessage` and `newMessage`. The parameters will follow the same behaviour as if you were using the `client.on()` method.
84+
85+
<Tabs items={['CommonJS', 'ESM', 'TypeScript']}>
86+
<Tabs.Tab label="CommonJS">
87+
```js filename="events/messageUpdate/log-message-update.js" copy
88+
module.exports = (oldMessage, newMessage, client) => {
89+
console.log(`Message edited from ${oldMessage.content} to ${newMessage.content}`);
90+
};
91+
```
92+
</Tabs.Tab>
93+
94+
<Tabs.Tab label="ESM">
95+
```js filename="events/messageUpdate/log-message-update.js" copy
96+
export default function (oldMessage, newMessage, client) {
97+
console.log(`Message edited from ${oldMessage.content} to ${newMessage.content}`);
98+
};
99+
```
100+
</Tabs.Tab>
101+
102+
<Tabs.Tab label="TypeScript">
103+
```ts filename="events/messageUpdate/log-message-update.ts" copy
104+
import type { Message, PartialMessage } from 'discord.js';
105+
import type { CommandKit } from 'commandkit';
106+
107+
export default function (oldMessage: Message<boolean> | PartialMessage, newMessage: Message<boolean> | PartialMessage, client: Client<true>, handler: CommandKit) {
108+
console.log(`Message edited from ${oldMessage.content} to ${newMessage.content}`);
109+
};
110+
```
111+
</Tabs.Tab>
112+
113+
</Tabs>
114+
115+
As you can see, even with multiple parameters, the last parameter will always be the `client` object.
116+
117+
## Stopping the event loop
118+
119+
The code above is just a simple example of how to set up an event function. But what if you want to stop the next event function in line from running? This is where the `return` statement comes in handy.
120+
121+
<Tabs items={['CommonJS', 'ESM', 'TypeScript']}>
122+
<Tabs.Tab label="CommonJS">
123+
```js filename="events/messageCreate/say-hi.js" copy
124+
module.exports = (message, client) => {
125+
if (message.content === 'hey') {
126+
message.reply('Hi!')
127+
128+
return true // This stops the event loop
129+
}
130+
}
131+
```
132+
</Tabs.Tab>
133+
134+
<Tabs.Tab label="ESM">
135+
```js filename="events/messageCreate/say-hi.js" copy
136+
export default function (message, client) {
137+
if (message.content === 'hey') {
138+
message.reply('Hi!')
139+
140+
return true // This stops the event loop
141+
}
142+
}
143+
```
144+
</Tabs.Tab>
145+
146+
<Tabs.Tab label="TypeScript">
147+
```js filename="events/messageCreate/say-hi.ts" copy
148+
import type { Message, Client } from 'discord.js';
149+
import type { CommandKit } from 'commandkit';
150+
151+
export default function (message: Message<true>, client: Client<true>, handler: CommandKit) {
152+
if (message.content === 'hey') {
153+
message.reply('Hi!')
154+
155+
return true // This stops the event loop
156+
}
157+
}
158+
```
159+
</Tabs.Tab>
160+
161+
</Tabs>
162+
163+
You can return any truthy value from this function to stop the next event function from running.
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,88 @@
1+
import { Tabs, Callout } from 'nextra/components';
2+
13
# Validations Setup
4+
5+
Validations are functions that are called before the `run()` function from a command object is called. They can be used for many things, including validating your command object, or even implementing features such as cooldowns where the user will not be able to run the command if a validation functions says so.
6+
7+
Validation functions are called on every command trigger, so it's important to keep them as lightweight as possible.
8+
9+
<Callout>
10+
Custom validation functions are called before the built-in validations provided by CommandKit.
11+
This provides you with more control over the flow of commands.
12+
</Callout>
13+
14+
<Tabs items={['CommonJS', 'ESM', 'TypeScript']}>
15+
<Tabs.Tab label="CommonJS">
16+
```js
17+
// validations/cooldowns.js
18+
const cooldowns = require('../cooldowns-cache');
19+
20+
module.exports = ({ interaction, commandObj, handler }) => {
21+
if (cooldowns.has(`${interaction.user.id}-${commandObj.data.name}`)) {
22+
interaction.reply({
23+
content: "You're on cooldown, please wait some time before running this command again.",
24+
ephemeral: true,
25+
});
26+
27+
return true; // This is important
28+
}
29+
};
30+
```
31+
</Tabs.Tab>
32+
33+
<Tabs.Tab label="ESM">
34+
```js
35+
// validations/cooldowns.js
36+
import cooldowns from '../cooldowns-cache';
37+
38+
export default function ({ interaction, commandObj, handler }) {
39+
if (cooldowns.has(`${interaction.user.id}-${commandObj.data.name}`)) {
40+
interaction.reply({
41+
content: "You're on cooldown, please wait some time before running this command again.",
42+
ephemeral: true,
43+
});
44+
45+
return true; // This is important
46+
}
47+
};
48+
```
49+
</Tabs.Tab>
50+
51+
<Tabs.Tab label="TypeScript">
52+
```js
53+
// validations/cooldowns.js
54+
import type { ValidationFunctionProps } from 'commandkit';
55+
import cooldowns from '../cooldowns-cache';
56+
57+
export default function ({ interaction, commandObj, handler }: ValidationFunctionProps) {
58+
if (cooldowns.has(`${interaction.user.id}-${commandObj.data.name}`)) {
59+
interaction.reply({
60+
content: "You're on cooldown, please wait some time before running this command again.",
61+
ephemeral: true,
62+
});
63+
64+
return true; // This is important
65+
}
66+
};
67+
```
68+
</Tabs.Tab>
69+
70+
</Tabs>
71+
72+
### Parameters explained
73+
74+
Within every validation function, you have the ability to check what command is trying to be executed using `commandObj` and the `interaction` object from the parameters and respond accordingly.
75+
76+
The `commandObj` object is what's being exported from your command file (excluding the `run()` function). This means you can access the `data` and `options` property from within your validation function.
77+
78+
The `handler` object is your [CommandKit instance](/api/classes/classcommandkit/).
79+
80+
### Stopping the command from running
81+
82+
You may notice that the code above is returning `true`. This is important as it tells the command handler to not run any other validations and to not run the command. If you do not return `true` (or any truthy value), the command will run as normal.
83+
84+
<Callout type="warning">
85+
Interactions (commands in this case) must be handled within 5 seconds, so make sure your
86+
validations are not using up much of that time. If you're using a database or an external API,
87+
it's recommended to implement caching to keep things quick.
88+
</Callout>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# CommandType
2+
3+
### ChatInput
4+
5+
- Value: `1`
6+
7+
### User
8+
9+
- Value: `2`
10+
11+
### Message
12+
13+
- Value: `3`
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"CommandType": "CommandType"
3+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,37 @@
11
# CommandData
2+
3+
### `default_member_permissions` (optional)
4+
5+
- Type: `string`
6+
7+
### `description`
8+
9+
- Type: `string`
10+
11+
### `description_localizations` (optional)
12+
13+
- Type: [`description_localizations`](https://discord-api-types.dev/api/discord-api-types-v10/interface/APIApplicationCommand#description_localizations)
14+
15+
### `dm_permission` (optional)
16+
17+
- Type: `boolean`
18+
19+
### `name`
20+
21+
- Type: `string`
22+
23+
### `name_localizations` (optional)
24+
25+
- Type: [`name_localizations`](https://discord-api-types.dev/api/discord-api-types-v10/interface/APIApplicationCommand#name_localizations)
26+
27+
### `nsfw` (optional)
28+
29+
- Type: `boolean`
30+
31+
### `options` (optional)
32+
33+
- Type: [`APIApplicationCommand[]`](https://discord-api-types.dev/api/discord-api-types-v10#APIApplicationCommandOption)
34+
35+
### `type` (optional)
36+
37+
- Type: [`CommandType`](/enums/CommandType)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,9 @@
11
# CommandObject
2+
3+
### `data`
4+
5+
- Type: [`CommandData`](/typedef/CommandData)
6+
7+
### `options` (optional)
8+
9+
- Type: [CommandOptions](/typedef/CommandOptions)

0 commit comments

Comments
 (0)