Skip to content

Commit 66dee0a

Browse files
committed
Simplified command API for improved usability and reduced complexity.
1 parent 9070787 commit 66dee0a

9 files changed

+55
-73
lines changed

README.md

+29-1
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ A simple Discord bot integrating OpenAI libraries for ChatGPT and DALL-E, capabl
8787
<li><a href="#embeds">Embeds</a></li>
8888
</ul>
8989
</li>
90+
<li><a href="#commands-api">Commands API</a></li>
9091
<li><a href="#roadmap">Roadmap</a></li>
9192
<li><a href="#contributing">Contributing</a></li>
9293
<li><a href="#license">License</a></li>
@@ -187,7 +188,7 @@ just add the bot to your server and enjoy.
187188
|-------------|-------------------------------------------|----------|-----------|---------------------------------|-------------------------------------|
188189
| `question` | `/chat` | `true` | None | None | The question to ask the bot |
189190
| `prompt` | `/image` | `true` | None | None | The text to generate the image from |
190-
| `quantity` | `/image` | `false` | `100` | `1` to `10` | Quantity of images to generate |
191+
| `quantity` | `/image` | `false` | `1` | `1` to `10` | Quantity of images to generate |
191192
| `size` | `/image` | `false` | `256x256` | `256x256` `512x512` `1024x1024` | Size of the image to generate |
192193
| `amount` | `/clear` | `false` | `100` | `1` to `100` | Amount of messages to clear |
193194
| `ephimeral` | `/ping` `/about` `/help` `/chat` `/image` | `false` | `false` | `true` `false` | Hide the response from other users |
@@ -207,6 +208,33 @@ The bot uses a variety of visual embeds code located in the footer of each messa
207208

208209
<p align="right">(<a href="#readme-top">back to top</a>)</p>
209210

211+
## Commands API
212+
213+
You can add new commands to the project by following these steps:
214+
215+
1. Create a new file in the `src/bot/commands` folder with the name of the command you want to add (e.g. `testCommand.ts`).
216+
2. Write a class that extends the `Command` and implements all the methods.
217+
3. Your command will be automatically added to the bot.
218+
219+
Command example:
220+
```ts
221+
import { Command } from '@/bot/models/command';
222+
import { Client, CommandInteraction } from 'discord.js';
223+
224+
export class TestCommand extends Command {
225+
public configure(): void {
226+
this.setName('test');
227+
this.setDescription('Test command');
228+
this.addEphemeralOption(); // Add the ephemeral option to the command
229+
}
230+
231+
protected async execute(client: Client, interaction: CommandInteraction): Promise<void> {
232+
await interaction.reply({content: 'Test command executed', ephemeral: this.ephermeral});
233+
}
234+
}
235+
```
236+
237+
<p align="right">(<a href="#readme-top">back to top</a>)</p>
210238

211239

212240
<!-- ROADMAP -->

src/bot/commands/aboutCommand.ts

+1-14
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,12 @@ import { SystemEmbed } from '@/bot/embeds/systemEmbed';
44
import { EmbedAuthor, EmbedType } from '@/bot/models/embed';
55

