6
3

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】v13でbotを作ってみる

Last updated at Posted at 2021-08-09

初書 : 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を作成し、この中で実行していく。

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 の利用に関するガイド

今回はとりあえずメッセージのやりとりを目標にするため、GUILDSGUILD_MESSAGESを設定した。1

(2)ではbotを稼働する準備ができたら呼ばれるイベント。client.onに関しては他にもメッセージの受信やコマンドの受信などで使う。

(3)ではbotにログインする。引数にはbotのトークンを渡す。今回は.envDISCORD_TOKEN=xxxxxxxと書き込んでいるのでそこから読み込む。

これが出来れば一旦起動してみる。

% node .
Ready!

・Ready!と出てそのまま実行が続いていること
・discord側でオンライン表示になっていること

これが確認できれば起動はOK!

メッセージを受信してみる

次はメッセージを受信してみる。ついでにおうむ返ししてみる。

readyイベントの次に以下を追加する

src/index.ts
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から、botapplications.commandsの2つをオンにした状態でurlを生成し、botをディスコードサーバーに追加する(既にディスコードサーバーに入っている場合、一度脱退させる必要はない)

コマンドを追加する

次はスラッシュコマンドをディスコードサーバーに追加するコードを追記する。
今回はボットの起動時に追加するので、readyイベントの中に記述する。

src/index.ts
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を使うこともできる。この場合、第一引数は配列ではなく、単体のコマンド情報で、かつ既存のコマンドは削除されない。主に途中で追加するときに使う用だと思われる。

これが出来れば一度実行し、ディスコードサーバー内チャットでスラッシュコマンドが打てるか確認する。(なお、この時押してもインタラクションに失敗しましたと出る)

コマンドを受け取る

コマンドは受け取って初めて動作するので、その部分を作成する。

src/index.ts
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

  1. メッセージの送受信だけだと一見GUILD_MESSAGESだけでいいように見えるが、それだと何故か動かなかったので2つ設定している。

  2. グローバルコマンドの場合は不要だと思う。確証はない

6
3
0

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
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?