Compare commits

...

7 Commits

Author SHA1 Message Date
neru efa52dffbc fix: implement clear cmd 2026-01-14 02:32:17 -03:00
neru 3354289207 feat: add ping command 2026-01-14 02:32:07 -03:00
neru 4fbf308650 feat: add commands command 2026-01-14 02:32:03 -03:00
neru 4033b6f6b5 feat: add general cat 2026-01-14 02:31:56 -03:00
neru d3a6decef6 fix: export CommandCategory 2026-01-14 02:31:51 -03:00
neru 4718e68c78 feat: add getCommands and getCategories 2026-01-14 02:31:44 -03:00
neru 7c282105d3 style: run format:apply 2026-01-14 01:32:45 -03:00
8 changed files with 106 additions and 30 deletions
+9 -1
View File
@@ -10,7 +10,7 @@ import {
} from 'discord.js'; } from 'discord.js';
import { Logger } from './utils/log'; import { Logger } from './utils/log';
import { config } from './utils/config'; import { config } from './utils/config';
import { CommandManager } from './commands'; import { Command, CommandCategory, CommandManager } from './commands';
import { DatabaseManager } from './modules/db'; import { DatabaseManager } from './modules/db';
type BotEventListeners = { type BotEventListeners = {
@@ -83,6 +83,14 @@ export class Bot {
await this.client.login(config.token); await this.client.login(config.token);
} }
public getCommands(): Array<Command> {
return this.cmdMgr.getAll();
}
public getCategories(): Array<CommandCategory> {
return this.cmdMgr.getCategories();
}
/* /*
event listeners event listeners
*/ */
+1 -1
View File
@@ -43,7 +43,7 @@ export interface CommandCategoryInfo {
description: string; description: string;
} }
interface CommandCategory { export interface CommandCategory {
info: CommandCategoryInfo; info: CommandCategoryInfo;
commands: Command[]; commands: Command[];
} }
+8
View File
@@ -0,0 +1,8 @@
import { CommandCategoryInfo } from '../../commands';
const info: CommandCategoryInfo = {
name: 'General',
description: 'General / uncategorized commands'
};
export default info;
+32
View File
@@ -0,0 +1,32 @@
import { ChatInputCommandInteraction, EmbedBuilder, SlashCommandBuilder } from "discord.js";
import { Command } from "../../commands";
import { Bot } from "../../bot";
const builder = new SlashCommandBuilder()
.setName('commands')
.setDescription('Shows a list of all the commands.');
const cmd: Command = {
name: builder.name,
builder: builder,
execute: async (interaction: ChatInputCommandInteraction): Promise<void> => {
const responseEmbed = new EmbedBuilder()
.setColor("Blurple")
.setTitle("Command List");
const bot = Bot.get;
bot.getCategories().forEach(({ info, commands }) => {
const fieldBody = commands
.filter(({ builder }) => builder)
.map(({ builder }) => `• **${builder?.name}** - ${builder?.description}`)
.join("\n");
responseEmbed.addFields({ name: info.name, value: fieldBody });
});
await interaction.reply({ embeds: [responseEmbed] });
}
};
export default cmd;
+16
View File
@@ -0,0 +1,16 @@
import { ChatInputCommandInteraction, SlashCommandBuilder } from "discord.js";
import { Command } from "../../commands";
const builder = new SlashCommandBuilder()
.setName('ping')
.setDescription('Pong.');
const cmd: Command = {
name: builder.name,
builder: builder,
execute: async (interaction: ChatInputCommandInteraction): Promise<void> => {
interaction.reply('pong!');
}
};
export default cmd;
+11 -1
View File
@@ -1,5 +1,7 @@
import { ChatInputCommandInteraction, SlashCommandBuilder } from 'discord.js'; import { ChatInputCommandInteraction, SlashCommandBuilder } from 'discord.js';
import { Command } from '../../commands'; import { Command } from '../../commands';
import { getVoiceConnection, VoiceConnectionStatus } from '@discordjs/voice';
import { AudioStreamManager } from '../../modules/audiostreams';
const builder = new SlashCommandBuilder() const builder = new SlashCommandBuilder()
.setName('tts-clear') .setName('tts-clear')
@@ -10,11 +12,19 @@ const cmd: Command = {
builder: builder, builder: builder,
requiresAdmin: true, requiresAdmin: true,
execute: async (interaction: ChatInputCommandInteraction): Promise<void> => { execute: async (interaction: ChatInputCommandInteraction): Promise<void> => {
if (!interaction.guildId) { if (!interaction.guild) {
interaction.reply('This command only works on Guilds'); interaction.reply('This command only works on Guilds');
return; return;
} }
const voiceConnection = getVoiceConnection(interaction.guild.id);
if (voiceConnection?.state.status !== VoiceConnectionStatus.Ready) return;
const stream = AudioStreamManager.get.getOrCreateStream(voiceConnection);
const queue = stream.getQueue('TTS');
queue.clear();
interaction.reply('Queue cleared.'); interaction.reply('Queue cleared.');
} }
}; };
+5 -3
View File
@@ -50,9 +50,11 @@ const cmd: Command = {
const modes = TTSManager.get.getModules(); const modes = TTSManager.get.getModules();
const filtered: string[] = modes const filtered: string[] = modes
.filter((mode) => .filter((mode) => {
mode.name.toLowerCase().startsWith(focused.value.toLowerCase()) return mode.name
) ? mode.name.toLowerCase().startsWith(focused.value.toLowerCase())
: undefined;
})
.map((mode) => mode.name) .map((mode) => mode.name)
.slice(0, 25); .slice(0, 25);
+24 -24
View File
@@ -1,37 +1,37 @@
import { TTSModule, TTSResponse } from "../tts"; import { TTSModule, TTSResponse } from '../tts';
import { VoicesManager, Communicate } from 'edge-tts-universal'; import { VoicesManager, Communicate } from 'edge-tts-universal';
class AzureTTS implements TTSModule { class AzureTTS implements TTSModule {
private voices: Array<string> | undefined = undefined; private voices: Array<string> | undefined = undefined;
public name: string = "Azure"; public name: string = 'Azure';
async getVoices(): Promise<Array<string> | undefined> {
if (!this.voices) {
const voiceMgr = await VoicesManager.create();
const voiceQuery = await voiceMgr.find({});
this.voices = voiceQuery.map((voice) => voice.ShortName); async getVoices(): Promise<Array<string> | undefined> {
} if (!this.voices) {
const voiceMgr = await VoicesManager.create();
const voiceQuery = await voiceMgr.find({});
return this.voices; this.voices = voiceQuery.map((voice) => voice.ShortName);
}; }
async generate(voice: string, text: string): Promise<TTSResponse> { return this.voices;
const comm = new Communicate(text, { }
voice: voice
});
const buffers: Buffer[] = []; async generate(voice: string, text: string): Promise<TTSResponse> {
for await (const chunk of comm.stream()) { const comm = new Communicate(text, {
if (chunk.type === 'audio' && chunk.data) { voice: voice
buffers.push(chunk.data); });
}
}
return { data: Buffer.concat(buffers) }; const buffers: Buffer[] = [];
}; for await (const chunk of comm.stream()) {
if (chunk.type === 'audio' && chunk.data) {
buffers.push(chunk.data);
}
}
return { data: Buffer.concat(buffers) };
}
} }
export default new AzureTTS(); export default new AzureTTS();