Discord Botの作り方(Python)
Discord Bot作りたいけれど、どうやって作ればいいのか分からない人向けに作り方を解説します。
開発言語について
Discord Botは色々な言語で開発できます。 各言語、ライブラリが存在しています。主に以下のライブラリがあります。
- Discord.js (JavaScript)
- Discord.py (Python)
- Pycord (Python)
- Discord.Net (C#)
その中で人気があるのは、Discord.jsで、Node.jsを使ってサーバー上で動かします。
どの言語を使うのがいいかといわれたら、個人的にはPythonがいいと思います。最終的にサーバーで動かすことを考えてもPythonかNodeになります。Pythonはプログラミング言語の中でもライブラリが豊富で機能を増やすのが比較的簡単です。
PythonでDiscord Botを作るのに使えるライブラリは上記の他にも色々ありますが、今回はPycordを使います。Discord.pyというライブラリもあるのですが、PycordはDiscord.pyをフォークして作られたライブラリなので機能がDiscord.pyよりも豊富です。 また、Pycordはスラッシュコマンドに対応しているため、モダンなBotを作るの適しています。
それでは早速作っていきます。
開発環境
- Ubuntu Server (Windows,Mac可)
- 言語:Python (3.10)
- ライブラリ:Pycord
- 仮想環境:Anaconda
* Windowsを使用する場合は「0. Windows向けの作業」を行ってください。
* 本記事はある程度Pythonがわかる方向けです。一応初心者の方でも分かるように詳しく書いたつもりではあります。
* これは余談ですが、Pythonのライブラリには依存関係というものがあります。インストール直後のPythonでは、ライブラリが少ないため問題ないですが、これが増えてくると依存関係解決が出来なくなり、エラーを吐くようになることがあります。これを回避するために、virtualenv
等で仮想環境つくることをおすすめします。ちなみに自分はAnaconda
を使っています。
前提知識 (コマンドについて)
Discordには、GuildコマンドとGlobalコマンドがあります。
次のような違いがあります。時と場合によって使い分けましょう。
- ギルドコマンド
- 反映時間:即時反映
- サーバー:特定のサーバーのみ
- グローバルコマンド
- 反映時間:1時間程度
- サーバー:全てのサーバー
全サーバーでコマンドを利用できるようにするためには、グローバルコマンドを使う必要があります。そのため、実際に運用するためにはグローバルコマンドでなくてはいけません。
反映時間は1時間程度となっていますが、経験上かなり早く反映されます。
本記事のコードではグローバルコマンドで実装していますが、記事の終わりにギルドコマンドの実装方法書いておきます。
トークンの取得方法
トークンの取得方法はこちらを見てください。
0. Windows向けの作業
ここはWindowsを使って開発する方向けの作業です。その他のOSを使用する場合は読み飛ばしてください。 WindowsにはPythonが標準インストールされていないのでインストールする必要があります。 こちらを参考にインストールしてください。インストールだけでいいので動作確認は不要です。
仮想環境を使う場合は、Anacondaをいれたほうがいいです。
1. ライブラリのインストール
ここからはすべてのOSで行う作業です。
まず、必要なライブラリをインストールします。
先程Pycordはスラッシュコマンドに対応していると書きましたが、実際にはPyPiに公開されているバージョンは対応していません。そのため、Githubから直接ソースを取得してインストールします。
最近、バージョン2.0.0がリリースされ、スラッシュコマンドに対応しましたので、普通にPyPiから入れましょう。
$ pip install -U py-cord
*Anacondaを使用する場合は、インストール前に仮想環境を作り、そこに入る必要があります。
$ conda create -n discordbot python=3.10
$ conda activate discordbot
$ pip install -U py-cord
これで最新版のPycordがインストールされます。
つぎに早速コードを書いていきます。
2. コードを書く
まずは、シンプルにPingコマンドを使うとPongと返信するコードを書いてみます。
(エディターですが、Windows、Macをお使いの方はVSCode、Ubuntu等のLinuxをお使いの方はvim等がオススメです。)
import discord
bot = discord.Bot()
@bot.slash_command(description="Pongと返信します。")
async def ping(
ctx,
):
await ctx.respond('pong')
bot.run('Token')
/ping
と送るとpong
と返信してくれます。
たったこれだけで、スラッシュコマンドが実装できます!
このとき、async def ping(ctx):
のping
の部分がスラッシュコマンドの名前になります。
Point
- 返信のバリエーションを増やすには、下記の部分をほしい分だけ追加します。
@bot.slash_command(description="説明")
async def command_name(
ctx,
):
# 処理
# ………
command_name
・・・コマンド名description
・・・コマンドの説明(""
内に説明をいれる)
3. 入力を受け取る
次に、スラッシュコマンドのオプションとして入力値を受け取るコードを書いていきます。
import discord
from discord.commands import Option
bot = discord.Bot()
@bot.slash_command(description="あなたに質問します。")
async def question(
ctx,
name: Option(str, '名前を入力してください'),
color: Option(str, '好きな色を選択してください', choices=['赤', '青', '黄', '緑']),
number: Option(int, '好きな数字を入力してください'),
):
await ctx.respond('お名前:' + name + '\n好きな色:' + color + '\n好きな数字' + str(number))
bot.run('Token')
Point
str
ではなくint
とすると入力値を数字のみにすることができます。choices
をlist
型で指定すると、選択式にすることができます。
4. 入力のオプション化
次に、値の入力のオプション化の方法を説明します。
先程のコードは全て入力・選択必須でしたが、オプション化することで、入力・選択しなくてもユーザーがコマンドを実行できるようになります。
それでは、先程のコードを編集して一部をオプション化してみます。
import discord
from discord.commands import Option
bot = discord.Bot()
@bot.slash_command(description="あなたに質問します。")
async def question(
ctx,
name: Option(str, '名前を入力してください'),
color: Option(str, '好きな色を選択してください', choices=['赤', '青', '黄', '緑'],required=False),
number: Option(int, '好きな数字を入力してください',required=False),
):
await ctx.respond('お名前:' + name + '\n好きな色:' + color + '\n好きな数字' + str(number))
bot.run('Token')
Point
- 一部のコマンドに
,required=False
を追加しました。これで付けたコマンドはオプションになります。 - 付与しないコマンドについては
,required=True
と同じ意味で、必須になります。
注意
必須の値は、オプションの値よりも上に書く必要があります。たとえば下記の例では、エラーになります。
@bot.slash_command(description="あなたに質問します。")
async def question(
ctx,
color: Option(str, '好きな色を選択してください', choices=['赤', '青', '黄', '緑'],required=False),
number: Option(int, '好きな数字を入力してください',required=False),
name: Option(str, '名前を入力してください'),
):
await ctx.respond('お名前:' + name + '\n好きな色:' + color + '\n好きな数字' + str(number))
この場合、name
は必須の値ですが、color
とnumber
はオプションです。そのため、name
はcolor
とnumber
よりも上(ctxのすぐ下)に書く必要があります。
5. ギルドコマンド
2のコードのコマンドをギルドコマンドにしてみます。
GUILD_ID
にはサーバーのIDを入力してください。list
型なので、複数のサーバーを指定することができます。
【注意】 (Pycordのアップデートにより、解消されたことを確認済み)
ギルドコマンドを使うと起動時にエラーが表示されますが、無視してください。動作に影響ないエラーです。Pycordのバグと想定されます。
import discord
bot = discord.Bot()
guild_id = [GUILD_ID]
@bot.slash_command(description="Pongと返信します。",guild_ids=guild_id)
async def ping(
ctx,
):
await ctx.respond('pong')
bot.run('Token')
Point
guild_ids
をリストで指定すると、ギルドコマンドにすることができます。リストなので、複数のサーバーに登録することもできます。
6. 録音
Pycordは録音機能を備えた数少ないライブラリです。
解説はこちら
今回は以上です。
[以降製作中…]