Discordで通話時間を測定するBotを作ってみた

#はじめに
discordでの通話時間を知りたかったのですが、discord内にそのような機能がないようなのでbotを作ってみました。勉強不足なため、用語などおかしいところがあるかもしれません。
#環境
Python 3.6.0
#作り方
##Botの作り方
こちらを参考にさせていただきました。
https://qiita.com/PinappleHunter/items/af4ccdbb04727437477f
##通話時間の取得
ボイスチャンネルへの入退室時にそれぞれ現在時刻を取得し、通話時間の計測を行います。

[ドキュメント](http://discordpy.readthedocs.io/en/latest/index.html)によると、`on_voice_state_update(before, after)`がボイスチャンネルで変化（ボイスチャットへの入退室、ボイスチャット内でのマイク・スピーカのミュート）があった際に呼び出されるようです。

パラメーターの`before`はボイスチャンネルで変化が起こる前の`Member`クラス、`after`は変化が起こった後の`Member`クラスのようです。

``` python
import discord

client = discord.Client()

@client.event
async def on_voice_state_update(before, after):
  print("ボイスチャンネルで変化がありました")

client.run("token")#botのトークン
```



今回は、ボイスチャットの入退出時のみ扱いたいため、マイク・スピーカのミュート時の呼び出しを弾きます。
`.voice.self_mute`でマイクミュートかどうかを確認し、同様にスピーカーも`.voice.self_deaf`で行います。その結果、前後で変化があれば`return`で弾きます。

```python
if((before.voice.self_mute is not after.voice.self_mute) or (before.voice.self_deaf is not after.voice.self_deaf)):
  print("ボイスチャンネルでミュート設定の変更がありました")
  return
```



次に、通話時間の取得をします。現在時刻の取得には標準ライブラリのdatetimeモジュールの`datetime.datetime.now()`を使いました。

`after.voice_channel`、`before.voice_channel`で入退出時の前後にボイスチャンネルが存在しているかを確認し、入退室を判定します。
ボイスチャンネル入室時に名前と現在時刻を辞書に登録し、ボイスチャンネル退出時に退出時の時刻から入室時の時刻を引きます。

通話時間の結果はマイナスで出てくるので、最後に-1を掛けておきます。また、秒数表示にしたかったため`.total_seconds()`を使っています。

```python
import datetime

pretime_dict = {}

if(before.voice_channel is None):#入室時
  pretime_dict[after.name] = datetime.datetime.now()
elif(after.voice_channel is None):#退出時
  duration_time = pretime_dict[before.name] - datetime.datetime.now()
  duration_time_adjust = int(duration_time.total_seconds()) * -1
```



最後に、Discord上にメッセージを送ります。メッセージは`client.send_message`を使うことで送れるようです。

```python
#メッセージを送りたいテキストチャンネルの名前
reply_channel_name = "general"
reply_channel = [channel for channel in before.server.channels if channel.name == reply_channel_name][0]
#送りたいメッセージ
reply_text = after.name + "　が　"+ before.voice_channel.name + "　から抜けました。　通話時間：" + str(duration_time_adjust) +"秒"

await client.send_message(reply_channel ,reply_text)
```

##全体のコード
```python
import discord
import datetime

client = discord.Client()
pretime_dict = {}

@client.event
async def on_voice_state_update(before, after):
  print("ボイスチャンネルで変化がありました")

  if((before.voice.self_mute is not after.voice.self_mute) or (before.voice.self_deaf is not after.voice.self_deaf)):
    print("ボイスチャンネルでミュート設定の変更がありました")
    return

  if(before.voice_channel is None):
    pretime_dict[after.name] = datetime.datetime.now()
  elif(after.voice_channel is None):
    duration_time = pretime_dict[before.name] - datetime.datetime.now()
    duration_time_adjust = int(duration_time.total_seconds()) * -1

    reply_channel_name = "general"
    reply_channel = [channel for channel in before.server.channels if channel.name == reply_channel_name][0]
    reply_text = after.name + "　が　"+ before.voice_channel.name + "　から抜けました。　通話時間：" + str(duration_time_adjust) +"秒"

    await client.send_message(reply_channel ,reply_text)

client.run("token")#ボットのトークン
```
#discord上の動作
![discord結果.PNG](https://qiita-image-store.s3.amazonaws.com/0/241903/c1797ba9-0fea-a65f-d9bf-39900b32b539.png)


#参考
[Discordドキュメント](http://discordpy.readthedocs.io/en/latest/index.html)
[Pythonで簡単なDiscord Botの作り方]
(https://qiita.com/PinappleHunter/items/af4ccdbb04727437477f)
[python 現在時刻取得]
(https://qiita.com/mykysyk@github/items/e15d7b2b1a988b8e29d4)