Discord 봇 Slash Command 등록 및 사용

코코블루·2022년 2월 22일
0

discord

목록 보기
1/2
post-thumbnail

작년 말에 Discord 팀에서 안내 메시지를 받았습니다.

상당히 번역기를 돌린 느낌인데, 블로그 내용까지 참고하여 간단하게 요약을 하면 아래과 같습니다.

  1. '인증된 봇(Verified Bot)'은 5월부터 봇을 직접적으로 호출하지 않는 이상 메시지 데이터에 접근할 수 없습니다. 꼭 필요한 경우, 접근 권한을 요청해야합니다.
  2. App의 태그를 정할 수 있고, 초대 링크를 프로필에 포함시킬 수 있습니다.

2번의 경우에는 사용자 레벨에서 문제가 없는데요. 이제 문제는 1번입니다. 기존 Discord 봇의 경우에는 ! 등의 기호로 봇을 호출하는 경우가 많았는데요. 이제는 봇을 멘션하거나 봇과 DM하거나 슬래시(/)를 통해 호출하는 등의 행동으로만 봇이 호출됩니다. 즉, 기존 방식으로 호출하기 위해서는 접근 권한을 요청해야하고, 필연적으로 개인정보 보호 문제에 부딪치게 됩니다. 기존 방식으로 처리하게 되면, 봇이 들어가 있는 서버의 대부분의 메시지를 볼 수 있기 때문입니다.

제가 운영하는 봇의 경우에는 정보 제공의 목적의 봇으로 봇 호출을 제외하면, 메시지 내용에 접근할 이유가 없었습니다. 그래서 해당 정책 시행에 맞추어서 대응하고자 하였습니다.


Slash Command란?

Slash Command는 봇에 명령을 호출하기 위한 시스템으로, Application 제작자가 Slash Command를 등록하면, 해당 봇이 들어가 있는 서버에서 슬래시(/)를 입력하면, 해당하는 명령어가 등장합니다.

기존에는 명령어를 기억해야했고, 잊어버리는 경우가 많았습니다. 이러한 문제로 !help, !설명서 등의 명령어를 추가했어야했었는데, 이제는 슬래시만 입력하면 사용할 수 있는 명령어의 리스트가 나오기 때문에 사용자의 입장에서는 정확한 명령어를 기억할 필요가 없습니다.

개발자의 입장에서는 명령어를 정의할 때 명령어의 종류, 옵션 필수 여부 등을 정의할 수 있기 때문에 명령어에 대한 예외 처리를 줄일 수 있게 됩니다. (예. 검색어가 없는 경우 등)


목표

  • Slash Command의 이름과 정보를 정의하고 등록해보겠습니다.
  • Slash Command의 interaction을 받았을 때의 처리를 정의해보겠습니다.

환경

기존에는 Discord.py를 통하여 진행하였지만, 개발 중단으로 인하여 Slash Command를 사용할 수 없고, 미래의 API 변경에 대해서도 보장을 받을 수 없습니다. 그래서 아래 환경으로 진행합니다.

  • NodeJS 16.13.2
  • discord.js 13.6
  • IDE: WebStorm (VSC로 해도 무관합니다.)

문법은 ES6을 사용하고자 노력하였지만, JS를 처음하기 때문에 문법의 특성을 살리지 못한 경우가 많습니다. 지적해주시면 너무나도 감사하겠습니다.


코딩

본격적으로 코딩을 해보겠습니다.

index.mjs 만들기

index.mjs를 만들어서 봇 구동을 위해 처음 실행할 코드를 정의하겠습니다.

import {Client, Intents} from "discord.js";
import {registerCommands} from "./deploy-commands.mjs";
import dotenv from 'dotenv'

dotenv.config({path: '.env'});
const client = new Client({intents: [Intents.FLAGS.GUILDS]});

// Slash Command 추가
registerCommands(process.env.DISCORD_BOT_TOKEN, process.env.CLIENT_ID, process.env.TO_REGISTER_GUILD);

