Skip to content

Commit

Permalink
Merge pull request #4 from DestroyCom/v0.9
Browse files Browse the repository at this point in the history
V0.9.0
DestroyCom authored Apr 14, 2022
2 parents cab1046 + d365743 commit 393dc6b
Showing 16 changed files with 1,718 additions and 1,486 deletions.
1 change: 0 additions & 1 deletion .env.dist
Original file line number Diff line number Diff line change
@@ -2,6 +2,5 @@ BOT_TOKEN = Your_Bot_Token
CHANNEL_ID = Your_Channel_Id
VOICE_CHANNEL_ID = Your_Voice_Channel_Id
USER_ID = Your_User_Id
GOOGLE_YOUTUBE_API_KEY = Your_Youtube_Api_Key
XIAOMI_SONG = false
TRIGGER_PREFIX = '&'
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -26,3 +26,5 @@ src
.env.prin
.env.copy
codeExample
OLD
wait_*
41 changes: 15 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -6,20 +6,18 @@ This project being at the beginning "Je Reviens Of DevilKing", so it can also se
## How to use it ?

The bot has 4 commands:
_You have to add the prefix before each command (e.g. `&p [music]`)_
_You have to add your prefix before each command (e.g. `&p [music]`)_

- `p [music url or music name]` is used to start playing music.
- `s` is used to skip the current music
- `w` is used to pause the current music
- `r` is used to resume the current music
- `fo` disconnects the bot and stops the music playing
- `ne` play the french Xiaomi 11 Lite NE Song.
- `q` display the current music queue.
- `feur` is used to be able to "feur" your friends
- `play [music url or music name]` is used to start playing music (or `p`).
- `skip` is used to skip the current music (or `s`).
- `pause` is used to pause the current music (or `pa`).
- `resume` is used to resume the current music (or `re`).
- `fuckoff` disconnects the bot and stops the music playing (or `fo`).
- `queue` display the current music queue (or `q`).

## Deploys

**You will need a _Youtube API Key_ and a _Discord Developper Application_ !!**
**You will need a _Discord Developper Application_ !!**

### Deploy on Heroku

@@ -46,33 +44,24 @@ The bot uses :

