discord.jsで計算認証

# 必要環境
Node.js v16.9.0以上
discord.js v14.1.2以上
# コード
```index.js
const discord = require('discord.js');
const Keyv = require('keyv');
const verify = new Keyv('sqlite://db.sqlite', { table: 'verify' });
const signale = require('signale');
const prefix = "!"
const client = new discord.Client({
  intents: Object.values(discord.IntentsBitField.Flags),
  partials: Object.values(discord.Partials),
});
client.commands = new discord.Collection();

function Random_num(max) {
  return Math.floor(Math.random() * max);
}
const fs = require('fs');
let command_int = 0;
const commandFiles = fs.readdirSync('./command');

for (const file of commandFiles) {
  command_int++;
  const command = require(`./command/${file}`);
  signale.success(`${file} がロードされました。`);
  client.commands.set(command.name, command);
}
signale.success(`合計${command_int}個がロードされました。`);

client.on('ready', async () => {
  await client.application.commands
    .set(
      [
        new discord.SlashCommandBuilder()
          .setName('verify')
          .setDescription('認証パネルを作成します。')
          .addStringOption((option) =>
            option
              .setAutocomplete(true)
              .setDescription('認証の種類')
              .setName('type')
              .setRequired(true)
          )
          .addRoleOption((option) =>
            option
              .setName('role')
              .setDescription('認証が完了した時に付与するロール')
              .setRequired(true)
          ),
      ].map((command) => command.toJSON())
    )
    .then(() => signale.pending('スラッシュコマンド登録中...'));
  signale.success('スラッシュコマンド登録完了。');
  signale.success(`Botの起動が完了しました。\n${client.user.tag}でログイン中`);

client.on('messageCreate', async (message) => {
  if (message.author.bot || message.system) return;
  const args = message.content.slice(prefix.length).trim().split(/ +/g);
  const command = args.shift().toLowerCase();
  client.commands.get('verify').execute(client, command, args, message, verify);
});
client.on('interactionCreate', async (interaction) => {
  if (
    interaction.type === discord.InteractionType.ApplicationCommandAutocomplete
  ) {
    client.commands.get('a_verify').execute(client, interaction, verify);
  }
  if (interaction.isChatInputCommand()) {
    client.commands.get('s_verify').execute(client, interaction, verify);
  }
  if (interaction.type === discord.InteractionType.MessageComponent) {
    client.commands.get('b_verify').execute(client, interaction, verify, Random_num);
  } if (interaction.type === discord.InteractionType.ModalSubmit) {
    client.commands.get('m_verify').execute(client, interaction, verify, Random_num);
  }
});
client
  .login(process.env.bot_token)
  .then(() => signale.pending('ログイン中...'))
  .catch((e) =>
    signale.fatal('ログインにエラーが発生しました。\nエラー内容: \n' + e)
  );

```
```command/auto_verify.js
const discord = require('discord.js');
const fs = require('fs');
const client = new discord.Client({
  intents: Object.values(discord.IntentsBitField.Flags),
  partials: Object.values(discord.Partials),
});
module.exports = {
  name: 'a_verify',
  description: '認証',
  async execute(client, interaction, verify) {
    if (interaction.commandName === 'verify') {
      const focusedValue = interaction.options.getFocused();
      const choices = ['足し算認証', '引き算認証', '掛け算認証', '割り算認証'];
      const filtered = choices.filter((choice) =>
        choice.startsWith(focusedValue)
      );
      await interaction.respond(
        filtered.map((choice) => ({ name: choice, value: choice }))
      );
    }
  },
};

```
```command/button_verify.js
const discord = require('discord.js');
const fs = require('fs');
const client = new discord.Client({
  intents: Object.values(discord.IntentsBitField.Flags),
  partials: Object.values(discord.Partials),
});
module.exports = {
  name: 'b_verify',
  description: '認証',
  async execute(client, interaction, verify,Random_num) {
    if (interaction.customId === 'b_verify') {
      var calc1 = Random_num(901);
      var calc2 = Random_num(10);
      var a = await verify.get(interaction.message.id + '_3');
      await verify.set(interaction.message.id + '_1', calc1);
      await verify.set(interaction.message.id + '_2', calc2);
      const modal = new discord.ModalBuilder()
        .setCustomId('myModal')
        .setTitle(`足し算認証`);
      const ma = new discord.TextInputBuilder()
        .setCustomId('kotae')
        .setLabel(`${calc1} + ${calc2}の答えは？`)
        .setStyle(discord.TextInputStyle.Short)
        .setPlaceholder('ここに入力して下さい。')
        .setRequired(true);
      const md = new discord.ActionRowBuilder().addComponents(ma);
      modal.addComponents(md);
      await interaction.showModal(modal);
    }
    if (interaction.customId === 'b_verify1') {
      var calc1 = Random_num(901);
      var calc2 = Random_num(10);
      var a = await verify.get(interaction.message.id + '_3');
      await verify.set(interaction.message.id + '_1', calc1);
      await verify.set(interaction.message.id + '_2', calc2);
      const modal = new discord.ModalBuilder()
        .setCustomId('myModal1')
        .setTitle(`引き算認証`);
      const ma = new discord.TextInputBuilder()
        .setCustomId('kotae')
        .setLabel(`${calc1} - ${calc2}の答えは？`)
        .setStyle(discord.TextInputStyle.Short)
        .setPlaceholder('ここに入力して下さい。')
        .setRequired(true);
      const md = new discord.ActionRowBuilder().addComponents(ma);
      modal.addComponents(md);
      await interaction.showModal(modal);
    }
    if (interaction.customId === 'b_verify2') {
      var calc1 = Random_num(901);
      var calc2 = Random_num(10);
      var a = await verify.get(interaction.message.id + '_3');
      await verify.set(interaction.message.id + '_1', calc1);
      await verify.set(interaction.message.id + '_2', calc2);
      const modal = new discord.ModalBuilder()
        .setCustomId('myModal2')
        .setTitle(`掛け算認証`);
      const ma = new discord.TextInputBuilder()
        .setCustomId('kotae')
        .setLabel(`${calc1} × ${calc2}の答えは？`)
        .setStyle(discord.TextInputStyle.Short)
        .setPlaceholder('ここに入力して下さい。')
        .setRequired(true);
      const md = new discord.ActionRowBuilder().addComponents(ma);
      modal.addComponents(md);
      await interaction.showModal(modal);
    }
    if (interaction.customId === 'b_verify3') {
      var calc1 = Random_num(901);
      var calc2 = Random_num(10);
      var a = await verify.get(interaction.message.id + '_3');
      await verify.set(interaction.message.id + '_1', calc1);
      await verify.set(interaction.message.id + '_2', calc2);
      const modal = new discord.ModalBuilder()
        .setCustomId('myModal3')
        .setTitle(`割り算認証`);
      const ma = new discord.TextInputBuilder()
        .setCustomId('kotae')
        .setLabel(`${calc1} ÷ ${calc2}の答えは？(小数点以下は消去)`)
        .setStyle(discord.TextInputStyle.Short)
        .setPlaceholder('ここに入力して下さい。')
        .setRequired(true);
      const md = new discord.ActionRowBuilder().addComponents(ma);
      modal.addComponents(md);
      await interaction.showModal(modal);
    }
  },
};

```
```command/modal_verify.js
const discord = require('discord.js');
const fs = require('fs');
const client = new discord.Client({
  intents: Object.values(discord.IntentsBitField.Flags),
  partials: Object.values(discord.Partials),
  allowedMentions: { repliedUser: false },
});
module.exports = {
  name: 'm_verify',
  description: 'Modal認証',
  async execute(client, interaction, verify, Random_num) {
    if (interaction.customId === 'myModal') {
      var role = await verify.get(interaction.message.id + '_3');
      var ca1 = await verify.get(interaction.message.id + '_1');
      var ca2 = await verify.get(interaction.message.id + '_2');
      if (interaction.fields.getTextInputValue('kotae') === `${ca1 + ca2}`) {
        await interaction.guild.members
          .resolve(interaction.user)
          .roles.add(role)
          .then(async () => {
            await interaction.reply({
              content: '認証が完了しました。',
              ephemeral: true,
            });
          })
          .catch(async (e) => {
            const er = String(e);
            if (er.indexOf('Missing Permissions') != -1) {
              await interaction.reply({
                embeds: [
                  {
                    title:
                      ':x: :権限がありません。',
                    description: `Botのロールが付与するロールよりも下になっていませんか?\nBotにロールを付与する権限がありますか？\n\nサーバーの管理者(<@${interaction.guild.ownerId}>)にご連絡下さい。`,
                  },
                ],
                ephemeral: true,
              });
              return;
            } else {
              const embed = new discord.EmbedBuilder()
                .setTitle(
                  ':x: : エラーが発生しました!!'
                )
                .setDescription(discord.codeBlock('xl', e))
              const msg1 = await client.channels.cache
                .get('エラーを送信するチャンネルのid')
                .send({ embeds: [embed] });
              interaction.reply({
                embeds: [
                  {
                    title:
                      ':x: :不明なエラーが発生しました。',
                    description:
                      'エラーid: `' +
                      msg1.id +
                      '`\nサポートサーバーで、エラーidと一緒にお問い合わせ下さい。\n\nサーバーの管理者(<@' +
                      interaction.guild.ownerId +
                      '>)にご連絡下さい。',
                  },
                ],
                ephemeral: true,
              });
              return;
            }
          });
      } else {
        await interaction.reply({
          content: '答えが違います。',
          ephemeral: true,
        });
      }
    }
    if (interaction.customId === 'myModal1') {
      var role = await verify.get(interaction.message.id + '_3');
      var ca1 = await verify.get(interaction.message.id + '_1');
      var ca2 = await verify.get(interaction.message.id + '_2');
      if (interaction.fields.getTextInputValue('kotae') === `${ca1 - ca2}`) {
        await interaction.guild.members
          .resolve(interaction.user)
          .roles.add(role)
          .then(async () => {
            await interaction.reply({
              content: '認証が完了しました。',
              ephemeral: true,
            });
          })
          .catch(async (e) => {
            const er = String(e);
            if (er.indexOf('Missing Permissions') != -1) {
              await interaction.reply({
                embeds: [
                  {
                    title:
                      ':x: :権限がありません。',
                    description: `Botのロールが付与するロールよりも下になっていませんか?\nBotにロールを付与する権限がありますか？\n\nサーバーの管理者(<@${interaction.guild.ownerId}>)にご連絡下さい。`,
                  },
                ],
                ephemeral: true,
              });
              return;
            } else {
              const embed = new discord.EmbedBuilder()
                .setTitle(
                  ':x: : エラーが発生しました!!'
                )
                .setDescription(discord.codeBlock('xl', e))

              const msg1 = await client.channels.cache
                .get('エラーを送信するチャンネルのid')
                .send({ embeds: [embed] });
              interaction.reply({
                embeds: [
                  {
                    title:
                      ':x: :不明なエラーが発生しました。',
                    description:
                      'エラーid: `' +
                      msg1.id +
                      '`\nサポートサーバーで、エラーidと一緒にお問い合わせ下さい。\n\nサーバーの管理者(<@' +
                      interaction.guild.ownerId +
                      '>)にご連絡下さい。',
                  },
                ],
                ephemeral: true,
              });
              return;
            }
          });
      } else {
        await interaction.reply({
          content: '答えが違います。',
          ephemeral: true,
        });
      }
    }
    if (interaction.customId === 'myModal2') {
      var role = await verify.get(interaction.message.id + '_3');
      var ca1 = await verify.get(interaction.message.id + '_1');
      var ca2 = await verify.get(interaction.message.id + '_2');
      if (interaction.fields.getTextInputValue('kotae') === `${ca1 * ca2}`) {
        await interaction.guild.members
          .resolve(interaction.user)
          .roles.add(role)
          .then(async () => {
            await interaction.reply({
              content: '認証が完了しました。',
              ephemeral: true,
            });
          })
          .catch(async (e) => {
            const er = String(e);
            if (er.indexOf('Missing Permissions') != -1) {
              await interaction.reply({
                embeds: [
                  {
                    title:
                      ':x: :権限がありません。',
                    description: `Botのロールが付与するロールよりも下になっていませんか?\nBotにロールを付与する権限がありますか？\n\nサーバーの管理者(<@${interaction.guild.ownerId}>)にご連絡下さい。`,
                  },
                ],
                ephemeral: true,
              });
              return;
            } else {
              const embed = new discord.EmbedBuilder()
                .setTitle(
                  ':x: : エラーが発生しました!!'
                )
                .setDescription(discord.codeBlock('xl', e))

              const msg1 = await client.channels.cache
                .get('エラーを送信するチャンネルのid')
                .send({ embeds: [embed] });
              interaction.reply({
                embeds: [
                  {
                    title:
                      ':x: :不明なエラーが発生しました。',
                    description:
                      'エラーid: `' +
                      msg1.id +
                      '`\nサポートサーバーで、エラーidと一緒にお問い合わせ下さい。\n\nサーバーの管理者(<@' +
                      interaction.guild.ownerId +
                      '>)にご連絡下さい。',
                  },
                ],
                ephemeral: true,
              });
              return;
            }
          });
      } else {
        await interaction.reply({
          content: '答えが違います。',
          ephemeral: true,
        });
      }
    }
    if (interaction.customId === 'myModal3') {
      var role = await verify.get(interaction.message.id + '_3');
      var ca1 = await verify.get(interaction.message.id + '_1');
      var ca2 = await verify.get(interaction.message.id + '_2');

      if (
        interaction.fields.getTextInputValue('kotae') ===
        `${Math.trunc(ca1 / ca2)}`
      ) {
        await interaction.guild.members
          .resolve(interaction.user)
          .roles.add(role)
          .then(async () => {
            await interaction.reply({
              content: '認証が完了しました。',
              ephemeral: true,
            });
          })
          .catch(async (e) => {
            const er = String(e);
            if (er.indexOf('Missing Permissions') != -1) {
              await interaction.reply({
                embeds: [
                  {
                    title:
                      ':x: :権限がありません。',
                    description: `Botのロールが付与するロールよりも下になっていませんか?\nBotにロールを付与する権限がありますか？\n\nサーバーの管理者(<@${interaction.guild.ownerId}>)にご連絡下さい。`,
                  },
                ],
                ephemeral: true,
              });
              return;
            } else {
              const embed = new discord.EmbedBuilder()
                .setTitle(
                  ':x: : エラーが発生しました!!'
                )
                .setDescription(discord.codeBlock('xl', e))

              const msg1 = await client.channels.cache
                .get('エラーを送信するチャンネルのid')
                .send({ embeds: [embed] });
              interaction.reply({
                embeds: [
                  {
                    title:
                      ':x: :不明なエラーが発生しました。',
                    description:
                      'エラーid: `' +
                      msg1.id +
                      '`\nサポートサーバーで、エラーidと一緒にお問い合わせ下さい。\n\nサーバーの管理者(<@' +
                      interaction.guild.ownerId +
                      '>)にご連絡下さい。',
                  },
                ],
                ephemeral: true,
              });
              return;
            }
          });
      } else {
        await interaction.reply({
          content: '答えが違います。',
          ephemeral: true,
        });
      }
    }
  },
};

