Compare commits

..

5 Commits

Author SHA1 Message Date
neru 8e8d5dc479 feat: set default voice if found 2026-01-14 21:51:20 -03:00
neru dfb58318af feat: check if mod can be used before listing it 2026-01-14 21:51:13 -03:00
neru 4abc2ff594 fix: make canBeUsed non async 2026-01-14 21:50:54 -03:00
neru 5877644ed9 feat: add default voices 2026-01-14 21:29:07 -03:00
neru 71da6e841d feat: add better checks before joining 2026-01-14 21:26:48 -03:00
7 changed files with 49 additions and 14 deletions
+8 -4
View File
@@ -30,6 +30,7 @@ const cmd: Command = {
const modeName = interaction.options.getString('mode', true);
const selectedMode = TTSManager.get
.getModules()
.filter(async (mod) => await mod.canBeUsed())
.find((mode) => mode.name === modeName);
if (!selectedMode) {
@@ -38,6 +39,8 @@ const cmd: Command = {
}
await userData.set('tts_mode', modeName);
if (selectedMode.defaultVoice)
await userData.set('tts_voice', selectedMode.defaultVoice);
await userData.save();
interaction.editReply(`TTS mode has been set to: ${modeName}.`);
@@ -50,12 +53,13 @@ const cmd: Command = {
const modes = TTSManager.get.getModules();
const filtered: string[] = modes
.filter((mode) => {
return mode.name
? mode.name.toLowerCase().startsWith(focused.value.toLowerCase())
.filter((mod) => mod.canBeUsed())
.filter((mod) => {
return mod.name
? mod.name.toLowerCase().startsWith(focused.value.toLowerCase())
: undefined;
})
.map((mode) => mode.name)
.map((mod) => mod.name)
.slice(0, 25);
await interaction.respond(
+25 -1
View File
@@ -1,6 +1,7 @@
import {
ChatInputCommandInteraction,
GuildMember,
PermissionsBitField,
SlashCommandBuilder
} from 'discord.js';
import { Command } from '../../commands';
@@ -25,7 +26,7 @@ const cmd: Command = {
return;
}
if (!member.voice.channelId) {
if (!member.voice.channel || !member.voice.channelId) {
interaction.reply('You are not currently on a voice channel');
return;
}
@@ -40,6 +41,29 @@ const cmd: Command = {
return;
}
const voiceChannel = member.voice.channel;
if (voiceChannel.userLimit != 0 && voiceChannel.members.size >= voiceChannel.userLimit) {
interaction.reply('Channel is full');
return;
}
const perms = voiceChannel.permissionsFor(me)
if (!perms.has(PermissionsBitField.Flags.ViewChannel)) {
interaction.reply("I don't have permissions to see that channel")
return;
}
if (!perms.has(PermissionsBitField.Flags.Connect)) {
interaction.reply("I don't have the permissions to join that channel");
return;
}
if (!perms.has(PermissionsBitField.Flags.Speak)) {
interaction.reply("I don't have permissions to speak on that channel")
return;
}
const voiceOptions: JoinVoiceChannelOptions & CreateVoiceConnectionOptions =
{
channelId: member.voice.channelId,
+2 -1
View File
@@ -6,6 +6,7 @@ class AzureTTS implements TTSModule {
private voices: Array<string> | undefined = undefined;
public name: string = 'Azure';
public defaultVoice: string = 'en-US-AvaNeural';
async getVoices(): Promise<Array<string> | undefined> {
if (!this.voices) {
@@ -33,7 +34,7 @@ class AzureTTS implements TTSModule {
return { data: Buffer.concat(buffers) };
}
async canBeUsed(): Promise<boolean> {
canBeUsed(): boolean {
return true;
}
}
+3 -1
View File
@@ -9,6 +9,8 @@ const USER_AGENT =
const ttsGoogle: TTSModule = {
name: 'Google',
defaultVoice: 'en',
async getVoices(): Promise<string[]> { return GOOGLE_TTS_VOICES.voices },
async generate(voice: string, text: string): Promise<TTSResponse> {
@@ -43,7 +45,7 @@ const ttsGoogle: TTSModule = {
});
},
async canBeUsed(): Promise<boolean> {
canBeUsed(): boolean {
return true;
}
};
+3
View File
@@ -5,6 +5,9 @@ const ttsNone: TTSModule = {
getVoices: async (): Promise<Array<string>> => [],
generate: async (): Promise<TTSResponse> => {
return { data: Buffer.from([]) };
},
canBeUsed: (): boolean => {
return true;
}
};
+1 -1
View File
@@ -82,7 +82,7 @@ class PollyTTS implements TTSModule {
return {};
}
async canBeUsed(): Promise<boolean> {
canBeUsed(): boolean {
if (!config.aws_access_id || !config.aws_access_key)
return false;
return true;
+2 -1
View File
@@ -11,9 +11,10 @@ export interface TTSResponse {
export interface TTSModule {
name: string;
defaultVoice?: string;
getVoices: () => Promise<Array<string> | undefined>;
generate: (voice: string, text: string) => Promise<TTSResponse>;
canBeUsed: () => Promise<boolean>;
canBeUsed: () => boolean;
}
export class TTSManager {