ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [뉴스검색봇] 2. 슬래시 커맨드 작동 확인하기
    DEVELOP/discord-bot 2022. 5. 1. 21:37

    기능구현에 앞서, 슬래시 커맨드가 잘 동작하는지 확인한다.

     

    discordjs에서는 명령어를 if/else문으로 이어붙이는 코드를 지양하라고 명시하고있다.

    명령어가 길어질 수록 스파게티 코드가 되기 때문.

    명령어를 수행하는 commands폴더를 따로 만들고, 그 명령어들을 불러와 사용하라고 권장한다.

     

    소스코드 작성에 앞서, @discordjs/builders, @discordjs/rest, discord-api-types를 설치한다.

    > npm install @discordjs/builders @discordjs/rest discord-api-types

     

    먼저 프로젝트 폴더 내에 commands 폴더를 만들고, 명령어 별로 js파일을 생성한다.

     

    각각의 js 파일 내 소스코드는 다음과 같다.

    const { SlashCommandBuilder } = require('@discordjs/builders');
    
    module.exports = {
    	data: new SlashCommandBuilder()
    		.setName('서버')
    		.setDescription('서버 정보를 봅니다.'),
    	async execute(interaction) {
    		await interaction.reply(`Server name: ${interaction.guild.name}\nTotal members: ${interaction.guild.memberCount}`);
    	},
    };

     

    data에 저것 말고도 추가 옵션을 지정해줄 수 있다.

    동작은 excute함수 내에서 구현하면 된다. 지금은 서버정보를 출력하도록 작성했다.

    다른 명령어 파일도 기본 골격은 똑같고, 안에 기능만 다르게 바꿔주면 된다.

     

    일단 테스트 용으로 간단히 서버정보, 유저정보, 검색 커맨드를 추가해봤다.

     


    다음으로 만들어줄 것은 deploy-commands.js 파일이다.

    const fs = require('node:fs');
    const { REST } = require('@discordjs/rest');
    const { Routes } = require('discord-api-types/v9');
    const { clientId, guildId, token } = require('./config.json');
    
    const commands = [];
    const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js'));
    
    for (const file of commandFiles) {
    	const command = require(`./commands/${file}`);
    	commands.push(command.data.toJSON());
    }
    
    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);
    
    console.log(commands);

    commands폴더 내 js파일들만 불러와 for loop으로 각 파일 데이터들을 json형식으로 commands에 추가한다.

     

    같은 방식으로 index.js파일에도 적용한다.

    // Require the necessary discord.js classes
    const fs = require('node:fs');
    const { Client, Collection, Intents } = require('discord.js');
    const { token } = require('./config.json');
    
    // Create a new client instance
    const client = new Client({ intents: [Intents.FLAGS.GUILDS] });
    
    client.commands = new Collection();
    const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js'));
    
    for (const file of commandFiles) {
    	const command = require(`./commands/${file}`);
    	// Set a new item in the Collection
    	// With the key as the command name and the value as the exported module
    	client.commands.set(command.data.name, command);
    }
    
    // When the client is ready, run this code (only once)
    client.once('ready', () => {
    	console.log('Ready!');
    });
    
    client.on('interactionCreate', async interaction => {
    	if (!interaction.isCommand()) return;
    
    	const command = client.commands.get(interaction.commandName);
    
    	if (!command) return;
    
    	try {
    		await command.execute(interaction);
    	} catch (error) {
    		console.error(error);
    		await interaction.reply({ content: 'There was an error while executing this command!', ephemeral: true });
    	}
    });
    
    // Login to Discord with your client's token
    client.login(token);

     

     

    명령어를 추가/삭제했을 경우, 반드시 deploy-commands.js 파일을 실행해야 한다.

    한번만 실행하면 되고, deploy파일을 새로 실행했을 경우 봇도 재시작해야 정상작동한다.

    > node deploy-commands.js
    > node .

     

    간혹 명령어가 여러개 있어도 하나만 뜨거나, 아예 안뜨거나 하는 경우가 있는데,

    정확히 어떤 조건에서 발생하는 오류인지 모르겠다.

    똑같은 코드를 쳐도 디스코드에 뜨지 않는 경우가 있고, 시간을 두고 실행하면 안뜨던게 뜨기도 한다...🙄

    한가지 확실한건 js파일명이 한글이면 인식이 안되는것 같다.

     

    아무튼 우여곡절 끝에 명령어들이 잘 등록됐다.

     

     

    반항하는 검색봇

    각각의 명령어들이 잘 동작한다.

    중간에 명령어 등록이 안되는건 왜 오류가 난건지 아직 이유를 못찾았다... 건드린게 없기 때문😑

     

    이제 여기다 기능을 잘 구현해넣으면 된다.

    댓글

Designed by Tistory.