discord.js
덤프버전 : (♥ 0)
1. 개요[편집]
디스코드 API를 사용하여 봇을 만드는 Node.js 라이브러리이다.
현재 자바스크립트로 디스코드 봇을 개발할 때 가장 많이 쓰이고 있으며, discord RPC를 지원하고 Commando라는 명령어를 알아서 핸들링해주는 공식 라이브러리가 있다.
2. 개발 시 주의사항[편집]
우선 이 예제를 따라하기 전에, discord.Collection() 객체를 완벽히 사용할 수 있어야 한다. Collection 객체는 거의 모든 종류의 cache에서[1] 리턴하는 값이기 때문에 .filter, .map 등의 메서드를 사용하는 데 익숙하지 않다면 해당 기능들을 활용하기 어렵다.
3. 설치[편집]
discord.js는 npm또는 yarn에서 설치할 수 있다.
npm i discord.js
yarn에서는
yarn add discord.js
참고로 구버전이 필요한 경우에는 npm의 경우
npm install discord.js@<버전번호>
[2] 로 설치할 수 있다.4. 예제[편집]
4.1. 예제 1[편집]
const Discord = require('discord.js');
const { GatewayIntentBits } = require('discord.js')
const client = new Discord.Client({
intents: [ // Intent를 설정합니다. 설정하지 않으면 CLIENT_MISSING_INTENTS 오류가 발생합니다.
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages
]
}); // Discord.Client 객체를 생성합니다.
client.on('ready', () => { // ready 이벤트시 실행할 함수
console.log(`Logged in as ${client.user.tag}!`); // client.user 는 자신의 유저 객체이고 tag 는 유저 객체의 프로퍼티 입니다.
});
client.on('messageCreate', msg => { // message 이벤트시 msg (Discord.Message) 매개변수를 받고 실행할 함수
if (msg.content === 'ping') { // Discord.Message 객체의 content 프로퍼티가 'ping' 일 때
msg.reply('Pong!'); // reply 는 멘션 + , msg 로 출력됩니다.
}
});
client.login('token'); // 토큰을 입력합니다. 올바르지 않은 토큰일 시 에러가 발생합니다.
이 코드는 if 문으로 명령어를 판단한다. 하지만 이런 식으로 한 파일에 if 문을 늘려가다 보면 어느샌가 코드가 300줄, 500줄, 심하면 3000줄까지 불어나는 문제가 발생한다. 해당 문제는 스파게티 코드를 발생시킬수 있어 후에 유지 보수가 매우 어려워지기 때문에 많은 유명한 discord.js 봇 들은 거의 다 명령어 또는 이벤트 파일을 분리하고, 명령어 추가를 자동화하고, 가독성을 중요시한다. 따라서 예제 1은 별로 좋지 않은 예시이다. 이 문제점은 discord.py의 Client 클래스를 사용해 개발하는 사람들에게서도 많이 나타난다[3] .
v12 이하를 사용한다면 client.on에서 messageCreate 대신 message를 사용해야 한다.
4.2. 예제 2[편집]
index.js
const Discord = require('discord.js');
const client = new Discord.Client({
intents: [ // Intent를 설정합니다. 설정하지 않으면 CLIENT_MISSING_INTENTS 오류가 발생합니다.
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages
]
});
const fs = require('fs');
const prefix = '!';
client.commands = new Discord.Collection()
// 명령어 캐시 컬렉션을 클라이언트 내에 선언한다. 해당 방법으로 명령어 파일 내에서도 client.commands로 다른 명령어들에 접근할수 있다.
client.commands.load = dir => {
for (const file of fs.readdirSync(dir)) {
const cmd = require(`${dir}/${file}`);
client.commands.set(cmd.name, cmd);
}
console.log(client.commands.map(c => c.name).join(', ') + ' 명령어가 로드됨.');
}
client.commands.load(__dirname + "/commands");
//해당 파일이 위치한 디렉터리에서 "/commands" 경로를 추가
client.on('ready', () => console.log(`${client.user.tag} 에 로그인됨`));
client.on('messageCreate', msg => {
if (msg.author.bot) return;
if (!msg.content.startsWith(prefix)) return;
if (msg.content.slice(0, prefix.length) !== prefix) return;
const args = msg.content.slice(prefix.length).trim().split(/ +/g);
const command = args.shift().toLowerCase();
let cmd = client.commands.get(command);
//get는 컬렉션 내에 해당 key 값을 가진 데이터가 없으면 false 값을 반환하므로 부분적으로 Collection#has처럼 사용할수 있습니다.
if(cmd) cmd.run(client, msg, args);
})
client.login('token');
commands/ping.js
//run이라는 메소드(function)을 export(수출)
exports.run = (client, msg, args) => {
msg.reply(`${client.ws.ping}ms`);
};
exports = {
name: 'ping'
};
이런 식으로 파일을 분리하고 가져오는 것을 자동화하면 앞의 문제를 바로 해결할 수 있다.
5. Commando 방식[편집]
이는 discord.js Client가 아닌 discord.js CommandoClient를 사용하여 봇을 만드는 것이다.
위의 파일 핸들링의 방식을 이 라이브러리로 대체할 수 있으며, 또 sqlite3를 지원하여 데이터베이스 저장도 쉽다.
CommandoClient는 단순히 discord.js Client의 확장이므로 Client에 있던 메서드, 클래스 등은 여기서도 사용할 수 있다.
5.1. 예제[편집]
const Commando = require('discord.js-commando')
const client = new Commando.Client({
owner: '소유자 아이디'
})
const path = require('path')
client.registry
// 명령어들의 그룹들을 등록합니다.
.registerGroups([
['fun', 'Fun commands'],
['some', 'Some group'],
['other', 'Some other group']
])
// 기본 명령어, 그룹 등을 등록합니다.
.registerDefaults()
// 다른 폴더 (여기서는 commands) 에 있는 명령어 파일 들을 불러오고 등록합니다.
.registerCommandsIn(path.join(__dirname, 'commands'));
const sqlite = require('sqlite');
// Commando에는 길드 별 접두사, 명령어 활성화 또는 비활성화 등의 기능이 있지만, 이를 저장해 놓으려면 데이터베이스가 필요하기 때문에 sqlite를 이용합니다.
client.setProvider(
sqlite.open(path.join(__dirname, 'settings.sqlite3')).then(db => new Commando.SQLiteProvider(db))
).catch(console.error);
client.login('token goes here'); // 마지막으로 discord.js Client 처럼 로그인합니다.
이러면 모든 준비는 끝이다.
명령어를 commands 폴더에 저장하고 코드를 짜는건 여기에서 확인하면 된다.
6. discord RPC[편집]
6.1. 예제[편집]
const clientId = '187406016902594560';
const scopes = ['rpc', 'rpc.api', 'messages.read'];
const client = new RPC.Client({ transport: 'websocket' });
client.on('ready', () => {
console.log('Logged in as', client.application.name);
console.log('Authenticated as user: ' + client.user.username);
client.selectVoiceChannel('81384788862181376');
});
client.login({ clientId, scopes });
6.2. 사용 불가[편집]
Discord Developer Portal에, RPC에 대한 신청을 더 이상 받지 않는다고 나와있다.
따라서 만들고 싶어도 만들지 못하며, 거의 필요가 없어진 라이브러리이다.
7. 여담[편집]
- Commando는 데이터베이스에 저장, 명령어 인식 등이 자동화 되어있어 더 편하다고 느껴질 수 있겠지만 대부분은 사용하지 않는다. Commando는 너무 틀에 맞춰져있어 선호되지 않는다.
- 9.x부터 Node.js 6.x, 12.x부터는 Node.js 12.x 버전을 요구한다.
- 9.x, 10.x, 11.x는 문법이 호환된다. 8.x 이하나 v12, v13은 서로 호환되지 않는다.
이 문서의 내용 중 전체 또는 일부는 2023-11-06 01:34:45에 나무위키 discord.js 문서에서 가져왔습니다.