개요
야매로 독학한 js에 한계를 느껴서 제대로 공부를 해보려고 했는데, 역시 나는 뭐라도 해보면서 배우는 게 맞는 거 같다.
js 연습 겸 요새 하는 게임의 디스코드 봇을 제작해봤다.
처음에는 이번 기회에 discord.py로 만들면서 파이썬 공부나 해볼까 했는데 개발이 종료된 걸 보고 하는 거 쭉 하는 게 역시 맞구나 싶었다.
0편은 한참 전에 썼던 글인데 다음 글부터는 슬래시 커맨드 기준으로 글을 작성할 예정이다.
내년 4월부터 메시지형 명령어가 제한되기 때문에 기존에 제작한 봇도 슬래시 커맨드로 새로 만들었다.
Node.js 설치
진행을 위해 필요한 것들을 아래 명령어로 설치한다.
$ sudo apt install curl wget
Node.js는 NodeSource Ubuntu binary distributions repository에서 받을 수 있다.
아래의 명령어로 Node.js를 설치한다.
$ curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -
$ sudo apt-get install -y nodejs
아래의 명령어로 node.js와 npm의 버전을 확인한다.
$ node -v
v14.16.0
$ npm -v
6.14.11
discord.js 설치
이번에도 내가 좋아하는 var 폴더에 nubibot 폴더를 생성해줬다.
생성 후에는 권한을 변경해준다.
$ sudo mkdir /var/nubibot
$ sudo chown ubuntu:ubuntu /var/nubibot
해당 폴더로 가서 아래의 명령어를 입력한다.
$ cd /var/nubibot
$ npm init
대충 설정이 끝나면 package.json 파일을 열어 아래의 내용을 추가한다.
"private": true
아래의 명령어로 discord.js를 설치한다.
음성 채팅 관련 기능도 사용을 할 예정이기 때문에 opusscript를 같이 설치했다.
$ npm install discord.js opusscript
기본적인 봇 생성
봇을 생성하려면 우선 디스코드 개발자 포털에서 새로운 어플리케이션을 생성해야 된다.
링크로 이동해서 New Application 버튼을 클릭하고 대충 이름을 입력하면 어플리케이션이 생성된다.
생성 후에 좌측의 Bot 메뉴에 들어가서 봇을 생성하면 위와 같은 화면이 나오는데, 작성할 자바스크립트 파일을 봇과 연동하려면 토큰이 필요하다.
Copy 버튼을 눌러 봇의 토큰을 복사할 수 있다.
이제 봇의 기능을 입력할 index.js 파일을 작성할 차례다.
discord.js 깃허브에 있는 기본 예제는 다음과 같다.
토큰을 지우고 생성한 봇의 토큰을 입력하면 된다.
const { Client, Intents } = require('discord.js');
const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] });
client.on('ready', () => {
console.log(`Logged in as ${client.user.tag}!`);
});
client.on('message', msg => {
if (msg.content === 'ping') {
msg.channel.send('pong');
}
});
client.login('토큰');
작성이 완료되면 아래의 명령어로 봇이 서버에 접속할 수 있다.
$ node index.js
접속에 성공하면 'Logged in as ...'라고 출력되고, 봇이 접속한 서버에서 ping이라는 메시지를 전송하면 봇이 pong이라는 메시지로 응답한다.
설정파일 생성
이렇게 제작한 봇은 깃허브에 업로드할 생각인데, 토큰이 index.js 파일에 나와있으니 이대로는 업로드를 할 수 없다.
nubibot/config/config.json 파일을 생성해서 토큰과 접두사(커맨드를 인식하게 할 문자)를 해당 파일에서 불러올 수 있게 아래의 내용을 입력한다.
{
"token": "토큰",
"prefix": "!"
}
이제 index.js 파일을 수정해서 설정 파일의 설정을 불러올 수 있게 한다.
설정 파일을 불러오는 것 외에도 접두사로 커맨드를 인식할 수 있게 하고, 커맨드 부분을 if로 작성하면 코드가 길어지기 때문에 switch로 변경해줬다.
const Discord = require("discord.js");
const { token, prefix } = require("./config/config.json");
const client = new Discord.Client();
client.on('ready', () => { // 여기서 사용되는 Arrow Function은 콜백함수
console.log(`${client.user.tag} 접속 성공!`); // Bot이 준비가 되면 실행할 콜백함수
});
client.on("message", function (message) {
// message 작성자가 봇이면 그냥 return
if (message.author.bot) return;
// message 시작이 prefix가 아니면 return
if (!message.content.startsWith(prefix)) return;
const commandBody = message.content.slice(prefix.length);
const args = commandBody.split(' ');
const command = args.shift().toLowerCase();
const input = args;
switch (command) {
case "뽕":
message.channel.send(`뿡!`);
break;
}
});
client.login(token);
다시 봇을 실행하면 정상적으로 접속이 된다.
서버에서 '!뽕'이라는 메시지를 전송하면 '뿡!'이라고 응답한다.
커맨드 추가
바로 위의 포스트에서 만든 봇에 몇 가지 기능을 추가해줬다.
case로 새로운 커맨드를 추가할 수 있다.
- 프로필 이미지 출력
- 채널 메시지 삭제
const Discord = require("discord.js");
const { token, prefix } = require("./config/config.json");
const client = new Discord.Client();
client.on('ready', () => { // 여기서 사용되는 Arrow Function은 콜백함수
console.log(`${client.user.tag} 접속 성공!`); // Bot이 준비가 되면 실행할 콜백함수
});
client.on("message", function (message) {
// message 작성자가 봇이면 그냥 return
if (message.author.bot) return;
// message 시작이 prefix가 아니면 return
if (!message.content.startsWith(prefix)) return;
const commandBody = message.content.slice(prefix.length);
const args = commandBody.split(' ');
const command = args.shift().toLowerCase();
const input = args;
switch (command) {
case "뽕":
message.channel.send(`뿡!`);
break;
case "프로필":
message.channel
.send(
message.author.displayAvatarURL(),
);
break;
case "삭제":
if (!message.member.hasPermission('MANAGE_MESSAGES')) {
return message.channel
.send(
"메시지 관리 권한이 없어요!",
);
}
if (isNaN(input)) {
return message.channel
.send('삭제할 메시지의 수를 입력해주세요!')
.then((sent) => {
setTimeout(() => {
sent.delete();
}, 2500);
});
}
if (Number(input) < 0) {
return message.channel
.send('양수만 입력이 가능해요!')
.then((sent) => {
setTimeout(() => {
sent.delete();
}, 2500);
});
}
const amount = Number(input) > 100
? 101
: Number(input) + 1;
message.channel.bulkDelete(amount, true)
.then((_message) => {
message.channel
.send(`명령어와 메시지 \`${_message.size - 1}\`개를 삭제했어요! :broom:`)
.then((sent) => {
setTimeout(() => {
sent.delete();
}, 2500);
});
});
}
});
client.login(token);
'!프로필'이라고 전송하면 사용자의 프로필 이미지를 출력하고, '!삭제 n'이라고 입력하면 커맨드(!삭제 n)와 입력한 숫자(n)만큼의 메시지를 삭제한다.
깃허브 업로드
아래의 명령어로 git 사용자 정보를 깃허브에서 사용하는 이름과 이메일로 수정해준다.
$ git config --global --edit
업로드를 하기 전에 내 깃허브에서 NubiBot이라는 리포지토리를 생성했다.
이제 콘솔에서 /var/nubibot 폴더를 업로드할 수 있다.
$ git init
$ git add index.js
$ git add package.json
$ echo "# NubiBot" >> README.md
$ git add README.md
$ git commit -m "first commit"
$ git branch -M master
$ git remote add origin https://github.com/nubihub/NubiBot.git
$ git push -u origin master
콘솔에서 깃허브에 업로드하는 건 처음인데 어찌저찌 되긴 했다..