cerus / jda-slash-commands

Slash commands (and message components) for JDA
GNU General Public License v3.0
15 stars 3 forks source link

Interaction failed #12

Closed Dei-Ma closed 3 years ago

Dei-Ma commented 3 years ago

Hi,

I managed ti get my first Slash Command and it works pretty good.

But I get en error in Discord that says "Interaction failed".

Maybe it has something to do with this

Interaction tokens are valid for 15 minutes and can be used to send followup messages but you must send an initial response within 3 seconds of receiving the event. If the 3 second deadline is exceeded, the token will be invalidated.

But I could not find out how to make an initial repond.

Can someone help me?

regards

cerus commented 3 years ago

Hello! You need to at least acknowledge the interaction using acknowledge() if you're not directly responding to it.

Dei-Ma commented 3 years ago

Hi, this leads me to my next Problem:

the acknowledge fails with this error.

Caused by: de.cerus.jdasc.http.DiscordApiException: Expected one of [200, 204] but got 400

cerus commented 3 years ago

Huh, that's strange. Do the commands register without problems? Does your bot have the right permissions?

Dei-Ma commented 3 years ago

Yes they do, but deleting a command does not work neither.

i guess that all permissions are ok.

Maybe it has to do with this

Using your favorite security library, you must validate the request each time you receive an interaction. If the signature fails validation, respond with a 401 error code. Here's a couple code examples:

cerus commented 3 years ago

Using your favorite security library, you must validate the request each time you receive an interaction. If the signature fails validation, respond with a 401 error code. Here's a couple code examples:

That's only if you use webhooks to receive interactions. This library hooks into the Discord bot so no webhook is needed.

Take a look at this reply from another issue, did you check this box when you generated an invite link for your bot?

Dei-Ma commented 3 years ago

My invitation Link ends like this: &permissions=3959946304&scope=bot%20applications.commands

cerus commented 3 years ago

interaction.acknowledge() will return you a CompletableFuture, you could check using whenComplete() if the throwable is an instance of DiscordApiException, and if it is one you can cast the throwable and print out the response body. This would help to diagnose the issue.

Dei-Ma commented 3 years ago

Do you mean this?:

