ひぃの雑多書き

日記からお役立ち情報まで色んなことを書きます。

【v14】discordjsのすゝめ 第2回「Replitでbotを起動する」

こんにちは。ひぃです。

discordjsもある程度理解できたということで書き始めた「discord botの作り方」の第2回です。
今回から少しずつソースコードを書いていきます。

◇環境
node: 16.13.2
discordjs: 14.7.1

2.Replitでbotを起動する

Replitに登録する

Replitに登録しましょう。URLを開いて画面の指示に従っていくとすんなり登録できるかなと思います。
Replitは簡単に言うと、ブラウザ上でソースコードを書いてそのまま動かすことができるサービスです。

Log In - Replit

自分は今回Googleのアカウントと連携してアカウントを作りました。

プロジェクトを作成する

登録が終わったら、Replitのマイページから左上辺りにある「+ Create」ボタンを押しましょう。

出てきたウィンドウの中でTemplateは「Node.js」を選びます。
Titleは自分の好きな名前でOKです。

無料版ではソースコードは強制的に公開(public)になります。

入力できたら「+ Create Repl」ボタンを押してプロジェクトを作成しましょう。 こんな画面が表示されると思います。

必要なPackageをインストールする

続いて、必要なパッケージをインストールします。
パッケージというのはアプリケーションを動かす為に必要になるもの、くらいの認識でOKです。

Node.jsで動くアプリケーションを作るので本来ならNode.jsもインストールする必要があるのですが、 テンプレートでNode.jsを選択したことで自動でインストールされます。
bot開発を進めていく上でReplit以外のサービスでbotを動かす=デプロイしたくなった時はNode.jsもインストールしましょう。

画面左下にあるToolsアイコンの中から「Packages」を選択します。
右側にウィンドウが出てきますので、検索ボックスに「discord」と入力しましょう。
検索結果に「discord.js」が出てきたら「+」ボタンを押してれっつインストール。

インストールが終わるとこんな感じになります。

最低限必要なのはdiscord.jsだけなのですが、オススメなので「app-root-path」もインストールしておきましょう。
インストールしておくとプロジェクト内で分けたファイルのインポート文が楽に書けます。

Secretsを追加する

続いてSecretsを追加します。
Secretsというのはソースコードに直接書きたくない『他人に教えたくない』物を記載するものです。

そうです、botのCLIENT IDとTOKENです。

先程と同様に画面左下にあるToolsアイコンの中から「Secrets」を選択します。 また右側にウィンドウが出てきますので、下記のように入力し「Add new secret」ボタンを押しましょう。

  • KEY:DISCORD_CLIENT_ID
  • VALUE:前回控えたbotのCLIENT ID

  • KEY:DISCORD_TOKEN

  • VALUE:前回控えたbotのTOKEN

登録が終わるとこんな感じになります。
Insertボタン押しちゃったのでindex.jsに1行書いてありますが、気にしなくてOKです。

config.jsを記載する

続いて、色々設定を記載するconfigファイルを作りましょう。

左上の「Files」と書いてある所の横に並んでいるアイコンの一番左を押します。
新規ファイルが作成されますので、「config.js」と入力しましょう。

入力が終わったらconfig.jsをクリックしてファイルを開き、次のように入力します。

module.exports = {
  clientId: process.env.DISCORD_CLIENT_ID,
  token: process.env.DISCORD_TOKEN,
  colors: {
    success: "000080",
  },
  channels: {
    log: "XXXXXXXXXXXXXXXXX",
  },
}

successの後の数字は16進数で好きな色にしてOKです。 channelsのlogはbotを追加したサーバの中から任意のチャンネルのIDを貼り付けてください。

チャンネルのIDをコピーするのはDiscordのオプションから「開発者モード」をONにした後、任意のチャンネルの上で右クリック→「IDをコピー」でいけます。

index.jsを記載する

続いてindex.jsを書いていきます。
ひとまずソースコードをぺたり。

// discord
const Discord = require("discord.js");
const { Client, GatewayIntentBits, Partials } = require("discord.js");
const client = new Client({
  intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers, GatewayIntentBits.GuildEmojisAndStickers,
  GatewayIntentBits.GuildIntegrations, GatewayIntentBits.GuildVoiceStates,
  GatewayIntentBits.GuildPresences, GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildMessageReactions,
  GatewayIntentBits.DirectMessages, GatewayIntentBits.DirectMessageReactions, GatewayIntentBits.MessageContent],

  partials: [Partials.User, Partials.Channel, Partials.GuildMember, Partials.Message, Partials.Reaction]
});

// お手製
const app_root = require("app-root-path");
const config = require(app_root + "/config.js");

