【Javascriptで作成する】Discordのbotの作り方 Discord.js v14

discordでbotを作る方法をご紹介します。

スラッシュコマンドに応答するプログラムでv14に対応しています。

公式のドキュメントに沿って不要な箇所をシンプルに構成しなおし、わかりやすく書きました。

とはいえ、初心者がなんとか作れるレベルかと思います。

また広範囲に浅く広くの知識が必要です。

意外と工程は多く、

  • 環境準備
  • botユーザーの作成
  • botプログラムの作成
  • botの登録

という4つのプロセスに分かれます。

大変ですが文章と図解を丁寧に読み飛ばさずに進めていけばおそらく完成できます。

今回のコードはGitHubにもアップしてあります。

GitHub - nyan-tama/discord-js-bot: discord.jsを利用してDiscordに独自のスラッシュコマンドを追加するサンプルコードです。
discord.jsを利用してDiscordに独自のスラッシュコマンドを追加するサンプルコードです。 - GitHub - nyan-tama/discord-js-bot: discord.jsを利用してDiscordに独自のスラッシュコマンドを追加するサンプルコードです。
github.com

どうぞ参考にしてみてください。

目次

インストールと環境準備

JavascriptでDiscordのbot(ボット)を作成するためにはdiscord.jsが必要です。

また、discord.jsを使用するにはNode.jsをインストールする必要があります。

Node.jsのインストールやLinux操作ついてはこの記事では説明しません。

後日、別の記事にて紹介しますのでそれまでは他サイトをご参照ください。

1.プロジェクトフォルダの作成

例のように新しいフォルダを作成しそのフォルダへ移動してください。

mkdir my-discord-bot
cd my-discord-bot

2.npmの初期化

Node.jsがインストールされている前提で進めます。

インストールしていない方は各自で用意してください。

Node.jsにあるnpm (Node.jsのパッケージマネージャー) を使ってプロジェクトを初期化し、package.jsonファイルを作成します。

以下のコマンドを実行してください。

npm init -y

このコマンドはpackage.jsonを作成し、プロジェクトが使用する外部ライブラリ(プログラム)を管理します。

3.discord.jsのインストール

npmを使用し、discord.jsライブラリをプロジェクトにインストールします。

以下のコマンドを実行してください。

npm install discord.js

これで環境準備は完了です。

botユーザーのセットアップ

botのプログラムを書く前にbotユーザーの作成と設定をする必要があります。

DiscordのWebサイトから、作成と設定ができます。

botユーザーの作成

まずDiscord 開発者ポータルサイトを開きアカウントにログインします。

次に「New Application」ボタンをクリックします。

ポップアップウィンドウが開くので、ボット名前を入力し、規約を確認しチェックを入れ、Createボタンをクリックします。

次のようなページが表示されます。

ここではアプリケーションの名前、説明、およびアバターを再編集できます。

今はデフォルトのままでも大丈夫です。

左側のメニューから [Bot] を選択して次に進みます。

Build-A-Bot項目の「Add Bot」ボタンをクリックし、「Yes, do it!」をクリックしてbotを追加します。

ボットトークンの作成

botユーザーを作成すると、次のような画面表示になります。

以下の項目でそれぞれ設定が可能です。

  • ICON欄...botのアイコンを設定できます
  • USERNAME欄...botの名前を設定できます
  • TOKEN欄...パスワードのようなものです。コピーしてメモ帳などに張り付けておいてください。

トークンがコピーできるのはボットを作成した直後だけです。

画面遷移など行いますとコピーできなくなります。

コピーしそびれた場合は、「Reset Token」ボタンを押して、再度、トークンを発行しコピーしましょう。

このトークンはパスワードのようなものです。

気を付けて保管しましょう。

botをDiscordサーバーに追加する

作成したbotユーザーを指定のDiscordサーバーに招待しましょう。

下記の招待リンクを利用すると簡単に追加できますが、そのためにはDiscordサーバーの『client_id』が必要となります。

