記事投稿日:
   最終更新日:

Discord Botの作り方(Python)

Discord Bot作りたいけど、どうやって作ればいいのか分からない人向けに作り方を解説します。

プログラミング言語

Discord Botは色々な言語で開発できます。 各言語、ライブラリが存在しています。主に以下のライブラリがあります。

その中で人気があるのは、Discord.jsで、Node.jsを使ってサーバー上で動かします。
どの言語を使うのがいいかといわれたら、個人的にはPythonがいいと思います。最終的にサーバーで動かすことを考えてもPythonかNodeになります。Pythonはプログラミング言語の中でもライブラリが豊富で機能を増やすのが比較的簡単です。

PythonでDiscord Botを作るのに使えるライブラリは上記の他にも色々ありますが、今回はPycordを使います。Discord.pyというライブラリもあるのですが、PycordはDiscord.pyをフォークして作られたライブラリなので機能がDiscord.pyよりも豊富です。 また、Pycordはスラッシュコマンドに対応しているため、モダンなBotを作るの適しています。

それでは早速作っていきます。

開発環境

* Windowsを使用する場合は「0. Windows向けの作業」を行ってください。
* 本記事はある程度Pythonがわかる方向けです。一応初心者の方でも分かるように詳しく書いたつもりではあります。
* これは余談ですが、Pythonのライブラリには依存関係というものがあります。インストール直後のPythonでは、ライブラリが少ないため問題ないですが、これが増えてくると依存関係解決が出来なくなり、エラーを吐くようになることがあります。これを回避するために、virtualenv等で仮想環境つくることをおすすめします。ちなみに自分はAnacondaを使っています。

前提知識 (コマンドについて)

Discordには、GuildコマンドとGlobalコマンドがあります。
次のような違いがあります。時と場合によって使い分けましょう。

全サーバーでコマンドを利用できるようにするためには、グローバルコマンドを使う必要があります。そのため、実際に運用するためにはグローバルコマンドでなくてはいけません。
反映時間は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と返信してくれます。

Point

返信のバリエーションを増やすには、下記の部分をほしい分だけ追加します。

@bot.slash_command(description="説明")
async def command_name(
    ctx,
):
    # 処理
    # ………

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, '好きな数字を入力してください'),
):
    name = f'{name}'
    color = f'{color}'
    number = f'{number}'
    await ctx.respond('お名前:' + name + '\n好きな色:' + color + '\n好きな数字' + number)

bot.run('Token')

Point

4. ギルドコマンド

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

5. 録音

Pycordは録音機能を備えた数少ないライブラリです。
[2022/10/15追加] Pycordのバグにより、二度目以降は録音できません。Issueに報告されていますが、直る気配がありません。
[2022/10/15追加] 自分のコードに問題があっただけでした。近々解説します。

[以降製作中…]