Создание музыкального бота в Discord
Всем привет! Сегодня поговорим про cоздание музыкального бота с помощью Discord.js в популярной бесплатной программе общения Discord. Итак, поехали!
API discord предоставляет инструмент для создания и использования ботов. Рассмотрим пример создания базового музыкального бота и добавления его на сервер. Бот сможет проигрывать, пропускать и останавливать музыку, а также будет поддерживать функцию очереди воспроизведения.
Установка discord-бота
Создаем новое приложение на портале разработки discord.
Переходим на портал и нажимаем на “new application”.
Затем вводим название приложения и нажимаем на кнопку “create”.
Затем переходим на вкладку бот и нажимаем на “add bot”.
Бот создан! Теперь можно перейти к добавлению его на сервер.
Добавление бота на сервер
Добавляем созданный бот с помощью генератора OAuth2 URL.
Для этого переходим на страницу OAuth2 и выбираем бота в панели scope.
Затем выбираем необходимые разрешения для проигрывания музыки и чтения сообщений.
Теперь копируем сгенерированный URL и вставляем его в браузер.
Затем выбираем сервер, на который хотим добавить URL и нажимаем на кнопку “authorize”.
Создание проекта
Переходим к созданию проекта с использованием терминала.
Для начала создаем директорию и переходим в нее, используя две следующие команды:
mkdir musicbot && cd musicbot
Затем создаем модули проекта с помощью команды npm init. После введения команды будут заданы несколько вопросов. Ответьте на них и продолжайте.
Создаем два файла, в которых мы будем работать.
touch index.js && touch config.json
Теперь откройте проект в текстовом редакторе. Я использую VS Code и открываю его с помощью следующей команды:
code.
Основы Discord js
Прежде чем начать, нужно установить несколько зависимостей.
npm install discord.js ffmpeg-binaries opusscript ytdl-core --save
После завершения установки продолжаем написание файла config.json. Сохраните для бота токен и префикс, который он должен слушать.
{
"prefix": "!",
"token": "your-toke"
}
Для получения токена снова зайдите на портал разработки discord и скопируйте его из раздела bot.
Это все, что нужно выполнить в файле config.json. Приступим к написанию кода javascript.
Сначала импортируем все зависимости.
const Discord = require('discord.js');
const {
prefix,
token,
} = require('./config.json');
const ytdl = require('ytdl-core');
Затем с помощью токена создаем клиента и логин.
const client = new Discord.Client();
client.login(token);
Добавляем несколько базовых listeners, выполняющих метод console.log при запуске.
client.once('ready', () => {
console.log('Ready!');
});
client.once('reconnecting', () => {
console.log('Reconnecting!');
});
client.once('disconnect', () => {
console.log('Disconnect!');
});
Теперь можно начать работу с ботом с помощью команды node. Бот должен быть online в discord и в консоль выведется“Ready!”
node index.js
Чтение извещений
Бот располагается на сервере и имеет возможность выходить online. Ныне возможно начать декламировать сообщения в чате и отвечать на них.
Для чтения извещений надо составить только 1 несложную функцию.
client.on('message', async message => {
}
Делаем listener для действия message, получаем известие и предохраняем его в объект message.
Испытываем: в случае если известие пришло от бота, то игнорируем его.
if (message.author.bot) return;
В данной строке проверяется, считается ли создателем сообщения бот. Известие воротится, в случае если это так.
Вслед за тем испытываем, наступает ли известие с раньше конкретного префикса. Известие воротится, в случае если нет.
if (!message.content.startsWith(prefix)) return;
Впоследствии сего испытываем, какую команду надо запустить. Это возможно исполнить с поддержкой несложных операторов if.
const serverQueue = queue.get(message.guild.id);
if (message.content.startsWith(`${prefix}play`)) {
execute(message, serverQueue);
return;
} else if (message.content.startsWith(`${prefix}skip`)) {
skip(message, serverQueue);
return;
} else if (message.content.startsWith(`${prefix}stop`)) {
stop(message, serverQueue);
return;
} else {
message.channel.send('You need to enter a valid command!')
}
В данном блоке кода проверяется, какую команду надо запустить, а еще исполняется вызов команды. В случае если приобретенная команда недопустима, то вводим известие об ошибке в чат с внедрением функции send().
Спросив, какие команды надо запустить, возможно перебежать к их реализации.
Добавление песен
Начнем с прибавления команды play. Для сего потребуется песня и гильдия (гильдия дает собой отделенную коллекцию юзеров и каналов и нередко упоминается в качестве сервера). Еще потребуется раньше поставленная книгохранилище ytdl.
Для начала делаем map с заглавием очереди, в котором станут сохранены все песни, введенные в чат.
const queue = new Map();
Вслед за тем делаем функцию async под заглавием execute и испытываем, располагается ли юзер в голосовом чате, и есть ли у бота отвечающее позволение. В случае если нет, то пишем известие об ошибке и возвращаем.
async function execute(message, serverQueue) {
const args = message.content.split(' ');
const voiceChannel = message.member.voiceChannel;
if (!voiceChannel) return message.channel.send('You need to be in a voice channel to play music!');
const permissions = voiceChannel.permissionsFor(message.client.user);
if (!permissions.has('CONNECT') || !permissions.has('SPEAK')) {
return message.channel.send('I need the permissions to join and speak in your voice channel!');
}
}
Перебегаем к получению инфы о песне и сохранении ее в объект song. Для сего пользуемся библиотеку ytdl, которая получает информацию о песне по ссылке на youtube.
const songInfo = await ytdl.getInfo(args[1]);
const song = {
title: songInfo.title,
url: songInfo.video_url,
};
Важная информация сберегается в объект song.
Впоследствии хранения инфы надо сделать договор для прибавления в очередь. Для сего испытываем, определен ли serverQueue, собственно что значит, собственно что музыка уже играет. В случае если да, то добавляем песню в имеющий место быть serverQueue и отправляем известие об успешном выполнении. В случае если нет, то делаем его, подключаемся к голосовому каналу и начинаем проигрывать музыку.
if (!serverQueue) {
}else {
serverQueue.songs.push(song);
console.log(serverQueue.songs);
return message.channel.send(`${song.title} has been added to the queue!`);
}
В данном куске мы испытываем, считается ли serverQueue пустующим. В случае если нет добавляем туда песню.
В случае если serverQueue содержит смысл null, делаем договор.
// Creating the contract for our queue
const queueContruct = {
textChannel: message.channel,
voiceChannel: voiceChannel,
connection: null,
songs: [],
volume: 5,
playing: true,
};
// Setting the queue using our contract
queue.set(message.guild.id, queueContruct);
// Pushing the song to our songs array
queueContruct.songs.push(song);
try {
// Here we try to join the voicechat and save our connection into our object.
var connection = await voiceChannel.join();
queueContruct.connection = connection;
// Calling the play function to start a song
play(message.guild, queueContruct.songs[0]);
} catch (err) {
// Printing the error message if the bot fails to join the voicechat
console.log(err);
queue.delete(message.guild.id);
return message.channel.send(err);
}
В данном блоке кода формируется договор, а песня прибавляется в массив songs.
Вслед за тем присоединяемся к голосовому чату юзера и вызываем функцию play(), которую вслед за тем продадим.
Проигрывание песен
Потому что ныне возможно добавлять песни в очередь и делать договор при его недоступности, возможно приступить к реализации функцию проигрывания.
В начале делаем функцию play, которая владеет 2-мя параметрами (гильдия и песня, которую надо проиграть) и инспектирует, считается ли объект song пустующим. В случае если да, то оставляем голосовой канал и удаляем очередь.
function play(guild, song) {
const serverQueue = queue.get(guild.id);
if (!song) {
serverQueue.voiceChannel.leave();
queue.delete(guild.id);
return;
}
}
Вслед за тем начинаем проигрывать песню с поддержкой функции playStream() и URL-адреса песни.
const dispatcher = serverQueue.connection.playStream(ytdl(song.url))
.on('end', () => {
console.log('Music ended!');
// Deletes the finished song from the queue
serverQueue.songs.shift();
// Calls the play function again with the next song
play(guild, serverQueue.songs[0]);
})
.on('error', error => {
console.error(error);
});
dispatcher.setVolumeLogarithmic(serverQueue.volume / 5);
В данном куске мы делаем stream и передаем его URL-адресу песни. Еще добавляем 2 listeners, которые обрабатывают действия end и error.
Примечание: это рекурсивная функция, которая повторяет вызов самой себя. Рекурсия применяется для проигрывания надлежащей песни, когда иная завершается.
Ныне возможно проиграть песню, введя !play URL в чат.
Пропуск песен
Перебегаем к реализации функции пропуска. Для сего надо исполнить окончания диспетчера, сделанного в функции play() для начала проигрывания надлежащей песни.
function skip(message, serverQueue) {
if (!message.member.voiceChannel) return message.channel.send('You have to be in a voice channel to stop the music!');
if (!serverQueue) return message.channel.send('There is no song that I could skip!');
serverQueue.connection.dispatcher.end();
}
В данном куске мы испытываем, располагается ли юзер, который ввел команду, в голосовом канале, а еще есть ли песни для пропуска.
Остановка песен
Функция stop() смахивает на skip(), за исключением такого, собственно что массив songs очищается, по причине чего бот удаляет очередь и оставляет голосовой чат.
function stop(message, serverQueue) {
if (!message.member.voiceChannel) return message.channel.send('You have to be in a voice channel to stop the music!');
serverQueue.songs = [];
serverQueue.connection.dispatcher.end();
}
Отправной код для index.js
Полный исходный код для музыкального бота:
const Discord = require('discord.js');
const {
prefix,
token,
} = require('./config.json');
const ytdl = require('ytdl-core');
const client = new Discord.Client();
const queue = new Map();
client.once('ready', () => {
console.log('Ready!');
});
client.once('reconnecting', () => {
console.log('Reconnecting!');
});
client.once('disconnect', () => {
console.log('Disconnect!');
});
client.on('message', async message => {
if (message.author.bot) return;
if (!message.content.startsWith(prefix)) return;
const serverQueue = queue.get(message.guild.id);
if (message.content.startsWith(`${prefix}play`)) {
execute(message, serverQueue);
return;
} else if (message.content.startsWith(`${prefix}skip`)) {
skip(message, serverQueue);
return;
} else if (message.content.startsWith(`${prefix}stop`)) {
stop(message, serverQueue);
return;
} else {
message.channel.send('You need to enter a valid command!')
}
});
async function execute(message, serverQueue) {
const args = message.content.split(' ');
const voiceChannel = message.member.voiceChannel;
if (!voiceChannel) return message.channel.send('You need to be in a voice channel to play music!');
const permissions = voiceChannel.permissionsFor(message.client.user);
if (!permissions.has('CONNECT') || !permissions.has('SPEAK')) {
return message.channel.send('I need the permissions to join and speak in your voice channel!');
}
const songInfo = await ytdl.getInfo(args[1]);
const song = {
title: songInfo.title,
url: songInfo.video_url,
};
if (!serverQueue) {
const queueContruct = {
textChannel: message.channel,
voiceChannel: voiceChannel,
connection: null,
songs: [],
volume: 5,
playing: true,
};
queue.set(message.guild.id, queueContruct);
queueContruct.songs.push(song);
try {
var connection = await voiceChannel.join();
queueContruct.connection = connection;
play(message.guild, queueContruct.songs[0]);
} catch (err) {
console.log(err);
queue.delete(message.guild.id);
return message.channel.send(err);
}
} else {
serverQueue.songs.push(song);
console.log(serverQueue.songs);
return message.channel.send(`${song.title} has been added to the queue!`);
}
}
function skip(message, serverQueue) {
if (!message.member.voiceChannel) return message.channel.send('You have to be in a voice channel to stop the music!');
if (!serverQueue) return message.channel.send('There is no song that I could skip!');
serverQueue.connection.dispatcher.end();
}
function stop(message, serverQueue) {
if (!message.member.voiceChannel) return message.channel.send('You have to be in a voice channel to stop the music!');
serverQueue.songs = [];
serverQueue.connection.dispatcher.end();
}
function play(guild, song) {
const serverQueue = queue.get(guild.id);
if (!song) {
serverQueue.voiceChannel.leave();
queue.delete(guild.id);
return;
}
const dispatcher = serverQueue.connection.playStream(ytdl(song.url))
.on('end', () => {
console.log('Music ended!');
serverQueue.songs.shift();
play(guild, serverQueue.songs[0]);
})
.on('error', error => {
console.error(error);
});
dispatcher.setVolumeLogarithmic(serverQueue.volume / 5);
}
client.login(token);
На этом про создание музыкального бота с помощью Discord.js у нас все. Всем мир!
Рейтинг:
(голосов:1)
Не пропустите похожие инструкции:
Популярное
Авторизация
Добавить комментарий!