まずは『client_id』を確認しましょう。

Oauth2メニューから遷移して、下記のコピーボタンをクリックします。

コピーしたら下記の『ここにCLIENT_IDを貼り付け』の箇所をご自分のCLIENT IDに置き換えましょう。

https://discord.com/api/oauth2/authorize?client_id=ここにCLIENT_IDを貼り付け&permissions=0&scope=bot%20applications.commands

これをブラウザのURL欄に入力しエンタキーを押して遷移します。

すると次のように表示されます。

追加したいサーバーを選択し、「承認」をクリックします。

この記事の場合は『ギークライブラリー』としています。

ボットをサーバーに追加するには、そのサーバーの管理者である必要があります。

これでbotがDiscordサーバーに追加されました。

サーバーのメンバーリストに次のように表示されます。

botのプログラムコードを作成する

botプログラムを書く前にあとひとつ重要な設定が残っています。

botをプログラムで使用するにはbotユーザーを作成した時のトークンを作業環境に用意しておく必要があります。

環境変数の設定

my-discord-botのフォルダの中に新たなファイルとして『config.json』を作成し、設定ファイルとして利用します。

『config.json』には、botユーザー作成時に発行したトークンを記載します。

以下がconfig.jsonのコードとなります。

{
	"token": "ここにトークンを貼り付ける"
}

トークンは基本的にbotのパスワードであるので、他人に見られないように気をつけましょう。

gitを使用している場合は、.gitignoreで管理対象外ファイルとしてください。

このような環境変数と呼ばれる設定はいくつか方法があります。

dotenvと呼ばれるライブラリを使用して管理したりもします。

環境変数についてはまた別記事でご紹介します。

とりあえずこだわりがなければconfig.jsonで大丈夫です。

メインファイルの作成

my-discord-botのフォルダの中に新たなファイルとして『index.html』を作成し、メインファイルとして利用します。

まずは起動までのコードを書きましょう。

// discord.jsライブラリの中から必要な設定を呼び出し、変数に保存します
const { Client, Events, GatewayIntentBits } = require('discord.js');

// 設定ファイルからトークン情報を呼び出し、変数に保存します
const { token } = require('./config.json');

// クライアントインスタンスと呼ばれるオブジェクトを作成します
const client = new Client({ intents: [GatewayIntentBits.Guilds] });

// クライアントオブジェクトが準備OKとなったとき一度だけ実行されます
client.once(Events.ClientReady, c => {
	console.log(`準備OKです! ${c.user.tag}がログインします。`);
});

// ログインします
client.login(token);

それでは起動だけをしてみます。

コンソール(ターミナル)に以下を入力して起動してみましょう。

node index.js

成功すると、以下のように表示されます。

起動したプログラムは『Ctrl + C』で終了します。

スラッシュコマンドの作成

ではいよいよ『/○○○』と入力したらbotが何らかの反応を返すプログラムを作りましょう。

まず、『my-discord-bot』フォルダの中に『commands』フォルダを新たに作成し、さらに『hey.js』を作成しましょう。

この『hey.js』中にはスラッシュコマンドの内容を記載します。

// SlashCommandBuilder という部品を discord.js からインポートしています。
// これにより、スラッシュコマンドを簡単に構築できます。
const { SlashCommandBuilder } = require('discord.js');

// 以下の形式にすることで、他のファイルでインポートして使用できるようになります。
module.exports = {
	data: new SlashCommandBuilder()
		.setName('hey')
		.setDescription('あいさつに反応してbotが返事します'),
	execute: async function(interaction) {
		await interaction.reply('Fuck.');
	},
};

// module.exportsの補足
// キー・バリューの連想配列のような形で構成されています。
//
// module.exports = {
//    キー: バリュー,
//    キー: バリュー,
// };
//

読むのが難しめのコードです。

特にmodule.exportsの箇所はわかりにくいので補足します。

module.exportsの構成は下記のようなキー・バリューの連想配列のオブジェクトになっています。

module.exports = {
 キー: バリュー,
 キー: バリュー,
};

