プリコネのクラバト管理botを作ったのでそのへんで気づいたことです
https://github.com/izmktr/yukarisan
on_readyでのイベント
on_readyはdiscordに接続したときに呼び出されます
また、不定期にdiscordから切断されるようで、
自動的に再接続したときにも呼び出されます。
ここでは内部的に持っている情報とdiscord.pyのデータを結びつけると良さそうです。
import discord
from discord.ext import tasks
from typing import List, Dict, Optional
#guild_idと内部的なクラスとの紐付け
guildhash: Optional[Dict[int, GuildData]] = None
@client.event
def on_ready():
global guildhash
if guildhash is None:
# ロード処理
guildhash = {}
for g in client.guilds:
gdata = guildhash.get(g.id)
if gdata is None:
gdata = GuildData()
guildhash[g.id] = gdata
gdata.guild = g
メッセージに付随する処理
リアクションを付ける/外すときに発生する、
on_reaction_add,on_reaction_remove ですが、呼び出されないことがあります。
大体、投稿されて15分程度経った後のメッセージでは反応しないことがあります。
(サーバの活発度によるのではないかと考えています)
おそらく、こうなるとon_message_deleteも飛んでこない気がします。
max_messagesが1000なので大きくすれば回避できるかと思いましたが、
こんな感じで100000を入れてみても回避できませんでした。
(この辺の知見求む)
# 意味がない?
client = discord.Client(max_messages = 100000)
on_raw_reaction_add,on_raw_reaction_remove を使えば、確実に飛んできます。
on_messageでmessageの情報を保存しておき、on_raw_reaction_~を使って
処理を解決するのがいいでしょう。
なお、on_raw_reaction_add → on_reaction_addの順で呼び出されます。
on_reaction_add が飛んできたらこちらで、飛んでこないならon_raw_reaction_addと考えてましたが、
順序が逆なのでこの処理は面倒そうです。
プライベートチャット
botにメッセージを送ることでbotとプライベートチャットができます。
開発用のコマンドを使う場合はプライベートチャットを使えば、
周りにログが見られない形で作業が行なえます。
@client.event
async def on_message(message):
# メッセージ送信者がBotだった場合は無視する
if message.author.bot:
return
# 通常のメッセージ
if message.channel.type == discord.ChannelType.text:
return
# 1:1のメッセージ
if message.channel.type == discord.ChannelType.private:
return
問題は、通常のメッセージとmessageの型が違います
ですから、なくなっているクラス変数やクラス関数があります。
また、プライベートメッセージではギルドがありませんので、
プライベートメッセージ内でギルドを指定する必要があります。
この差異を吸収するような設計にして各種コマンドの処理を作っておくと
便利だっただろう、という反省点です。