Discordでbotを作る手順まとめる

# Discord でBotを作成する備忘録

::: note info
自分のために作ってるけど一応忘れないために書き残す用
曖昧な部分については詳しい人がいたら教えてください
2022/10/27 開発中なので作成しながら追加していく予定
:::

<details><summary>プロフィール</summary>

- 触ったことのある言語
    - C++
    - C#
    - JavaScript
    - Python
- プログラミング歴
    - 大学4年間
    - 社会人2年

</details>

[Discord Developers](https://discord.com/developers/)
[DiscordPy ドキュメント](https://discordpy.readthedocs.io/ja/latest/index.html)

Python 3.10.*
Discord.py 2.0.*

## Pythonをインストール

WindowsのStoreにあった
公式サイトからでも良さそうだけどどう違うのかとかはわかんない


## Discord.pyをインストール
公式ドキュメントには
`python3 -m pip install -U discord.py`
とあるが
`python3 -m pip install git+https://github.com/Rapptz/discord.py`
こっちのほうがいいかも？違いがわかんない


## 読み上げ機能を付けるためのいろいろをインストール
読み上げいらない人やとりあえず動けば良い人はいらない

<details><summary>必要な人はここを開く</summary>

### 必要なもの
- Opegjtalk.exe
- Openjtalkの辞書フォルダ
- htsvoice
- ffmpeg

それぞれ説明する

#### Openjtalk
テキストファイルをWAVファイルに変換するもの
#### Openjtalkの辞書フォルダ
変換する際に必要日本語の辞書が入ってるっぽい
#### htsvoice
読み上げる音声ファイル
男性や女性など様々で好きなものを使えば良い
#### ffmpeg
DiscordでWAVファイルを再生するために必要なもの(たぶん)

インストールする際はここら辺が役に立つ

https://appli-world.jp/posts/16908
https://qiita.com/mkgask/items/0bf9c26dc96e7b0b45ac
https://web.plus-idea.net/2015/11/windows-ffmpeg/

</details>


## Botを作成する

[Discord Developers](https://discord.com/developers/) からBotを作成する
Intentsを許可してあげると良いかも
[ここら辺が役に立つ](https://qiita.com/PinappleHunter/items/af4ccdbb04727437477f)


## プログラムを書く

とりあえずコピペしたら動くはず...
コマンドは `python main.py` (main.pyはファイル名なのでなんでも良い)

```Python
import discord
from discord.ext import commands

TOKEN = 'Your Token'
cmd = '.'

client = commands.Bot(
    intents=discord.Intents.all(),
    command_prefix=cmd
)

@client.event
async def on_ready():
    print('Login')
    print(client.user.name)
    print('------')

@client.command()
async def test(ctx):
    ctx.send('コマンドが発動')

@client.event
async def on_message(message):
    if message.content.startswith(cmd):
        pass
    else:
        print(message.content)

    await client.process_commands(message)

client.run(TOKEN)
```


## 説明

- `@client.event` は何もしなくても動くやつ
ユーザーがメッセージを送ったり、ボイチャに入退室したりしたときに勝手に発火してくれる

- `@client.command()` はコマンドを打つと発火するもの

```python
@client.command()
async def test(ctx):
    ctx.send('コマンドが発動')

# ディスコードにメッセージ入力
# .test
# ディスコードにメッセージ出力
# コマンドが発動

@client.command()
async def test2(ctx, memo):
    ctx.send(memo, "だよ。")

# ディスコードにメッセージ入力
# .test2 ああああ
# ディスコードにメッセージ出力
# ああああだよ。
```

基本的にはこの2つを利用してプログラムを書いていくことになる

---

- 関数は自分でも作れる

```python
def test2():
    print("test2")
```

- async や awaitは同期非同期あたりの話

- コマンドの [`ctx`](https://discordpy.readthedocs.io/ja/latest/ext/commands/api.html#context) に鯖の様々な情報が入っていてここから鯖のメンバーだったりチャンネルだったりを取得できる
同じく [`message`](https://discordpy.readthedocs.io/ja/latest/api.html#message) にもいろいろ入っていて `message.content` で文字列を取得できる


## .envファイルの作成

トークンなどの環境変数に関してgitなどパブリックな状態にしたくない値などを入れる
`.gitignore` で除外しておくと良い
以下のように書くことで環境変数を読み込める

#### インストール方法
```text
$ pip install python-dotenv
```

#### プログラム

```python
import os
from dotenv import load_dotenv

load_dotenv()

TOKEN = os.environ.get('TOKEN')
```
## プログラムが長くなってきてファイルを分けたい場合

discord.pyにあるCogという機能を使う
以下のような階層をすれば良い
cogsディレクトリに入ってるファイルにはdiscord.pyの機能を使うプログラムを記述
libsディレクトリに入ってるファイルにはdiscord.pyの機能を使わないプログラムの記述

```text
$ tree
|-- cogs 　　　　　　　　　　　　　　　　　　　　　　　　　
|   |-- cogfile1.py
|   `-- cogfile2.py
|-- libs 　　　　　　　　　　　　　　　　　　　　　　　　　
|   |-- file1.py
|   `-- file2.py
|-- main.py 　　　　　　　　　　
`-- .env
```