Discord APIを利用して入室通知Botをつくってみた

はじめに

今やオンラインでゲームをする人の間ではメジャーなチャットアプリとなったDiscord
手軽にボイスチャットができるだけでなく、コミュニケーションの場としてサーバーを用意したり、日ごろの会話、連絡などもこれ1つでできるため、SlackやLINEの代わりに使っている人も多いのではないでしょうか?
(私もその1人です)

そんな便利なDiscordですが、日々利用していると、「こういう機能があったらいいのに!」と思うことが少なからずあります。
例えば、特定のゲーム用にメッセージを流してくれる機能であったり、自動でチーム分けをしてくれる機能であったり...

そんなときに使えるのが、公式から提供されているDiscord API というわけです!
APIを利用してBotを作成すれば、そういった「あったらいいな」機能を実現させることができます。

今回の記事では、私が作成した簡単なBotの紹介とその作り方について載せていきますので、こちらを参考にDiscordをより便利に使うお手伝いができたらと思います!

目次

作成したBotの仕様

今回私が作成したBotは下記のような機能を実装しています。

■目的
ボイスチャンネルの入室・退室情報を通知することで、メンバーのコミュニケーション参加をより闊達にしたい

■機能

  • ボイスチャンネルに入室したとき、そのチャンネル名と入室した人をテキストチャンネルに投稿する
  • ボイスチャンネルを退室したとき、そのチャンネル名と退室した人をテキストチャンネルに投稿する
  • デスクトップ通知や、スマホアプリのPush通知でその投稿を確認できる

Botの動作

詳細な作成手順の前にまずはBotの動作から紹介します。

今回は下記のようなチャンネルに対応するように作りました。

  • テキストチャンネル
    入室通知用: 入退室があったときにBotからメッセージが書き込まれる
  • ボイスチャンネル
    テスト:ここに入退室があった場合に通知を行う
    ロビー:テスト同様に、ここに入退室があった場合に通知を行う

Botが起動しているときに、特定のボイスチャンネルに入室すると、メッセージ投稿用に指定したテキストチャンネルに入室のメッセージが投稿されます。
また、退室した際も同様に、メッセージが投稿されます。

そして、メッセージが投稿用に指定したテキストチャンネル(入室通知用)の通知設定をONにしておくことで、デスクトップ通知やアプリのPush通知が送信される、というような仕組みになっています。


このようにして、サーバーのメンバーがボイスチャンネルに入室したことが通知されることで、他のメンバーがそれに気づいて参加していく、という効果を狙っています。

動作環境

今回作成する環境では、Google Cloud Platform の Compute Engine にインスタンスを立て、その中でBotを実行するプログラムを起動し、サーバー内のイベントを監視させています。

・OS:Ubuntu 20.04 LTS
・Bot開発言語:Python 3.8.5
・利用ライブラリ:discord.py
※discord.pyの利用はPython3.5.3以降のバージョンである必要があります。

これら動作環境の整備に関する手順は省略しますが、Pythonのバージョンにだけ気を付けて、プログラムを実行する環境さえあればBotを作成できるかと思います。
(以前はAWSのEC2にインスタンスを立てて実行していました)

Bot作成手順

作成手順は以下の通りです。

  1. BotをDiscordのデベロッパーサイトに登録する
  2. サーバーのチャンネル情報を取得するプログラムを実行し、チャンネルIDを割り出す
  3. 通知対象のチャンネルIDを用いて入退室通知プログラムを実行する

...これだけです!とっても簡単ですね!

1. BotをDiscordのデベロッパーサイトに登録する

まず初めにやることとして、Botのアカウントを取得し、Botを導入するサーバーに招待してあげる必要があります。
具体的なやり方はこちらのdiscord.pyを提供してくださっている方のページが非常にわかりやすいので参考にしてみてください。

2. サーバーのチャンネル情報を取得するプログラムを実行し、チャンネルIDを割り出す

サーバーにあるチャンネルのIDを表示するプログラムを例示します。
※xxxxxxとマスクしている部分は、導入したBotの情報をデベロッパーサイトで確認して置換してください。