この形にすることで他のjsファイルから『キー』を指定するだけで、『バリュー』を呼び出すことができます。

ですので、『data』というキーを指定すれば、『:』以降の

new SlashCommandBuilder()
.setName('hey')
.setDescription('あいさつに反応してbotが返事します')

のバリューを呼び出せます。

以下に、それぞれのキー: バリュー箇所の説明を簡潔にまとめます。

  1. data: スラッシュコマンドの定義
data: new SlashCommandBuilder()
              .setName('hey')
              .setDescription('あいさつに反応してbotが返事します'),

バリューではSlashCommandBuilder を使ってコマンドの名前(hey)とコマンドの説明('あいさつに反応してbotが返事します')を設定しています。

ここでは『setName('hey')』とすれば『/hey』 のようスラッシュコマンドを使えるようになります。

setNameには命名ルールがあり、『1 ~ 32 文字であること』大文字、スペース、および『-』『_』以外の記号が使えません。

  1. execute: コマンドが使用されたときに実行する関数定義
execute: async function(interaction) {
    await interaction.reply('Fuck.');
}

asyncを使った非同期関数が定義されており、スラッシュコマンドが実行されると "Fuck." と応答する関数定義となっています。

また応答させる最も簡単な方法が、interaction.reply()メソッドを使用することです。 

ちなみに上記のコードは、キーと、バリューを『execute』の関数名で統一できるので、jsでは下記のようにキーを省略して書くこともできます。

async execute(interaction) {
    await interaction.reply('Fuck.');
}

この省略した記載のほうをチュートリアルで紹介されていますが、キー・バリューの構造と気づきにくいので、初心者泣かせになっています。

話が長くなりましたが、まとめますと、このmodule.exportsの構造により、他のファイルで require して使用することができます。

『data』と『execute』を使って、スラッシュコマンドの定義やスラッシュコマンド実行時の関数定義にアクセスできるようになっています。

コマンド処理の呼び出し

スラッシュコマンドのファイルが完成したので、botの起動前に『hey.js』を読み込み、利用しましょう。

hey.jsのdataキー、executeキーには、それぞれheyFile.data、heyFile.executeで利用することができます。

それではindex.jsを以下のように追加します。

// hey.jsのmodule.exportsを呼び出します。
const heyFile = require('./commands/hey.js');

// discord.jsライブラリの中から必要な設定を呼び出し、変数に保存します
const { Client, Events, GatewayIntentBits } = require('discord.js');
// 設定ファイルからトークン情報を呼び出し、変数に保存します
const { token } = require('./config.json');
// クライアントインスタンスと呼ばれるオブジェクトを作成します
const client = new Client({ intents: [GatewayIntentBits.Guilds] });


// クライアントオブジェクトが準備OKとなったとき一度だけ実行されます
client.once(Events.ClientReady, c => {
	console.log(`準備OKです! ${c.user.tag}がログインします。`);
});


//スラッシュコマンドに応答するには、interactionCreateのイベントリスナーを使う必要があります
client.on(Events.InteractionCreate, async interaction => {

    // スラッシュ以外のコマンドの場合は対象外なので早期リターンさせて終了します
    // コマンドにスラッシュが使われているかどうかはisChatInputCommand()で判断しています
    if (!interaction.isChatInputCommand()) return;

    // heyコマンドに対する処理
    if (interaction.commandName === heyFile.data.name) {
        try {
            await heyFile.execute(interaction);
        } catch (error) {
            console.error(error);
            if (interaction.replied || interaction.deferred) {
                await interaction.followUp({ content: 'コマンド実行時にエラーになりました。', ephemeral: true });
            } else {
                await interaction.reply({ content: 'コマンド実行時にエラーになりました。', ephemeral: true });
            }
        }
    } else {
        console.error(`${interaction.commandName}というコマンドには対応していません。`);
    }
});


// ログインします
client.login(token);

上記コードの補足をしますと、heyFile.dataではなく、heyFile.data.nameとして利用しています。

