身内コミュニティ向け discord bot を複数人で開発しているので,有用そうなレシピを書いていきます.
python の discordAPI ラッパーである discordpy 製 bot を github で管理し,heroku 上で動かしています.
/tmp/
以下でのみ書き込み可能.Cog というのは,discordpy で提供されている,機能を分割するためのクラスです. メインの Bot に Cog を追加していく形になります.
最低限の要素だけで構成されたテンプレートです.
bot.add_cog(cog)
で Cog を追加します
bot = Bot(command_prefix=["!"])
bot.add_cog(YourCog(bot))
bot.run(TOKEN)
Cog クラスを継承した YourCog クラスを定義します. コンストラクタ__init__
に取り込まれる先の bot を与えて保持します. これにより YourCog 内でも bot にアクセスできます.例えば,bot 自身の User は,self.bot.user
でアクセスできるわけです.
class YourCog(commands.Cog):
def __init__(self,bot):
self.bot = bot
デフォルトのヘルプは英語だし見にくいので,おしゃれにしてあげたいです. commands.HelpCommand を継承したクラスのメソッドをオーバーライドして実装します. クラスは,Bot クラスのコンストラクタで指定します.
send_bot_help メソッドを上書きすれば,!help
コマンドが呼ばれたときの動作を指定できます.今回は Embed を使ってリッチにしてみました.
class Help(commands.HelpCommand):
def __init__(self):
super().__init__()
async def send_bot_help(self,mapping):
description = ""
for cog,commands in mapping.items():
if not cog or type(cog) == Core:
continue
for command in commands:
description += "`?{}` : {}\n".format(command.name,command.description if command.description else cog.qualified_name)
embed=Embed(title="コマンド一覧", description=description, color=0xedff66)
await self.get_destination().send(embed=embed)
bot = Bot(command_prefix=PREFIX,help_command=Help())
bot.run(TOKEN)
その他にも書き換えられる要素があるので,以下を参考にしてみてください. Discord.py Bot Commands Framework の help コマンドについて - Qiita
例えば,〇と ✖ のリアクションが押されたメッセージを用意して,YES か NO を訪ねたいときに使います. タイムアウト時間も指定できます.押された絵文字が返されます.
"""
messageにリアクションをし,最初に押されたリアクションを返す.
allow_userにのみ反応.
"""
async def wait_button(bot,message: Message,emoji_strs: List[str],allow_user=None,timeout=None) -> Emoji:
for e in emoji_strs:
await message.add_reaction(e)
def check(react,user):
if allow_user:
is_author = user == allow_user
else:
is_author = True
return str(react.emoji) in emoji_strs\
and react.message.id == message.id\
and is_author
reaction, user = await bot.wait_for('reaction_add',check=check,timeout=timeout)
return reaction.emoji
pillow(PIL の後継)で文字入れした画像を投稿します. 以下は最低限文字入れするならの記事です. pillow で図形に文字を挿入 - Qiita
文字数に合わせていい感じの大きさにしたり,縁取りなどの装飾や縦書き対応もしたんですが,長くなりそうなので後日別記事で書きます.
HOOK_NAME = "BOT_HOOK"
async def on_message(msg):
if msg.content == "おわりだ":
hooks = await msg.channel.webhooks()
bot_hook = next(filter(lambda h:h.name==HOOK_NAME,hooks),None)
if not bot_hook:
bot_hook = await channel.create_webhook(name=HOOK_NAME)
await msg.delete()
await bot_hook.send(
username=msg.author.display_name,
avatar_url=msg.author.avatar_url,
file=img)
適宜追加していく予定です.
おわり