Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
16
Help us understand the problem. What is going on with this article?
@allegrogiken

Discord.jsによるBotでボイスチャンネルに触れてみる

More than 3 years have passed since last update.

Discord Advent Calendar 2017 の11日目!1

まだまだ枠が空いています!
Discordに興味が湧いた方、どうぞお気軽に参加くださいませ :wink:

ボイスチャンネルを活用したDiscord Bot

先日はdiscord.jsによるBot開発の記事を書きました。
この界隈では、Discordの大きな特徴であるボイスチャンネルを活用したBot開発も行われているようです。具体的にはYoutubeやSoundCloudから引用してボイスチャンネルに流すなどの機能を持つBotをいくつか確認しています。
今回はDiscordらしい、ボイスチャンネルに触れることのできるBotの開発をやってみます。入門ということで、あまり大したことはやりません :sweat_smile: 殆ど公式ドキュメントで触れらているチュートリアル2に従っていきます。

開発環境

今回もNode.js, discord.jsを使っていきます。
ボイス系の機能を扱う場合、加えてnode-opus, opusscript NPMパッケージが必要になります2が、これらのパッケージはNode.jsにおけるネイティブ拡張を含むためnode-gypが自動インストールされます。
私はWindowsで開発していますが、npm installだけではうまくいきませんでした。先人の知恵 を参考に事前セットアップを済ませましょう。折角なので、コマンドの並びを載せておきます。

各々のシェル環境で

# (windowsの場合、管理者にて) 
npm install --global windows-build-tools

# (あとは共通) 
npm install discord.js
npm install node-opus
npm install opusscript

コードを書いていく

基礎的なところはスキップして、さっそくコード解説に移りたいと思います。
認証やDiscordへの接続など、基礎的なコードはスキップしています。

メンションされたら音楽流して帰るBot
client.on('message', message =>
{
    if (message.isMemberMentioned(client.user) && message.member.voiceChannel)
    {
        message.member.voiceChannel.join().then( connection => {
            const dispatcher = connection.playFile('test.mp3');
            dispatcher.on('end', reason => {
                connection.disconnect();
            });
        })
        .catch(console.log);
        return;
    }
});

上記のコードだけで音声チャンネルに参加・垂れ流しが出来ました。簡単ですね。

コード解説

ボイスチャンネルに接続するにあたり、チャンネルの特定をしなければなりません。
(公式ドキュメント2の引用ですが)今回はメンションして来たユーザのボイスチャンネルを参照しています。ユーザは1つのボイスチャンネルにしか接続できないため、member.voiceChannel にて参照できるというわけです。詳しい解説はこちらをご参照ください。

ボイスチャンネルへの参加と音声の再生

message.member.voiceChannel.join().then(Func)

上記の VoiceChannel 自体にjoinというメソッドがあり、これを使うだけでボイスチャンネルへの接続ができます。接続が成功した時は非同期で join().then(Func) のような形式で書いておくと関数Funcがコールバックされます。

connection => { ... }

上記の関数には VoiceConnection が引数として渡されてきます。ボイスチャンネルに何か作用したいときはここのブロックに記載することになります。今回は test.mp3 というローカルファイルを置いて再生させています。

dispatcher.on('end', reason => { ... } )

ファイルの再生が終わったらボイスチャンネルを抜ける、目的のためにこのコードを記載しています。比較的わかりやすいですね。dipatcherは音声を再生した時に得られる StreamDispatcher です。

書いてみて(まとめ)

今回はほとんどサンプルのままですが、非常に簡単にボイスチャンネルに影響を与えるBotが作れました。単純なファイル再生であればファイル名指定だけで済んでしまうので、ライブラリが実に便利に作られているな・・と感じます。私個人はガッツリJavascriptを書く人間ではないので、Promiseやラムダ式を活用するサンプルコードを真似るだけでも大きな学びになりますね。
実は、今回の記事ではdiscord.jsの各クラスの紹介を交えることを目的としました。ドキュメントの充実っぷりはかなり良いと思いますので、ぜひ色々読んでみてくださいね。


  1. すみません。遅刻しました :worried:  

  2. https://discord.js.org/#/docs/main/stable/topics/voice 

16
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
allegrogiken
柴犬がエンジニアやってます。静的型付け+型推論が好き。 学生時代はD言語とOpenGLで3Dゲームとか作ってました。 今はJavaとJavascript多めです。Kotlinに期待寄せてます。 チャットツールはDiscordが好きです。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
16
Help us understand the problem. What is going on with this article?