// bot起動時の処理
client.on("ready", () => {
  console.log("ready!");
  client.user.setPresence({ activities: [{ name: `Blue Archive` }], status: "online" });
  client.channels.cache.get(config.channels.log).send("うん、たまにはこういうのも悪くない");
});

// bot起動処理
(async () => {
  try {
    // Discordログイン
    client.login(config.token);
  } catch (error) {
    console.log(error);
  }
})();

さて、ここで声を大にして言いたいのが「必要に応じてコメント行を残しましょう」ということです。
結構プログラマあるあるだと思うんですが、他人の書いたソースコードは愚か1ヵ月前の自分が書いたソースコードですら「何書いてあるのかわからん」が発生します。

「このソースコード公開する気ないしw」とか思うかもしれませんが、悪いことは言わないのでマジで丁寧にコメント書くのをオススメします。

(1) // discord

ここは「discord.jsを使うよ!」「discord botの権限設定はこうだよ!」って言ってるとこです。

GatewayIntentBitsとPartialsについてはもっとスッキリ書く方法もあった気がするんですが、個人的には全部書きたい派です。
後から要らない権限が出てきた時に整理しやすいのと、今botが持ってる権限がわかりやすいかなーと思ってます。

逆に、権限回りに変更があった時は調べ直しになります。
でも権限回りに変更あった時はどの道ソースに色々と変更入ると思うので、権限の付与不足でエラー吐いてくれるのはむしろメリットな気も。

詳しいことはこの辺見てね。

Gateway Intents | discord.js Guide

Discord Developer Portal

(11) // お手製

ここは「自分で作ったファイルのうちコレを使うよ!」って言ってるとこです。

前述のapp-root-pathを入れたお陰で、絶対パスでファイルの指定ができます。
こいつがないと、今後スラッシュコマンドを沢山追加した時に相対パスで"../../config.js"とか"../../parameters/music_tracks.js"とか書くハメになります。
そして何より、そのインポート文を他のファイルにコピペできない。

(14) // bot起動時の処理

ここはbotが起動した時に実行される処理を書く所です。

client.user.setPresence~ の部分でbotのステータスを記載しています。
ゲームを起動したら変わる「VRChatをプレイ中」みたいな部分ですね。

nameの後に書いてあるのが「VRChat」に相当する部分で、statusの後に書いてあるのが「オンライン」「退席中」みたいなステータスのことです。
ステータスの対応はこの辺見ると良いと思います。

ユーザーのステータスを取得する - Discord.js Japan User Group

client.channels.cache.get~ の部分でbot起動時にメッセージを送信しています。
そうです、configファイルで記載したlogのIDを持つチャンネルです。

.send("xxxxx")のダブルクォーテーションの中を変えると送信するメッセージの内容も変えられます。

(20) // bot起動処理

ここは実際にbotを起動する処理と、エラー時にエラーログを出力する所です。
とはいえ、基本的にエラーが出ることはないはず。

大事なのは「async」ですかね。これは非同期処理と言って、「いつ終わるかわからない処理を取り扱うよ」っていう宣言です。
通常「いつ終わるかわからない処理」は終わるのを待たないのですが、asyncの範囲内で「await」を使うことで非同期処理の終了を待つことができます。
スラッシュコマンドを色々作っていくと絶対必要になると思いますので、頭の片隅にでも入れておいて下さい。

肝心の起動処理本体は client.login(config.token); の部分です。
極論、この行だけでもbotは起動します。

botを起動する

ソースコードが書けたら、画面上部にある「Run」ボタンを押しましょう!
エラーがなければbotがオンラインになり、指定したチャンネルにメッセージが送信されるはずです。

もし動かない場合は落ち着いてコンソールに表示されているであろうエラーログを見ましょう。
英語が見たくない人は英語のこと好きになるチャンスです。やったね。

手入力でソースを書いてるなら、スペルミスとかしてないですか?

コピペしてる場合でも、discord.jsのバージョンが変わって同じ書き方では動作しなくなってたりするかも。
その時は公式が出してる移行ガイドを見て、変更点を確認するのがオススメです。
下記リンクはv13からv14になった時のやつ。

Updating from v13 to v14 | discord.js Guide

もし何もエラーっぽいのが出ないけどログインされないなら、単純にReplitの調子が悪いだけの可能性もあります。 自分も開発用で今でもReplitを使う時が結構あるんですが、半日くらい開発してたら1回くらい調子悪い時に遭遇します。無料なので仕方ないね。

まだ内容としては全然難しいことやってないので、頑張って起動しましょう!
次回はスラッシュコマンドを作っていきます。