discord.js

덤프버전 :


discord.js

파일:discordjs.png

필요한 Node.js 버전
v16.9 이상
최신 버전
v14.13.0
지원되는 가장
오래된 버전
v13.9
관련 링크
파일:홈페이지 아이콘.svg 파일:GitHub 아이콘.svg[[파일:GitHub 아이콘 화이트.svg
파일:npm, lnc. n-logo.png 파일:디스코드 아이콘.svg
1. 개요
2. 개발 시 주의사항
3. 설치
4. 예제
4.1. 예제 1
4.2. 예제 2
5. Commando 방식
5.1. 예제
6. discord RPC
6.1. 예제
6.2. 사용 불가
7. 여담



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은 서로 호환되지 않는다.
파일:크리에이티브 커먼즈 라이선스__CC.png 이 문서의 내용 중 전체 또는 일부는 2023-11-06 01:34:45에 나무위키 discord.js 문서에서 가져왔습니다.

[1] 유저, 길드 등[2] 삼각괄호는 빼야한다.[3] 현재는 Cog 시스템으로 인해 많이 줄어든 편이나 discord.Client를 사용하는 오래된 강의들로 인해 아직 적지 않다