見出し画像

プリンbot(プリコネ凸管理bot)を作っているお話 ~3凸報告編~

はじめに

どうも、いちょと申します。

前回はプリンbotのおおまかな機能紹介をさせていただきました
(前回の記事はこちら)

今回は3凸報告のプログラミング(動作の仕組み)についてお話ししようと思います。
あくまでも私が思いついた実装方法なので鵜呑みにはしないで、他の方々からも情報収集して各々で考えて開発してもらえると幸いです(そしていい方法があれば私に教えてください)
また今回は仕組みのお話だけにして、bot実装などの事前準備のお話は各自ググっていただきたいです(確実に私が説明するよりもわかりやすい)

筆者の開発環境など

・python 3.8.2

・discord.py

・c言語とJavaScriptの経験が少しあり

おおまかな仕組み(イメージ)

画像1

おおまかなコードと解説

       if message.content.startswith("!done"): #「!done」と入力された場合、報告済みのリストを表示
           await message.channel.send("3凸報告が終わった方のリストなの")
           channel = client.get_channel(message.channel)
           embed = discord.Embed(color=discord.Colour.from_rgb(0,255,0))
           if len(donelist_id) == len(getMemberList()):
               embed.add_field(name="3凸報告済みの方", value="今日は全員報告済みなの!")
           elif len(donelist_id) == 0:
               embed.add_field(name="3凸報告済みの方", value="まだ誰も報告してないの...")
           else:
               embed.add_field(name="3凸報告済みの方", value=(donelist))
           await message.channel.send(embed=embed)
           return
       
       elif message.content.startswith("!yet"):  #「!yet」と入力された場合、未報告者のリストを表示
           await message.channel.send("3凸報告が終わっていない方のリストなの")
           channel = client.get_channel(message.channel)
           embed = discord.Embed(color=discord.Colour.from_rgb(255,0,0))
           if len(donelist_id) == len(getMemberidList()):
               embed.add_field(name="3凸報告がまだの方", value="今日は全員報告済みなの!")
           elif len(donelist_id) == 0:
               embed.add_field(name="3凸報告がまだの方", value="まだ誰も報告してないの...")
           else:
               yetlist_id = list(set(getMemberidList()) - set(donelist_id))
               yetlist = list(set(getMemberList()) - set(donelist))
               embed.add_field(name="3凸報告がまだの方", value=(yetlist))
           await message.channel.send(embed=embed)
           return
   
       else:   # コマンド以外は3凸報告
           if str(message.author.id) in donelist_id:    # donelist_idにIDがあれば報告済み
               await message.channel.send("すでに報告済みなの")
               return
           else:
               donelist_id.append(message.author.id)   # メッセージ送信者IDをdonelist_idへ追加
               content = random.choice(random_houkoku_contents)
               await message.channel.send(content + "\n" + message.author.display_name + "さんは" + str(len(donelist_id)) + "番目の3凸完了報告なの!")
               if len(donelist_id) == len(getMemberidList()):
                   await message.channel.send("=========================\n以上で本日" + str(len(donelist_id)) + "人3凸完了なの!\nみんな、お疲れさまなの~\n=========================")
                   return

想像以上に見にくくなってしまったので、おおまかな動きがわかればいいかなとかなり端折っています🤷‍♂️(これでも見にくいと思う)

以下少しコードを抜粋しながらコメントアウトで注釈をつける形で詳細を書かせていただきます。

if message.content.startswith("〇〇"):
# これでコマンドを判別します。
if str(message.author.id) in donelist_id:
# ここでメッセージ送信者のIDがすでにdonelist_idにあるかどうかを判別します
yetlist_id = list(set(getMemberidList()) - set(donelist_id))
yetlist = list(set(getMemberList()) - set(donelist))
''' yetlist は getMemberidList関数(鯖内のメンバーリストを返す自作関数) と
    donelist の引き算で求めています。'''
if len(donelist_id) == len(getMemberidList()):
''' ここでdonelistとgetMemberidList()の長さ(要素の数)が同じならば、
    クラメン全員が3凸完了したと判断します。''' 

基本的にリストは discord id で管理しており、出力はembed(埋め込み)を利用しています。
idのリストの要素がstr型なのはスプシにidを転記する際にint型のままでは、str型に比べて厳しい桁数の制限があり、正確に表示できないことがあるからです。
上記のようにyetlistは必要な時だけ作成する形をとっているので、id関係の判定はdonelistを用いています。

おまけ

最後に、調べればすぐに出てくると思いますが、getMemberidList関数を軽く紹介しておきます。

def getMemberidList():  # メンバーIDの取得
   members_id = [str(member.id) for member in client.get_all_members()]
   if str(client.user.id) in members_id:
       members_id.remove(str(client.user.id))  # botのidをmembers_idから削除
   return members_id

おわりに

正直どこまで掘り下げて書くかかなり悩みました。
とりあえず、できるだけざっくり簡単に書こうとしましたがうまくいったとは言えない気がします。申し訳ありません。
質問や感想などありましたら、コメントや @icho_bangdream まで連絡いただけたら幸いです。

ありがとうございました。

この記事が気に入ったらサポートをしてみませんか?