【Discord Bot】Pycordを使ってSlashCommandの使えるBOTの作り方


今までDiscord.pyを使ってBotを作成してきたが、今後Updateがされないと発表されていることからPycordに乗り換えて、比較的SlashCommandも対応しやすいことが確認できたので共有したい。

> 現時点でdiscord.pyの開発はされているため、選択肢としてpy-cordを選択するのは良いですが、日本語のドキュメントも充実しているdiscord.pyのほうが良いかもしれません。
> 私個人は現在(2023/01/26)でもpy-cordで開発しています。（結構構文違うのでマイグレーションメンドイ）

初心者でも0から構築できるように説明していきますのでよろしくおねがいします。

## まず準備から

以下のインストールをしていきます
- Python 3.10
- Visual Studio Code


### Pythonの準備

**Python**今回はPythonを使ってDiscord向けのコマンドを作成するのでインストールしていきます。
下の記事を参考にしながらインストールしていけばOKですが、~~バージョンが少し古いので現在（2022/03/26)の最新バージョンの3.10をインストールするのをオススメします。~~
2023/01/26時点でpy-cordがPython3.11で動作しないなどサポートされていない事確認しましたので3.10が現時点でおそらく一番無難です。

https://qiita.com/ssbb/items/b55ca899e0d5ce6ce963

コマンドプロンプトはWindowsボタンを押して`cmd`と打つとすぐに開くことができます



### Visual Studio Codeの準備

**Visual Studio Code**でコーディングをする前提なので以下の記事などを参考にしながらインストールします。

https://qiita.com/cmssai/items/cde9080e32b7dfd75030

個人的には以下のチェックはいれる事を推奨しています
- エクスプローラーのファイルコンテキストメニューに[Code で開く] アクションを追加する
- エクスプローラーのディレクトリコンテキストメニューに[Code で開く] アクションを追加する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239781/55054fa5-b1df-eb59-a2aa-3e52ed03e4b7.png)

上記のチュートリアル通りに勧めばPythonの実行までが確認できると思います。


## Discord BOTの準備

まずDiscord Developer Portalでログインします

https://discord.com/login?redirect_to=%2Fdevelopers

ログインすると右上に**NewApplication**というボタンがあるのでそれをクリックし、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239781/5f350f90-c05a-777e-b449-eaff5df20b63.png)

任意の名前を入力して**Create**をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239781/b1235e8c-e4b9-d5ab-a513-d20af616d56e.png)

左のメニューバーにある**Bot**をクリックし、**Add Bot**をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239781/189b45d8-f0ac-662e-92f4-af54f5474915.png)

**Yes, do it**をクリックして作成します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239781/962a20e4-055b-1f5c-e3ea-9469929731cb.png)

すると以下のような画面が出てきますので、**Reset Token**を押してトークンを取得します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239781/27b3b23a-e773-813f-915d-0b76755dcf87.png)

**Yes, do it**をクリックすると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239781/e73b37c0-d6c2-da22-ffb2-1b372b2c650e.png)

以下の画面でTOKENを**Copy**できるようになるので、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239781/d99e391a-524b-dd21-6d7f-7c73319866f5.png)

一度BOTを入れておくフォルダを作成しておき、適当な名前のテキストファイルに
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239781/7ed64afa-54a4-71d4-9a75-98f6852b0fdb.png)

以下のように`TOKEN = `という文字を頭に付けて、`""`で囲った状態で保存します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239781/33c9e004-7473-3983-482d-c92ed993d09c.png)

保存し終わったらサーバーに対してBOTを追加していきます。

まず、左のメニューから`OAuth2`を選択し、`URL Generator`を選択、
チェックボックスの`bot`と`applications.commands`を有効にしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239781/628654cb-bedb-892b-877d-742debe7c7a1.png)

また、下にスクロールすると**BOT PERMISSONS**というものがあるので、今回は`Send Messages`のみ選択してください。
（Administratorを選択すると全ての権限が付与されるのですが、悪意のあるユーザーに`TOKEN`を知られた際にサーバーを荒らされるなどのリスクがあります）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239781/b0784ace-3844-830a-4be8-b287bd0e5768.png)

すると下部にURLが生成されているので、Copyします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239781/0cc67b15-9930-82b4-e907-ba973c8cabe9.png)

### サーバー管理者の場合は以下の通りに実行します

> サーバーの管理者でない場合は以下スキップしてください

ブラウザのアドレスバーにURLを入力すると以下の画面になるので、
自分の呼び込みたいサーバーを選択して`はい`を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239781/0e2a6f74-433c-4835-3f66-931e8913cf5f.png)
ここでAdministratorなどを選択していた場合は管理者権限を与える事になりますので、今回はメッセージを送信のみがチェックされていることを確認してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239781/0c506d65-ca9e-0321-7355-aa2a5f3c7d5c.png)
あなたが人間かをチェックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239781/360e1022-19f5-9cc0-0bb7-d5f588107784.png)
すると以下のように新しいBotが追加されるのが確認できると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239781/cf433e00-f2db-5b20-27b6-52040a90ccca.png)

### サーバー管理者ではない場合

サーバー管理者ではない場合はセルフで追加ができません。
なので、サーバー管理者に入れて貰う必要があります。

先程コピーしたURLをDiscordに貼り付けしてもらうとサーバー管理者がBOTを導入することができます。
このときに管理者権限が無いことを確認してもらう事が重要なので、その旨を伝えていただけると良いと思います。

> 個人的には上記で示した権限であれば全然問題ないレベルだと思っています
（最悪連投荒らし的に使われたりする可能性は十分にありますが）

