【Java】DiscordBotの作り方 2023年版

## はじめに
初投稿かつQiita初心者です。
DiscordのBotを作る際にすごーーく戸惑ったので、初心者目線でリファレンスを置いておきます。
なお、私自身はJavaのすこーし書けるぐらいです。

## 使用するもの
* Eclipse（Pleiades）
* Discord
* JDA

※ダウンロード方法などは下に書いておきます！

## ライブラリ
※あんまり気しなくてよいです。このバージョン使ってるよーっていう記述だけ。
* JDA
バージョン：5.0.0-beta.16
公式（github）
https://github.com/discord-jda/JDA

* Eclipse
バージョン：2023
日本語版のPleiadesを使用しています。
公式サイト
https://willbrains.jp/


## Discord サーバーの用意
DiscordのBotをテストする自分だけのサーバーを作りましょう。
※他の人がいるサーバーでテストすると通知音がうるさく迷惑がかかるので。

サーバーの＋マークをクリック
![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/3e0ad30c-0399-3538-f0e5-a76076d6101f.png)

オリジナルの作成（何でもよいです。）
![キャプチャ3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/e036b5cf-2181-9f31-f993-94da2a1f3443.png)

自分と友達のためを押下（どっちでもよいです。）
![キャプチャ4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/ad79526f-72b1-f924-80d7-b928658d8378.png)

好きな名前のサーバーに設定して新規作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/edceb896-e2c8-af31-64c7-6321e420c29d.png)


## Discord Botの用意
まずはDiscordのBotを作成しましょう。
下記のサイトに行っていただき、ログインを行ってください。
https://discord.com/developers/applications

New Applicationをクリック
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/46aa3ce7-6115-a4b3-6268-fdf22df75a72.png)

Botの名前とチェックを入れてCreateを押下
※名前は後で変えられます。
※日本語でもOK
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/2a01461d-37aa-fb83-8261-224257962646.png)

左のメニューからBotを選択し、MESSAGE CONTENT INTENTにチェックを入れる
![キャプチャ32.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/93e63788-db53-ce4c-0d39-cca94d69e250.png)


左のメニューからOAuth2→URLGeneratorを押下
![キャプチャ1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/d70bdb90-a320-7331-fcb4-babc7574d2c4.png)

SCOPESには「applications.commands」と「bot」をチェック
BOT PERMISSIONSには「Administrator」にチェックを入れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/a57b6de6-866e-0ebd-3282-fe9afd763375.png)

一番下に出てくるGENERATED URLをコピー
![キャプチャ5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/c26a9f1c-d5d5-562d-f6f6-1b40e5840a03.png)

コピーしたURLをブラウザの上部に張り付けてエンター
（新しいタブでやったほうがいいかも！）
![キャプチャ6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/c015fa23-8c25-cd33-0f96-af096a044b85.png)

ブラウザ上でサーバーを自分が追加したサーバーを選んで「はい」を押下
（ここで出てこない場合はサーバーを作っていない方か、サーバーの権限が足りない可能性があります。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/c81421c8-59d2-7457-9cc0-26e20cf7b45f.png)

認証を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/4c2b34bc-c52f-d61b-e4ab-2f6536fd55f0.png)

そうすると、サーバーにBotが入ってきたと思います。
![キャプチャ8.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/7551e5da-482e-67c2-20ab-3368dca0663f.png)


## 環境開発の用意
ぶっちゃけJavaが動けばいいので自身が好きなエディタでよいです。
（VSCode、IntelliJ IDEAなど...）

今回はEcripseで紹介します。
下記のサイトからEcripseをダウンロードしてください。
https://mergedoc.osdn.jp/

Ecripse2023を押下
![キャプチャ9.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/97a7fae2-c102-7045-ef10-943dcf2c42ff.png)

Java版をダウンロード
![キャプチャ10.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/ac93236b-0063-cf28-8a80-a3f5f7123d82.png)

