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

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは3日間一緒に夫と一緒に寝て、25年経ってもまだ夫と結婚しています

ケイト・ブランシェットは、夫に会ったとき、典型的な交際のアドバイスに逆らいました。

マイケルシーンが非営利の俳優である理由

マイケルシーンが非営利の俳優である理由

マイケルシーンは非営利の俳優ですが、それは正確にはどういう意味ですか?

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

ホールマークスターのコリンエッグレスフィールドがRomaDramaLiveでスリル満点のファンと出会う![エクスクルーシブ]

特徴的なスターのコリン・エッグレスフィールドは、RomaDrama Liveでのスリル満点のファンとの出会いについて料理しました!加えて、大会での彼のINSPIREプログラム。

「たどりつけば」をオンラインでストリーミングできない理由

「たどりつけば」をオンラインでストリーミングできない理由

ノーザンエクスポージャーが90年代の最も人気のある番組の1つになった理由を確認するには、Blu-rayまたはDVDプレーヤーをほこりで払う必要があります。

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

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

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

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖:アクセスは簡単ではありませんが、ハイキングする価値があります

ドミニカのボイリング湖は、世界で2番目に大きいボイリング湖です。そこにたどり着くまでのトレッキングは大変で長いですが、努力する価値は十分にあります。

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

私たちの水をきれいに保つのを助けるためにあなたの髪を寄付してください

サロンからのヘアトリミングや個人的な寄付は、油流出を吸収して環境を保護するのに役立つマットとして再利用できます。

ホワイトハウスの最も記憶に残る結婚式を見てください

ホワイトハウスの最も記憶に残る結婚式を見てください

過去200年以上の間にホワイトハウスで結婚したのはほんの数人です。彼らは誰でしたか、そしてそこで結婚式を獲得するために何が必要ですか?

グッドジョブ、ESPN

グッドジョブ、ESPN

今日のホワイトハウスの記者会見で、報道官のサラ・ハッカビー・サンダースは、スポーツセンターのホストであるイェメル・ヒルのドナルド・トランプに関する最近のツイートについてコメントするよう求められ、大統領と彼の政策を白人至上主義者として説明した。ヒルは彼女のつぶやきのためにESPNによって公に叱責されました。

アマゾンからのこのレミントンツールセールで髪を整える、スタイルを整える、乾かす、または取り除く

アマゾンからのこのレミントンツールセールで髪を整える、スタイルを整える、乾かす、または取り除く

基本的に頭のあらゆる部分から髪の毛を整えたり、ブロードライしたり、まっすぐにしたり、脱毛したりする必要がある場合は、このレミントンゴールドボックスが最適です。今日だけ、Amazonは、すでに人気のあるShortcut Pro Self-HaircutKitやPearlPro Ceramic Flat Ironのように、グルーミングをはるかに簡単にするヘアツールをマークダウンしています。

カナダの元桂冠詩人が、史上最高の文化の盗用でトゥパックとマヤアンジェロウから盗んだ

カナダの元桂冠詩人が、史上最高の文化の盗用でトゥパックとマヤアンジェロウから盗んだ

トゥパックシャクール(ティムモーゼンフェルダー/ゲッティイメージズ); マヤアンジェロウ(マーティンゴッドウィン/ゲッティイメージズ)移動、テイラースウィフト。ケンドールとカイリーは、必要な数の座席を持っています。

テスラは、ハリケーンイルマによる避難を容易にするために、フロリダでの車両の範囲を拡大しています

テスラは、ハリケーンイルマによる避難を容易にするために、フロリダでの車両の範囲を拡大しています

写真:Tesla Motorsフロリダに住んでいて、Tesla Model S、Model X 60、またはModel 60Dを使用している場合、車の自律性は50 km(約30マイル)高くなります。これは失敗ではなく、ハリケーンイルマによる避難作業を容易にするために会社自身が命じた自治権の一時的な延長です。

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya Wishes Boyfriend Tom Holland Happy Birthday with Cuddly Photo: He 'Makes Me the Happiest'

Zendaya shared a sweet photo in honor of boyfriend Tom Holland's 26th birthday Wednesday

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

小さな女性:脳卒中を患った後に病院から解放されたアトランタのジューシーな赤ちゃん:「まだ癒し」

シーレン「Ms.JuicyBaby」ピアソンは、先月脳卒中で入院した後、「もう一度たくさんのことをする方法を学ばなければならない」ため、言語療法を受けていることを明らかにしました。

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

エマストーンは彼女のクリフサイドマリブビーチハウスを420万ドルでリストアップしています—中を見てください!

オスカー受賞者の世紀半ばの家には、3つのベッドルーム、2つのバス、オーシャンフロントの景色があります。

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、母乳育児の経験の中で、彼女は「本当に、本当に落ち込んでいる」と言います

ジーニー・メイ・ジェンキンスは、生後4か月の娘、モナコに母乳育児をしていると語った。

投資ノート:Bioscout AU$300万シード

投資ノート:Bioscout AU$300万シード

Bioscoutは、農家を運転席に置くという使命を負っています。Artesian(GrainInnovate)やUniseedと並んで、最新のシードラウンドでチームを支援できることをうれしく思います。問題真菌症による重大な作物の損失は、農民にとって試練であることが証明されています。

リトルマーケットリサーチ1| 2022年のクイックグリンプス遠隔医療市場

リトルマーケットリサーチ1| 2022年のクイックグリンプス遠隔医療市場

遠隔医療は、パンデミック後の時代では新しいものではなく、時代遅れの分野でもありません。しかし、業界を詳しく見ると、需要と供給の強力な持続可能性と、米国で絶え間ない革命となる強力な潜在的成長曲線を示しています。

スタートアップ資金調達環境:タイのスタートアップエコシステムの次は何ですか?

スタートアップ資金調達環境:タイのスタートアップエコシステムの次は何ですか?

2021年は、世界的なベンチャーキャピタル(VC)の資金調達にとって記録的な年でした。DealStreetAsiaによると、東南アジアも例外ではなく、この地域では年間で記録的な25の新しいユニコーンが採掘されました。

ムーアの法則を超えて

ムーアの法則を超えて

計算に対する私たちの欲求とムーアの法則が提供できるものとの間には、指数関数的に増大するギャップがあります。私たちの文明は計算に基づいています—建築と想像力の現在の限界を超える技術を見つけなければなりません。

Language