mirror of
https://github.com/BluemediaGER/muse.git
synced 2024-11-10 03:55:29 +01:00
✨ add autocomplete
This commit is contained in:
parent
43baa57c51
commit
7901fcce3d
23
src/bot.ts
23
src/bot.ts
|
@ -87,29 +87,42 @@ export default class {
|
||||||
});
|
});
|
||||||
|
|
||||||
this.client.on('interactionCreate', async interaction => {
|
this.client.on('interactionCreate', async interaction => {
|
||||||
if (!interaction.isButton()) {
|
try {
|
||||||
return;
|
if (interaction.isButton()) {
|
||||||
}
|
|
||||||
|
|
||||||
const command = this.commandsByButtonId.get(interaction.customId);
|
const command = this.commandsByButtonId.get(interaction.customId);
|
||||||
|
|
||||||
if (!command) {
|
if (!command) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
if (command.handleButtonInteraction) {
|
if (command.handleButtonInteraction) {
|
||||||
await command.handleButtonInteraction(interaction);
|
await command.handleButtonInteraction(interaction);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interaction.isAutocomplete()) {
|
||||||
|
const command = this.commandsByName.get(interaction.commandName);
|
||||||
|
|
||||||
|
if (!command) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command.handleAutocompleteInteraction) {
|
||||||
|
await command.handleAutocompleteInteraction(interaction);
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
debug(error);
|
debug(error);
|
||||||
|
|
||||||
|
// Can't reply with errors for autocomplete queries
|
||||||
|
if (interaction.isButton()) {
|
||||||
if (interaction.replied || interaction.deferred) {
|
if (interaction.replied || interaction.deferred) {
|
||||||
await interaction.editReply(errorMsg('something went wrong'));
|
await interaction.editReply(errorMsg('something went wrong'));
|
||||||
} else {
|
} else {
|
||||||
await interaction.reply({content: errorMsg(error as Error), ephemeral: true});
|
await interaction.reply({content: errorMsg(error as Error), ephemeral: true});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const spinner = ora('📡 connecting to Discord...').start();
|
const spinner = ora('📡 connecting to Discord...').start();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import {SlashCommandBuilder} from '@discordjs/builders';
|
import {SlashCommandBuilder} from '@discordjs/builders';
|
||||||
import {ButtonInteraction, CommandInteraction} from 'discord.js';
|
import {AutocompleteInteraction, ButtonInteraction, CommandInteraction} from 'discord.js';
|
||||||
|
|
||||||
export default interface Command {
|
export default interface Command {
|
||||||
readonly slashCommand: Partial<SlashCommandBuilder> & Pick<SlashCommandBuilder, 'toJSON'>;
|
readonly slashCommand: Partial<SlashCommandBuilder> & Pick<SlashCommandBuilder, 'toJSON'>;
|
||||||
|
@ -7,4 +7,5 @@ export default interface Command {
|
||||||
readonly requiresVC?: boolean;
|
readonly requiresVC?: boolean;
|
||||||
execute: (interaction: CommandInteraction) => Promise<void>;
|
execute: (interaction: CommandInteraction) => Promise<void>;
|
||||||
handleButtonInteraction?: (interaction: ButtonInteraction) => Promise<void>;
|
handleButtonInteraction?: (interaction: ButtonInteraction) => Promise<void>;
|
||||||
|
handleAutocompleteInteraction?: (interaction: AutocompleteInteraction) => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {CommandInteraction, GuildMember} from 'discord.js';
|
import {AutocompleteInteraction, CommandInteraction, GuildMember} from 'discord.js';
|
||||||
import {URL} from 'url';
|
import {URL} from 'url';
|
||||||
import {Except} from 'type-fest';
|
import {Except} from 'type-fest';
|
||||||
import {SlashCommandBuilder} from '@discordjs/builders';
|
import {SlashCommandBuilder} from '@discordjs/builders';
|
||||||
|
@ -12,6 +12,7 @@ import {getMostPopularVoiceChannel, getMemberVoiceChannel} from '../utils/channe
|
||||||
import errorMsg from '../utils/error-msg.js';
|
import errorMsg from '../utils/error-msg.js';
|
||||||
import GetSongs from '../services/get-songs.js';
|
import GetSongs from '../services/get-songs.js';
|
||||||
import {prisma} from '../utils/db.js';
|
import {prisma} from '../utils/db.js';
|
||||||
|
import getYouTubeSuggestionsFor from '../utils/get-youtube-suggestions-for.js';
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export default class implements Command {
|
export default class implements Command {
|
||||||
|
@ -21,7 +22,8 @@ export default class implements Command {
|
||||||
.setDescription('play a song or resume playback')
|
.setDescription('play a song or resume playback')
|
||||||
.addStringOption(option => option
|
.addStringOption(option => option
|
||||||
.setName('query')
|
.setName('query')
|
||||||
.setDescription('YouTube URL, Spotify URL, or search query'))
|
.setDescription('YouTube URL, Spotify URL, or search query')
|
||||||
|
.setAutocomplete(true))
|
||||||
.addBooleanOption(option => option
|
.addBooleanOption(option => option
|
||||||
.setName('immediate')
|
.setName('immediate')
|
||||||
.setDescription('adds track to the front of the queue'))
|
.setDescription('adds track to the front of the queue'))
|
||||||
|
@ -191,4 +193,17 @@ export default class implements Command {
|
||||||
await interaction.editReply(`u betcha, **${firstSong.title}** and ${newSongs.length - 1} other songs were added to the queue${extraMsg}`);
|
await interaction.editReply(`u betcha, **${firstSong.title}** and ${newSongs.length - 1} other songs were added to the queue${extraMsg}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async handleAutocompleteInteraction(interaction: AutocompleteInteraction): Promise<void> {
|
||||||
|
const query = interaction.options.getString('query')?.trim();
|
||||||
|
|
||||||
|
if (!query || query.length === 0) {
|
||||||
|
return interaction.respond([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
await interaction.respond((await getYouTubeSuggestionsFor(query)).map(s => ({
|
||||||
|
name: s,
|
||||||
|
value: s,
|
||||||
|
})));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
15
src/utils/get-youtube-suggestions-for.ts
Normal file
15
src/utils/get-youtube-suggestions-for.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import got from 'got';
|
||||||
|
|
||||||
|
const getYouTubeSuggestionsFor = async (query: string): Promise<string[]> => {
|
||||||
|
const [_, suggestions] = await got('https://suggestqueries.google.com/complete/search?client=firefox&ds=yt&q=', {
|
||||||
|
searchParams: {
|
||||||
|
client: 'firefox',
|
||||||
|
ds: 'yt',
|
||||||
|
q: query,
|
||||||
|
},
|
||||||
|
}).json<[string, string[]]>();
|
||||||
|
|
||||||
|
return suggestions;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default getYouTubeSuggestionsFor;
|
Loading…
Reference in a new issue