OnyxPrograms13
OnyxPrograms13

Reputation: 17

Make JDA Discord Bot send a random image

I'm currently working on a bot for my Discord server and I was wondering how to implement various image commands (for example, !cat, !meme) to make the bot send a random image each time the command is called.

Almost every bot I've seen has a feature like that but for some reason I can't seem to find a working way to do this in JDA. And any JDA example I found was either outdated or it simply didn't work, so I really hope someone can give me a hand here.

Here's a (very basic) example I already did, but the problem is that the pictures don't randomize with each call and just stay the same until I restart discord

public void sendCatImage() {
        EmbedBuilder result= new EmbedBuilder();
        result.setTitle("Here's a cat!");
        result.setImage("http://thecatapi.com/api/images/get?format=src&type=png");
        event.getChannel().sendMessage(result.build()).queue();
    }

I'm using JDA Version 4.1.0_100, if it helps

Any help will be greatly appreciated!

Upvotes: 0

Views: 2621

Answers (1)

Minn
Minn

Reputation: 6134

Discord will cache the image based on the URL. You can append a random number as a query to prevent this:

public String randomize(String url) {
    ThreadLocalRandom random = ThreadLocalRandom.current();
    return url + "&" + random.nextInt() + "=" + random.nextInt();
}

...
result.setImage(randomize(url));
...

Furthermore, you can avoid discord updating the image by also uploading it alongside the embed. For that you first need to download the image and then upload it:

// Use same HTTP client that jda uses
OkHttpClient http = jda.getHttpClient();
// Make an HTTP request to download the image
Request request = new Request.Builder().url(imageUrl).build();
Response response = http.newCall(request).execute();
try {
    InputStream body = response.body().byteStream();
    result.setImage("attachment://image.png"); // Use same file name from attachment
    channel.sendMessage(result.build())
           .addFile(body, "image.png") // Specify file name as "image.png" for embed (this must be the same, its a reference which attachment belongs to which image in the embed)
           .queue(m -> response.close(), error -> { // Send message and close response when done
               response.close();
               RestAction.getDefaultFailure().accept(error);
           });
} catch (Throwable ex) {
// Something happened, close response just in case
    response.close();
// Rethrow the throwable
    if (ex instanceof Error) throw (Error) ex;
    else throw (RuntimeException) ex;
}

Upvotes: 1

Related Questions