Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const { Client } = require('discord.js');
- const { SlashCommandBuilder } = require('discord.js-slash-command');
- const { createAudioPlayer, createAudioResource, joinVoiceChannel, AudioPlayerStatus, NoSubscriberBehavior } = require('@discordjs/voice');
- const ytdl = require('ytdl-core');
- const youtubeDl = require('youtube-dl-exec');
- const SoundCloudDownloader = require('soundcloud-downloader');
- const SpotifyWebApi = require('spotify-web-api-node');
- const { GatewayIntentBits } = require('discord.js');
- require('dotenv').config();
- const { getInfo } = require('ytdl-core');
- const { EmbedBuilder } = require('discord.js');
- const { ActionRowBuilder } = require('discord.js');
- const { ButtonBuilder } = require('discord.js');
- const { ButtonStyle } = require('discord.js');
- const spotifyApi = new SpotifyWebApi({
- clientId: process.env.SPOTIFY_CLIENT_ID,
- clientSecret: process.env.SPOTIFY_CLIENT_SECRET,
- });
- async function getAccessToken() {
- const data = await spotifyApi.clientCredentialsGrant();
- return data.body.access_token;
- }
- async function setAccessToken() {
- const accessToken = await getAccessToken();
- spotifyApi.setAccessToken(accessToken);
- }
- const client = new Client({
- intents: [
- GatewayIntentBits.Guilds,
- GatewayIntentBits.GuildVoiceStates
- ]
- });
- const queue = new Map();
- const player = createAudioPlayer({ behaviors: { noSubscriber: NoSubscriberBehavior.Pause } });
- client.on('ready', () => {
- console.log(`Logged in as ${client.user.tag}`);
- registerSlashCommands();
- });
- client.on('interactionCreate', async (interaction) => {
- if (!interaction.isCommand()) return;
- const { commandName, options } = interaction;
- if (commandName === 'play') {
- const query = options.getString('query');
- const voiceChannel = interaction.member.voice.channel;
- if (!voiceChannel) {
- return interaction.reply({ content: 'You need to be in a voice channel to use this command!', ephemeral: true });
- }
- const connection = joinVoiceChannel({
- channelId: voiceChannel.id,
- guildId: voiceChannel.guild.id,
- adapterCreator: voiceChannel.guild.voiceAdapterCreator,
- });
- try {
- const trackInfo = await getTrackInfo(query);
- const resource = await createAudioResource(trackInfo.url);
- player.play(resource);
- const serverQueue = getQueue(interaction.guildId);
- serverQueue.songs.push(trackInfo);
- if (!serverQueue.playing) {
- playSong(interaction.guildId);
- }
- const embed = createNowPlayingEmbed(trackInfo);
- const row = createPlaybackButtons();
- interaction.reply({ embeds: [embed], components: [row] });
- } catch (error) {
- console.error(error);
- interaction.reply({ content: 'An error occurred while playing the track.', ephemeral: true });
- }
- } else if (commandName === 'stop') {
- stopPlayback(interaction.guildId);
- interaction.reply('Stopped playback.');
- } else if (commandName === 'queue') {
- const serverQueue = getQueue(interaction.guildId);
- if (serverQueue.songs.length === 0) {
- interaction.reply('The queue is empty.');
- } else {
- const queueList = serverQueue.songs.map((song, index) => `${index + 1}. ${song.title}`);
- interaction.reply(`Queue:\n${queueList.join('\n')}`);
- }
- }
- });
- async function getTrackInfo(query) {
- if (!query || query.trim().length === 0) {
- throw new Error('Invalid query.');
- }
- if (ytdl.validateURL(query)) {
- const info = await ytdl.getInfo(query);
- return {
- url: info.videoDetails.video_url,
- title: info.videoDetails.title,
- thumbnail: info.videoDetails.thumbnails[0].url,
- duration: parseInt(info.videoDetails.lengthSeconds),
- };
- } else if (query.includes('soundcloud.com')) {
- const info = await SoundCloudDownloader.download(query);
- return {
- url: info.url,
- title: info.title,
- thumbnail: info.thumbnail,
- duration: parseInt(info.duration),
- };
- } else if (query.includes('spotify.com')) {
- const match = query.match(/track\/(\w+)/);
- if (match) {
- try {
- await setAccessToken();
- const trackId = match[1];
- const data = await spotifyApi.getTrack(trackId);
- const track = data.body;
- return {
- url: track.external_urls.spotify,
- title: `${track.name} - ${track.artists[0].name}`,
- thumbnail: track.album.images[0].url,
- duration: Math.floor(track.duration_ms / 1000),
- };
- } catch (error) {
- throw new Error('Failed to fetch track information from Spotify.');
- }
- } else {
- throw new Error('Invalid Spotify track URL.');
- }
- } else {
- throw new Error('Unsupported URL or search query.');
- }
- }
- function getQueue(guildId) {
- if (!queue.has(guildId)) {
- queue.set(guildId, { songs: [], playing: false });
- }
- return queue.get(guildId);
- }
- function playSong(guildId) {
- const serverQueue = getQueue(guildId);
- if (serverQueue.songs.length === 0) {
- serverQueue.playing = false;
- return;
- }
- const currentSong = serverQueue.songs[0];
- const resource = createAudioResource(currentSong.url);
- player.play(resource);
- player.on(AudioPlayerStatus.Idle, () => {
- serverQueue.songs.shift();
- playSong(guildId);
- const nowPlayingEmbed = createNowPlayingEmbed(serverQueue.songs[0]);
- const nowPlayingMessage = client.channels.cache.get(serverQueue.textChannelId).messages.cache.get(serverQueue.nowPlayingMessageId);
- nowPlayingMessage.edit({ embeds: [nowPlayingEmbed] });
- });
- serverQueue.playing = true;
- }
- function stopPlayback(guildId) {
- const serverQueue = getQueue(guildId);
- serverQueue.songs = [];
- player.stop();
- }
- function createNowPlayingEmbed(songInfo) {
- const embed = new EmbedBuilder()
- .setColor('#FF0000')
- .setTitle('Now Playing')
- .setDescription(songInfo.title)
- .setThumbnail(songInfo.thumbnail)
- .addFields(
- { name: 'Duration', value: formatDuration(songInfo.duration) },
- { name: 'Progress', value: '▶️' + createProgressBar(songInfo.duration, player.state.resource.playbackDuration) }
- );
- return embed;
- }
- function createPlaybackButtons() {
- const playButton = new ButtonBuilder()
- .setCustomId('play')
- .setLabel('▶️ Play')
- .setStyle(ButtonStyle.Primary)
- const pauseButton = new ButtonBuilder()
- .setCustomId('pause')
- .setLabel('⏸️ Pause')
- .setStyle(ButtonStyle.Primary)
- const nextButton = new ButtonBuilder()
- .setCustomId('next')
- .setLabel('⏭️ Next')
- .setStyle(ButtonStyle.Primary)
- const previousButton = new ButtonBuilder()
- .setCustomId('previous')
- .setLabel('⏮️ Previous')
- .setStyle(ButtonStyle.Primary)
- const row = new ActionRowBuilder().addComponents(playButton, pauseButton, previousButton, nextButton);
- return row;
- }
- function formatDuration(duration) {
- const minutes = Math.floor(duration / 60);
- const seconds = duration % 60;
- return `${minutes}:${seconds.toString().padStart(2, '0')}`;
- }
- function createProgressBar(totalSeconds, currentSeconds) {
- const length = 15;
- const progress = Math.floor((currentSeconds / totalSeconds) * length);
- const bar = '▬'.repeat(progress) + '🔘' + '▬'.repeat(length - progress);
- return bar;
- }
- function registerSlashCommands() {
- client.guilds.cache.forEach(async (guild) => {
- try {
- await guild.commands.set([
- {
- name: 'play',
- description: 'Play a song',
- options: [
- {
- name: 'query',
- description: 'Song name or URL',
- type: 3,
- required: true,
- },
- ],
- },
- {
- name: 'stop',
- description: 'Stop playback',
- },
- {
- name: 'queue',
- description: 'Show the current song queue',
- },
- ]);
- console.log(`Registered slash commands for guild ${guild.name}`);
- } catch (error) {
- console.error(`Failed to register slash commands for guild ${guild.name}:`, error);
- }
- });
- }
- client.login(process.env.TOKEN);
Advertisement
Add Comment
Please, Sign In to add comment