はじめに
この記事は CCS Advent Calendar 2021の13日目の記事です。
ちにくんの記事: 【ゲーム制作向け】イージングのすゝめ←前|次→うしくんの記事: 今年のよかったこと2021
Discord bot について
みなさんDiscordは使っていますか?CCSの人はサークルのDiscordサーバーがあるし、それ以外でもサーバーを作ったりして便利に利用している人がぼくのまわりでは多いのかなと思っています。
さて、DiscordではBotを登録することができます。ご存知でしょうか。
自分で作らなくても、投票Botなどかなりの数のBotを自由に導入することができます。いろいろ「Discord Bot」などで検索してみると出てきます。
Bot を自作する
さて、DiscordのBotですが、それでもやはり物足りないときがあります。 たとえばサーバーの仲間とプレイしているゲームに特化したBotとか。
なんと、Discordはbotを作れるよう公式APIを公開しています!!
こいつをつかってやれば、好きなBotを作ることができそうです。
ちなみに、ぼくは一緒にDQ10をプレイする仲間と使うために、PT募集したりするBotを作りました。 CCSの皆さんにはほとんど関係ないですが、例として使っていきます。
ライブラリの話
さて、じゃあさっそくBotを作るか、となるんですが、上記のAPIを叩くものを一から作るのは結構面倒です。ただみんな考えることは一緒なので、先人たちがラッパーライブラリを作ってくれています。てことでぼくらはこの恩恵に預かっていくことにしましょう。
有名なライブラリは以下の2つだと思います。
- discord.py
- discord.js
今回はdiscord.py
を使う想定で話を進めていきます。
Bot を自作する
さて、それではかんたんにbotの作り方を載っけていきます。
Botにもいろんなものがありますが、今回は次のようなものを作ります。
- メッセージで
/
で始まるコマンドを打つとなにかしてくれる
Bot登録
ここにアクセスします。
「New Application」を押してアプリケーションを登録。必要な情報を入力しましょう。
あとは右側の「Bot」をひらいて「TOKEN」のところからBotのトークンをコピーしておきます。このトークンを公開しないように!!!!
Bot をサーバーに登録
同じページの右側のメニューから、「OAuth2」を選択。「URL Generator」から 「bot」を選んで、必要な権限を設定して、生成されたURLにアクセスすると、自分が管理者になっているサーバーにBotを追加することができます。
これで準備が整いました。
Bot のコーディング
Pythonはすでに使えるものとして、更にライブラリが必要です。
まずはじめに、discord.py
をインストールしておきましょう。
$ pip install discord.py
.env
に変数を書いて、管理できるようにしておきたいので、次のライブラリもいれておきます。
$ pip install dotenv
ちなみにpipenv
を使える人なら、先程のDQ10-botのリポジトリをからpipfileをダウンロードしてきて、pipenv install
すれば一通り環境は揃います。使っているのはPython3.8です。
余談ですが、ぼくは基本的に仮想環境を使う派なので、Pythonでなにかするときはたいていpipenv
を使っています。
コーディングの前準備
最初に、先程取得しておいたトークンを読み込む部分を作っておきます。
コードに直書きは嫌なので、.env
にでも設定しておいてとってくることにしましょう。
DISCORD_BOT_TOKEN = *****(先程コピーしたやつ)
あとはPython側から読み込むだけ。
import os from dotenv import load_dotenv load_dotenv() DISCORD__BOT_TOKEN = os.getenv('DISCORD_BOT_TOKEN')
これでOKですね。無事読み込めます。
.env
ファイルはバージョン管理に含めずにちゃんと管理してね
コーディング
あとはBotの根幹部分を書いていくだけです。
ここで今回特に紹介したいのが、discord.py
の拡張であるcommands
クラスです。
文字列を取得して、コマンドに変換するコードを直書きしなくても良くなる上、help
コマンドなどをなんと自動で生成してくれます!たすかる!(argparse
とかで似たようなの見たことありますかね)
結構ネット上でもon_message
とかBotに限らないイベントに対応した書き方の記事は多くても、コマンド拡張の話はあまり見ないので......。
import discord from discord.ext import commands class MyCommands(commands.Cog): def __init__(self, client): super().__init__() self.client = client @commands.command(name="hello") async def hello(self, ctx, arg1, arg2): await ctx.send(f"hello {arg1}, {arg2}") return intents = discord.Intents.default() intents.typing = False client = commands.Bot(command_prefix='/', intents=intents) client.add_cog(MyCommands(client=client)) client.run(DISCORD_BOT_TOKEN)
適当なコードですが、だいたいの書き方がこんな感じです。
少しずつ説明していきます。
intents = discord.Intents.default() intents.typing = False client = commands.Bot(command_prefix='/', intents=intents) client.add_cog(MyCommands(client=client)) client.run(TOKEN)
Botを動かしているメインの部分です。intents
の2行で受け取るイベントの種類が制御できます。まあ小規模なBotとか公開しないBotならそんな気にしなくていいです。おまじない。
あとはコマンドの開始文字列(prefix)を/
にして設定、コマンドとして自作のクラスを設定し、最後にトークンを渡しています。
class MyCommands(commands.Cog): def __init__(self, client): super().__init__() self.client = client @commands.command(name="hello") async def hello(self, ctx, arg1, arg2): await ctx.send(f"hello {arg1}, {arg2}") return
コマンド部分のクラスです。/hello arg1 arg2
とDiscord上で入力したときに実行されるやつ。/hello mattyan 1053
とかね。特に意味はない、サンプルなので。
今回はcommands拡張を用いているので、指定のprefix(=/
)のメッセージが来たときに自動で呼ばれます。しかも、コマンド引数も自動で分けてクラスメソッドの引数に渡してくれます!引数も可変長とか諸々対応してたはず。
面倒な文字列処理なくて助かる!ctx
はDiscordのコンテキストなので、通常のライブラリと同じ。公式ドキュメントにいろいろあります。
ということで、あとはあまり深いことは考えずにBotにしてほしい処理を記述してあげるだけでOK!APIとか考えずそれっぽいメソッドを呼んじまえ!ラッパー最高!
ここからリアクションをつけたりもできます。
サーバーに置く
あとは出来上がったのをサーバーにおいて実行しっぱなしにしておきましょう。 サークル用Botならサークルのサーバーとかでもいいんじゃないかな。Web管に相談しましょう。私用なら適当にGCP無料枠とかでも余裕で動きます。軽いので。
ぼくのpipfile
に従うならpipenv run start
で動きます。
おわりに
お疲れさまでした!これでみなさんも自由にBotがつくれますね!
サークルの総会用Botとか誰か作ったらおもしろそう。委任状機能付きの投票機能とか?
余談
Discord、サーバー内絵文字を使うとき:emojiname:
みたいに指定するだけでいいけれど、Bot側から飛ばすときは<:emojiname:emojiid>
みたいに指定しないといけないらしい。絵文字IDをとってきて添えないと......。なんかもっといいやり方あるかも。emojiクラスよく読んでない。