Discord Bot용 슬래시 명령 설정

시작하기



이 봇으로 먼저 시작하려면 특정 종속성을 설치해야 합니다. 그렇지 않은 경우 다음과 같습니다.
npm install @discordjs/builders @discordjs/rest discord-api-types
Discord에서 사용할 슬래시 명령을 만드는 데 사용됩니다.

이 블로그는 이 게시물에서 이전에 빌드된 내용을 이미 읽었다고 가정합니다.

또한 Discord 서버에서 봇에 사용할 명령을 생성하려면 "bot"및 "applications.commands"를 포함하는 새 URL을 생성해야 합니다.

배포 명령.js




const { SlashCommandBuilder } = require('@discordjs/builders')
const { REST } = require('@discordjs/rest')
const { Routes } = require('discord-api-types/v9')
const { clientId, guildId, token } = require('./config.json')
const rest = new REST({ version: '9' }).setToken(token)

const commands = [
  new SlashCommandBuilder()
    .setName('ping')
    .setDescription('Replies with pong'),
  new SlashCommandBuilder()
    .setName('server')
    .setDescription('Replies with server info'),
  new SlashCommandBuilder()
    .setName('user')
    .setDescription('Replies with user info'),
].map((command) => command.toJSON())

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

clientId는 봇의 개발자 포털에서 가져오고 guildId는 이러한 명령을 대상으로 하려는 길드입니다.

봇이 가입하는 모든 서버를 전달하기 위해 guildId를 생략하는 명령을 만드는 방법이 있습니다.

index.js



다음은 초기화 시 클라이언트가 호출된 후 추가됩니다.

clinet.on('interactionCreate', async interaction => {
  if (!interaction.isCommand()) return

  const { commandName } = interaction

  if (commandName === 'ping') {
    await interaction.reply('Pong!')
  } else if (commandName === 'server') {
    await interaction.reply(`
      Server name: ${interaction.guild.name}\n
      Total members: ${interaction.guild.memberCout}\n
      Server created on: ${interaction.guild.createdAt}
    `)
  } else if (commandName === 'user') {
    await interaction.reply(`
      Your tag: ${interaction.user.tag}\n
      Your id: ${interaction.user.id}
    `)
  }
})


이제 node deploy-commands.js 를 실행해야 합니다. 명령이 빌드되는 방식이나 명령을 배포하려는 서버를 변경하지 않는 한 한 번만 실행하면 됩니다.

사용된 guildId로 서버에서 봇을 실행하면 텍스트 필드에 "/"를 배치하면 이제 봇에서 사용하기 위해 만든 명령이 있어야 합니다. 슬래시 명령을 사용하면 명령 이름과 작성한 대로 description가 표시됩니다.

리팩토링!



당신이 나와 같고 서버의 일반적인 조정을 돕기 위해 많은 명령을 추가하는 경향이 있다면 이와 같은 명령을 작성하는 데 약간 지칠 것입니다. 지저분한 일이 어떻게 끝날지는 말할 것도 없습니다.

몇 개의 디렉토리를 생성하고 기존 디렉토리 중 일부를 리팩토링할 수 있습니다.

궁극적으로 원하는 모든 명령의 새 홈이 될 새 파일을 생성하여 시작하겠습니다.
commands라는 새 디렉토리를 만듭니다.

명령 디렉토리 내에서 ping , serveruser 는 자체 ".js"파일이 됩니다.

ping.js




// commands/ping.js
const { SlashCommandBuilder } = require('@discordjs/builders')

module.exports = {
  data: new SlashCommandBuilder()
    .setName('ping')
    .setDescription('Replies with Pong!'),
  async execute(interaction) {
    await interaction.reply('Pong!')
  },
}


서버.js




// commands/server.js
const { SlashCommandBuilder } = require('@discordjs/builders')

module.exports = {
  data: new SlashCommandBuilder()
    .setName('server')
    .setDescription('Display info about this server.'),
  async execute(interaction) {
    return interaction.reply(
      `Server name: ${interaction.guild.name}\nTotal members: ${interaction.guild.memberCount}`
    )
  },
}


user.js




// commands/user.js
const { SlashCommandBuilder } = require('@discordjs/builders')

module.exports = {
  data: new SlashCommandBuilder()
    .setName('user')
    .setDescription('Display info about yourself.'),
  async execute(interaction) {
    return interaction.reply(
      `Your username: ${interaction.user.username}\nYour ID: ${interaction.user.id}`
    )
  },
}


다음으로 deploy-commands.js 및 index.js 파일을 편집합니다.

배포 명령.js




// node modules that will be included to existing file
const fs = require('node:fs')
const path = require('node:path')

...

// remove everything inside the commands array and replace with an empty array
const commands = []

const commandsPath = path.join(__dirname, 'commands')
const commandFiles = fs
  .readdirSync(commandsPath)
  .filter((file) => file.endsWith('.js'))

for (const file of commandFiles) {
  const filePath = path.join(commandsPath, file)
  const command = require(filePath)
  commands.push(command.data.toJSON())
}

...


모든 명령을 생성하기 위해 index.js 파일을 사용하여 유사한 작업을 수행합니다.

index.js




const fs = require('node:fs')
const path = require('node:path')
const { Client, Intents, Collection } = require('discord.js')
const { token } = require('./config.json')

const client = newClient({ intents: [Intents.FLAGS.GUILDS] })

client.commands = new Collection()
const commandsPath = path.join(__dirname, 'commands')
const commandFiles = fs
  .readdirSync(commandsPath)
  .filter((file) => file.endsWith('.js'))

for (const file of commandFiles) {
  const filePath = path.join(commandsPath, file)
  const command = require(filePath)
  client.commands.set(command.data.name, command)
}

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,
    })
  }
})

client.login(token)


이제 index.js 및 deploy-commands.js를 정리했습니다. 명령에 추가할 옵션options을 여는 명령을 하나 더 추가합니다.

echo.js




// commands/echo.js
const { SlashCommandBuilder } = require('@discordjs/builders')

module.exports = {
  data: new SlashCommandBuilder()
    .setName('echo')
    .setDescription('Replies with you input!')
    .addStringOption((option) =>
      option
        .setName('input')
        .setDescription('The input to echo back')
        .setRequired(true)
    ),
  async execute(interaction) {
    await interaction.reply({
      content: interaction.options.getString('input'),
      ephemeral: true,
    })
  }
}

.addStringOption()는 입력을 허용하며, 이 경우 우리가 말한 내용에 응답하고 이를 사용하여 작업을 수행합니다. 서버에서 누군가를 음소거하려는 경우 사용할 수 있으며/mute @this-noisy-user 봇이 이를 대신 수행합니다. 음소거 기간을 설정하는 것은 귀하에게 달려 있으며 음소거 해제를 위해 봇이 계속 실행되는지 여부에 달려 있습니다.

좋은 웹페이지 즐겨찾기