質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.33%

  • Java

    14441questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Java、Discord4Jを用いたBotでのメッセージ送信

受付中

回答 0

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 349

yogurt

score 4

 前提・実現したいこと

Discord4Jを使ってBotを作成し、特定の発言に対してbotが返答を行うだけの簡単なプログラムを書いています。

メッセージを返信する機能を実装中に以下のエラーメッセージが発生しました。

 発生している問題・エラーメッセージ

Message could not be sent with error: 
sx.blah.discord.util.DiscordException: Attempt to send message before shard is ready!
    at sx.blah.discord.api.IShard.checkReady(IShard.java:73)
    at sx.blah.discord.handle.impl.obj.Channel.sendMessage(Channel.java:459)
    at sx.blah.discord.handle.impl.obj.Channel.sendMessage(Channel.java:449)
    at sx.blah.discord.handle.impl.obj.Channel.sendMessage(Channel.java:439)
    at main.com.ensemblebox.iberisbot.BotUtils.lambda$sendMessage$0(BotUtils.java:30)
    at sx.blah.discord.util.RequestBuffer.lambda$request$1(RequestBuffer.java:84)
    at sx.blah.discord.util.RequestBuffer$RequestFuture$RequestCallable.call(RequestBuffer.java:286)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at sx.blah.discord.util.RequestBuffer$RequestFuture.run(RequestBuffer.java:259)
    at sx.blah.discord.util.RequestBuffer$RequestFuture.access$200(RequestBuffer.java:162)
    at sx.blah.discord.util.RequestBuffer.lambda$request$0(RequestBuffer.java:50)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1135)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at java.base/java.lang.Thread.run(Thread.java:844)

 該当のソースコード

/*Main.java*/
package main.com.marumaru.bot;

import sx.blah.discord.api.IDiscordClient;

public class Main {

    public static void main(String[] args) {

        if(args.length != 1){
            System.out.println("Please enter the bots token as the first argument e.g java -jar thisjar.jar tokenhere");
            return;
        }

        IDiscordClient client = BotUtils.getBuiltDiscordClient(args[0]);

        /*
        // Commented out as you don't really want duplicate listeners unless you're intentionally writing your code
        // like that.
        // Register a listener via the IListener interface
        cli.getDispatcher().registerListener(new IListener<MessageReceivedEvent>() {
            public void handle(MessageReceivedEvent event) {
                if(event.getMessage().getContent().startsWith(BotUtils.BOT_PREFIX + "test"))
                    BotUtils.sendMessage(event.getChannel(), "I am sending a message from an IListener listener");
            }
        });
        */

        // Register a listener via the EventSubscriber annotation which allows for organisation and delegation of events
        client.getDispatcher().registerListener(new MyEvents());

        // Only login after all events are registered otherwise some may be missed.
        client.login();
    }

}
/*BotUtils.java*/
package main.com.marumaru.bot;

import sx.blah.discord.api.ClientBuilder;
import sx.blah.discord.api.IDiscordClient;
import sx.blah.discord.handle.obj.IChannel;
import sx.blah.discord.util.DiscordException;
import sx.blah.discord.util.RequestBuffer;

class BotUtils {

    // Constants for use throughout the bot
    static String BOT_PREFIX = "i!";

    // Handles the creation and getting of a IDiscordClient object for a token
    static IDiscordClient getBuiltDiscordClient(String token) {

        // The ClientBuilder object is where you will attach your params for configuring the instance of your bot.
        // Such as withToken, setDaemon etc
        return new ClientBuilder()
                .withToken(token)
                .build();

    }

    // Helper functions to make certain aspects of the bot easier to use.
    static void sendMessage(IChannel channel, String message){
        // This might look weird but it'll be explained in another page.
        RequestBuffer.request(() -> {
            try{
                channel.sendMessage(message);/* 問題の30行目 */
            } catch (DiscordException e){
                System.err.println("Message could not be sent with error: ");
                e.printStackTrace();
            }
        });

        /*
        // The below example is written to demonstrate sending a message if you want to catch the RLE for logging purposes
        RequestBuffer.request(() -> {
            try{
                channel.sendMessage(message);
            } catch (RateLimitException e){
                System.out.println("Do some logging");
                throw e;
            }
        });
        */

    }
}
/* MyEvents.java*/
package main.com.marumaru.bot;

import sx.blah.discord.api.events.EventSubscriber;
import sx.blah.discord.handle.impl.events.ReadyEvent;
import sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent;

public class MyEvents {

    @EventSubscriber
    public void onReady(ReadyEvent event) {
        System.out.println("Bot is Stand by ready.");
    }

    @EventSubscriber
    public void onMessageReceived(MessageReceivedEvent event) {
        System.out.println(event.getMessage().getContent());
        if(event.getMessage().getContent().startsWith(BotUtils.BOT_PREFIX + "test"))
            BotUtils.sendMessage(event.getChannel(), "I am sending a message from an EventSubscriber listener");
    }

}

 試したこと

Readyする前にメッセージの送信を行っているからエラーを吐いているのだと思いますが…

参照したQiitaの記事ではログインが完了するとReadyEventsが実行されるとありましたので、client.isLoggedIn()やclient.isReady()などで状態を確認しましたが、ログインはtrueが帰るのに対し、isReadyはfalseを返し続けてしまい。良く分かっていない状態です…

何卒みなさんのお力をお貸ししていただけないでしょうか…?

 補足情報(FW/ツールのバージョンなど)

Intellij IDEA
JavaSE10
ソースコード自体はこれと全く同じです。
https://discord4j.readthedocs.io/en/latest/Basic-bot/

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.33%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • Java

    14441questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。