ダウンロードしたファイルを解凍
※7zipとかで解凍してもよいのですが、7Zipなど解凍ツール持っていない方はPleiadesのツールで解凍しましょう。
フォルダの格納先はCドライブ配下の「pleiades」配下に入れてください。
参照：c:\pleiades
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/0744d2dc-a72d-168f-00a7-ef8f180fd383.png)

解凍が終わると下記のような形になっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/9395c5fa-fd0d-74c7-71b1-ac8012e85fae.png)

eclipse→eclipse.exeを起動しましょう。
![キャプチャ11.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/b85aeaee-3fb9-e2d3-fd8c-3d153f0f90d6.png)

起動するたび毎回このフォルダに来るのが面倒なので
ディスクトップにeclipse.exeのショートカットを作成しましょう。
![キャプチャ12.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/ca04e32b-ec9b-fea2-227f-a8a4b452ce6d.png)

そのまま起動を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/5eeae8dc-a186-2543-1e19-519c63b3101a.png)

eclipseが立ち上がればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/b6ded0db-a0ad-cd63-3cbb-004c976026a2.png)

## プロジェクトの作成
左上の新規を押下
![キャプチャ13.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/0e66ceb7-aa0e-5d57-f020-54d427fb3407.png)

ウィザードが出てくるので
ウィザードに「Maven」と記述し、Mavenプロジェクトを選択、次へをクリック
![キャプチャ14.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/9259f07e-c793-2fad-42d6-99a29cfc0444.png)

そのまま次へ
![キャプチャ15.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/fd04ee2c-131e-6819-bbdf-f3aac298aa63.png)

フィルターに「maven-archetype-quickstart」と入力し、
グループIDが「org.apache.maven.archetypes」を選択して次へ
![キャプチャ16.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/2270cbd4-89d7-c447-8d2b-a85f9ef99b3c.png)

グループIdとアーティファクトIdには適当な名前を付けておけばOK
考えるのが面倒な人は
グループID：com.discord
アーティファクトId：samplebot
こんな感じでつけておいてください。
入力したら完了を押下
![キャプチャ17.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/21348647-d901-b802-4fec-7173dfeb1c4e.png)

コンソールにこのパッケージでよいですかー？みたいな感じで出てくるので、

![キャプチャ18.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/cebd9d85-33ed-b2dc-67a6-1ae7f2ac4c04.png)

コンソールに「Y」を入力してエンター
![キャプチャ19.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/d65ca5a9-c91a-7bc7-74c1-c17b6f08672c.png)

コンソールにBUILD SUCCESSと出てきて、
新たなフォルダができているはずです。
![キャプチャ20.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/0b7613b3-e0e9-e523-7e0f-9a2d7ee0e0e6.png)

作成したフォルダ内のpom.xmlを開く
dependenciesっていうタグがあるので、その中にいろいろ入れる
※コードが出てこない場合は下の方にあるpom.xmlのタブを開いてください。（画像参照）
![キャプチャ21.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/2a3ecefc-5fde-1a80-23e0-ca046286404f.png)

```diff_java
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
```
↓
```diff_java
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
+	<dependency>
+	  <groupId>net.dv8tion</groupId>
+	  <artifactId>JDA</artifactId>
+	  <version>5.0.0-beta.16</version>
+	</dependency>
+   <dependency>
+	  <groupId>org.slf4j</groupId>
+	  <artifactId>slf4j-api</artifactId>
+	  <version>2.0.9</version>
+	</dependency>
+	<dependency>
+	  <groupId>org.slf4j</groupId>
+	  <artifactId>slf4j-jdk14</artifactId>
+	  <version>2.0.9</version>
+	</dependency>
  </dependencies>
```

projectを右クリックしてプロパティーを押下
![キャプチャ22.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/fb735ca1-6587-8511-1261-6db0fb35264a.png)

プロジェクト・ファセットを選択し、
ファセット・フォームへ変換を押下
![キャプチャ23.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/a9ce645b-3035-47fb-f90f-14068bc2032e.png)

この画面になったら適応して閉じるを押下
![キャプチャ24.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/5ce420fa-560e-149f-0385-5b0dc53cd981.png)