- Discord.JS - [Website](https://discord.js.org/#/) - [Github repository](https://github.com/discordjs/discord.js/)
- dotenv - [dotenv on npm](https://www.npmjs.com/package/dotenv)
- esm - [esm on npm](https://www.npmjs.com/package/esm)
- google APIs [Website](https://developers.google.com/) - [npm](https://www.npmjs.com/package/googleapis)
- ffmpeg - [website](https://www.ffmpeg.org/)
- fluent ffmpeg - [fluent-ffmpeg on npm](https://www.npmjs.com/package/fluent-ffmpeg)
- ytdl core - [Github repository](https://github.com/fent/node-ytdl-core) - [ytdl on npm](https://www.npmjs.com/package/ytdl-core)
- play-dl - [Github repository](https://github.com/play-dl/play-dl) - [ytdl on npm](https://www.npmjs.com/package/play-dl)
- Heroku Buildpack FFMPEG - [Github repository](https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest)

# Made by DestCom

| Who | Mail | LinkedIn | GitHub | Portfolio |
| ------------------------ | ------------------------------------------ | ------------------------------------------------ | ------------------------------------- | -------------------------------------------- |
| Azevedo Da Silva Antoine | [HERE](antoine.azevedo-da-silva@hetic.net) | [HERE](https://www.linkedin.com/in/antoine-ads/) | [HERE](https://github.com/DestroyCom) | [HERE](https://destroykeaum.alwaysdata.net/) |
| Azevedo Da Silva Antoine | [HERE](antoine.azevedo-da-silva@hetic.net) | [HERE](https://www.linkedin.com/in/antoine-ads/) | [HERE](https://github.com/DestroyCom) | [HERE](https://destcom.herokuapp.com/) |

#### Roadmap

- [x] Basic features (play/skip/quit)
- [x] Searching music (Youtube API)
- [x] Add first discord embeds
- [x] Update Readme (How to deploy)
- [x] Handle playlist request [Planned for 0.7 realease]
- [x] Add "pause" & "resume" feature [Planned for 0.8 realease]
- [x] Delete request message [Planned for 0.8 realease]
- [x] Display actual song queue [Planned for 0.8 realease]
- [ ] Transform current function into modules [Planned for 0.9 realease]
- [x] Add customs prefix [Planned for 0.8 realease]
- [ ] Add help for getting API Key [Planned for 0.9 realease]
- [ ] Change the "Xiaomi Song" into a custom song selection & add a disabling method [Planned before 0.9 realease]
_See old steps of the roadmap at [archives/TODO.md](./archives/TODO.md)_

- [ ] Transform repetitive code into modules or functions [Planned for 0.9 realease]
- [ ] Add a redo play [Planned before 1.0 realease]
- [ ] Change the "Xiaomi Song" into a custom song selection & add a disabling method [Planned before 1.0 realease]
- [ ] Fix "I'll be back" features and creates a disabling method [Planned before 1.0 realease]
- [ ] Add multi-language support (English/French to start) [Planned before 1.0 realease]
- [ ] Add Smart Assistant support [No plan]
680 changes: 98 additions & 582 deletions app.js

Large diffs are not rendered by default.

7 changes: 1 addition & 6 deletions app.json
Original file line number Diff line number Diff line change
@@ -33,11 +33,6 @@
"required": "true",
"value": "YOUR CHANNEL_ID"
},
"GOOGLE_YOUTUBE_API_KEY": {
"description": "The API Key from google API used for the music search.",
"required": "true",
"value": "YOUR GOOGLE_YOUTUBE_API_KEY"
},
"XIAOMI_SONG": {
"description": "Boolean. if True: Activate the NE command for playing Xiaomi 11 Lite NE Song.",
"required": "true",
@@ -49,6 +44,6 @@
"value": "&"
}
},
"success_url": "https://destroykeaum.alwaysdata.net/caard.html",
"success_url": "https://destcom.herokuapp.com/",
"keywords": ["nodejs", "discord", "discordjs", "esm", "dotenv", "music", "youtube"]
}
12 changes: 12 additions & 0 deletions archives/TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Roadmap Archive

- [x] Basic features (play/skip/quit)
- [x] Searching music (Youtube API)
- [x] Add first discord embeds
- [x] Update Readme (How to deploy)
- [x] Handle playlist request [Planned for 0.7 realease]
- [x] Add "pause" & "resume" feature [Planned for 0.8 realease]
- [x] Delete request message [Planned for 0.8 realease]
- [x] Display actual song queue [Planned for 0.8 realease]
- [x] Add customs prefix [Planned for 0.8 realease]
- [x] ~~Add help for getting API Key [Planned for 0.9 realease]~~ (unnecessary)
718 changes: 718 additions & 0 deletions archives/before-modules/app.js

Large diffs are not rendered by default.

54 changes: 54 additions & 0 deletions archives/before-modules/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"name": "StroyCord/D-Key Bot - Music Bot for discord",
"description": "A discord bot to play music on discord's VC",
"repository": "https://github.com/DestroyCom/JE-REVIENS-OF-DEVILKING",
"logo": "https://destroykeaum.alwaysdata.net/assets/other/stroybot_logo.png",
"website": "https://destroykeaum.alwaysdata.net/",
"buildpacks": [{
"url": "heroku/nodejs"
},
{
"url": "https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest"
}
],

"env": {
"BOT_TOKEN": {
"description": "The token of your bot discord.",
"required": "true",
"value": "YOUR BOT_TOKEN"
},
"USER_ID": {
"description": "The id of the user you want to see when he logs out.",
"required": "true",
"value": "YOUR USER_ID"
},
"VOICE_CHANNEL_ID": {
"description": "The id of the voice room you are checking.",
"required": "true",
"value": "YOUR VOICE_CHANNEL_ID"
},
"CHANNEL_ID": {
"description": "The id of the salon where you want to send the message.",
"required": "true",
"value": "YOUR CHANNEL_ID"
},
"GOOGLE_YOUTUBE_API_KEY": {
"description": "The API Key from google API used for the music search.",
"required": "true",
"value": "YOUR GOOGLE_YOUTUBE_API_KEY"
},
"XIAOMI_SONG": {
"description": "Boolean. if True: Activate the NE command for playing Xiaomi 11 Lite NE Song.",
"required": "true",
"value": "false"
},
"TRIGGER_PREFIX": {
"description": "Single Character. The prefix with which you intend to use the bot (e.g. to trigger commands).",
"required": "true",
"value": "&"
}
},
"success_url": "https://destroykeaum.alwaysdata.net/caard.html",
"keywords": ["nodejs", "discord", "discordjs", "esm", "dotenv", "music", "youtube"]
}
33 changes: 33 additions & 0 deletions archives/before-modules/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "stroycord",
"description": "La fameuse phrase \"je reviens\" de DevilKing a chaque depart de ce dernier de discord INCLUS MAINTENANT UN BOT MUSICAL",
"version": "0.8.4",
"engines": {
"node": "16.13.2"
},
"scripts": {
"start": "node app.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/DestroyCom/JE-REVIENS-OF-DEVILKING.git"
},
"author": "Dest.Com",
"license": "MIT",
"bugs": {
"url": "https://github.com/DestroyCom/JE-REVIENS-OF-DEVILKING/issues"
},
"homepage": "https://github.com/DestroyCom/JE-REVIENS-OF-DEVILKING#readme",
"dependencies": {
"@discordjs/opus": "^0.5.3",
"@discordjs/voice": "^0.7.5",
"discord.js": "^13.6.0",
"dotenv": "^12.0.3",
"ffmpeg": "^0.0.4",
"ffmpeg-static": "^4.4.1",
"googleapis": "^92.0.0",
"libsodium-wrappers": "^0.7.9",
"play-dl": "^1.7.8"
}
}
157 changes: 157 additions & 0 deletions components/action_function.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
const playdl = require("play-dl");
const { AudioPlayerStatus, createAudioResource } = require("@discordjs/voice");

const embed_constructor = require("./embed_constructor");

const play = async (guild, song, queue) => {
const serverQueue = queue.get(guild.id);
if (!song) {
queue.delete(guild.id);
try {
if (serverQueue) {
serverQueue.connection.destroy();
}
} catch (e) {
console.log("Connection already destroyed");
console.log(e);
}
return;
}

var source = await playdl.stream(song.url);

const stream = createAudioResource(source.stream, {
inputType: source.type,
});

serverQueue.player.play(stream);

serverQueue.connection.subscribe(serverQueue.player);

serverQueue.player.on(AudioPlayerStatus.Idle, () => {
serverQueue.songs.shift();
play(guild, serverQueue.songs[0], queue);
});

return;
};

const skip = (message, serverQueue, queue) => {
if (message !== "skipError") {
if (!message.member.voice.channel)
return message.channel.send({
content:
"Vous avez besoin d'etre dans un salon vocal pour arreter une musique !",
});
}
if (!serverQueue) {
return message.channel.send({
content: "Aucune musique n'est jouée actuellement !",
});
}

let tmpGuildObject = {
id: message.guildId,
};

serverQueue.songs.shift();
play(tmpGuildObject, serverQueue.songs[0], queue);
};

const stop = (message, serverQueue, queue) => {
if (!message.member.voice.channel)
return message.channel.send({
content:
"Vous avez besoin d'etre dans un salon vocal pour arreter le bot !",
});

if (!serverQueue)
return message.channel.send({
content: "Aucune musique n'est jouée actuellement !",
});

try {
serverQueue.connection.destroy();
} catch (e) {
console.log("Connection already destroyed");
console.log(e);
}
queue.delete(message.guildId);

return message.channel
.send({
content: `❌ ${message.author} a déconnecté le bot !`,
})
.catch(console.error);
};

const pause = (message, serverQueue) => {
if (!message.member.voice.channel)
return message.channel.send({
content:
"Vous avez besoin d'etre dans un salon vocal pour controler le bot !",
});

if (!serverQueue)
return message.channel.send({
content: "Aucune musique n'est jouée actuellement !",
});

if (serverQueue.playing) {
serverQueue.playing = false;
serverQueue.player.pause();
return message.channel
.send({
content: `⏸ ${message.author} a mis en pause la musique !`,
})
.catch(console.error);
}
};

const resume = (message, serverQueue) => {
if (!message.member.voice.channel)
return message.channel.send({
content:
"Vous avez besoin d'etre dans un salon vocal pour controler le bot !",
});

if (!serverQueue)
return message.channel.send({
content: "Aucune musique n'est jouée actuellement !",
});

if (!serverQueue.playing) {
serverQueue.playing = true;
serverQueue.player.unpause();
return message.channel
.send({
content: `▶ ${message.author} a repris la musique !`,
})
.catch(console.error);
}
};

const queue = (message, queue) => {
const serverQueue = queue.get(message.guild.id);
if (!serverQueue)
return message.channel.send({
content: "Aucune musique n'est jouée actuellement !",
});
let songsList = serverQueue.songs;

if (!serverQueue || songsList.length === 0)
return message.channel.send({
content: "Aucune musique n'est jouée actuellement !",
});

return message.channel.send({
embeds: [embed_constructor.queue(songsList)],
});
};

exports.play = play;
exports.skip = skip;
exports.stop = stop;
exports.pause = pause;
exports.resume = resume;
exports.queue = queue;
12 changes: 12 additions & 0 deletions components/bases.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const embed_constructor = require("./embed_constructor");

exports.dependencies_reports = () => {
let { generateDependencyReport } = require("@discordjs/voice");
console.log(generateDependencyReport());
};

exports.errors = (errorMsg, message) => {
return message.channel.send({
embeds: [embed_constructor.error(errorMsg)],
});
};
176 changes: 176 additions & 0 deletions components/embed_constructor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
const { MessageEmbed } = require("discord.js");

exports.new = (song, message, PREFIX) => {
return new MessageEmbed()
.setTitle(song.title)
.setAuthor({
name: message.author.username,
iconURL: message.author.avatarURL(),
})
.setColor("#C4302B")
.setFooter({
text: "StroyCord/D-Key Bot",
iconURL:
"https://destroykeaum.alwaysdata.net/assets/other/stroybot_logo.png",
})
.setThumbnail(song.thumbnail)
.setTimestamp()
.setURL(song.url)
.addFields(
{
name: message.author.username + " a demandé cette musique !",
value: song.title,
},
{
name: "De :",
value: song.videoAuthor,
inline: true,
},
{
name: "Trouvé avec :",
value: PREFIX + "p " + song.url,
inline: true,
},
{
name: "Durée :",
value: song.videoLength,
}
);
};

exports.list = (message, playlistData, PREFIX) => {
let size = playlistData.videos.length;
if (size > 30) size = 30;

let msg = new MessageEmbed()
.setTitle(message.author.username + " a ajouté une playlist !")
.setAuthor({
name: message.author.username,
iconURL: message.author.avatarURL(),
})
.setColor("#C4302B")
.setFooter({
text: "StroyCord/D-Key Bot",
iconURL:
"https://destroykeaum.alwaysdata.net/assets/other/stroybot_logo.png",
})
.setTimestamp()
.setURL(playlistData.url)
.addFields(
{
name: "Trouvé avec :",
value: PREFIX + "p " + playlistData.url,
},
{
name: "Nom de la playlist :",
value: playlistData.title,
inline: true,
},
{
name: "Playlist crée par :",
value: playlistData.channel.name,
inline: true,
},
{
name: "Mis en file d'attente :",
value:
(playlistData.videos.length > 30 ? 30 : playlistData.videos.length) +
" musiques",
}
);

if (playlistData.thumbnail !== undefined)
msg.setThumbnail(playlistData.thumbnail.url);

return msg;
};

exports.added = (song, message, PREFIX) => {
return new MessageEmbed()
.setTitle(
message.author.username + " a ajouté une musique sur la file d'attente !"
)
.setAuthor({
name: message.author.username,
iconURL: message.author.avatarURL(),
})
.setColor("#C4302B")
.setFooter({
text: "StroyCord/D-Key Bot",
iconURL:
"https://destroykeaum.alwaysdata.net/assets/other/stroybot_logo.png",
})
.setThumbnail(song.thumbnail)
.setTimestamp()
.setURL(song.url)
.addFields(
{
name: song.title,
value: "\u200B",
},
{
name: "De :",
value: song.videoAuthor,
inline: true,
},
{
name: "Trouvé avec :",
value: PREFIX + "p " + song.url,
inline: true,
},
{
name: "Durée :",
value: song.videoLength,
}
);
};

exports.queue = (songsList) => {
let tabEmbeds = [];
songsList.forEach((song, index) => {
if (index > 10) {
return;
} else if (index === 10) {
tabEmbeds.push({
name: "...",
value: "\u200B",
});
} else {
tabEmbeds.push({
name: index + 1 + ". " + song.title,
value: song.videoAuthor + ", " + song.videoLength + " minutes.",
});
}
});

return new MessageEmbed()
.setTitle(
"Vous avez " + songsList.length + " musiques en liste d'attente !"
)
.setAuthor({
name: "Stroycord",
iconURL:
"https://destroykeaum.alwaysdata.net/assets/other/stroybot_logo.png",
})
.setColor("#37123C")
.setFooter({
text: "StroyCord/D-Key Bot",
iconURL:
"https://destroykeaum.alwaysdata.net/assets/other/stroybot_logo.png",
})
.setTimestamp()
.addFields(tabEmbeds);
};

exports.error = (errorMsg) => {
return new MessageEmbed()
.setTitle("⚠️ UNE ERREUR S'EST PRODUITE !")
.setDescription(errorMsg)
.setAuthor({
name: "Stroycord",
iconURL:
"https://destroykeaum.alwaysdata.net/assets/other/stroybot_logo.png",
})
.setColor("#181818")
.setTimestamp();
};
92 changes: 92 additions & 0 deletions components/queue_constructor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
const playdl = require("play-dl");
const { createAudioPlayer, joinVoiceChannel } = require("@discordjs/voice");

const bases = require("./bases");
const embed_constructor = require("./embed_constructor");
const song_constructor = require("./song_constructor");
const actions = require("./action_function");

const queue_create = async (
message,
video,
voiceChannel,
index,
embed,
type,
queue,
PREFIX
) => {
const serverQueue = queue.get(message.guild.id);
var songInfo = {};

try {
var songInfo = await playdl.video_info(video.url);

let minutes = Math.floor(songInfo.video_details.durationInSec / 60);
let seconds = songInfo.video_details.durationInSec - minutes * 60;

const song = await song_constructor.song(
songInfo,
message,
minutes,
seconds
);

if (index == 0 && !serverQueue) {
const queueContruct = {
textChannel: message.channel,
voiceChannel: voiceChannel,
connection: null,
player: null,
songs: [],
volume: 5,
playing: true,
};

queue.set(message.guild.id, queueContruct);

queueContruct.songs.push(song);

try {
var connection = await joinVoiceChannel({
channelId: voiceChannel.id,
guildId: voiceChannel.guild.id,
adapterCreator: voiceChannel.guild.voiceAdapterCreator,
});
queueContruct.connection = connection;

var player = createAudioPlayer();
queueContruct.player = player;

actions.play(message.guild, queueContruct.songs[0], queue);

if (type == "playlist") {
return message.channel.send({
embeds: [embed_constructor.list(embed[0], embed[1], PREFIX)],
});
} else {
return message.channel.send({
embeds: [embed_constructor.new(song, embed[0], embed[1])],
});
}
} catch (error) {
queue.delete(message.guild.id);
require("./bases").errors(error, message);
return "ERR";
}
} else {
serverQueue.songs.push(song);
if (serverQueue && index === 0)
return message.channel.send({
embeds: [embed_constructor.added(song, embed[0], embed[1])],
});
}
} catch (err) {
console.log(err);
bases.errors(err.toString(), message);
return "ERR";
return;
}
};

exports.queue_create = queue_create;
14 changes: 14 additions & 0 deletions components/song_constructor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
exports.song = async (songInfo, message, minutes, seconds) => {
return {
title: songInfo.video_details.title,
url: songInfo.video_details.url,
thumbnail:
songInfo.video_details.thumbnails[
songInfo.video_details.thumbnails.length - 1
].url,
requestAuthor: message.author,
querySearch: "p",
videoAuthor: songInfo.video_details.channel.name,
videoLength: minutes + ":" + seconds,
};
};
1,190 changes: 327 additions & 863 deletions package-lock.json

Large diffs are not rendered by default.

15 changes: 7 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"name": "stroycord",
"description": "La fameuse phrase \"je reviens\" de DevilKing a chaque depart de ce dernier de discord INCLUS MAINTENANT UN BOT MUSICAL",
"version": "0.8.4",
"version": "0.9.0-beta.5",
"engines": {
"node": "16.13.2"
"node": ">=16.14.*"
},
"scripts": {
"start": "node app.js",
@@ -20,14 +20,13 @@
},
"homepage": "https://github.com/DestroyCom/JE-REVIENS-OF-DEVILKING#readme",
"dependencies": {
"@discordjs/opus": "^0.5.3",
"@discordjs/voice": "^0.7.5",
"@discordjs/opus": "^0.7.0",
"@discordjs/voice": "^0.8.0",
"discord.js": "^13.6.0",
"dotenv": "^12.0.3",
"ffmpeg": "^0.0.4",
"ffmpeg-static": "^4.4.1",
"googleapis": "^92.0.0",
"libsodium-wrappers": "^0.7.9",
"play-dl": "^1.7.8"
"ffmpeg-static": "^5.0.0",
"libsodium-wrappers": "^0.7.10",
"play-dl": "^1.9.4"
}
}

0 comments on commit 393dc6b

Please sign in to comment.