Response{protocol=h2, code=400, message=, url=https://discord.com/api/v8/interactions/..........

cerus commented 3 years ago

Yes, but the response should have a method that returns you only the body that was sent. That's all we need

Dei-Ma commented 3 years ago

response.body.toString() -> okhttp3.internal.http.RealResponseBody@37df9063

sorry I am very new to this

I kept trying....

may this be the response body?: {"redirect":false,"successful":false}

cerus commented 3 years ago

response.body().string() should work

Dei-Ma commented 3 years ago

{"code": 50035, "errors": {"type": {"_errors": [{"code": "BASE_TYPE_CHOICES", "message": "Value must be one of (1, 4, 5, 6, 7)."}]}}, "message": "Invalid Form Body"}

cerus commented 3 years ago

Hm, looks like you chose an invalid option for one of your sub commands (I think). Would you mind sharing your code where you register the commands?

Dei-Ma commented 3 years ago
public static void initCommands(JDA jda) throws ExecutionException, InterruptedException {
        JDASlashCommands.initialize(jda, Config.BOT_TOKEN, Config.APPLICATION_ID);

        List<ApplicationCommandOptionChoice> choices = new ArrayList<>();
        choices.add( new ApplicationCommandOptionChoice("Liga 1", "1"));
        choices.add( new ApplicationCommandOptionChoice("Liga 2", "2"));

        JDASlashCommands.submitGuildCommand(new CommandBuilder()
                .name("standings") // Set command name to '/test-command'
                .desc("Shows the standings of a league")
                .option(new ApplicationCommandOption(ApplicationCommandOptionType.STRING,
                        "league",
                        "Specify your league",
                        true,
                        choices,
                        null))
                .option(new ApplicationCommandOption(ApplicationCommandOptionType.INTEGER,
                        "group",
                        "Specify your group league",
                        false))
                .build(), channelId ,new ApplicationCommandListener() {

            @Override
            public void onInteraction(final Interaction interaction) {
                try {
                    interaction.acknowledge(true).get();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
                try {
                    switch (interaction.getCommandName().toLowerCase()) {
                        case "standings": cmd.standings(interaction, false);break;
                        default: cmd.unknownCommand(interaction);break;
                    }
                } catch (Exception e) {
                    interaction.getChannel().sendMessage(e.getMessage()).queue();
                    return;
                }
                String result =  interaction.getCommandName() + " " + interaction.getOption("league").getValue();
                System.out.println(result);
            }});
    }
cerus commented 3 years ago

Looks like you can't use the STRING option directly on commands. It looks like you will have to register a sub command to use that option.

Dei-Ma commented 3 years ago

I changed it. But first of all, it does not look like that what I want anymore, and second, it has the same Problem:

{"code": 50035, "errors": {"type": {"_errors": [{"code": "BASE_TYPE_CHOICES", "message": "Value must be one of (1, 4, 5, 6, 7)."}]}}, "message": "Invalid Form Body"}

Dei-Ma commented 3 years ago

I tried to delete my first Test Commands.

List<ApplicationCommand> existingCommands = JDASlashCommands.getGlobalCommands().get(); for(ApplicationCommand currentCommand : existingCommands){ JDASlashCommands.deleteGlobalCommand(currentCommand.getId()); }

This is not working to. Maybe it has a same kind of reason.

In this case I get

Caused by: de.cerus.jdasc.http.DiscordApiException: Expected one of [204] but got 401 {"message": "401: Unauthorized", "code": 0}

In your code I find this:

public CompletableFuture<Response> deleteGlobalCommand(final long commandId) { return this.execute(new Request.Builder() .url(String.format("https://discord.com/api/v8/applications/%s/commands/%d", this.applicationId, commandId)) .delete() .build(), 204); }

public CompletableFuture<Response> deleteGuildCommand(final long commandId, final long guildId) { return this.execute(new Request.Builder() .url(String.format("https://discord.com/api/v8/applications/%s/guilds/%d/commands/%d", this.applicationId, guildId, commandId)) .delete() .addHeader("Authorization", "Bot " + this.botToken) .build(), 204); }

is the Header with Authorization not needed in case of deleting a GlobalCommand?

Dei-Ma commented 3 years ago

I changed it. But first of all, it does not look like that what I want anymore, and second, it has the same Problem:

{"code": 50035, "errors": {"type": {"_errors": [{"code": "BASE_TYPE_CHOICES", "message": "Value must be one of (1, 4, 5, 6, 7)."}]}}, "message": "Invalid Form Body"}

Back to this Problem.

if I Change from interaction.acknowledge(true) to interaction.acknowledge(false)

I get this Response

{"message": "Unknown interaction", "code": 10062}

and this error Cannot invoke "de.cerus.jdasc.interaction.response.InteractionResponseOption.getValue()" because the return value of "de.cerus.jdasc.interaction.Interaction.getOption(String)" is null

Caused by: de.cerus.jdasc.http.DiscordApiException: Expected one of [200, 204] but got 404

I found out that the InteractionResponseType ACKNOWLEDGE has the Value 2, so this response makes sense. 2 Is not valid.

{"code": 50035, "errors": {"type": {"_errors": [{"code": "BASE_TYPE_CHOICES", "message": "Value must be one of (1, 4, 5, 6, 7)."}]}}, "message": "Invalid Form Body"}

https://discord.com/developers/docs/interactions/slash-commands#interaction-response

Dei-Ma commented 3 years ago

Ok After I added okhttp to my Gradle some of the Problems are fixed. implementation group: 'com.squareup.okhttp3', name: 'okhttp', version: '4.9.1'

But others are still there.

  1. Delete Global Commands does not work. I Guess because of the missing .addHeader("Authorization", "Bot " + this.botToken
  2. interaction.acknowledge(true). I Guess because the InteractionResponseType ACKNOWLEDGE has the Value 2, which seems to be not valid.
  3. interaction.respond(true, "Test Respond"). I Guess because the InteractionResponseType CHANNEL_MESSAGE has the Value 3, which seems to be not valid.

On the other Hand. This ist working

  1. interaction.respond(false, "Test Respond"). Works fine
  2. interaction.acknowledge(true). Works but leads in to an endless loading state for the interaction
cerus commented 3 years ago

Works but leads in to an endless loading state for the interaction

What exactly do you mean by that?

Looks like Discord completely changed the slash commands api, great. I'll have to make a few changes to get everything working again.

Dei-Ma commented 3 years ago

image

The bot ist still thinking......

cerus commented 3 years ago

I'll wait for #11 to get ready and then I'll update the library. Danke Discord.

cerus commented 3 years ago

Alright, updating the lib was less work than I expected. Everything should work as expected now. Updates are in develop

Dei-Ma commented 3 years ago

I tried to delete my first Test Commands.

List<ApplicationCommand> existingCommands = JDASlashCommands.getGlobalCommands().get(); for(ApplicationCommand currentCommand : existingCommands){ JDASlashCommands.deleteGlobalCommand(currentCommand.getId()); }

This is not working to. Maybe it has a same kind of reason.

In this case I get

Caused by: de.cerus.jdasc.http.DiscordApiException: Expected one of [204] but got 401 {"message": "401: Unauthorized", "code": 0}

In your code I find this:

public CompletableFuture<Response> deleteGlobalCommand(final long commandId) { return this.execute(new Request.Builder() .url(String.format("https://discord.com/api/v8/applications/%s/commands/%d", this.applicationId, commandId)) .delete() .build(), 204); }

public CompletableFuture<Response> deleteGuildCommand(final long commandId, final long guildId) { return this.execute(new Request.Builder() .url(String.format("https://discord.com/api/v8/applications/%s/guilds/%d/commands/%d", this.applicationId, guildId, commandId)) .delete() .addHeader("Authorization", "Bot " + this.botToken) .build(), 204); }

is the Header with Authorization not needed in case of deleting a GlobalCommand?

Didn't you fix this, or am I wrong?

cerus commented 3 years ago

It's fixed in the dev branch

Dei-Ma commented 3 years ago

ok I found it. Thank you! I am looking forward to the release until then my workarounds work ;)

cerus commented 3 years ago

Alright, great! I'm going to close this issue then. Feel free to open another one if you have any further questions.

Dei-Ma commented 3 years ago

P.S. I send you a friend request on discord