こんにちは、えあーです。
Discordで喋ってると時々寝落ちしている人がいるので、
寝落ちする人を公開処刑するDiscord botを作りました。
こんな感じで寝落ちしたらどれだけ寝落ちしたのかbotに晒されます。
翌日の話のネタにピッタリです(?)
仕組み
やってる事自体は単純です。
・特定のボイスチャンネルを『寝落ちチャンネル』として定義
・そこに入った時間と出た時間を使って、どれだけの時間そこにいたのかを計算
・そのチャンネルにいた時間を寝落ち時間として、チャンネルから出たときに公開
という動き。
なので、該当のボイスチャンネルをAFKチャンネルにするか、
寝た人を誰かがそのチャンネルに移動する必要があります。
……寝たかどうかを判定するのはさすがに無理です。はーい。
ソースコード
import discord
import asyncio
import datetime
import pytz
#初期設定
client = discord.Client()
neochi_vc_id = (寝落ちボイチャのID)
neochi_text_id = (寝落ち情報を吐き出すテキストチャンネルのID)
# 寝てる人の辞書
sleeping_dict = {}
@client.event #-----ボイス系イベント-----
async def on_voice_state_update(member, before, after):
# =======================================================================
# ===== beforeのチャンネルとafterのチャンネルが寝落ち部屋か確認する =====
# =======================================================================
before_is_neochi = False
after_is_neochi = False
if before.channel != None:
if before.channel.id == neochi_vc_id:
before_is_neochi = True
if after.channel != None:
if after.channel.id == neochi_vc_id:
after_is_neochi = True
# ==================================================
# ===== 寝落ちに参加した場合、時間取得して保持 =====
# ==================================================
if (after_is_neochi == True) and (before_is_neochi == False):
now = datetime.datetime.now(pytz.timezone('Asia/Tokyo'))
sleeping_dict[member.id] = now
# ========================================================
# ===== 寝落ちから出た場合、時間取得して情報書き込み =====
# ========================================================
if (before_is_neochi == True) and (after_is_neochi == False):
now = datetime.datetime.now(pytz.timezone('Asia/Tokyo'))
neochi_begin = sleeping_dict.pop(member.id, None)
if neochi_begin == None:
# 異常な寝落ち情報
return
neochi_time = abs(now - neochi_begin)
# 5分以内ならノーカン
if neochi_time < datetime.timedelta(minutes = 5):
return
text_channel = client.get_channel(neochi_text_id)
await text_channel.send("<@" + str(member.id) + "> の寝落ち時間: " + str(neochi_time))
client.run("トークン")
※変更すべきところは適宜変更してください。
・寝落ちボイチャのID
・寝落ち情報を吐き出すテキストチャンネルのID
・トークン
は絶対修正が必要な箇所です。それぞれ入れておいてください。
解説
beforeのチャンネルとafterのチャンネルが寝落ち部屋か確認する
True/Falseにしとくとわかりやすいので先に直してるだけです。
別にやらなくてもいいです。and使えばネストも深くならないのでそれでもOK。
Optionalを?とかで外したい(swift式)
寝落ちに参加した場合、時間取得して保持
datetime型を使うと現在時刻が取得できるのでこれで取得します。
タイムゾーンをAsia/Tokyoにしていますがよく考えたら差分を取るだけなのでいらなかった気もします。
後々ファイルに保存とか考えて一応合わせてます。
sleeping_dictは「key:ID(int)」「value:datetime」の辞書です。
あとからIDを元に時間を参照できるようにしておきます。
寝落ちから出た場合、時間取得して情報書き込み
同様の方法で現在時刻を取得、その後寝落ち辞書から情報を取得。
一応いたずらで入れられる対策等のために、5分以内ならノーカンにしてます。
絶対値を取ってるのは一応マイナスにならないようにですが、
まぁ多分いらない気がします。念の為です。
最後に対象のチャンネルを取得して、そのチャンネルに情報を投げつけて終わりです。
「<@ID>」でメンション?になるので、その方法でその人向けにメンションを投げて
時間を公開して完了です。
timedelta(datetime)はstrで囲めばそのまま時間として出力できるので楽です。
正直マイクロ秒とかはいらないので不要なら適当に整形してください。
さいごに
あとはずっと動いてるPCで動かすかVPSとかでsystemdで常時起動とかすればOKです。
これを導入してからサーバーの寝落ち頻度が減りました。
健康のためにもご検討くださいませ(?)
コメント
天才
天才