discordのボイスチャンネル入室を通知するbotの作成

discordのボイスチャンネルに誰かが入室したとき、既にボイスチャンネルに入室している人には入室音が鳴り知らされますが、それ以外の人に通知する設定は現時点では存在しません。 そこで、ボイスチャンネルへ入室したことをテキストチャンネルに送ることで通知するbotを作成してみます。また、discord以外にもLINEへ通知する方法についても紹介します。

目次

動作環境

  • Discord 1.0.9024
  • LINE 13.19.1
  • Amazon Linux 2
  • discord.py==2.3.2
  • python-dotenv==1.0.0
  • requests==2.25.1

Discord Botの準備

  1. まずDiscord Developer Portalを開きます。 ログインページが開くのでdiscordにログインしてください。

  2. ログインするとこのような画面が出てくるので画面右上の「New Application」を押します。

  3. アプリ名の入力とポリシーの同意にチェックを入れたら「Create」を押します。

  4. すると作成したアプリの管理画面が開くので画面左側の「bot」と書かれているところを押します。

  5. 「Reset Token」と書かれているボタンを押すとトークンを取得することができます。 何回も押すことはできますが、ボタンを押すとそれ以前に取得したトークンは無効になるので注意してください。 取得したトークンは後ほど使いますのでコピーしてどこかに保存しておいてください。

ec2インスタンスの起動・接続

ec2起動の設定を開いて名前を入力します。

「新しいキーペアの作成」を押してキーペア名を入力します。 (キーペア作成時にダウンロードされる鍵は後ほど接続するときに使用します)

ネットワーク設定の編集ボタンを押し、セキュリティグループ名と説明を入力します。
ここでインバウンドグループで22番ポートが解放されていることを確認しておく。

確認できたら「インスタンスの起動」ボタンを押してインスタンスを起動してください。

インスタンスの起動が出来たらローカルPCのターミナルを立ち上げて次のコマンドを実行することでサーバに接続します。

ssh -i {鍵のパス} ec2-user@{ec2パブリックIPv4アドレス}

以下のような表示がされた場合はyesと入力してEnterを押してください。

Are you sure you want to continue connecting (yes/no/[fingerprint])?

このような表示がされれば接続成功です。

   ,     #_
   ~\_  ####_        Amazon Linux 2023
  ~~  \_#####\
  ~~     \###|
  ~~       \#/ ___   https://aws.amazon.com/linux/amazon-linux-2023
   ~~       V~' '->
    ~~~         /
      ~~._.   _/
         _/ _/
       _/m/'

ボイスチャンネルのIDを調べる

ボイスチャンネルのIDを調べるためにプログラムを書いていきますが、まずはその準備をします。

既にpythonのインストールなどはされていましたが念のため以下のコマンドを実行します。

sudo yum update
sudo yum install python3

次に必要なライブラリのインストールをします。

sudo yum install pip
pip install discord
pip install python-dotenv

次にチャンネルのIDを調べるためのプログラムを作成します。

まず以下のコマンドを実行して.envファイルを編集していきます。 今回はvimを用いていますが、お好みのエディタを使って頂いて大丈夫です。

vim .env

実行するとエディタが開かれます。iキーを押すと編集できるようになるので、まずiキーを押してから以下の内容を貼り付けてください。

※「取得したトークン」と書かれている箇所は先ほど確認したトークンに変更してください。

DISCORD_TOKEN=取得したトークン

ESCキーを押した後に:wqと入力してEnterを押すと保存して終了します。

同様に以下のコマンドを実行してchannel_id.pyを貼り付けてください。

vim channel_id.py
#channel_id.py
import os
import discord
from dotenv import load_dotenv

load_dotenv()
DISCORD_TOKEN = os.getenv("DISCORD_TOKEN")

intents = discord.Intents.default()
client = discord.Client(intents=intents)

@client.event
async def on_ready():
    for channel in client.get_all_channels():
        print(channel.name + "," + str(channel.id))

client.run(DISCORD_TOKEN)

