[취미생활] 디코 음악봇 gkdis6_discord_bot

sangyong·2023년 8월 5일
0

취미생활

목록 보기
2/2

이번에 같이 게임하는 친구들의 요청을 받아 디코봇에 유튜브 음악 스트리밍 기능을 추가해봤다.
기본적으론 https://github.com/brokiem/broki-s-music-bot/tree/master 해당 깃허브 소스를 참고했다.
해당 방식으로 진행하기 위해서
1. 유튜브 음악 기능 가져와 필요없는 부분 버리기
2. 파일 시스템을 사용하여 커맨드 당 하나의 파일 가지게 하기
3. 이전 봇에서 필요한 기능 재구현 및 추가 기능 구현
4. discord.js의 버전 업
로 진행했다.

봇을 만들 때 docs, 가이드와는 다른 점들이 꽤 많아 참고하지 못하였고, 내부 요소들을 찍어보고 테스트해보며 만들어서 시간이 좀 오래 소요되어 다른 분들은 좀 더 편하게 갔으면 하는 마음에 이 글을 작성하게 되었다.

전체적인 소스가 궁금하다면 https://github.com/gkdis6/gkdis6_discord_bot/tree/master 이곳을 참고하길 바랍니다.

  1. 유튜브 음악 기능을 처음부터 만드는 것도 재밌었겠지만, docs와 예시 등도 버전마다 많이 달라 참고하기 어려웠고 시간이 많지는 않았기에 위의 broki-s-music-bot을 일단 다 가져왔고, 유튜브 기능을 제외한 것은 배제하였다. topgg라는 디스코드 랭킹 사이트와 연관된 코드들(음악 큐 사이즈 제한, topgg 사이트에서 투표를 할 시 웹훅으로 투표 이벤트를 받아 유튜브 음악 큐의 사이즈를 늘려주는 기능 등)을 제거했다.

  2. 해당 부분은 다른 사람들도 많이 사용하는 방식으로 커맨드가 늘어날수록 하나의 파일 내에서 코드가 길어지는 것을 방지할 수 있고, 한 커맨드 당 하나의 파일을 가지기 때문에 유지보수도 쉬워지기 때문에 진행하였다.
    커맨드를 추가할 시 해당 봇의 서버에 명령어에 대한 정보를 배포하는 과정이 필요하다. deploy_commands.js 파일을 참고하면 된다.


import { REST, Routes } from "discord.js";
import fs from "fs";
import dotenv from "dotenv";
dotenv.config();

const token = process.env.DISCORD_TOKEN;
const rest = new REST({ version: "10" }).setToken(token);
const commands = [];
const command_files = fs.readdirSync("./commands").filter((file) => file.endsWith(".js"));
for await (const file of command_files) {
	const { data } = await import(`./commands/${file}`);
	commands.push(data.toJSON());
	console.log("Loaded command: " + data.name);
}

console.log("Loaded " + commands.length + " commands!\n");
console.log("Registering global commands...");

await rest.put(Routes.applicationCommands(process.env.CLIENT_ID), {
	body: commands,
}).then((dat) => console.log(dat))
.catch(console.error);
console.log("Successfully registered global commands.");
  1. 이 부분은 /commands/save.js 파일로 간단한 설명을 하면 data를 통해 입력 시 어떤 설명과 어떤 type의 데이터를 받을지 자기가 입력하는 데이터가 어떤 것인지를 쉽게 알 수 있다. 그리고 const code 부분을 보면 해당 입력값을 어떻게 받아오는지 알 수 있고 나머지는 잘 사용하면 된다.

import { SlashCommandBuilder } from "@discordjs/builders";
import { make_simple_embed } from "../utils/utils.js";
import { saveCode } from "../utils/notion.js";

export const data = new SlashCommandBuilder()
.setName("save")
.setDescription("Save the code")
.addStringOption((option) => option.setName("code").setDescription("Save Code!").setRequired(true));
//숫자일 경우 .addNumberOption((option) => 

export async function execute(interaction) {
	const code = interaction.options.getString("code");
	const message = await interaction.channel.send({
		embeds: [await make_simple_embed(`<a:loading:1032708714605592596> Saving to ${code}...`)],
		allowedMentions: { repliedUser: false },
	});

	if (saveCode(interaction.member.user.username, code)) {
		await message.edit({
			embeds: [make_simple_embed(`Success Save ${code} !!!`)],
			allowedMentions: { repliedUser: true },
		});
	} else {
		await message.edit({
			embeds: [make_simple_embed(`Failed Save ${code}...`)],
			allowedMentions: { repliedUser: true },
		});
	}
}
  1. 버전업이 사실 가장 어려웠고 오래 걸린 작업이다. 버전간 호환성을 알 수 없어 나오는 에러 코드를 하나씩 찾아봤고,
{
	"name": "gkdis6-music-bot",
	"version": "3.1.0",
	"license": "MIT",
	"type": "module",
	"dependencies": {
		"node": "^18.17.0",
		"@discordjs/builders": "^1.6.3",
		"@discordjs/opus": "^0.9.0",
		"@discordjs/rest": "^1.7.1",
		"@discordjs/voice": "^0.16.0",
		"discord-api-types": "^0.37.42",
		"discord.js": "^14.11.0",
		"play-dl": "^1.9.6",
		"prettier": "^2.8.4",
		"sodium-native": "^4.0.4",
		"dotenv": "^16.0.3",
		"@notionhq/client": "^2.2.3"
	},
	"scripts": {
		"test": "echo \"Error: no test specified\" && exit 1",
		"start": "node index.js",
		"dev": "nodemon index.js",
		"deploy-commands": "node deploy_commands.js",
		"pretty": "prettier --write ."
	}
}

opus와 discord.js, node 버전 간 호환성에 문제가 있어 opus의 해당 버전을 사용하기 위해선 discord.js의 버전이 14.11.0, 그리고 그 버전에 맞는 node 버전이 18.17.0 이라는 것을 여러번 빌드해보며 알게되었다. 참고가 되었으면 좋겠다.

+음악 볼륨을 조절하는 명령어를 추가했지만 https://discord-kr.js.org/#/docs/main/korean/class/VolumeInterface, https://github.com/discord/discord-api-docs/blob/main/docs/game_sdk/Discord_Voice.md#setlocalvolume 등의 문서와 같이 보이스채널의 음량을 조절하고 싶었지만 결국 찾지 못해 inline volume을 조절하는 방식으로 구현하였다.(내가 해당 볼륨을 조절하면 다른 사용자의 볼률도 같이 조절됨, 스트리밍 되는 동영상 자체의 음량을 바꾸는 방식) 혹시나 다른 방법이나 참고할만한 코드가 있다면 댓글로 알려주시면 감사하겠습니다.

0개의 댓글