## プログラムの初期設定

パッケージを右クリックして新規→クラスを選択
![キャプチャ25.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/a5d0d9d2-bfe9-06fc-b9ba-8ebe6aabe79a.png)

名前は何でもよし！
入力したら完了を押下
※先頭文字は必ず大文字にしてください。
![キャプチャ26.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/d5856fb8-f700-2127-554a-4e90eb3a7dea.png)

作成したファイルの中に初期設定をしていきます。
```diff_java
public class DiscordBot {

}
```
↓
```diff_java
public class DiscordBot extends ListenerAdapter {
	private static JDA jda = null;
	private static final String BOT_TOKEN = "Botのトークン";

	public static void main(String[] args) {
		jda = JDABuilder.createDefault(BOT_TOKEN)
                .setRawEventsEnabled(true)
                .enableIntents(GatewayIntent.MESSAGE_CONTENT)
                .addEventListeners(new DiscordBot())
                .setActivity(Activity.playing("ステータス"))
                .build();

		jda.updateCommands().queue();

	}
	
	//メッセージの反応メソッド
	@Override
    public void onMessageReceived(MessageReceivedEvent event) {
        if (event.getAuthor().isBot()) return;
	}
	
	//コマンドの反応メソッド
	@Override
    public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {
		
	}
}
```
※.addEventListeners(new クラスの名前())
ここの部分は自分の作ったクラスの名前に変更してください。


それぞれ解説
Botのトークンは下記から取得してください。
https://discord.com/developers/applications

作成したBotを選択
![キャプチャ27.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/bf5b3089-ac6f-cbb6-8537-1b33c09ec434.png)

Reset Tokenを押下
![キャプチャ28.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/c4cdfc6a-94d8-15b5-5148-ebe00814f920.png)

Yes, do it!を押下
![キャプチャ29.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/d4b0b1bc-c609-47e4-7e30-09837f048c9a.png)

出てきたトークンをコピー
※このトークンは絶対に人に教えないでください！！！
![キャプチャ30.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/2629a842-ee8a-ab95-ee96-63402275aacb.png)

Botのトークンに張り付け
![キャプチャ31.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/878413b3-bbe0-a57e-ae5c-b65fe407d98c.png)

## botを動かしてみる
作成したクラスを右クリック→実行→Javaアプリケーションを押下
![キャプチャ34.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/4f38f2b3-18bf-b60c-51c8-5ad57c4b11c3.png)

コンソールに下記のような感じで出ていればOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/0b645462-0e51-5ffd-3f92-59b9db438026.png)

失敗する場合はエラー情報をネットで調べるか読み込んでいるJDAとかが古くないか確認してみてください。

Botがオンラインになっていると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/61cc0fe4-2174-dfca-fadb-4a60faa03891.png)


## いざBotの実装へ！
そしたら、コーディングしていきましょう。
※コーディングを反映させたい場合はJavaアプリをいったん落としてから起動しなおしましょう。

#### ステータスの変更
```diff_java
    .setActivity(Activity.playing("ステータス"))
```
Activityには種類があり、様々な文字列に変更することができます。
![キャプチャ33.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/b19730d2-d55c-9ac8-46ef-43ba817ba564.png)

* Activity.playing("好きな文字列")
〇〇をプレイ中
* Activity.competing("好きな文字列")
〇〇に参戦中です
* Activity.listening("好きな文字列")
〇〇を再生中
* Activity.streaming("好きな文字列","url")
〇〇を配信中(ユーザーをクリックすることで設定したURLに飛ぶようです)
* Activity.watching("好きな文字列")
〇〇を視聴中

どれかのステータスにしたい場合はもとから変更するようにしてください。

#### メッセージによる反応
```diff_java
    @Override
    public void onMessageReceived(MessageReceivedEvent event) {
        if (event.getAuthor().isBot()) return;
        
	}
```
このメソッドはDiscordのテキストチャットを送った時動きます。
> ```diff_java
>     if (event.getAuthor().isBot()) return;
> ```
> Botが打ったチャットには反応しないようにしています。