```
```command/slash_verify.js
const discord = require('discord.js');
const fs = require('fs');
const client = new discord.Client({
  intents: Object.values(discord.IntentsBitField.Flags),
  partials: Object.values(discord.Partials),
  allowedMentions: { repliedUser: false },
});
module.exports = {
  name: 's_verify',
  description: 'スラッシュコマンド認証',
  async execute(client, interaction, verify) {
    if (interaction.commandName === 'verify') {
      if ((await interaction.options.getString('type')) === '足し算認証') {
        var role = await interaction.options.getRole('role');
        var button = new discord.ButtonBuilder()
          .setCustomId('b_verify')
          .setStyle(discord.ButtonStyle.Success)
          .setLabel(`認証`);

        var embed = new discord.EmbedBuilder()
          .setTitle('足し算認証')
          .setDescription(
            `下のボタンを押して、認証して下さい。\n付与されるロール: <@&${role.id}>`
          )

        var msg = await await client.channels.cache
          .get(interaction.channel.id)
          .send({
            embeds: [embed],
            components: [new discord.ActionRowBuilder().addComponents(button)],
          });
        await interaction.reply({
          ephemeral: true,
          content: 'パネルの生成が完了しました。',
        });
        await verify.set(msg.id + '_3', role.id);
      }
      if ((await interaction.options.getString('type')) === '引き算認証') {
        var role = await interaction.options.getRole('role');
        var button = new discord.ButtonBuilder()
          .setCustomId('b_verify1')
          .setStyle(discord.ButtonStyle.Success)
          .setLabel(`認証`);

        var embed = new discord.EmbedBuilder()
          .setTitle('引き算認証')
          .setDescription(
            `下のボタンを押して、認証して下さい。\n付与されるロール: <@&${role.id}>`
          )

        var msg = await await client.channels.cache
          .get(interaction.channel.id)
          .send({
            embeds: [embed],
            components: [new discord.ActionRowBuilder().addComponents(button)],
          });
        await interaction.reply({
          ephemeral: true,
          content: 'パネルの生成が完了しました。',
        });
        await verify.set(msg.id + '_3', role.id);
      }
      if ((await interaction.options.getString('type')) === '掛け算認証') {
        var role = await interaction.options.getRole('role');
        var button = new discord.ButtonBuilder()
          .setCustomId('b_verify2')
          .setStyle(discord.ButtonStyle.Success)
          .setLabel(`認証`);

        var embed = new discord.EmbedBuilder()
          .setTitle('掛け算認証')
          .setDescription(
            `下のボタンを押して、認証して下さい。\n付与されるロール: <@&${role.id}>`
          )

        var msg = await await client.channels.cache
          .get(interaction.channel.id)
          .send({
            embeds: [embed],
            components: [new discord.ActionRowBuilder().addComponents(button)],
          });
        await interaction.reply({
          ephemeral: true,
          content: 'パネルの生成が完了しました。',
        });
        await verify.set(msg.id + '_3', role.id);
      }
      if ((await interaction.options.getString('type')) === '割り算認証') {
        var role = await interaction.options.getRole('role');
        var button = new discord.ButtonBuilder()
          .setCustomId('b_verify3')
          .setStyle(discord.ButtonStyle.Success)
          .setLabel(`認証`);

        var embed = new discord.EmbedBuilder()
          .setTitle('割り算認証')
          .setDescription(
            `下のボタンを押して、認証して下さい。\n付与されるロール: <@&${role.id}>`
          )

        var msg = await await client.channels.cache
          .get(interaction.channel.id)
          .send({
            embeds: [embed],
            components: [new discord.ActionRowBuilder().addComponents(button)],
          });
        await interaction.reply({
          ephemeral: true,
          content: 'パネルの生成が完了しました。',
        });
        await verify.set(msg.id + '_3', role.id);
      }
    }
  },
};

```
# コマンドの使い方
!verify 足し算認証 @ロール
!verify 引き算認証 @ロール
!verify 掛け算認証 @ロール
!verify 割り算認証 @ロール
/verify type: 足し算認証 role: @ロール
/verify type: 引き算認証 role: @ロール
/verify type: 掛け算認証 role: @ロール
/verify type: 割り算認証 role: @ロール