この記事はWanoグループ Advent Calendar 2020の5日目の記事になります。
つい先日から、EDOCODDEではリモートワークのツールとして、Discordが導入されました。Discordはゲームにおけるコミュニケーションでよく使われているツールですが、最近は、リモートワークのツールとしても、注目を浴びているようです。
リモートワーク discord
でぐぐると色々でてきますね。
以下、前置きが長いので、コードが見たい人は、スクロールしてください。
当社でのDiscordの使い方
まず最初に、どのように使っているかをざっくり説明します。
以下のようなボイスチャンネルを用意しています。
- general ... みんなが一緒にいるチャンネル
- in-meeting ... zoom 等、Discord以外でミーティングしている時にはいるチャンネル
- lunch ... ご飯中に入るチャンネル
- leaving ... 外出したり、仕事終わったら入るチャンネル
それに加えて、ミーティング用のボイスチャンネルとして
- SAKURA
- AZUKI
- RURI
- MOEGI
- UNOHANA
といった名前のミーティング用のチャンネルがあります。
参加者の初期状態は
- general に参加
- ミュート状態
- スピーカーはオン
Discordでミーティングしたいときの使い方
- 声をかけたい時に、ミュートを解除し、誰かに声を書ける(みんなに聞こえる)
- ミーティングルームに移動
- ミーティングが終わったら general に移動(ミュートにする)
といったような感じで使っています。
誰かが誰かに用事があるんだなーとか、オフィスにいれば、聞こえてくるようことが、Discord上で再現できている感じです。
Discord以外でミーティングしているときの使い方
Discord以外でミーティングをする場合(zoomや、Google Meet等)、in-meetingのチャンネルに移動して、ミュートにします。
そうしておくことで、視覚的に、ミーティング中なんだなーというのがわかるようになります。
問題点
1. 独り言を聞かれてしまう
ミーティングが終わったあとに、general に戻る時に、高確率でミュートに戻し忘れます(僕が)。
何が起きるかと言うと...
- ミーティングがおわって、generalに戻る
- ちょうどよく、可愛い猫の写真がSlackの雑談チャンネルにながれる
- 「うわ、めっちゃかわいいなー。やばい。飼いたい」とかつぶやく
- みんなに聞こえる
ちょっと恥ずかしいですね!
2. in-meetingでミュートにし忘れる
Discordのスピーカーはみんなオンの状態なので、他の人のミーティングに、関係ない別のミーティングの音声が混じることになります。
- zoom で AさんとBさんが話している
- 別の zoom で CさんとDさんが話している
- A,B,C,D は全員 in-meeting でスピーカーON
この時に、Cさんがミュートを解除してしまっていると、AさんとBさんの会議にCさんの声が混じってしまいます。
カオスですね!
問題点を解決するボットを作る
先程の2つの問題を解決するために、下記の機能を実現します。
- ミーティングルームから general に戻った時にミュート解除状態だったらダイレクトメッセージで教える
- in-meeting や leaving 等のチャンネルにいる時は、強制的にミュートにする
1. Discord Developer Portal でアプリを作る
この辺の手順は、そこらにあるので、ググってもらえれば良いかと思います。
下記の記事は英語ですが、簡潔にまとまってると思います。
https://discordpy.readthedocs.io/en/latest/discord.html
ざっくりまとめると
- Appを作る
- Botを作る
- Oauth2 のURLを取得する
- 3のURLをブラウザに貼ってログインする
途中で権限を選択しますが、この記事でやりたいことは、Administrator
じゃないと無理なようです。
Manage Server
でできるかなーと思ったのですが、権限エラーとなりました。
2. コードを書く
discord.js
が必要なので、
npm install discord.js
しておいてください。
下記程度の簡単なコードで書けてしまいます。チャンネルIDは、ボットを手元に動かして、チャンネルに出たり入ったりして、調べて下さい。
// ボットのトークンをここに貼る
const token = '*トークン*';
const Discord = require("discord.js");
const bot = new Discord.Client();
// ミーティング用のチャンネルIDを ... のところに入れる
const meetingChannel = {
"....": true,
"....": true,
"....": true
};
// 強制ミュート用のチャンネルIDを ... のところに入れる
const muteChannel = {
"....": true,
"....": true,
"....": true
};
bot.on('ready', () => {
console.log(`Logged in as ${bot.user.tag}!`);
});
bot.on('voiceStateUpdate', (oldMember, newMember) => {
// チャンネルIDを調べる用
console.log(newMember.channelID);
// チャンネルが変わったら
if(oldMember && oldMember.channelID !== newMember.channelID) {
if (muteChannel[newMember.channelID]) {
// 強制ミュート
newMember.setMute(true);
} else {
// ミュート解除
newMember.setMute(false);
// ミーティング用のチャンネルではないのに、ユーザーがミュートしてない場合
if (!meetingChannel[newMember.channelID] && !newMember.selfMute) {
// Muteを促す
bot.users.fetch(newMember.id).then((user) => {
user.send("Muteし忘れてないですか?");
})
}
}
}
});
bot.login(token);
3. ボットを動かす
下記のように動かせば、ボットが動きます。
node App.js
ミュート解除したまま、general に移動すると...
と、ダイレクトメッセージが来るようになりました。
leaving に入ると、赤いミュートマーク(サーバ側で強制ミュートしている状態)になりました。
ちょっとハマった所
ハマったと言うほどでもないのですが、
- StackOverFlowとかで紹介されている、
voiceStateUpdate
使った例がだいたい間違えていた -
client.users.get(ユーザーID).send("message")
でダイレクトメッセージを送れると書いているのが多かったが、使えない
ちゃんとドキュメント読みましょうという感じですね。
おわり
という感じで、とても簡単にボットが作れました。
discord.js は、ドキュメントを見ると、かなりAPIが充実しているので、色々遊べるのじゃないかなーという気がしています。
とりあえず、これで恥ずかしい思いはしなくなると思うので、一安心です。
Wanoは積極的にエンジニア採用を行なっています!
まずはオンラインでVPoEとのカジュアル面談から。お好きな入り口からお気軽にお声がけください!
Wano Recruitページ https://group.wano.co.jp/recruit/
QiitaJobs https://jobs.qiita.com/employers/wano-inc/postings/1297
Wantedly https://www.wantedly.com/companies/wano/projects
Findy https://findy-code.io/companies/522
EDOCODEも積極的にエンジニア採用を行っています!
興味のある方は下記を参照ください。
Green https://www.green-japan.com/job/94118