保存して閉じたら以下のように実行してみてください。

python3 discord-channelname.py

すると、以下のように実行したターミナルに全てのチャンネル名とidが表示されます。 (xxxxxxxxxxxxxxxxxxx、yyyyyyyyyyyyyyyyyyの部分にはチャンネルのidが数字で表示されます。)

チャンネル名1,xxxxxxxxxxxxxxxxxxx
チャンネル名2,yyyyyyyyyyyyyyyyyy
・・・
・・・
(以下略)

idが表示できたら監視したいボイスチャンネルのidと通知したいテキストチャンネルのidをどこかにコピーするなどして後で確認できるようにしておいてください。コピーできたらCtrl+Cで実行していたプログラムを停止してください。 ここまででボイスチャンネルのIDを調べる作業は完了となります。

入室を通知するプログラムを作成する

次に入室を通知するプログラムを作成していきます。 Discordのテキストチャンネルに通知する場合とLINEに通知する場合で分けて解説していますが共通する部分もあるので、そのような箇所についてはテキストチャンネルの方でのみ解説をしています。

Discordのテキストチャンネルに通知する

botの作成

.envファイルに監視するボイスチャンネルのidと通知するテキストチャンネルのidを設定します。

vim .env

を実行して以下のように修正してください。 (右辺は先ほど調べたidを入力してください。)

DISCORD_TOKEN=取得したトークン
VOICE_CHANNEL_ID=監視したいボイスチャンネルのID
TEXT_CHANNEL_ID=通知を送信したいテキストチャンネルのID

次に通知を送るためのbotプログラムを作成します。 以下のコマンドを実行してプログラムを貼り付けてください。

vim bot_text_channel.py
#bot_text_channel.py
import os
import discord
from dotenv import load_dotenv

load_dotenv()
DISCORD_TOKEN = os.getenv("DISCORD_TOKEN")
VOICE_CHANNEL_ID = int(os.getenv("VOICE_CHANNEL_ID"))
TEXT_CHANNEL_ID = int(os.getenv("TEXT_CHANNEL_ID"))

intents = discord.Intents.default()
client = discord.Client(intents=intents)

@client.event
async def on_voice_state_update(user, before, after):
    if before.channel != after.channel:
        botRoom = client.get_channel(TEXT_CHANNEL_ID)
        if after.channel is not None and after.channel.id == VOICE_CHANNEL_ID:
            await botRoom.send("**" + after.channel.name + "** に、__" + user.display_name + "__  が参加しました")

client.run(DISCORD_TOKEN)

ここまでできたら以下のコマンドを実行して動かしてみてください。

python3 bot_text_channel.py

プログラムを動かした状態でボイスチャンネルに入室するとテキストチャンネルに「△△に、〇〇が参加しました」と通知されます。

プログラムの説明

async def on_voice_state_update(user, before, after):
    if before.channel != after.channel:
        botRoom = client.get_channel(TEXT_CHANNEL_ID)
        if after.channel is not None and after.channel.id == VOICE_CHANNEL_ID:
            await botRoom.send("**" + after.channel.name + "** に、__" + user.display_name + "__  が参加しました")

まず最初の行ではボイスの状態が変化したというイベントを受け取る設定をしており、ボイスチャンネルへの入退室やミュートの切り替えなどを受け取ります。今回通知したいのは入室のみなので1つ目のif文でミュート切り替えに反応しないようにしています。2つ目のif文では条件が2つありますが、1つ目の条件では退室に反応しないようにしており、2つ目の条件では監視対象のボイスチャンネルのみに反応するようにしています。そのため、2つ目の条件を削除することでサーバ内のボイスチャンネル全てを監視対象とすることもできます。

LINEに通知する

LINE Notifyの設定

