commands/outro.js (view raw)
1const path = require('node:path');
2const { SlashCommandBuilder } = require('discord.js');
3const { createAudioResource, createAudioPlayer, joinVoiceChannel, NoSubscriberBehavior, AudioPlayerStatus } = require('@discordjs/voice');
4
5const outros = [
6 { name: 'Random!', value: 'random' },
7 { name: 'TheFatRat - Xenogenesis', value: 'thefatrat_xenogenesis.mp3' },
8 { name: 'OMFG - Hello', value: 'omfg_hello.mp3' },
9 { name: 'Pegboard Nerds - Disconnected', value: 'pegboard_nerds_disconnected.mp3' },
10 { name: 'Gym Class Heroes - Stereo Hearts', value: 'gym_class_heroes_stereo_hearts.mp3' },
11];
12
13async function reply_efemeral(interaction, reply) { return await interaction.reply({ content: reply, ephemeral: true }); }
14
15function get_player(resource) {
16
17 const player = createAudioPlayer({ behaviors: { noSubscriber: NoSubscriberBehavior.Pause } });
18 player.on('error', error => console.error(`Error: ${error.message} with resource ${error.resource.metadata.title}`));
19 player.on(AudioPlayerStatus.Idle, () => {
20 player.stop();
21 player.subscribers.forEach(element => element.connection.disconnect());
22 });
23
24 player.play(createAudioResource(resource));
25 return player;
26}
27
28module.exports = {
29 data: new SlashCommandBuilder()
30 .setName('outro')
31 .setDescription('Leave with an outro.')
32 .addStringOption(option =>
33 option.setName('which')
34 .setDescription('Select which outro to play')
35 .setRequired(false)
36 .addChoices(...outros))
37 .addStringOption(option =>
38 option.setName('kick')
39 .setDescription('Do you actually want to log off?')
40 .setRequired(false)
41 .addChoices({ name: 'Yes', value: 'true' }, { name: 'No', value: 'false' })),
42
43 async execute(interaction) {
44 const member = interaction.member;
45 if (!member) return await reply_efemeral(interaction, 'Please use this in your current server.');
46
47 const user_connection = member.voice;
48 const channel = user_connection.channel;
49 if (!channel) return await reply_efemeral(interaction, 'You\'re not in a voice channel.');
50
51 const guild = channel.guild;
52 const bot_connection = joinVoiceChannel({ channelId: channel.id, guildId: guild.id, adapterCreator: guild.voiceAdapterCreator });
53
54 const outro = interaction.options.getString('which');
55 const kick = interaction.options.getString('kick');
56
57 let outro_file = outro ? outro : 'random';
58 if (outro_file == 'random')
59 outro_file = outros[Math.floor(Math.random() * (outros.length - 1)) + 1].value;
60
61 const song_path = path.join(process.cwd(), 'resources', outro_file);
62 const outro_title = outros.find(element => element.value == outro_file).name;
63 bot_connection.subscribe(get_player(song_path));
64
65 const kick_switch = kick ? kick : 'true';
66 if (kick_switch == 'true') {
67 setTimeout(() => user_connection.disconnect(), 20_000);
68 return await reply_efemeral(interaction, `Prepare for takeoff with ${outro_title}!`);
69 }
70 return await reply_efemeral(interaction, `Playing ${outro_title}.`);
71 },
72};