【実用編】discord.js v13 ユーザー・メンバーをBAN・KICK・UNBAN

## 前書き
Discordは世界的に有名なンスタントメッセージ・ビデオ通話・音声通話・VoIPフリーウェアです。
そのため、日々いろいろな個性あふれるユーザーが使用します。
中には、**毎日自分の性癖を暴露するのが趣味な方**、**小学3年生レベルの下ネタを1秒に数十件も送るのが興奮してやまない方**。
などなど様々な方がいます。自分のサーバーに**危険な危ないデンジャラスなユーザーを入れない、追放するためのコマンド**の作成方法を解説します。

## ユーザーとメンバー、おいしいのどっち？
タイトルに「ユーザー・メンバー」とありますが、「**ユーザーとメンバーなんて何が違うねん、ちょっと辛いのがユーザーって感じだけじゃね？**」と思う方も多いことでしょう。
discord.jsでは**ユーザーとメンバーには明確な違い**があります。スパイスだけの違いではありません。

### ユーザー
* Discordを使用しているアカウント（ユーザー）を指す
* 基本的なアカウント情報（ユーザーネーム、ユーザーID等）を取得できる
* **インド産のスパイスを使用**

### メンバー
* コマンドを実行したサーバー内にいるユーザーを指す
* より細かな情報（サーバー参加日、所持しているロール等）を取得できる
* 基本的なアカウント情報（ユーザーネーム、ユーザーID等）も取得できる
* **パキスタン産のスパイスを使用**

#### 結局どう使い分ければよいのか
**基本的にメンバーの方を選択**するのが良いかと思われます。
v13 のスラッシュコマンドでのユーザーを入力する際に出てくるリストに現在サーバーに参加しているメンバーのみしか表示されていないため、より多くの情報を取得できるメンバーのほうが良いかと思われます。
しかし、DM等はサーバーではないため、ユーザーでの取得でないと正常に取得できない可能性があります。

## BAN・KICK・UNBANとは
上記の3つはいずれもユーザー・メンバーに対する処罰（処罰解除）を行う意味があります。
### BAN
ネット用語だと思われがちですが、「ban」という英単語は実際に「禁止する」という意味を持ちます。
「KICK」や「UNBAN」はすべて小文字で表す風習がかなりありますがなぜか「BAN」のみすべて大文字で表す風習のほうが強い気がします。

こちらには「**禁止する**」という意味を持ち、**実行したサーバーへ任意のメンバー・ユーザーの接続を指定した期間禁止**します。
招待リンクから入ろうとしてもBANされている状態だと参加できません。また、**そのユーザー・メンバーが過去に送信したメッセージを、選択した期間内のものを削除する**こともできます。
また、**今現在サーバーに参加していないユーザーもあらかじめBANしておく**というのも可能です。グローバルBANとかはこのような感じです。
しかしスラッシュコマンドでは現在サーバー内にいるメンバーしか指定ができないようなので、ユーザー入力方式でのあらかじめのBANは難しいかもです。

### KICK
KICKもまた「kick」という「**蹴る**」という意味を持つ英単語です。
こちらは先ほどの「BAN」よりも軽い処罰の方法です。**そのメンバーを実行したサーバーから一度切断**します。
「BAN」と違い、**またすぐにサーバーに入りなおすことが可能**です。

### UNBAN
こちらは「BAN」に「不」や「逆」の意味を表す「UN」をつけた「**禁止（BAN）を解除する**」という意味があります。
その名の通り、**期間中のBANを解除します。**
BANしたユーザーに**十分反省が見られた場合や、誤ってBANしてしまった際**に行います。

## コーディング
早速コーディングをしていきまっしょい！

### BAN
今回は新しく`ban.js`というファイルを作成します。そして以下のような構文を記述しましょう。
今回は「**実行したサーバーで指定したユーザーのBANを作成する**」というような流れで行います。