66
export class AboutCommand extends Command {
7-
constructor() {
8-
/**
9-
* Call the parent constructor
10-
*/
11-
super();
12-
13-
/**
14-
* Set command data for Discord API
15-
*/
7+
public configure(): void {
168
this.setName('about');
179
this.setDescription('About the bot');
1810
this.addEphemeralOption(); // Add the ephemeral option to the command
1911
}
2012

21-
/**
22-
* Execute the command with the given interaction
23-
* @param client
24-
* @param interaction
25-
*/
2613
protected async execute(client: Client, interaction: CommandInteraction): Promise<void> {
2714
/**
2815
* Defer the reply to the interaction

src/bot/commands/chatCommand.ts

+14-22
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,7 @@ import { ChatEmbed } from '@/bot/embeds/chatEmbed';
77
import { SystemEmbed } from '@/bot/embeds/systemEmbed';
88

99
export class ChatCommand extends Command {
10-
constructor() {
11-
/**
12-
* Call the parent constructor
13-
*/
14-
super();
15-
16-
/**
17-
* Set command data for Discord API
18-
*/
10+
public configure(): void {
1911
this.setName('chat');
2012
this.setDescription('Chat with the bot');
2113
this.addStringOption((option) => option
@@ -79,33 +71,33 @@ export class ChatCommand extends Command {
7971
chatHistory.push(currentQuestion);
8072

8173
/**
82-
* Embeds array to store the embeds
83-
*/
84-
const embeds: EmbedBuilder[] = [];
85-
86-
/**
87-
* Create the question embed and add it to the embeds array
74+
* Embeds array with initial embed for the question
8875
*/
89-
const questionEmbed = new ChatEmbed(client, interaction, EmbedAuthor.User, question as string);
90-
embeds.push(questionEmbed);
76+
const embeds: EmbedBuilder[] = [
77+
new ChatEmbed(client, interaction, EmbedAuthor.User, question as string),
78+
];
9179

9280
/**
9381
* Get the answer from the AI
9482
*/
9583
await ai?.chatCompletion(chatHistory)
9684
.then((response) => {
97-
const responseEmbed = new ChatEmbed(client, interaction, EmbedAuthor.Bot, response.content); // Create a new text embed with the response
98-
embeds.push(responseEmbed); // Add the response embed to the embeds array
85+
/**
86+
* Add the response to the embeds array
87+
*/
88+
embeds.push(new ChatEmbed(client, interaction, EmbedAuthor.Bot, response.content));
9989
}) // Get the content from the response
10090
.catch((error: Error) => {
101-
const errorEmbed = new SystemEmbed(
91+
/**
92+
* Add the error to the embeds array
93+
*/
94+
embeds.push(new SystemEmbed(
10295
client,
10396
interaction,
10497
EmbedAuthor.Bot,
10598
EmbedType.Error,
10699
error.message,
107-
); // Create a new error embed with the error message
108-
embeds.push(errorEmbed); // Add the error embed to the embeds array
100+
));
109101
});
110102

111103
/**

src/bot/commands/clearCommand.ts

+1-9
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,7 @@ import { SystemEmbed } from '@/bot/embeds/systemEmbed';
44
import { EmbedAuthor, EmbedType } from '@/bot/models/embed';
55

66
export class ClearCommand extends Command {
7-
constructor() {
8-
/**
9-
* Call the parent constructor
10-
*/
11-
super();
12-
13-
/**
14-
* Set command data for Discord API
15-
*/
7+
public configure(): void {
168
this.setName('clear');
179
this.setDescription('Clear the chat history with the bot');
1810
this.addNumberOption((option) => option

src/bot/commands/helpCommand.ts

+1-9
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,7 @@ import { SystemEmbed } from '@/bot/embeds/systemEmbed';
44
import { EmbedAuthor, EmbedType } from '@/bot/models/embed';
55

66
export class HelpCommand extends Command {
7-
constructor() {
8-
/**
9-
* Call the parent constructor
10-
*/
11-
super();
12-
13-
/**
14-
* Set command data for Discord API
15-
*/
7+
public configure(): void {
168
this.setName('help');
179
this.setDescription('Get all the commands available');
1810
this.addEphemeralOption(); // Add the ephemeral option to the command

src/bot/commands/imageCommand.ts

+1-9
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,7 @@ import { AI } from '@/models/ai';
1010
import { ChatEmbed } from '@/bot/embeds/chatEmbed';
1111

1212
export class ImageCommand extends Command {
13-
constructor() {
14-
/**
15-
* Call the parent constructor
16-
*/
17-
super();
18-
19-
/**
20-
* Set command data for Discord API
21-
*/
13+
public configure(): void {
2214
this.setName('image');
2315
this.setDescription('Generate an image with the prompt provided');
2416
this.addStringOption((option) => option

src/bot/commands/pingCommand.ts

+1-9
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,7 @@ import { SystemEmbed } from '@/bot/embeds/systemEmbed';
44
import { EmbedAuthor, EmbedType } from '@/bot/models/embed';
55

66
export class PingCommand extends Command {
7-
constructor() {
8-
/**
9-
* Call the parent constructor
10-
*/
11-
super();
12-
13-
/**
14-
* Set command data for Discord API
15-
*/
7+
public configure(): void {
168
this.setName('ping');
179
this.setDescription('Ping the bot to check if it is online');
1810
this.addEphemeralOption(); // Add the ephemeral option to the command

src/bot/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ export class Bot implements Runnable {
9999
const ImportedCommand = module[exportedKey];
100100
if (typeof ImportedCommand === 'function' && ImportedCommand.prototype instanceof Command) {
101101
const commandInstance = new ImportedCommand(); // Create command instance
102+
commandInstance.configure(); // Configure command
102103
loadedCommands.push(commandInstance); // Add command to the container
103104
}
104105
});

src/bot/models/command.ts

+6
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ export abstract class Command extends SlashCommandBuilder {
2626
*/
2727
protected _interactionResolver!: CommandInteractionOptionResolver;
2828

29+
/**
30+
* Configure the command without using the constructor on child classes
31+
* @public
32+
*/
33+
public abstract configure(): void;
34+
2935
/**
3036
* Add Ephemeral option to command
3137
* @protected

0 commit comments

Comments
 (0)