バージョン情報
Python 3.8.12
discord.py 2.1.0
最小限に近いもの
メインファイル
main.py
import discord
from discord.ext import commands
prefix = '!'
COGS = [
"Greeting"
]
class MyBot(commands.Bot):
"""起動用のあれこれ"""
async def setup_hook(self):
for cog in COGS:
try:
await self.load_extension(cog)
except Exception as e:
print(e)
await self.tree.sync()
# 接続に必要なオブジェクトを生成
intents = discord.Intents.default()
intents.messages = True
bot = MyBot(
command_prefix = prefix,
intents = intents,
)
)
bot.run(str型のtoken)
同ディレクトリの別ファイルのcog例
Greeting.py
import discord
from discord.ext import commands
class Greeting(commands.Cog):
@commands.hybrid_command()
async def meow(self, ctx):
await ctx.send('にゃーん')
async def setup(bot):
await bot.add_cog(Greeting(bot))
個人的に好みな書き方
メインファイル
main.py
import discord
from discord.ext import commands
import os #getenvに必須
prefix = ['!', '?'] #list型で複数の接頭辞に対応
MY_GUILD = discord.Object(int(os.getenv('guild_id')))
COGS = [
#"Second_Cog", #list型でコグを好きなだけ追加する
"Greeting"
]
class JapaneseHelpCommand(commands.DefaultHelpCommand):
def __init__(self):
super().__init__()
self.commands_heading = "コマンド:"
self.no_category = "その他"
self.command_attrs["help"] = "コマンド一覧と簡単な説明を表示"
def get_ending_note(self):
return (f"各コマンドの説明: {prefix[0]}help コマンド名\n"
f"各カテゴリの説明: {prefix[0]}help カテゴリ名\n")
class MyBot(commands.Bot):
"""起動用のあれこれ"""
async def setup_hook(self):
for cog in COGS:
try:
await self.load_extension(cog)
except Exception as e:
print(e)
#self.tree.copy_global_to(guild = MY_GUILD) #ギルドコマンドにコピーして実験をしたい時にコメントアウトを解除する
await self.tree.sync(guild = MY_GUILD) #何故かこれを入れると、グローバルコマンドも即同期される
await self.tree.sync()
async def on_ready(self):
print('Logged in as') #seetup_hookの完遂を知らせる
for cog in COGS:
try:
await self.reload_extension(cog) #コグをリロードする
except Exception as e:
print(e)
#self.tree.copy_global_to(guild = MY_GUILD) #setup_hookと意図は同じ
#await self.tree.sync(guild = MY_GUILD) #setup_hookと意図は同じ
await self.tree.sync() #リロードしたコグを再同期する
print(self.user.name) #リロードの完遂を知らせる
print(self.user.id)
print('------')
# 接続に必要なオブジェクトを生成
intents = discord.Intents.default()
intents.messages = True
intents.message_content = True
intents.presences = True
bot: commands.Bot = MyBot(
command_prefix = prefix,
case_insensitive = True, #コマンドの大文字小文字を無視する(True)
intents = intents,
status = discord.Status.online,
activity = discord.Activity(
type = discord.ActivityType.listening,
name = "!help してみて!"
),
help_command = JapaneseHelpCommand()
)
#エラー処理
@bot.event
async def on_command_error(ctx: commands.Context, error):
if ctx.author.bot: #botが起こしたエラーなら
return #何もしない
if isinstance(error, commands.errors.CheckFailure): #スラッシュコマンドでのみ動作するように制約
await ctx.send(f'勘の良いガキは嫌いだよ', ephemeral = True) #権限を持たずにコマンドを実行した際に警告する
bot.run(os.getenv('TOKEN'))
同ディレクトリの別ファイルのcog例
Greeting.py
import discord
from discord.ext import commands
class Greeting(commands.Cog, name = 'あいさつ'):
"""あいさつを返すよ"""
def __init__(self, bot: commands.Bot):
super().__init__()
self.bot: commands.Bot = bot
async def cog_check(self, ctx: commands.Context):
if ctx.author.bot:
return False
else:
return True
@commands.hybrid_command(name = "にゃーん", aliases = ["にゃ", "にゃん", "cat"])
async def meow(self, ctx: commands.Context):
"""鳴き声を返すにゃ"""
await ctx.send(
f'{ctx.author.mention} にゃーん'
)
async def setup(bot: commands.Bot):
await bot.add_cog(Greeting(bot))
コンバーター
bot: commands.Bot = MyBot(
のように○○: △△
と書いているのは、コンバーターを指定している。
str型、int型などのよく知られている型だけでなく、公式ガイドで示される、多数のdiscord.py独自の型に指定できる。
最小限のコードには不要だが、コンバーターを使う事で例外を弾きやすくなり、扱いやすくなるだろう。
特にスラッシュコマンドの引数では、Discordサーバー側でエラーメッセージを表示してくれる。楽チンである。