```javascript:ban.js
const { SlashCommandBuilder } = require('@discordjs/builders');

module.exports = {
	data: new SlashCommandBuilder()
		.setName('ban')
		.setDescription('そのメンバーをサーバーから禁止します。')
		.addUserOption(option => option.setName('対象').setDescription('ユーザーを選択').setRequired(true)) //必須にする
		.addStringOption(option => option.setName('理由').setDescription('禁止する理由'))
		.addStringOption(option => option.setName('メッセージ削除').setDescription('メッセージ履歴の削除期間を選択').addChoice('削除しない', '0').addChoice('過去24時間', '1').addChoice('過去7日', '7')), //3つから選択
	async execute(interaction, client) {
		const user = interaction.options.getUser('対象'); //今回はユーザーを指定
		const reasons = interaction.options.getString('理由') || 'None'; //理由がない場合「None」
		const messages = interaction.options.getString('削除') || '0';

		// BANが出来ない祭の動作
		if (interaction.guild.ownerId !== interaction.user.id && member.roles.highest.comparePositionTo(interaction.member.roles.highest) >= 0) return await interaction.reply('無効なユーザーです。') //指定したユーザーが実行したユーザーよりも権限が上の場合
		if (!user.bannable) return await interaction.reply('無効なユーザーです。') //指定したユーザーのBANが不可能な場合
		if (!interaction.member.permissions.has('BAN_MEMBERS')) return await interaction.reply('権限がありません。') //実行したユーザーに権限がない場合

		interaction.guild.bans.create(user.id, { reason: reasons, days: messages }); //実行したサーバーでBANを作成
		await interaction.reply('指定したユーザーをBANしました: ' + user.tag);//成功した際に送るメッセージ
	},
};
```

### KICK
今回は新しく`kick.js`というファイルを作成します。そして以下のような構文を記述しましょう。
```javascript:kick.js
const { SlashCommandBuilder } = require('@discordjs/builders');

module.exports = {
	data: new SlashCommandBuilder()
		.setName('kick')
		.setDescription('そのメンバーをサーバーから追放します。')
		.addUserOption(option => option.setName('対象').setDescription('メンバーを選択').setRequired(true))
		.addStringOption(option => option.setName('理由').setDescription('追放する理由')),
	async execute(interaction, client) {
		const member = interaction.options.getMember('対象'); //今回はメンバーを指定
		const reasons = interaction.options.getString('理由') || 'None'; //理由がない場合「None」

		// KICKが出来ない祭の動作
		if (!user) return await interaction.reply('無効なユーザーです。') //ユーザーが指定されていない場合
		if (interaction.guild.ownerId !== interaction.user.id && member.roles.highest.comparePositionTo(interaction.member.roles.highest) >= 0) return await interaction.reply('無効なユーザーです。') //指定したユーザーが実行したユーザーよりも権限が上の場合
		if (!member.kickable) return await interaction.reply('無効なユーザーです。')//指定したユーザーのKICKが不可能な場合
		if (!interaction.member.permissions.has('KICK_MEMBERS')) return await interaction.reply('権限がありません。') //実行したユーザーに権限がない場合

		member.kick({ reason: reasons }); //指定したメンバーをKICK
		await interaction.reply('指定したユーザーをKICKしました: ' + user.tag);//成功した際に送るメッセージ
	},
};
```

### UNBAN
今回は新しく`unban.js`というファイルを作成します。そして以下のような構文を記述しましょう。
今回は「**実行したサーバーで指定したユーザーのBANを削除する**」というような流れで行います。

```javascript:unban.js
const { SlashCommandBuilder } = require('@discordjs/builders');

module.exports = {
	data: new SlashCommandBuilder()
		.setName('unban')
		.setDescription('そのユーザーの禁止を解除します')
		.addUserOption(option => option.setName('対象').setDescription('ユーザーを選択').setRequired(true))
		.addStringOption(option => option.setName('理由').setDescription('禁止する理由')),
	async execute(interaction, client) {
		const member = interaction.options.getUser('対象'); //今回はユーザーを指定
		const reasons = interaction.options.getString('理由') || 'None'; //理由がない場合「None」

		// UNBANが出来ない祭の動作
		if (interaction.guild.bans.fetch(user.id)) return await interaction.reply('無効なユーザーです。')
		if (!interaction.member.permissions.has('BAN_MEMBERS')) return await interaction.reply('権限がありません。') //実行したユーザーに権限がない場合

		interaction.guild.bans.remove(user.id, { reason: reasons }); //実行したサーバーでの指定したユーザーのBANを削除
		await interaction.reply('指定したユーザーのBANを解除しました: ' + user.tag); //成功した際に送るメッセージ
	},
};
```

以上です。**お疲れサマンサ！**