記事内に広告が含まれています

サルでもわかる Discord Botの作り方⑤ ~メッセージに反応するBot~

テクノロジー
この記事は約8分で読めます。

こんにちは!今日は、サルでもわかる Discord Botの作り方のパート⑤です。今回は、Discordサーバーのテキストチャンネルに特定の文字が含まれるメッセージが送信されたらBotが反応するBotを作っていこうと思います。

まだ、パート1・2・3・4を見ていない場合は先に1・2・3・4を見ることをオススメします!

サルでもわかる Discord Botの作り方

サルでもわかる Discord Botの作り方をゼロから説明していくシリーズです。

スポンサーリンク

どのようなBotになるのか

まず最初に、今回作るメッセージに反応するBotがどのようなものか先に説明しておきます。

ユーザーが送信したメッセージに特定の文字が含まれていたら、Botがメッセージを送信するというBotになります。

Discord Developer Portalでメッセージインテントを有効にする

まずインテントを設定していきます。「前回のパート④で有効にしたよ。」とと思う方もいるかもしれませんが、前回はサーバーメンバーインテントという種類のインテントを有効にしただけです。

今回は、メッセージの読み取りインテントが必要ですので、そちらを有効化します。

以前と同様に、Discord Developer PortalからBotタブを開きます。

Discord Developer Portal — API Docs for Bots and Developers
Integrate your service with Discord — whether it's a bot or a game or whatever your wildest imagination can come up with...

そして、”Privileged Gateway Intents“の中にある“MESSAGE CONTENT INTENT”にチェックを入れます。

チェックが入れれたら、いつも通りに「Save Changes」を押して保存します。
これで、Discordでのインテントの有効化は完了です。

コードを書いていく

では、さっそくコードを書いていきます。ファイルは以前と同様で問題ありません。

前回のパート④では、サーバーに参加すると通知するBotでした。今回のコードでは、そちらのコードは取り扱いません。

今回使うコード全体は以下になります。コピーしてペーストしてもいいですし、練習がてら入力するのもいいでしょう。

const { Client, Events, GatewayIntentBits } = require('discord.js');

const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers, GatewayIntentBits.MessageContent, GatewayIntentBits.GuildMessages] });

client.once(Events.ClientReady, c => {
	console.log(`Ready! (${c.user.tag})`); // 起動した時に"Ready!"とBotの名前をコンソールに出力する
});

client.on(Events.MessageCreate, message => {
    if (message.author.bot) return; // Botには反応しないようにする
    if (message.guild.id !== "利用するサーバーId") return; // 指定のサーバー以外では動作しないようにする
    if (message.content.includes("Discord")) {
        message.channel.send("こんにちは!Discord Botです。");
    }
});

client.login("前回メモしたToken");

※利用するサーバーId、前回メモしたTokenについては各自で書き換えをしてください

以前作ったBotと合体する場合

また、以前作ったサーバーに参加したらメッセージを送信するBotと合体させる場合は、インテントと以前作ったguildMemberAddイベントの下に今回のMessageCreateイベントを追加するだけです。

const { Client, Events, GatewayIntentBits } = require('discord.js');

const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers, GatewayIntentBits.MessageContent, GatewayIntentBits.GuildMessages] });

client.once(Events.ClientReady, c => {
	console.log(`Ready! (${c.user.tag})`); // 起動した時に"Ready!"とBotの名前をコンソールに出力する
});

client.on(Events.guildMemberAdd, member => {
    if (member.guild.id !== "利用するサーバーId") return; // 指定のサーバー以外では動作しないようにする
    member.guild.channels.cache.get("送信するチャンネルId").send(`${member.user}が参加しました!`);
});

client.on(Events.MessageCreate, message => {
    if (message.author.bot) return; // Botには反応しないようにする
    if (message.guild.id !== "利用するサーバーId") return; // 指定のサーバー以外では動作しないようにする
    if (message.content.includes("Discord")) {
        message.channel.send("こんにちは!Discord Botです。");
    }
});

client.login("前回メモしたToken");

実際に動かしてみよう

では、動かしてみます。動かし方は前回の記事を見てください。

Botを起動させると、コンソールにReady! ([Botの名前]) と出てきたら正常に起動ができています。
試しにDiscord と送信してみます。正しく動作すれば、Botからメッセージが返されます。

コードの解説

では、コードの解説を簡単に行っていきます。
1行目~8行目と17行目は以前と同様ですので、省略します。

9行目~15行目は、以下のようになっています。

まず、メッセージが送信された際にはMessageCreateイベント発火します。

client.on(Events.MessageCreate, message => {
    if (message.author.bot) return; // Botには反応しないようにする
    if (message.guild.id !== "利用するサーバーId") return; // 指定のサーバー以外では動作しないようにする
    if (message.content.includes("Discord")) {
        message.channel.send("こんにちは!Discord Botです。");
    }
});

まず最初にコメントにあるようにBotを反応しないようにしています

if (message.author.bot) return; // Botには反応しないようにする

反応しないようにしている理由は、無限ループを防ぐためです。もし、この1行がなかった場合は、Botが送ったメッセージに反応してイベントが発火し送信するというループが発生します。