## もう少し準備があります。

BOTのTOKENをテキストファイルに保存した際に新しいフォルダを作成したものがあると思いますので、それを右クリックし`Code で開く`を選択しVisual Studio Codeを起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239781/8761c316-df9b-ebe4-344a-2c68ee72c855.png)

> インストール時にチェックを入れ忘れていた場合はこの項目は出てきません。
> Visual Studio Codeを再度インストールしてチェックを付けておくと使いやすいです。

するとこのような画面で起動すると思いますので、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239781/9a890269-7e7f-26f2-e3b3-722c5d0ed942.png)
下のターミナルの部分の`PS H:\discordbot> `となっている部分をクリックしてカーソルをもっていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239781/3d81bfcf-3475-e110-c8da-db24223f4ee4.png)
> この部分はコマンドプロンプトとほぼ同等の機能が提供されているので、ここにコマンドを打ち込むことでプログラムの実行などが可能になっています。

ここに今回使うライブラリのインストールコマンドを入力します。
```powershell
py -3 -m pip install py-cord
```
```powershell
py -3 -m pip install python-dotenv
```
> ~~今回紹介するSlashCommandはプレリリース版が必要なため --pre の引数が追加されます。~~
> 現時点では正式にSlashCommandが利用できるので --preは必要ありません

以下のように`Successfully`と出ればOKです(現在(2023/01/26)はバージョン2.3.xが最新となります）
```powershell
Successfully installed py-cord-2.0.0b5
Successfully installed python-dotenv-0.20.0
```
これで準備万端です！

> ライブラリというのは基本的にはプログラムを簡略化して書くことができるようにいろんな人が作ってくれてるものです。
> これがないとプログラムを作るのは至難の業となりますので、製作者やコントリビュートしてくれる方に感謝しながら使いましょう

## やっとBOTのが作れる！


Visual Studio Codeで適当な名前のpythonファイルを作成しましょう、
こちらでは`bot.py`としましたが`.py`拡張子がついていれば基本的にどんな名前でも大丈夫なはずです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239781/258177ef-1819-23aa-47d2-9be4644538d3.png)

とりあえず最初はコピペでOKです！
```py
import discord
from discord import Option
import os
from dotenv import load_dotenv

load_dotenv()
TOKEN = os.getenv("TOKEN")

bot = discord.Bot()
GUILD_IDS = [0000000000000]  # ← BOTのいるサーバーのIDを入れます


@bot.event
async def on_ready():
    print(f"Bot名:{bot.user} On ready!!")


@bot.slash_command(description="あなたの名前か入力した名前に挨拶します", guild_ids=GUILD_IDS)
async def hello(
    ctx: discord.ApplicationContext,
    name: Option(str, required=False, description="名前を入力してね", )
):
    if not name:
        name = ctx.author
    await ctx.respond(f"こんにちは！ {name} さん！")

bot.run(TOKEN)
```

SlashCommandではサーバーID（Guild ID）が必要になるためBOTのいるサーバーを右クリックしてIDをコピーしてきます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239781/43706a59-a0e0-f011-d733-5fa07e64bf6e.png)
先程のソースの以下の部分を変更します
```py
GUILD_IDS = [0000000000000]  # ←ここの000...と置き換えます
```

基本的な処理部分は完成です！

### dotenvを使えるようにします

ソース上の以下命令は「`.env`ファイルからTOKENを取得してきなさい。」という命令なので、`.env`ファイルがない場合は機能しません。
```py
import os
from dotenv import load_dotenv

load_dotenv()
TOKEN = os.getenv("TOKEN")
```

準備でメモしておいたTOKENが書いてあるテキストファイルは`.env`の書式で書いたものになるので、
ファイル名を変えることで対応します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239781/9c5d502a-43c7-71db-505a-2489c338f94a.png)
ファイルを選択した状態で`F2`キーを押すとファイル名の変更ができるので`.env`としてファイル名を変更します。
すると歯車状のアイコンに変化して文字に色がついてくれるので間違いがないことが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239781/0b61880a-5298-b4f3-1cad-214880cf75da.png)

## あとは実行するだけです！

ターミナルに以下のコマンドを入れて実行します
`bot.py`の部分はあなたの作ったPythonファイル名を入力します
```powershell
py -3 bot.py
```
すると、以下のような実行結果が出て準備が完了していることがわかります
```
Bot名:New Bot#2308 On ready!!
```

この状態で`/hello`と入力するとあなたの入力したBOTが起動している事がわかります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239781/952dfe86-f6b4-8fef-95d4-d522a420effc.png)
そのままエンターを押すとコマンドを呼び出した人が表示されていることがわかります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239781/c5b77df7-14af-5c67-7751-0617ab1bfc61.png)
また今回は任意引数として`name`という値を一緒に受け取ることができるので
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239781/5453c934-361f-8f71-4fa5-d586f9d04fda.png)
任意の名前を呼ぶことができるようになっています！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1239781/3ea4a546-9d54-9674-bebc-7837a260d3e8.png)


## ここまで読んでくれた方に感謝

けっこう長い説明になってしまいましたが、読んでくれてありがとうございます！

詳しいPycordの仕様や、Pythonの書き方などは別途説明できる機会があれば説明しようと思いますが、今回はここまでです。

Pycordの詳しいドキュメントは英語で書いているので読みにくいかもしれませんが、詳しくはそちらを見ると何ができるか？などが書かれていますので、こんなものが作りたいなどあればWord検索などを駆使して読んでみると良いと思います！

https://docs.pycord.dev/en/master/index.html