9
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

discord.js v12でVCの入退室に反応するbotを作るメモ

Last updated at Posted at 2021-07-17

はじめに

discord.jsを使ったbotの資料はたくさんありますが、

  • v12対応
  • voiceStateUpdateを利用
  • VCの入退室に関連した資料

というのが殆どなかったのでメモっときます。v11対応だったりErisだったりするとあるんだけどdiscord.js v12がいいんだよ!!

このページに載っている情報でなにができる?

  • 入退室時、ミュートなどの状態を変更したときに関数を発火させることができる
  • 状態を変化させたユーザやチャンネル、ギルド(サーバ)などの情報を取得することができる

環境

Node.js v14.17.0
discord.js v12.5.3

サンプルコード

// discord.js モジュールのインポート
const Discord = require('discord.js');

// Discord Clientのインスタンス作成
const client = new Discord.Client();

// トークンの用意
const discord_token = `hogehogehoge`; //ここは各自のトークンを入力

client.on("voiceStateUpdate",  (oldState, newState) => {
    if(newState && oldState){

        //newState関係
        console.log(`NEW:userid   : ${newState.id}`);       //ユーザID
        console.log(`NEW:channelid: ${newState.channelID}`);//チャンネルID、nullならdisconnect
        console.log(`NEW:guildid  : ${newState.guild.id}`); //ギルドID

        //oldState関係
        console.log(`OLD:userid   : ${oldState.id}`);       //ユーザID
        console.log(`OLD:channelid: ${oldState.channelID}`);//チャンネルID、nullならconnect
        console.log(`OLD:guildid  : ${oldState.guild.id}`); //ギルドID
        
        if(oldState.channelID===newState.channelID){
            //ここはミュートなどの動作を行ったときに発火する場所
            concole.log(`other`);
        }
        if(oldState.channelID===null && newState.channelID != null){
            //ここはconnectしたときに発火する場所
            concole.log(`connect`);
            }
        }
        if(oldState.channelID !=null && newState.channelID === null){
            //ここはdisconnectしたときに発火する場所
            console.log(`disconnect`);
            }
        }
    }
});

// Discordへの接続
client.login(discord_token);

コード解説

##discord.jsを使うに当たって当然必要な物たち

// discord.js モジュールのインポート
const Discord = require('discord.js');

// Discord Clientのインスタンス作成
const client = new Discord.Client();

// トークンの用意
const discord_token = `hogehogehoge`; //ここは各自のトークンを入力

~~中略~~

// Discordへの接続
client.login(discord_token);
  • この辺りはおまじない的役割
  • token流出に注意しましょう

##voiceStateUpdate

client.on("voiceStateUpdate",  (oldState, newState) => {
~~中略~~
});

このページの肝となる場所です。
voiceStateUpdateをdiscordより受信すると、この関数が動きます。

###voiceStateUpdateを受信する条件

botが参加しているサーバ(guild)で

  • ユーザがVCに参加する
  • ユーザがVCから退出する
  • ユーザが各種ミュートをする

の模様。

###oldState,newStateとは何ぞや?
documentを見るとこんなことが書いてあります
image.png

これしか書いてないです。説明雑では?
oldStateが変化前の状態で、newStateが変化後の状態です。
VoiceState型でデータをくれるみたいですね。

###VoiceState型とは?

documentにはたくさん情報があるのですが、はっきり言って読みづらいですね。

今回は、

  • 状態の変化したチャンネルID取得
  • 状態の変化したサーバ(guild)のID取得
  • 状態の変化したユーザID取得

この3つに絞って説明します。

        //newState関係
        console.log(`NEW:userid   : ${newState.id}`);       //ユーザID
        console.log(`NEW:channelid: ${newState.channelID}`);//チャンネルID、nullならdisconnect
        console.log(`NEW:guildid  : ${newState.guild.id}`); //ギルドID

        //oldState関係
        console.log(`OLD:userid   : ${oldState.id}`);       //ユーザID
        console.log(`OLD:channelid: ${oldState.channelID}`);//チャンネルID、nullならconnect
        console.log(`OLD:guildid  : ${oldState.guild.id}`); //ギルドID

ただ表示するだけの部分ですが、以下のように取得することができます。

oldState newState 備考
ユーザーID oldState.id newState.id newState.guild.members.resolve(newState.id).user.username とかでユーザ名を取得できる。
チャンネルID oldState.channelID newState.channelID nullになる場合あり。newState.channel.name とかでチャンネル名を取得できる。
ギルドID oldState.guild.id newState.guild.id このIDでサーバごとの設定変更とか状態保持とかするといいかも

さらに、oldStateとnewStateのchannelIDの状態を確認することで以下のように判別できます。

oldState.channelID newState.channelID 状態
チャンネルID チャンネルID ミュートなどをした場合。
oldStateとnewStateでチャンネルIDが別IDとなっていると、VC間の移動を検出できるようです。
null チャンネルID 入室
チャンネルID null 退室

ということで、

        if(oldState.channelID===newState.channelID){
            //ここはミュートなどの動作を行ったときに発火する場所
            concole.log(`other`);
        }
        if(oldState.channelID===null && newState.channelID != null){
            //ここはconnectしたときに発火する場所
            concole.log(`connect`);
            }
        }
        if(oldState.channelID !=null && newState.channelID === null){
            //ここはdisconnectしたときに発火する場所
            console.log(`disconnect`);
            }
        }

このようにコードを書くことができます。

以上、実際にDiscordの動作に反応すれば完了です。

9
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?