コマンドフレームワークを使ってみよう
より簡単にコマンドを扱えるようになるフレームワーク
コマンドフレームワークとは?
先程まで、on_message
を使用したコマンド判定を行っていました。
が、これには自力ではめんどくさくいつか限界が訪れてしまいます。
これを解決するために、主なラッパーにはコマンドフレームワークという、コマンドの作成から設定、管理に至るまで凄く簡単に行う事が出来る機能があります。
プリフィックス設定をしよう
プリフィックスは前回までと同様にc!
とします。
これを読み込ませてあげる必要があります。
botのインスタンス化時に設定することができます。
- bot = commands.Bot(intents=intents)
+ bot = commands.Bot(intents=intents, command_prefix="c!")
たったこれだけで設定することができます。
あとは、コマンドを作るだけです。
挨拶コマンドを作ろう
挨拶してくれるコマンドを作りましょう。
とりあえず、一旦何も考えないでon_message
の部分は消しておいてください。後で説明します。
on_message
の上のデコレーターを消すだけでいいです。
- @bot.event
async def on_message(message: nextcord.Message):
...
そしたら次のコードを追加してみましょう。
@bot.command()
async def greed(ctx: commands.Context):
await ctx.reply("コンチワーッス")
そしたらBOTを実行して、c!greed
と実行してみましょう。
すると、挨拶を返してくれます!!
この種類のコマンドを「コンテキストコマンド」と言います。
覚えておいてくれると嬉しいです。
というわけで、説明していきますね。
@bot.command()
関数をコンテキストコマンドにするためのデコレータです。
色々設定項目はありますが、特に何も書かなくても普通に動きます。
ctx: commands.Context
コンテキストコマンドに与えられる関数です。
よくctx
が使われてるからctxにしてるだけです。
commands.Context
はコンテキストオブジェクトと呼ばれ、メッセージオブジェクトや、ユーザーオブジェクトなど、いろいろな情報が含まれています。
すごいわかりやすい説明だと、メッセージオブジェクトの拡張版です。
ctx.reply()
コンテキストオブジェクトの関数です。
message.reply()
と同様に、メッセージに対してリプライを飛ばします。
おおすごいすごい
これが簡単なコンテキストコマンドの説明です。
これをたくさん作ることでBOTは完成していきます。
では、先ほど削除したon_message
。
つけるとどうなるのでしょうか。
答えは、コマンドが正常に動作しなくなります。
このコンテキストコマンド、所詮はラッパーがメッセージを解析してコマンド風に扱えるようにしているだけ。DiscordのAPIに公式に用意されている者ではありません。
そのため、on_message
を作ると、「メッセージを解析してコマンド風に扱えるようにする処理」がon_message
にオーバーライドされてしまい、on_message
の処理のみが行われてしまいます。
よって、コマンドの処理が行われなくなってしまいます。
しかし、もちろん対策はあります。
コマンドとon_message
を両立させる方法もあります。
process_commands
@bot.event
async def on_message(message):
# on_messageの処理
await bot.process_commands(message)
こんな風に、on_message
の最後にコマンド解析をする関数を入れることでコマンドの解析が行われます。
bot.listen
@bot.listen('on_message')
async def on_message(message):
# on_messageの処理
こんな風に、bot.event
の代わりにbot.listen
を使用することで、メッセージの処理と解析の両方を行うことができます。
私はこれが好きです。
コマンドやでぇ...ドヤァ...
世の中のBOTプログラマの大半はこんな感じで作っていきます。
...もちろんまだまだ足りません。
クリスマスまで後少しです。
そ、そ、そ、そりゃあ私はクリスマスぐらい超絶美少女とデートする約束が...(絶賛募集中)
つまり、もうすぐこの記事シリーズも終わってしまいます。
私も頑張って書いてるので、褒めてくれてもいいんですよもちろん。
では、次の記事で!