概要
discordでオンライン勉強会を行っている。
勉強時間を自動で記録したいと思いdiscord botを作成したので以下に方法を記載する。
処理としてはボイスチャンネルにいた時間を計測し、メンバーが退室した時点で該当のメンバーのボイスチャンネル滞在時間を出力するものになる。
方法
bot作成
処理内容は置いといてまずはbotを作成してみる。
ローカルで稼働するbotの作成方法については以下の記事が非常にわかりやすいので参考にした。
https://qiita.com/PinappleHunter/items/af4ccdbb04727437477f
ひとまずこれで作成して動いたらbotの作成は完了。
常時稼働させる
上記はローカルで稼働するbotであり、自環境でプロセスを稼働させ続ければbotを動き続けるが、
当然自環境(プロセス)を停止すれば非稼働となる。
そこでクラウドでアプリケーション実行環境を用意し、そこで稼働させ続けることで常時稼働させる。
常時稼働botの作成は以下を参考にした。
https://fuurinblog.com/settigs-discordbot/
時間記録処理の作成
APIリファレンスは以下。
https://discordpy.readthedocs.io/en/latest/api.html
リファレンスを見ると、on_voice_state_update()
がボイスチャンネルへの入退室が行われるたびに呼び出されるらしい。
入室時・退室時の処理をそれぞれ分けて書く。
本処理では、特定のボイスチャンネルの滞在時間のみ出力しているが、時間の記録自体は全ボイスチャンネル分行っているので、
WATCH_CHANNEL_ID
の処理を削除、部屋名を出力するようにすれば部屋ごとの滞在時間も出力可能である。
import discord
import datetime
from os import getenv
client = discord.Client()
pretime_dict = {}
SEND_CHANNEL_ID = <メッセージを送信するテキストチャンネルのID>
WATCH_CHANNEL_ID = <滞在時間を記録するボイスチャンネルのID>
@client.event
async def on_ready():
print('Logged in as')
print(client.user.name)
print(client.user.id)
print('------')
@client.event
async def on_voice_state_update(member,before,after):
# 入室時
if before.channel is None:
pretime_dict[after.channel.name] = datetime.datetime.now()
# 退室時
elif after.channel is None:
if before.channel.id != WATCH_CHANNEL_ID:
return
duration_time = pretime_dict[before.channel.name] - datetime.datetime.now()
duration_time_adjust = int(duration_time.total_seconds()) * -1
hours = duration_time_adjust // 3600
remain = duration_time_adjust - (hours * 3600)
minutes = remain // 60
seconds = remain - (minutes * 60)
time_text = '{:02}:{:02}:{:02}'.format(int(hours), int(minutes), int(seconds))
send_channel = client.get_channel(SEND_CHANNEL_ID)
send_text = f'【{member.nick}】勉強時間: {time_text}'
# print(send_text)
await send_channel.send(send_text)
token = getenv('DISCORD_BOT_TOKEN')
client.run(token)