初書 : 2021/08/09
node : 16.6.0
discord.js: v13.0.1
前書き
先日、discord.jsがv13をリリースしたので、早速使ってみる。
なお、初書時点ではスレッドやボタンなど、v13で新しく登場した機能の一部は触れていないが、興味はあるので近々追記もしくは別記事で投稿する予定。
前提
・botのトークンの取得やサーバーへの導入の準備が終わっていること
・nodejsの基本的な扱いは出来ること。
インストール
まずはnodeのバージョン確認。v13は最低要件で16.6.0を要求するので、それ以下の場合はアップデートする必要がある。
% node --version
v16.6.1
もし更新していない場合はnodebrewなどでアップデートする必要がある。
出来れば、次はプロジェクトの作成。今回は単純に% npm init -y
で作成した。
あとはdiscord.jsをインストールする。
% npm install discord.js
また、discordのapiを使う時にenvファイルを使うので、dotenvもインストールしておく。
% npm install dotenv
あとはtypescriptでやる場合など、必要なものを各自インストールする。
(以降、コードはTypescriptで記述する。)
% npm install -save-dev typescript
botを起動してみる
まずはbotの起動から。
今回はsrc/index.ts
を作成し、この中で実行していく。
import { Client, Intents } from 'discord.js';
import dotenv from 'dotenv';
dotenv.config(); // envファイルを読み込む
const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] }); // 1
client.once('ready', () => { // 2
console.log('Ready!');
});
client.login(process.env.DISCORD_TOKEN); // 3
軽く説明
dotenv.config();
はenvファイルを読み込むためのおまじない。
(1)
ではdiscord botを操作するクラスを生成する。
なお、v12までとは違い、引数ClientOptions
が必須となった。
その中でもintents
のみ必須で、これはdiscord apiからどのイベントを受信するかを指定する。
どのフラグがどのイベントに対応しているかはこちら:
公式:Discord Developer Portal — Documentation — Gateway
Discord.js Japan User Group:Gateway Intents の利用に関するガイド
今回はとりあえずメッセージのやりとりを目標にするため、GUILDS
とGUILD_MESSAGES
を設定した。1
(2)
ではbotを稼働する準備ができたら呼ばれるイベント。client.on
に関しては他にもメッセージの受信やコマンドの受信などで使う。
(3)
ではbotにログインする。引数にはbotのトークンを渡す。今回は.env
にDISCORD_TOKEN=xxxxxxx
と書き込んでいるのでそこから読み込む。
これが出来れば一旦起動してみる。
% node .
Ready!
・Ready!と出てそのまま実行が続いていること
・discord側でオンライン表示になっていること
これが確認できれば起動はOK!
メッセージを受信してみる
次はメッセージを受信してみる。ついでにおうむ返ししてみる。
readyイベントの次に以下を追加する
client.on("messageCreate", (message) => {
if (message.author.bot) { // 1
return;
}
console.log(message.content); // 2
message.channel.send({ // 3
content: `受信したメッセージ:${message.content}`,
reply: {messageReference: message.id},
// allowedMentions: { repliedUser: false }, // 4
});
});
これも軽く説明
(1)
では、botからの送信を無視する。これを飛ばすと、botのメッセージも認識する。
ちなみに他のbotのメッセージを受信したい場合は、message.author.id === client.user?.id
をif文に入れる必要がある。
これを忘れた場合は、自身のメッセージを認識し、それを返すという無限ループが起きてしまう。
(2)
では、受け取ったメッセージ文をログに出力する。
(3)
では、受け取ったメッセージをそのチャンネルに送信する。
contentが本文で、replyが返信先のメッセージID。
もしメンション通知を飛ばしたくない場合は、(4)
のallowMentionsを追記する。
これで実行してみて、受信したメッセージ:xxx
が返ってきたら成功。
スラッシュコマンドを使ってみる
最近のbotによくあるスラッシュコマンドが、discord.jsのv13でようやく対応したので、それを使ってみる。
ちなみにグローバルコマンドとギルドコマンドの2種類あるのだが、テストする時はギルドコマンドを使用する。
と言うのも、グローバルコマンドはリアルタイムで反映されず、最長1時間待たないと変化しないため、何回もテストするには向いていないから。
権限を追加する
ギルドコマンド2を追加する場合は、別でサーバーに権限が必要なので追加する。
Discord Developer Portalから、該当のbotのOauth2
から、bot
とapplications.commands
の2つをオンにした状態でurlを生成し、botをディスコードサーバーに追加する(既にディスコードサーバーに入っている場合、一度脱退させる必要はない)
コマンドを追加する
次はスラッシュコマンドをディスコードサーバーに追加するコードを追記する。
今回はボットの起動時に追加するので、ready
イベントの中に記述する。
client.once("ready", async () => {
const data: ApplicationCommandData[] = [{ // 1
name: "run_the_slash_command",
description: "テストとしてコマンドを実行します。",
}];
const command = await client.application?.commands.set(data,'server id'); // 2
console.log("Ready!");
});
コード解説
(1)
は登録するコマンドを配列で登録する。
nameはコマンド名、必ず英語の小文字である必要がある。descriptionはコマンドの説明。下の方に表示される。
他にもオプションなどがあるが、詳しくは:Registering slash commands | Discord.js Guide
(2)
は登録するコマンドを追加する。
setの第1引数に(1)
を、第二引数に登録するディスコードサーバーidを記述する。なお、第二引数を省略した場合はグローバルコマンドになる。
また、setの代わりにcreateを使うこともできる。この場合、第一引数は配列ではなく、単体のコマンド情報で、かつ既存のコマンドは削除されない。主に途中で追加するときに使う用だと思われる。
これが出来れば一度実行し、ディスコードサーバー内チャットでスラッシュコマンドが打てるか確認する。(なお、この時押してもインタラクションに失敗しました
と出る)
コマンドを受け取る
コマンドは受け取って初めて動作するので、その部分を作成する。
client.on("interactionCreate", async (interaction) => { // 1
if (!interaction.isCommand()) { // 2
return;
}
if (interaction.commandName === 'run_the_slash_command') { // 3
await interaction.reply('コマンドを実行しました!'); // 4
}
console.log(interaction);
});
コード解説
(1)
で新規イベントを作成。
(2)
で受信したinteractionがコマンドかどうかチェックし、コマンド以外を拒否する。
(3)
では登録したイベントを判断し、(4)
で該当コマンドに返信している。
終わりに
簡単にbotを作成できる部分をまとめてみた。
他にもいろんな機能があるので、一度ガイドやドキュメントをみるといいかもしれない。
参考サイト:
Introduction | Discord.js Guide
discord.js
node.js - Missing Access for Slash Commands - Stack Overflow