# DiscordChannels.py

import discord

client = discord.Client()

# 起動時処理
@client.event
async def on_ready():
    for channel in client.get_all_channels():
        print("----------")
        print("チャンネル名:" + str(channel.name)
        print("チャンネルID:" + str(channel.id)
        print("----------")

# Botのトークンを指定(デベロッパーサイトで確認可能)
client.run("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")

プログラムを作成したら、このBotプログラムを実行します。

$ python3 DiscordChannels.py

実行すると、起動時の処理が行われ、下記のような表示が現れるかと思います。

$ python3 DiscordChannels.py
----------
チャンネルID:aaaaaaaaaaaaaaaaaa
チャンネル名:入室通知用
----------
チャンネルID:bbbbbbbbbbbbbbbbbb
チャンネル名:テスト
----------
チャンネルID:cccccccccccccccccc
チャンネル名:ロビー
----------
...(以下略)

これでBotを起動し、チャンネルの情報を取得することができました。
続いて、本題のチャンネルの入室通知について説明します。
※いったん起動したBotは終了して問題ありません。

3. 通知対象のチャンネルIDを用いて入退室通知プログラムを実行する

先ほど取得したチャンネル情報から下記の情報を用いてプログラムを書いていきます。
①入退室のメッセージを投稿する対象のテキストチャンネル
※本記事上ではID: aaaaaaaaaaaaaaaaaa と表記する
②入退室を監視する対象のボイスチャンネル
※本記事上ではID: bbbbbbbbbbbbbbbbbb と ID: cccccccccccccccccc と表記する

これらを下記プログラムのマスクしているところに当てはめてプログラムを書いていきます。

# DiscordBot.py

import discord

client = discord.Client()

# チャンネル入退室時の通知処理
@client.event
async def on_voice_state_update(member, before, after):

    # チャンネルへの入室ステータスが変更されたとき(ミュートON、OFFに反応しないように分岐)
    if before.channel != after.channel:
        # 通知メッセージを書き込むテキストチャンネル(チャンネルIDを指定)
        botRoom = client.get_channel(aaaaaaaaaaaaaaaaaa)

        # 入退室を監視する対象のボイスチャンネル(チャンネルIDを指定)
        announceChannelIds = [bbbbbbbbbbbbbbbbbb, cccccccccccccccccc]

        # 退室通知
        if before.channel is not None and before.channel.id in announceChannelIds:
            await botRoom.send("**" + before.channel.name + "** から、__" + member.name + "__  が抜けました!")
        # 入室通知
        if after.channel is not None and after.channel.id in announceChannelIds:
            await botRoom.send("**" + after.channel.name + "** に、__" + member.name + "__  が参加しました!")

# Botのトークンを指定(デベロッパーサイトで確認可能)
client.run("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")

プログラムを作成したら2.と同様に実行します。

$ python3 DiscordBot.py

実行すると、実行端末側には変わりないと思いますが、Discordのアプリケーション画面を見ると、Botがオンライン状態(ステータスの●が緑)になっていることが確認できるかと思います。

その上で、先ほどプログラムの中で「入退室を監視する対象」としたボイスチャンネルに入ってみましょう。
すると、「入退室のメッセージを投稿する対象」としたテキストチャンネルにメッセージが投稿されていることが確認できます。

これで、「入退室のメッセージを投稿する対象」としたテキストチャンネルの通知機能をONにしておけば、誰かが監視しているボイスチャンネルに入室したことをデスクトップ通知なり、スマホの通知なりで察知することができるようになりました!

おわりに

今回は非常に簡単な機能としてDiscord APIを利用したBotを作ってみましたが、これをうまく使えば、特定の文字列を含む投稿に対して応答させたり、時間を見て予定のリマインドをさせたりと幅広く機能を追加することができます!
(私は今流行りの宇宙人狼のミュート忘れ防止用にオートミュート機能を作れないかなーとか考えてます)

Discordを利用していて、何か「あったらいいな」と思う機能があれば、ぜひ利用してみてください!

参考リンク