Discord.jsボットのイベント/コマンドハンドラーをコーディングするにはどうすればよいですか?

4
slothiful 2019-06-11 17:00.

Discord.jsライブラリを使用してNode.jsでDiscordボットの作成を開始しました。ただし、すべてのコードは単一のインデックスファイルに含まれています。

コマンドとイベントをそれぞれ別々のファイルに整理し、必要に応じて実行するにはどうすればよいですか?

1 answers

10
slothiful 2019-06-12 00:00.

ボットのコードを整理するための優れたクリーンな方法は、イベントハンドラーとコマンドハンドラーを使用することです。


簡単な言葉で。

クライアントと残りのコードを初期化するために、小さなインデックスファイルから始めます。イベントハンドラーは、各イベントのファイルを保持し、イベントが発行されたときにそれらを呼び出します。次に、クライアントの中にmessageイベント、あなたが長く避けることができifチェーンおよびswitch/case意図したコマンドのファイルからコードを実行することにより、完全に。


モジュールとは何ですか?

理解する必要のある基本的なNode.js構造はですmodule

[モジュールとは]アプリケーションに含めたい関数のセットです。

w3schools.comから引用。

したがって、モジュールは、コードの断片を含むきちんとテープで留められたボックスと考えてください。パッケージをどこかに持っていき、開けて、開梱することができます。JavaScriptの用語では、プログラムの別の場所にモジュールを要求し、その中に含まれるコードを利用できます。モジュールには、コード全体のさまざまな場所で使用する必要のある変数、クラス、関数などを含めることができます。


モジュールとエクスポートの操作。

モジュールとは何かがわかったので、モジュールの操作方法を理解する必要があります。

ハンドラーの目的のためexportsに、moduleオブジェクトのプロパティのみを使用します。require()モジュールに使用することにより、module.exportsが返されます。次の設定を検討してください。

単一のエクスポート。

Question.js

class Question {
  constructor(author, details) {
    this.author = author;
    this.details = details;
    this.answers = [];
  }
}

module.exports = Question;

newQuestion.js

const Question = require('./Question.js');

const myQuestion = new Question('me', 'How to code event/command handlers?');

ではQuestion.js、新しいクラスQuestionが作成され、に割り当てられmodule.exportsます。ときに、Question.js中に必要とされnewQuestion.jsQuestionエクスポートされたクラスとして宣言されています。いつものように使えます。

複数のエクスポート。

たとえば、複数のクラスをエクスポートする必要がある場合は...

Posts.js

class Question {...}
class Answer {...}

module.exports = { Question, Answer };

// Alternatively...
// module.exports.Question = Question;
// module.exports.Answer = Answer;

newQuestion.js

const { Question } = require('./Posts.js');

const myQuestion = new Question(...);

このように、module.exportsは、作成されたクラスを含むオブジェクトとして定義されます。この手段require()のことができますので、代わりにオブジェクトを返しますdestructureオブジェクトから必要なクラスを。


イベントハンドラーの作成。

まず、イベント用のフォルダーを作成し、各イベント用のファイルを作成する必要があります。イベントの名前に従ってファイルに名前を付けます。たとえば、クライアントのmessageイベントの場合、ファイルにはmessage.js。という名前を付ける必要があります。

イベントファイルの設定。

モジュールについて現在知っていることを実装して、イベントファイルをコーディングできます。例えば...

message.js

module.exports = (client, message) => {
  // This code will be executed when
  // the 'message' event is emitted.
};

ハンドラーの設定。

実際のハンドラーを作成するには、イベントをロードする関数に次のコードを配置します。

const requireAll = require('require-all');   // Don't forget to install!

const files = requireAll({                   // Require all the files within your
  dirname: `${__dirname}/events`, // event directory which have a name filter: /^(?!-)(.+)\.js$/                  // ending in '.js' NOT starting
});                                          // with '-' (a way to disable files).

client.removeAllListeners();                 // Prevent duplicate listeners on reload.
                                             // CAUTION: THIS REMOVES LISTENERS
                                             // ATTACHED BY DISCORD.JS!

for (const name in files) {                  // Iterate through the files object
  const event = files[name];                 // and attach listeners to each
                                             // event, passing 'client' as the
  client.on(name, event.bind(null, client)); // first parameter, and the rest
                                             // of the expected parameters
  console.log(`Event loaded: ${name}`);      // afterwards. Then, log the
}                                            // successful load to the console.

これで、クライアントがファイルのあるイベントの1つを発行すると、その中のコードが実行されます。


コマンドハンドラーの作成。

イベントハンドラーの場合と同様に、コマンド用に個別のフォルダーを作成することから始め、個々のコマンドごとにファイルを作成する必要があります。

コマンドファイルの設定。

1つの関数だけをエクスポートする代わりに、「実行」関数構成オブジェクトをエクスポートできます。

help.js

module.exports.run = async (client, message, args) => {
  // This code will be executed to
  // run the 'help' command.
};

module.exports.config = {
  name: 'help',
  aliases: ['h'] // Even if you don't want an alias, leave this as an array.
};