そのためifでBotかどうかを判断してBotであれば無視するという処理を追加する必要があります。

次にサーバーの判断です。こちらの処理は正直あってもなくてもどちらでもいいです。
一つのサーバーでのみ動かしたい場合は、こちらを入れておいて問題ないと思います。逆に、導入サーバーすべてで動作させたい場合は、こちらの判断を消す必要があります。

if (message.guild.id !== "利用するサーバーId") return; // 指定のサーバー以外では動作しないようにする

次にメッセージが含まれているかを判断するコードです。JavaScriptには、文字列に特定の文字が含まれているかを判断する際にincludesメソッドを利用します。

if (message.content.includes("Discord"))

今回は、”Discord“という文字列が含まれているかを判断したいので上記のようなコードになりました。
別に”Discord“という文字列が完全一致でのみ反応するとしたい場合は以下のようなコードにすれば動作させることができます。

if (message.content === "Discord")

次にメッセージを送信するコードです。こちらは、メッセージを送信したチャンネルにメッセージを送信するというコードになります。sendメソッドを利用しています。

message.channel.send("こんにちは!Discord Botです。");

これとは別に、送信されたメッセージに返信するというメソッドもあります。それは、replyメソッドです。
以下のようなコードに変更すると、画像のようにメッセージに返信する形でBotがメッセージを送信します。

message.reply("こんにちは!Discord Botです。これは、replyメソッドを利用した場合です。");

最後に

これでメッセージに特定のワードが含まれていた場合に、反応するBotが作ることが出来るようになりました。

次のパートでは、簡単なコマンドを作ってじゃけんBotを作ります。次回から内容がやや難しくなります。

最後までお読みいただきありがとうございました!

サルでもわかる Discord Botシリーズ記事一覧

サルでもわかる Discord Botの作り方

サルでもわかる Discord Botの作り方をゼロから説明していくシリーズです。

困ったことがあったら、、
この記事に関して、困ったことがありましたらなりかくんのブログ公式Discordサーバーにて質問をすることが可能です!
ぜひ入ってみましょう!

Discordサーバー「Narikakun Network」に参加しよう!
このサーバーでは、プログラミングの質問などや気になったことなどなんでも話し合える雑談Discordです。 | 980人のメンバー

コメント

  1. ちょっとした興味で一般アカウントでもこのような自動化された動作を行えるのか気になったので、botのトークンを自分のアカウントのトークンに書き換えたところ、全く動作しませんでした。原因はなんでしょうか。

    • 一般アカウントを自動化することは利用規約違反のため、通常は出来ません。
      また、紹介することも私は出来ません。

  2. ここまで拝見させていただきました。

    ReferenceError: Events is not definedとエラーがでてしまいます。

    どのように対処するといいですか?

    • 1行目の、const { Client, Events, GatewayIntentBits } = require('discord.js');が正しいか確認してみてください。
      Eventというのが定義されていないというエラーです。

  3. Botに二つのメッセージに反応しないようにする方法はありますか?
    例えば反応するワードに「こんにちは」と「さようなら」があり、
    ユーザーが「こんにちはさようなら」と言った場合に
    Botが二つの言葉に同時に反応してしまいます。

    • 記事をお読みいただきありがとうございます。
      以下のようにすれば、if elseという文を使えば条件に1つ当てはまればその処理をするということが出来ます。

      if (message.content.includes("こんにちは")) {
      message.channel.send("こんにちは!Discord Botです。");
      } else if (message.content.includes("こんばんは")) {
      message.channel.send("こんばんは!Discord Botです。");
      }

  4. 勉強になりました!
    質問ですが、返信したい特定のワードが複数ある場合はどのように入力したらいいでしょうか。
    例えば、「おはよう」「こんにちは」「こんばんは」のどれが入力されても、「こんにちは!Discord Botです!」と返信させたいです。

    • 記事をお読みいただきありがとうございます。
      以下のようにすれば、複数の条件を作れます。

      if (message.content.includes("おはよう") || message.content.includes("こんにちは") || message.content.includes("こんばんは")) {
      message.channel.send("こんにちは!Discord Botです。");
      }

      是非参考にしてみてください。

  5. 本当に分かりやすい説明で助かっています。
    質問なのですが、ランダムなメッセージで返信させることはできますか??

    • ありがとうございます。ランダムにするにはmessage.channel.send();の部分を以下のように変更するとランダムにできます。

      let messageList = ["メッセージ1", "メッセージ2", "メッセージ3"];
      message.channel.send(messageList[Math.floor(Math.random()*messageList.length)]);

      • 特定のチャンネルにランダムなメッセージを送信する方法はありますか?

      • ありがとうございます。ランダムにするにはmessage.channel.send();の部分を以下のように変更するとランダムにできます。

        let messageList = ["メッセージ1", "メッセージ2", "メッセージ3"];
        message.channel.send(messageList[Math.floor(Math.random()*messageList.length)]);

        また、特定のチャンネルの場合は以下のようにチャンネルIDを指定してあげることで特定のチャンネルに送信させるようにすることが出来ます。
        message.guild.channels.cache.get("チャンネルID").send()

タイトルとURLをコピーしました