LINEに通知すると言ってもLINEの公式アカウントを作成してそのアカウントからメッセージを送信する、LINE Notifyを用いてメッセージを送信するなどいくつか方法がありますが、今回はLINE Notifyを用いて通知をしていきます。

  1. まずはLINEにログインする必要があるのでLINE Notifyを開いてください。

  2. このような画面が表示されるので右上のログインボタンを押してください。

  3. LINEアカウントに登録しているメールアドレスとパスワードを入力してログインします。

  4. すると右上に自分のLINEのプロフィールに設定している名前が表示されているので、そこを押すと「マイページ」という表示が出てくるので押します。

  5. マイページに移動すると「トークンを発行する」と書かれている場所があるので押してください。

  6. トークンを発行する際にトークン名とトークンを送信するトークルームを設定する必要があるので設定します。

  7. 設定が終わるとトークンが表示されますが、一度閉じると二度と確認することができないためコピーしてどこかに保存しておいてください。 後ほどここで取得したトークンを使用していきます。

LINEの設定

LINE Notifyをしたので通知を受け取るLINE側の設定をしていきます。

  • 個人のトークルームに送信する場合

LINE Notifyの公式アカウントを友達に追加しておく必要があるので、もし追加していない場合は[友だち追加]>[ID/電話番号]より @linenotify と入力し検索・追加してください。

  • グループに送信する場合

グループに送信する場合はLINE Notifyの公式アカウントをグループに招待する必要があるので、通知をしたいグループにLINE Notifyを追加しておいてください。

botの作成

.envファイルに監視するボイスチャンネルのidとLINEのを設定します。

vim .env

を実行して以下のように修正してください。 (右辺は先ほど調べたidとLINEのトークンを入力してください。)

DISCORD_TOKEN=取得したトークン
VOICE_CHANNEL_ID=監視したいボイスチャンネルのID
LINE_TOKEN=取得したトークン

次に通知を送るためのbotプログラムを作成します。 以下のコマンドを実行してプログラムを貼り付けてください。

vim bot_line.py
#bot_line.py
import os
import discord
import requests
from dotenv import load_dotenv

load_dotenv()
DISCORD_TOKEN = os.getenv("DISCORD_TOKEN")
VOICE_CHANNEL_ID = int(os.getenv("VOICE_CHANNEL_ID"))
LINE_TOKEN=os.getenv("LINE_TOKEN")

intents = discord.Intents.default()
client = discord.Client(intents=intents)

def send_line_msg(msg):
    acc_token = LINE_TOKEN
    url = 'https://notify-api.line.me/api/notify'
    headers = {'Authorization': 'Bearer ' + acc_token}
    payload = {'message': msg}
    requests.post(url, headers=headers, params=payload)

@client.event
async def on_voice_state_update(user, before, after):
    if before.channel != after.channel:
        if after.channel is not None and after.channel.id == VOICE_CHANNEL_ID:
            send_line_msg(after.channel.name+ "に" + user.display_name + "が参加しました")

client.run(DISCORD_TOKEN)

ここまでできたら以下のコマンドを実行して動かしてみてください。

python3 bot_line.py

プログラムを動かした状態でボイスチャンネルに入室するとLINEのトークルームに「△△に、〇〇が参加しました」と通知されます。

プログラムの説明

def send_line_msg(msg):
    acc_token = LINE_TOKEN
    url = 'https://notify-api.line.me/api/notify'
    headers = {'Authorization': 'Bearer ' + acc_token}
    payload = {'message': msg}
    requests.post(url, headers=headers, params=payload)

ここではLINE Notifyからメッセージを送信するための関数を定義しています。
引数で送信したいメッセージを受け取り、LINE Notifyを通して通知するようにしています。

send_line_msg(after.channel.name+ "に" + user.display_name + "が参加しました")

この行で関数を使っており、「△△に、〇〇が参加しました」というメッセージをLINEに通知します。

まとめ

今回はdiscordのボイスチャンネル入室を通知するbotの作成をしました。

入室以外にも例えばボイスチャンネルの人数が一定以上になったら通知したり、特定のチャンネルに投稿した内容をそのままLINEに通知したりすることもできるのでプログラムを書き換えればもっと便利なbotを作成できるかもしれません。