// 메시지를 받으면 호출되는 함수
client.on('interactionCreate', async interaction => {
    // Original: https://discordjs.guide/interactions/replying-to-slash-commands.html#receiving-interactions
    if (!interaction.isCommand()) return;

    if (interaction.commandName === '안녕하세요') {
        await interaction.reply('인사 잘한다~');
    }
});

client.login(process.env.DISCORD_BOT_TOKEN).then(function () {
    console.log("LOGIN SUCCESS.");
});

위 코드는 아래 순서대로 진행됩니다.

1. dotenv 라이브러리가 .env 파일을 참고하여 환경변수를 등록시킴.
2. 'deploy-commands.mjs' 파일을 참고하여 슬래시 명령어를 등록시킵니다.
3. 봇에 로그인하여, 메시지를 받을 준비를 합니다.

deploy-commands.mjs 만들기

index.mjs에서 명령어 처리 코드를 정의해도 명령어를 호출했다는 사실을 디스코드 쪽에서 알리지 않으면 아무런 효과가 없습니다. 유효한 명령어 리스트를 Discord에 전달해줘야하는데요.

// Original: https://discordjs.guide/creating-your-bot/creating-commands.html#command-deployment-script
import {SlashCommandBuilder} from "@discordjs/builders";
import {REST} from '@discordjs/rest';
import {Routes} from 'discord-api-types/v9';

const commands = [
    new SlashCommandBuilder().setName('안녕하세요').setDescription('인사를 합니다.'),
].map(command => command.toJSON());

export const registerCommands = (token, clientId, guildId) => {
    const rest = new REST({version: '9'}).setToken(token);

    rest.put(Routes.applicationGuildCommands(clientId, guildId), {body: commands})
        .then(() => console.log('Successfully registered application commands.'))
        .catch(console.error);
}

위 코드에서는 예제이므로 서버 ID를 추가로 지정하여 하나의 서버에만 명령어를 정의하고 등록합니다. 위 코드를 실행하면 지정된 서버 외에 다른 서버에서는 명령이 보이지 않습니다.

중복 명령어를 정의한 경우에는..?

동일한 이름을 여러 명령어에 등록한 경우, 마지막에 등록한 명령어만 유효합니다. 하지만, 전역 명령어와 특정 서버 명령어는 명령어 이름이 동일하더라도 중복으로 등록됩니다.

구동을 위한 .env 정의하기

.env 파일을 만들어서 사용할 환경변수를 정의합니다.

DISCORD_BOT_TOKEN=(Discord 봇 토큰)
CLIENT_ID=(Discord Application ID)
TO_REGISTER_GUILD=(명령어를 등록할 서버 ID)

그 다음, index.mjs를 실행하면, 실행됩니다.

위와 같이 Successfully registered application commands.가 등장한 뒤에, LOGIN SUCCESS가 나오면 명령을 받을 준비가 되는 것입니다.

테스트

코드가 제대로 작동하는지 테스트하기 위해서는 Discord 서버에 접속합니다.

그 다음, 메시지 입력 화면에 슬래시(/)를 입력하면, 등록된 명령어가 나오고 선택하고, 전송하면 아래와 같이 답장이 옵니다.

답장의 형태이기 때문에 어떤 사람의 발화에 대답을 한 것인지 명확하게 알 수 있습니다.

Trouble Shooting

명령어 등록이 되지 않는 경우

봇을 초대할 때 권한에 application.commands를 추가했는지 확인하시기 바랍니다. 만일, 권한이 없다면 다시 초대하시기 바랍니다.

마무리

위와 같이 간단한 Slash Command를 추가해보았습니다. 다음에는 Slash Command 옵션의 종류를 간단하게 소개해보도록 하겠습니다.

참고 사이트

Discord.js Guide

소스 코드

Github

profile
Have A Happy Coding Time!

0개의 댓글