ハンドラーの設定。

イベントハンドラーと同様に、このコードを関数に配置してコマンドをロードします...

const requireAll = require('require-all');   // Using the same npm module...

const files = requireAll({                   // Require all the files within your
  dirname: `${__dirname}/commands`,          // command directory which have a name
  filter: /^(?!-)(.+)\.js$/ // ending in '.js' NOT starting }); // with '-' (a way to disable files). client.commands = new Map(); // Create new Maps for the corresponding client.aliases = new Map(); // command names/commands, and aliases. for (const name in files) { // Iterate through the files object const cmd = files[name]; // and set up the 'commands' and // 'aliases' Maps. Then, log the client.commands.set(cmd.config.name, cmd); // successful load to the console. for (const a of cmd.config.aliases) client.aliases.set(a, cmd.config.name); console.log(`Command loaded: ${cmd.config.name}`);
}

クライアントのmessageイベントでは、次のコードを使用してコマンドを実行できます...

const prefix = '!'; // Example
const [cmd, ...args] = message.content.trim().slice(prefix.length).split(/\s+/g);

const command = client.commands.get(cmd) || client.commands.get(client.aliases.get(cmd));
if (command) {
  command.run(client, message, args);
  console.log(`Executing ${command.config.name} command for ${message.author.tag}.`);
}

よくある質問。

イベント/コマンドを通過する必要があるデータベース関連またはその他の変数がある場合はどうなりますか?

イベントの場合、event.on(...)に続いて、に変数を渡すことができますclient。次に、実際のイベントでは、関数の後にそのパラメーターを含める必要がありますclient

コマンドの場合、messageイベントで変数を呼び出すときに、変数をrun関数に渡すことができます。繰り返しますが、関数には、適切に配置されたパラメーターを含める必要があります。

サブフォルダー内にコマンド/イベントを入れたい場合はどうすればよいですか?

この回答をチェックして、再帰的に検索してください。

これらのハンドラーをリロードコマンドに使用するにはどうすればよいですか?

それらのコードを関数内に配置した場合、それらの関数を呼び出す「リロード」コマンドを設定して、イベントとコマンドを再度ロードできます。


関連リソース。

  • Node.jsドキュメント
  • MDNドキュメント
  • W3Schoolsチュートリアル
  • require-all パッケージ
  • Discord.jsドキュメント

編集...

  • client.removeAllListeners()クライアントのインスタンス化から発生したリスナーを含め、クライアントに接続されているすべてのリスナーを削除ます。これにより、音声接続関連のエラー、特にVoice connection not established within 15 secondsスローされる可能性があります。この問題を防ぐには、すべてのリスナー関数を追跡し、を使用してそれぞれを個別に削除しclient.removeListener(listener)ます。

Related questions

MORE COOL STUFF

「水曜日」シーズン1の中心には大きなミステリーがあります

「水曜日」シーズン1の中心には大きなミステリーがあります

Netflixの「水曜日」は、典型的な10代のドラマ以上のものであり、実際、シーズン1にはその中心に大きなミステリーがあります.

ボディーランゲージの専門家は、州訪問中にカミラ・パーカー・ボウルズが輝くことを可能にした微妙なケイト・ミドルトンの動きを指摘しています

ボディーランゲージの専門家は、州訪問中にカミラ・パーカー・ボウルズが輝くことを可能にした微妙なケイト・ミドルトンの動きを指摘しています

ケイト・ミドルトンは、州の夕食会と州の訪問中にカミラ・パーカー・ボウルズからスポットライトを奪いたくなかった、と専門家は言う.

一部のファンがハリー・スタイルズとオリビア・ワイルドの「非常に友好的な」休憩が永続的であることを望んでいる理由

一部のファンがハリー・スタイルズとオリビア・ワイルドの「非常に友好的な」休憩が永続的であることを望んでいる理由

一部のファンが、オリビア・ワイルドが彼女とハリー・スタイルズとの間の「難しい」が「非常に友好的」な分割を恒久的にすることを望んでいる理由を見つけてください.

エリザベス女王の死後、ケイト・ミドルトンはまだ「非常に困難な時期」を過ごしている、と王室の専門家が明らかにする 

エリザベス女王の死後、ケイト・ミドルトンはまだ「非常に困難な時期」を過ごしている、と王室の専門家が明らかにする 

エリザベス女王の死後、ケイト・ミドルトンが舞台裏で「非常に困難な時期」を過ごしていたと伝えられている理由を調べてください.

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セント ヘレナ島のジェイコブズ ラダーは 699 段の真っ直ぐ上る階段で、頂上に到達すると証明書が発行されるほどの難易度です。

The Secrets of Airline Travel Quiz

The Secrets of Airline Travel Quiz

Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

パンデミックは終わったかもしれないが、Covid-19 は終わっていない

パンデミックは終わったかもしれないが、Covid-19 は終わっていない

2021 年 6 月 8 日にニューヨーク市で開催された covid-19 パンデミックで亡くなった人々の命を偲び、祝うために、ネーミング ザ ロスト メモリアルズが主催するイベントと行進の最中に、グリーンウッド墓地の正門から記念碑がぶら下がっています。週末、ジョー・バイデン大統領は、covid-19 パンデミックの終息を宣言しました。これは、過去 2 年以上にわたり、公の場でそうするための長い列の中で最新のものです。

デビル・イン・オハイオの予告編は、エミリー・デシャネルもオハイオにいることを明らかにしています

デビル・イン・オハイオの予告編は、エミリー・デシャネルもオハイオにいることを明らかにしています

オハイオ州のエミリー・デシャネル みんな早く来て、ボーンズが帰ってきた!まあ、ショーボーンズではなく、彼女を演じた俳優. エミリー・デシャネルに最後に会ってからしばらく経ちました.Emily Deschanel は、長期にわたるプロシージャルな Bones の Temperance “Bones” Brennan としてよく知られています。

ドナルド・トランプはFBIのマー・ア・ラーゴ襲撃映像をリリースする予定ですか?

ドナルド・トランプはFBIのマー・ア・ラーゴ襲撃映像をリリースする予定ですか?

どうやら、ドナルド・トランプに近い人々は、今月初めにFBIによって家宅捜索された彼のMar-a-Lago財産からの映像を公開するよう彼に勧めています. 前大統領はテープを公開するかどうかを確認していませんが、息子はフォックス・ニュースにそうなるだろうと語った.

Andor は、他の Star Wars ショーから大きな距離を置きます。

Andor は、他の Star Wars ショーから大きな距離を置きます。

アンドールの一場面。数十年前、ジョージ・ルーカスがスター・ウォーズのテレビ番組を制作するのを妨げた主な理由は、お金でした。

ケイト・ミドルトンとウィリアム王子は、彼らが子供たちと行っているスパイをテーマにした活動を共有しています

ケイト・ミドルトンとウィリアム王子は、彼らが子供たちと行っているスパイをテーマにした活動を共有しています

ケイト・ミドルトンとウィリアム王子は、子供向けのパズルの本の序文を書き、ジョージ王子、シャーロット王女、ルイ王子と一緒にテキストを読むと述べた.

事故で押しつぶされたスイカは、動物を喜ばせ水分補給するために野生生物保護団体に寄付されました

事故で押しつぶされたスイカは、動物を喜ばせ水分補給するために野生生物保護団体に寄付されました

Yak's Produce は、数十個のつぶれたメロンを野生動物のリハビリ専門家であるレスリー グリーンと彼女のルイジアナ州の救助施設で暮らす 42 匹の動物に寄付しました。

デミ・ロヴァートは、新しいミュージシャンのボーイフレンドと「幸せで健康的な関係」にあります: ソース

デミ・ロヴァートは、新しいミュージシャンのボーイフレンドと「幸せで健康的な関係」にあります: ソース

8 枚目のスタジオ アルバムのリリースに向けて準備を進めているデミ ロヴァートは、「スーパー グレート ガイ」と付き合っている、と情報筋は PEOPLE に確認しています。

Plathville の Kim と Olivia Plath が数年ぶりに言葉を交わすことへようこそ

Plathville の Kim と Olivia Plath が数年ぶりに言葉を交わすことへようこそ

イーサン プラスの誕生日のお祝いは、TLC のウェルカム トゥ プラスビルのシーズン 4 のフィナーレで、戦争中の母親のキム プラスと妻のオリビア プラスを結びつけました。

仕事の生産性を高める 8 つのシンプルなホーム オフィスのセットアップのアイデア

仕事の生産性を高める 8 つのシンプルなホーム オフィスのセットアップのアイデア

ホームオフィスのセットアップ術を極めよう!AppExert の開発者は、家族全員が一緒にいる場合でも、在宅勤務の技術を習得しています。祖父や曽祖父が共同家族で暮らしていた頃の記憶がよみがえりました。

2022 年、私たちのデジタル ライフはどこで終わり、「リアル ライフ」はどこから始まるのでしょうか?

20 年前のタイムトラベラーでさえ、日常生活におけるデジタルおよびインターネットベースのサービスの重要性に驚くことでしょう。MySpace、eBay、Napster などのプラットフォームは、高速化に焦点を合わせた世界がどのようなものになるかを示してくれました。

ニューロマーケティングの秘密科学

ニューロマーケティングの秘密科学

マーケティング担当者が人間の欲望を操作するために使用する、最先端の (気味が悪いと言う人もいます) メソッドを探ります。カートをいっぱいにして 3 桁の領収書を持って店を出る前に、ほんの数点の商品を買いに行ったことはありませんか? あなたは一人じゃない。

地理情報システムの日: GIS 開発者として学ぶべき最高の技術スタック

地理情報システムの日: GIS 開発者として学ぶべき最高の技術スタック

私たちが住んでいる世界を確実に理解するには、データが必要です。ただし、空間参照がない場合、このデータは地理的コンテキストがないと役に立たなくなる可能性があります。

Language