> ```diff_java
> String msg = "にゃーん";
> event.getChannel().sendMessage(msg).queue();
> ```
> このコードを打つことで、メッセージを飛ばしてくれます。

例1：組み合わせるとこんな感じ
```diff_java
    @Override
	public void onMessageReceived(MessageReceivedEvent event) {
		if (event.getAuthor().isBot()) return;
		String msg = "にゃーん";
		event.getChannel().sendMessage(msg).queue();
	}
```
例1:動かすとこんな感じ
![Animation2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/a8054d4e-afaf-1dc3-5c7b-5520f58f8e6b.gif)

例2:特定のメッセージによって反応を変えたい場合
```diff_java
	@Override
	public void onMessageReceived(MessageReceivedEvent event) {
		if (event.getAuthor().isBot()) return;
		String message = event.getMessage().getContentRaw(); //メッセージを受け取る
        System.out.println("message:" + message);
        String msg = "";
        switch (message) {
        case "sample1":
        	msg = "にゃーん1";
        	break;
        case "sample2":
        	msg = "にゃーん2";
        	break;
        case "sample3":
        	msg = "にゃーん3";
        	break;
        case "sample4":
        	msg = "にゃーん4";
        	break;
        }
        if(!msg.isEmpty()) {
        	event.getChannel().sendMessage(msg).queue();
        }
	}
```
例2:動かすとこんな感じ
![Animation2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/1a02c4f7-1c9e-94cc-d98c-49042057e41c.gif)

#### スラッシュコマンドの対応
```diff_java
	@Override
	public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {

	}
```
このメソッドはDiscordのコマンドによって動きます。

コマンドの登録
mainメソッド内にコマンドを登録しましょう。
```diff_java
    jda.upsertCommand("コマンド","コマンド説明").queue();
```
> ![キャプチャ36.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/2a290ef1-159b-7e1c-3d9f-48f0336a8b42.png)
> 左側がスラッシュの後に来るコマンドで、右側がコマンドの説明部分になります。
> 実際の画面
> ![キャプチャ35.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/03a0c9cb-ddc4-c10f-febb-c450f52ad42a.png)

コマンドの実行処理
onSlashCommandInteractionメソッド内に実行処理を記述しましょう。
```diff_java
String command = event.getName();
```
コマンドメッセージを受け取ります。

```diff_java
event.reply("メッセージ").setEphemeral(false).queue();
```
コマンドが打たれた場所にメッセージを返します。

例1:コマンドによるメッセージの返し
※さっきの登録したコマンドを使用する
```diff_java
    @Override
	public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {
		String command = event.getName(); //コマンドを受け取る
		String msg = ""; 
		if (command.equals("コマンド")) {
			msg = "コマンドを打ったよ！";
			event.reply(msg).setEphemeral(false).queue();
			return;
		}
		
		event.reply("不明なコマンドです。").setEphemeral(false).queue();
	}
```

例1:動かすとこんな感じ
![Animation2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/422d32bd-5c44-c513-8f50-6f78028e7670.gif)

例2:ロールダイスを作る
コマンドを登録する。
```diff_java
jda.upsertCommand("ロール", "0～99まで出してくれるダイスです").queue();		
```

先ほどのコマンド処理を作った下に下記の内容を追加する
```diff_java
    if (command.equals("ロール")) {
		Random rnd = new Random();
		String roll = Integer.toString(rnd.nextInt(100));
		event.reply(roll).setEphemeral(false).queue();
		return;
	}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/da5358d4-8ea6-659e-3361-1715873afa75.png)

例2:動かすとこんな感じ
![Animation2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580801/d4ee80a2-6ad6-f9ef-9f00-48f52933a4df.gif)

## まとめ
いかがでしたでしょうか。
他のQiitaを見ていると初学者だとここの書き方だとわからんなぁというところが多かったため、
今回画像を多めに使用して説明しました。
基本さえわかれば後はJavaと同じように実装するだけなのでいろいろできると思います！
ぜひいろいろ試してみてね！