はじめに
この記事はdiscord.pyのcommandsフレームワークに移行する方法を書いたものです。
執筆初心者なので、間違いを見つけたらどんどん指摘してください。
環境
- Python v3.8.3-final
- discord.py v1.6.0-final
- aiohttp v3.6.3
- system info: Windows 10 10.0.17134
(python -m discord -v
の情報)
最初のコード
以下のコードから始めるモノとします:
import discord
client = discord.Client()
RESPONSES = {
"おは": "おはよう!",
"おやすみ": "おやすみ!",
"落ち": "おつかれ!"
}
@client.event
async def on_ready():
print('We have logged in as {0.user}'.format(client))
@client.event
async def on_message(message):
if message.author == client.user:
return
for rk, rv in RESPONSES.items():
if rk in message.content:
await message.reply(rv)
if message.content.startswith('$ping'):
await message.channel.send('Pong!')
elif message.content.startswith('$greet'):
await message.channel.send(f'Hello, `{message.content[7:]}`.')
client.run('Th1sIsN0tT0k3n.B3cause.1fiShowB0tWillG3tH4cked')
1. インポート
commandsフレームワークをインポートするには
import discord
+ from discord.ext import commands
のようにします。
普通のdiscordは残しておきます。(isinstanceでの判定やEmbedの作成に必要になります。が、今回は不必要です。)
詳細
実際、
import discord.ext.commands
でも動きはしますが、
毎回
discord.ext.commands.Bot(command_prefix="!")
や
@bot.command()
@discord.ext.commands.has_permissions(administrator=True)
と書く必要があり、面倒なためfrom~importを使っています。
#2. ClientをBotにする
ClientをBotにしていきます。
移行にはそんな心配は要らず、discord.Clientをcommands.Botに置き換えるだけで移行できます。
Botを使うにはプレフィックス(/
や!
など、コマンドの最初につける文字)を決める必要があります。
今回は$
にしました。
- client = discord.Client()
+ bot = commands.Bot(command_prefix="$")
また、clientをbotにしたため、clientをbotに置き換えていきます。
- @client.event
+ @bot.event
async def on_ready():
- print('We have logged in as {0.user}'.format(client))
+ print('We have logged in as {0.user}'.format(bot))
- @client.event
+ @bot.event
async def on_message(message):
- if message.author == client.user:
+ if message.author == bot.user:
return
for rk, rv in RESPONSES.items():
if rk in message.content:
await message.channel.send(rv)
if message.content.startswith('$ping'):
await message.channel.send('Pong!')
elif message.content.startswith('$greet'):
await message.channel.send(f'Hello, `{message.content[7:]}`.')
- client.run('Th1sIsN0tT0k3n.B3cause.1fiShowB0tWillG3tH4cked')
+ bot.run('Th1sIsN0tT0k3n.B3cause.1fiShowB0tWillG3tH4cked')
#3. コマンドを定義する
「commands」フレームワークの名の通り、このフレームワークはコマンドを簡単に作ることができます。
コマンドを作るには@bot.commandが一般的です。
関数名がそのままコマンド名になります。
詳細
@commands.commandで定義後、bot.add_commandで追加する方法もありますがそれほど使わないので割愛。
@bot.command()
async def ping(ctx):
await ctx.reply("Pong!")
@bot.command()
async def greet(ctx, name):
await ctx.reply(f"Hello, `{name}`.")
覚えていると役立つこと
list
のように関数名がかぶりそうなときはname=を引数に指定します。
@bot.command(name="greet")
async def command_greet(ctx, name):
await ctx.reply(f"Hello, `{name}`.")
エイリアスを追加するにはaliases=を指定します。
@bot.command(aliases=["hi", "hello"])
async def greet(ctx, name):
await ctx.reply(f"Hello, `{name}`.")
空白を無視して受け取りたいときは*,をつけます。
@bot.command()
async def greet(ctx, *, name):
await ctx.reply(f"Hello, `{name}`.")
これらは全て一緒に使うことが出来ます。
@bot.command(name="greet", aliases=["hi", "hello"])
async def command_greet(ctx, *, name):
await ctx.reply(f"Hello, `{name}`.")
コマンドを定義したため、on_messageのコマンドを削除します。
@bot.event
async def on_message(message):
if message.author == bot.user:
return
for rk, rv in RESPONSES.items():
if rk in message.content:
await message.channel.send(rv)
- if message.content.startswith('$ping'):
- await message.channel.send('Pong!')
- elif message.content.startswith('$greet'):
- await message.channel.send(f'Hello, `{message.content[7:]}`.')
#4. コマンドを動作させる
on_messageを定義するとコマンドが実行されなくなります。
このようなときにはprocess_commandsを使います。
@bot.event
async def on_message(message):
if message.author == bot.user:
return
for rk, rv in RESPONSES.items():
if rk in message.content:
await message.channel.send(rv)
+ await bot.process_commands(message)
これで移行は終了です。
最終コード
import discord
from discord.ext import commands
bot = commands.Bot(command_prefix="$")
RESPONSES = {
"おは": "おはよう!",
"おやすみ": "おやすみ!",
"落ち": "おつかれ!"
}
@bot.event
async def on_ready():
print('We have logged in as {0.user}'.format(bot))
@bot.command()
async def ping(ctx):
await ctx.reply("Pong!")
@bot.command()
async def greet(ctx, name):
await ctx.reply(f"Hello, `{name}`.")
@bot.event
async def on_message(message):
if message.author == bot.user:
return
for rk, rv in RESPONSES.items():
if rk in message.content:
await message.reply(rv)
await bot.process_commands(message)
bot.run('Th1sIsN0tT0k3n.B3cause.1fiShowB0tWillG3tH4cked')
終わりに
この記事が役に立てば幸いです。
読んでいただきありがとうございました。