これはhey.jsファイルのdataキーに対するバリューとして、SlashCommandBuilderクラスを使った設定がされています。

hey.jsファイルには次のように設定されていました。

data: new SlashCommandBuilder()
		.setName('hey')
		.setDescription('あいさつに反応してbotが返事します'),

SlashCommandBuilderクラスでは、.setName()で設定した値を内部的にnameプロパティとして保持しています。

ここで.setName('hey')が実行されたとき、SlashCommandBuilderインスタンスのnameプロパティに'hey'が設定されます。

そして、このSlashCommandBuilderインスタンスがdataプロパティに設定されています。

なかなか理解しにくい箇所ですが、heyCommand.data.nameと書くことで、hey.jsファイルで.setName()で設定された値(この場合は'hey')にアクセスすることができます。

これにより、heyCommand.data.nameは"hey"という文字列を返しています。

スラッシュコマンドの登録

最後に、Discordにスラッシュコマンドを登録します。

登録もソースコードで行うようになっています。

登録用ソースの作成

『my-discord-bot』フォルダの中に『deploy-commands.js』ファイルを作成します。

deploy-commands.jsに以下を記述します。  

// discord.js v14では、下記のようにRESTとRoutesはdiscord.jsパッケージから直接インポートできます
const { REST, Routes } = require('discord.js');

// hey.jsのmodule.exportsを呼び出します。
const heyFile = require('./commands/hey.js');

// 環境変数としてapplicationId, guildId, tokenの3つが必要です
const { applicationId, guildId, token } = require('./config.json');

// 登録コマンドを呼び出してリスト形式で登録
const commands = [heyFile.data.toJSON()];

// DiscordのAPIには現在最新のversion10を指定
const rest = new REST({ version: '10' }).setToken(token);

// Discordサーバーにコマンドを登録
(async () => {
    try {
        await rest.put(
			Routes.applicationGuildCommands(applicationId, guildId),
			{ body: commands },
		);
        console.log('サーバー固有のコマンドが登録されました!');
    } catch (error) {
        console.error('コマンドの登録中にエラーが発生しました:', error);
    }
})();

上記コードで新たな環境変数『clientId』と『guildId』が必要になっています。

applicationIdの取得方法

  • 左側のメニューから「Applications」をクリックして、作成済みのアプリケーション一覧を表示します。
  • 一覧から対象のボットアプリケーションを選択します。
  • アプリケーションのページが表示されたら、「Application ID」の下にあるIDをコピーします(画像を参照)。

guildIdの取得方法

guildIdは、DiscordサーバーのIDです。以下の手順で取得できます。

  • Discordデスクトップアプリまたはウェブアプリを開きます。
  • 左下の歯車アイコン「ユーザーの設定」をクリックして、設定メニューを開きます。
  • 左側のメニューから「詳細設定」を選択します。
  • 「開発者モード」スイッチをオンにします。これで、開発者モードが有効になります(画像を参照)。

  • 設定メニューを閉じ、取得したいサーバーのアイコンを『右クリック』します。
  • コンテキストメニューから「サーバーIDをコピー」を選択します。これがguildIdです(画像を参照)。

config.jsonに追加の設定

config.jsonに追加の設定を記入しましょう。※文末のカンマを忘れずに!

{
    "applicationId": "ここにAPPLICATION_IDを貼り付け",
    "guildId": "ここにGuild_IDを貼り付け",
    "token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}

コマンドの登録を実施

コンソール(ターミナルで)スラッシュコマンドの登録を実行します。

node deploy-commands.js

成功メッセージがでますと、スラッシュコマンドがDiscordに登録されます。

いざ、プログラムを起動してスラッシュコマンドを実行

まず、『index.js』を起動します。

node index.js

コンソールに以下の表示がされます。

これですべてがうまくいけば、Discord でボットの応答を確認できるはずです!

以下をDiscordに入力して試してみましょう!

/hey

うまくいきましたね🎉

大変お疲れさまでした!