Skip to content

Commit aa878b8

Browse files
committed
remove the need for a youtube api key
1 parent 84f7ac5 commit aa878b8

File tree

5 files changed

+100
-6737
lines changed

5 files changed

+100
-6737
lines changed

README.md

+1-4
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ This is the minimum amount of settings that need to be set for the core part (mu
2626
{
2727
"mongo_URI": "your-mongodb-uri",
2828
"client_id": "the-bots-discord-id",
29-
"token": "Your-Bot-Token",
30-
"youtubeAPI": "youtube-api-key"
29+
"token": "Your-Bot-Token"
3130
}
3231
```
3332

@@ -163,8 +162,6 @@ What each option affects can be seen here in further detail:
163162

164163
## Resources
165164

166-
[Getting a YouTube API key](https://developers.google.com/youtube/v3/getting-started)
167-
168165
[Getting a Tenor API key](https://tenor.com/developer/keyregistration)
169166

170167
[Getting a NewsAPI API key](https://newsapi.org/)

commands/music/play.js

+63-98
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
const { SlashCommandBuilder } = require('@discordjs/builders');
22
const { MessageSelectMenu, MessageActionRow } = require('discord.js');
33
const Player = require('../../utils/music/Player');
4-
const Youtube = require('simple-youtube-api');
5-
const ytsr = require('ytsr');
64
const { getData } = require('spotify-url-info');
7-
const { youtubeAPI } = require('../../config.json');
5+
const YouTube = require('youtube-sr').default;
86
let {
97
playLiveStreams,
108
playVideosLongerThan1Hour,
@@ -23,7 +21,6 @@ const {
2321
} = require('@discordjs/voice');
2422
const createGuildData = require('../../utils/createGuildData');
2523

26-
const youtube = new Youtube(youtubeAPI);
2724
// Check If Options are Valid
2825
if (typeof playLiveStreams !== 'boolean') playLiveStreams = true;
2926
if (typeof maxQueueLength !== 'number' || maxQueueLength < 1) {
@@ -404,17 +401,17 @@ module.exports = {
404401
const artistsAndName = concatSongNameAndArtists(
405402
spotifyPlaylistItems[i].track
406403
);
407-
const ytResult = await ytsr(artistsAndName, { limit: 1 });
404+
const ytResult = await YouTube.search(artistsAndName, {
405+
limit: 1
406+
});
408407
const video = {
409-
title: ytResult.items[0].title,
410-
url: ytResult.items[0].url,
411-
thumbnails: {
412-
high: {
413-
url: `https://i.ytimg.com/vi/${ytResult.items[0].id}/hqdefault.jpg`
414-
}
408+
title: ytResult[0].title,
409+
url: ytResult[0].url,
410+
thumbnail: {
411+
url: video.thumbnail.url
415412
},
416-
// the true value is used to differentiate this duration from the rawDuration recieved from the YT API
417-
duration: [ytResult.items[0].duration, true]
413+
durationFormatted: ytResult[0].durationFormatted,
414+
duration: ytResult[0].duration
418415
};
419416
if (nextFlag || jumpFlag) {
420417
flagLogic(interaction, video, jumpFlag);
@@ -439,17 +436,15 @@ module.exports = {
439436
else {
440437
const artistsAndName = concatSongNameAndArtists(data);
441438
// Search on YT
442-
const ytResult = await ytsr(artistsAndName, { limit: 1 });
439+
const ytResult = await YouTube.search(artistsAndName, { limit: 1 });
443440
const video = {
444-
title: ytResult.items[0].title,
445-
url: ytResult.items[0].url,
446-
thumbnails: {
447-
high: {
448-
url: `https://i.ytimg.com/vi/${ytResult.items[0].id}/hqdefault.jpg`
449-
}
441+
title: ytResult[0].title,
442+
url: `https://www.youtube.com/watch?v=${ytResult[0].id}`,
443+
thumbnail: {
444+
url: ytResult[0].thumbnail.url
450445
},
451-
// the true value is used to differentiate this duration from the rawDuration recieved from the YT API
452-
duration: [ytResult.items[0].duration, true]
446+
durationFormatted: ytResult[0].durationFormatted,
447+
duration: ytResult[0].duration
453448
};
454449
if (nextFlag || jumpFlag) {
455450
flagLogic(interaction, video, jumpFlag);
@@ -477,21 +472,22 @@ module.exports = {
477472
}
478473

479474
if (isYouTubePlaylistURL(query)) {
480-
const playlist = await youtube.getPlaylist(query);
475+
const playlist = await YouTube.getPlaylist(query);
481476
if (!playlist) {
482477
deletePlayerIfNeeded(interaction);
483478
return interaction.followUp(
484479
':x: Playlist is either private or it does not exist!'
485480
);
486481
}
487482

488-
let videosArr = await playlist.getVideos();
483+
let videosArr = await playlist.fetch();
489484
if (!videosArr) {
490485
deletePlayerIfNeeded(interaction);
491486
return interaction.followUp(
492487
":x: I hit a problem when trying to fetch the playlist's videos"
493488
);
494489
}
490+
videosArr = videosArr.videos;
495491

496492
if (AutomaticallyShuffleYouTubePlaylists || shuffleFlag) {
497493
videosArr = shuffleArray(videosArr);
@@ -510,42 +506,32 @@ module.exports = {
510506
//variable to know how many songs were skipped because of privacyStatus
511507
var skipAmount = 0;
512508

513-
await videosArr.reduce(async (memo, video, key) => {
514-
await memo;
509+
await videosArr.reduce(async (__, video, key) => {
515510
// don't process private videos
516-
if (
517-
video.raw.status.privacyStatus == 'private' ||
518-
video.raw.status.privacyStatus == 'privacyStatusUnspecified'
519-
) {
511+
if (video.private) {
520512
skipAmount++;
521513
return;
522514
}
523-
524-
try {
525-
const fetchedVideo = await video.fetch();
526-
if (nextFlag || jumpFlag) {
527-
player.queue.splice(
528-
key - skipAmount,
529-
0,
530-
constructSongObj(
531-
fetchedVideo,
532-
interaction.member.voice.channel,
533-
interaction.member.user
534-
)
535-
);
536-
} else {
537-
player.queue.push(
538-
constructSongObj(
539-
fetchedVideo,
540-
interaction.member.voice.channel,
541-
interaction.member.user
542-
)
543-
);
544-
}
545-
} catch (err) {
546-
return console.error(err);
515+
if (nextFlag || jumpFlag) {
516+
player.queue.splice(
517+
key - skipAmount,
518+
0,
519+
constructSongObj(
520+
video,
521+
interaction.member.voice.channel,
522+
interaction.member.user
523+
)
524+
);
525+
} else {
526+
player.queue.push(
527+
constructSongObj(
528+
video,
529+
interaction.member.voice.channel,
530+
interaction.member.user
531+
)
532+
);
547533
}
548-
}, undefined);
534+
});
549535
if (
550536
jumpFlag &&
551537
player.audioPlayer.state.status === AudioPlayerStatus.Playing
@@ -560,15 +546,15 @@ module.exports = {
560546
// interactiveEmbed(interaction)
561547
// .addField('Added Playlist', `[${playlist.title}](${playlist.url})`)
562548
// .build();
563-
return;
549+
return interaction.followUp('Added playlist to queue!');
564550
}
565551
}
566552

567553
if (isYouTubeVideoURL(query)) {
568-
const id = query
569-
.replace(/(>|<)/gi, '')
570-
.split(/(vi\/|v=|\/v\/|youtu\.be\/|\/embed\/)/)[2]
571-
.split(/[^0-9a-z_\-]/i)[0];
554+
// const id = query
555+
// .replace(/(>|<)/gi, '')
556+
// .split(/(vi\/|v=|\/v\/|youtu\.be\/|\/embed\/)/)[2]
557+
// .split(/[^0-9a-z_\-]/i)[0];
572558

573559
const timestampRegex = /t=([^#&\n\r]+)/g;
574560
let timestamp = timestampRegex.exec(query);
@@ -583,18 +569,15 @@ module.exports = {
583569
}
584570
timestamp = Number(timestamp);
585571

586-
const video = await youtube.getVideoByID(id).catch(function() {
572+
const video = await YouTube.getVideo(query).catch(function() {
587573
deletePlayerIfNeeded(interaction);
588574
interaction.followUp(
589575
':x: There was a problem getting the video you provided!'
590576
);
591577
});
592578
if (!video) return;
593-
594-
if (
595-
video.raw.snippet.liveBroadcastContent === 'live' &&
596-
!playLiveStreams
597-
) {
579+
console.log(video);
580+
if (video.live === 'live' && !playLiveStreams) {
598581
deletePlayerIfNeeded(interaction);
599582
interaction.followUp(
600583
'Live streams are disabled in this server! Contact the owner'
@@ -713,11 +696,13 @@ var searchYoutube = async (
713696
nextFlag,
714697
jumpFlag
715698
) => {
716-
const videos = await youtube.searchVideos(query, 5).catch(async function() {
717-
return interaction.followUp(
718-
':x: There was a problem searching the video you requested!'
719-
);
720-
});
699+
const videos = await YouTube.search(query, { limit: 5 }).catch(
700+
async function() {
701+
return interaction.followUp(
702+
':x: There was a problem searching the video you requested!'
703+
);
704+
}
705+
);
721706
if (!videos) {
722707
player.commandLock = false;
723708
return interaction.followUp(
@@ -768,13 +753,11 @@ var searchYoutube = async (
768753
}
769754
const videoIndex = parseInt(value);
770755

771-
youtube
772-
.getVideoByID(videos[videoIndex - 1].id)
756+
YouTube.getVideo(
757+
`https://www.youtube.com/watch?v=${videos[videoIndex - 1].id}`
758+
)
773759
.then(function(video) {
774-
if (
775-
video.raw.snippet.liveBroadcastContent === 'live' &&
776-
!playLiveStreams
777-
) {
760+
if (video.live && !playLiveStreams) {
778761
if (playOptions) {
779762
playOptions.delete().catch(console.error);
780763
return;
@@ -912,20 +895,6 @@ var shuffleArray = arr => {
912895
return arr;
913896
};
914897

915-
// timeString = timeObj => 'HH:MM:SS' // if HH is missing > MM:SS
916-
var timeString = timeObj => {
917-
if (timeObj[1] === true) return timeObj[0];
918-
return `${timeObj.hours ? timeObj.hours + ':' : ''}${
919-
timeObj.minutes ? timeObj.minutes : '00'
920-
}:${
921-
timeObj.seconds < 10
922-
? '0' + timeObj.seconds
923-
: timeObj.seconds
924-
? timeObj.seconds
925-
: '00'
926-
}`;
927-
};
928-
929898
// var millisecondsToTimeObj = ms => ({
930899
// seconds: Math.floor((ms / 1000) % 60),
931900
// minutes: Math.floor((ms / (1000 * 60)) % 60),
@@ -944,20 +913,16 @@ var concatSongNameAndArtists = data => {
944913
};
945914

946915
var constructSongObj = (video, voiceChannel, user, timestamp) => {
947-
let duration = timeString(video.duration);
916+
let duration = video.durationFormatted;
948917
if (duration === '00:00') duration = 'Live Stream';
949918
// checks if the user searched for a song using a Spotify URL
950-
let url =
951-
video.duration[1] == true
952-
? video.url
953-
: `https://www.youtube.com/watch?v=${video.raw.id}`;
954919
return {
955-
url,
920+
url: video.url,
956921
title: video.title,
957922
rawDuration: video.duration,
958923
duration,
959924
timestamp,
960-
thumbnail: video.thumbnails.high.url,
925+
thumbnail: video.thumbnail.url,
961926
voiceChannel,
962927
memberDisplayName: user.username,
963928
memberAvatar: user.avatarURL('webp', false, 16)

commands/music/save-to-playlist.js

+12-34
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
const { SlashCommandBuilder } = require('@discordjs/builders');
22
const Member = require('../../utils/models/Member');
3-
const Youtube = require('simple-youtube-api');
4-
const { youtubeAPI } = require('../../config.json');
5-
const youtube = new Youtube(youtubeAPI);
3+
const YouTube = require('youtube-sr').default;
64

75
module.exports = {
86
data: new SlashCommandBuilder()
@@ -91,55 +89,38 @@ function validateURL(url) {
9189
);
9290
}
9391

94-
function formatDuration(durationObj) {
95-
const duration = `${durationObj.hours ? durationObj.hours + ':' : ''}${
96-
durationObj.minutes ? durationObj.minutes : '00'
97-
}:${
98-
durationObj.seconds < 10
99-
? '0' + durationObj.seconds
100-
: durationObj.seconds
101-
? durationObj.seconds
102-
: '00'
103-
}`;
104-
return duration;
105-
}
106-
10792
function constructSongObj(video, user) {
108-
let duration = formatDuration(video.duration);
93+
let duration = video.durationFormatted;
10994
return {
110-
url: `https://www.youtube.com/watch?v=${video.raw.id}`,
95+
url: `https://www.youtube.com/watch?v=${video.id}`,
11196
title: video.title,
11297
rawDuration: video.duration,
11398
duration,
114-
thumbnail: video.thumbnails.high.url,
99+
thumbnail: video.thumbnail.url,
115100
memberDisplayName: user.username,
116101
memberAvatar: user.avatarURL('webp', false, 16)
117102
};
118103
}
119104

120105
async function processURL(url, interaction) {
121106
if (url.match(/^https?:\/\/(www.youtube.com|youtube.com)\/playlist(.*)$/)) {
122-
const playlist = await youtube.getPlaylist(url).catch(function() {
107+
const playlist = await YouTube.getPlaylist(url).catch(function() {
123108
interaction.followUp(
124109
':x: Playlist is either private or it does not exist!'
125110
);
126111
});
127112
if (!playlist) {
128113
return false;
129114
}
130-
const videosArr = await playlist.getVideos().catch(function() {
131-
interaction.followUp(
132-
':x: There was a problem getting one of the videos in the playlist!'
133-
);
134-
return;
135-
});
115+
let videosArr = await playlist.fetch();
116+
videosArr = videosArr.videos;
136117
let urlsArr = [];
137118
for (let i = 0; i < videosArr.length; i++) {
138-
if (videosArr[i].raw.status.privacyStatus == 'private') {
119+
if (videosArr[i].private) {
139120
continue;
140121
} else {
141122
try {
142-
const video = await videosArr[i].fetch();
123+
const video = videosArr[i];
143124
urlsArr.push(constructSongObj(video, interaction.member.user));
144125
} catch (err) {
145126
return console.error(err);
@@ -148,17 +129,14 @@ async function processURL(url, interaction) {
148129
}
149130
return urlsArr;
150131
}
151-
url = url
152-
.replace(/(>|<)/gi, '')
153-
.split(/(vi\/|v=|\/v\/|youtu\.be\/|\/embed\/)/);
154-
const id = url[2].split(/[^0-9a-z_\-]/i)[0];
155-
const video = await youtube.getVideoByID(id).catch(function() {
132+
133+
const video = await YouTube.getVideo(url).catch(function() {
156134
interaction.followUp(
157135
':x: There was a problem getting the video you provided!'
158136
);
159137
return;
160138
});
161-
if (video.raw.snippet.liveBroadcastContent === 'live') {
139+
if (video.live) {
162140
interaction.followUp("I don't support live streams!");
163141
return false;
164142
}

0 commit comments

Comments
 (0)