Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot use buttons in version: 7c8e8ad #8

Closed
devan-mysterio opened this issue Jul 16, 2023 · 17 comments
Closed

Cannot use buttons in version: 7c8e8ad #8

devan-mysterio opened this issue Jul 16, 2023 · 17 comments

Comments

@devan-mysterio
Copy link

I'm using discord jda library version 5.0.0-beta.12

java.lang.IllegalArgumentException: Unknown button expBooster
at dev.ruffrick.jda.commands.event.ButtonInteractionListener.onEvent(ButtonInteractionListener.kt:21)
at dev.ruffrick.jda.kotlinx.event.SuspendEventManager$handle$1.invokeSuspend(SuspendEventManager.kt:38)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1426)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)

@flerouwu
Copy link
Contributor

flerouwu commented Jul 20, 2023

Hey @devan-mysterio! I assume you've tried to follow the instructions in the README? If so, they seem to be outdated.

The way that this library generates button IDs are as follows:

"$commandName.${button.id.ifEmpty { function.name.lowercase() }}"

Please give this a try. Note that the commandName is the name parameter that was passed to @Command (on your class), otherwise it defaults to the class name, removing the suffix Command.

Here's an example:
Class Name: HelloWorldCommand
Button Function Name: coolButton
Button ID: HelloWorld.coolButton


If you are still unable to fix the issue, please provide some code samples.

I'll update the README in a pull request, and make an example bot using this library once PR #9 has been merged. I got no motivation for this lmao

@devan-mysterio
Copy link
Author

Wait, I'm confused where do I put that code at?

@flerouwu
Copy link
Contributor

flerouwu commented Jul 20, 2023

That code I provided is simply how the library generates IDs, you aren't meant to put it anywhere.

You just gotta update your button IDs when adding them to your message (in the action row).

e.g.

@Command
fun mood(event: SlashCommandEvent) {
    event.reply("How are you?").addActionRow(
        success(id = "Mood.good", label = "Good"), // here
        danger(id = "Mood.bad", label = "Bad") // and here, notice the `id = "Mood.bad"`
    ).queue()
}

@devan-mysterio
Copy link
Author

And then the function would be just fun good(...)
fun bad(...)

@flerouwu
Copy link
Contributor

Correct! It should work as intended now.

@devan-mysterio
Copy link
Author

I'll definitely give it a try when I wake up

@devan-mysterio
Copy link
Author

but let me ask what if they're in events? how would that work?

@ruffrick
Copy link
Owner

What do you mean by "if they're in events"?

@devan-mysterio
Copy link
Author

What do you mean by "if they're in events"?

They error when using buttons in modals i made a modal and it errors when i check the buttoninteractionevent saying unknown button blah blah

@ruffrick
Copy link
Owner

ruffrick commented Jul 24, 2023

Can you share the code where you create the button and the declaration of the handler function?

@devan-mysterio
Copy link
Author

Don't mind it, still needs cleaned up but eh

class StaffAppListener : SuspendEventListener() {
override suspend fun onEvent(event: GenericEvent) {
if (event is ModalInteractionEvent) {
if (event.modalId == "staffapp") {

            val builder =
                StringBuilder().appendLine("**Minecraft Username**: \n${event.getValue("username")?.asString}").appendLine()
                    .appendLine("**Age**: \n${event.getValue("age")?.asString}").appendLine()
                    .appendLine("**Why do you want to be staff on Flash-Networks**: \n${event.getValue("staff")?.asString}")
                    .appendLine()
                    .appendLine("**Do you have any experience working as a staff member**: \n${event.getValue("experience")?.asString}")
                    .appendLine().appendLine(
                        "**What do you have to bring to Flash-Networks that other people that are applying don't**: \n${
                            event.getValue(
                                "differences"
                            )?.asString
                        }"
                    )

            event.guild?.getChannelById(
                MessageChannel::class.java, 1133058777000722472L
            )?.sendMessage(
                SuccessAlert(
                    "Incoming Staff Application From: ${event.user.name}\nJoined: ${
                        event.member?.timeJoined?.format(
                            DateTimeFormatter.RFC_1123_DATE_TIME
                        ).toString()
                    }", builder.toString()
                ).asMessage(
                    event.user
                )
            )?.addContent(
                "**Warning** Ensure that whenever an application comes in you check the user's punishment records and look at how long they've been with us on Flash-Networks."
            )?.addActionRow(success("accepted", "Accept Application"), danger("denied", "Deny Application"))
                ?.complete()

            event.reply("Sent Application to Staff Management").setEphemeral(true).queue()
            return
        }
    }
    if (event is ButtonInteractionEvent) {
        if (event.button.id == "accepted") {
            event.message.editMessageComponents().queue()
            event.message.reply("Application has been Accepted!").queue()
            return
        }
        if (event.button.id == "denied") {
            event.message.editMessageComponents().queue()
            event.message.reply("Application has been Denied!").queue()
            return
        }
    }
}

}

@ruffrick
Copy link
Owner

The library automatically registers an event listener for ButtonInteractionEvents. This listeners expects button IDs to be formatted as commandName.buttonId and throws an exception if it can't find a handler function matching that ID.

The issue here is you creating 'regular' buttons which are not bound to any command/handler function:

success("accepted", "Accept Application"), danger("denied", "Deny Application")

(Within a command this would look something like Btn("accepted", "Accept Application").success().)

When clicked, the event listener (obviously) can't find handlers for the IDs accepted and denied, hence the exception.
I only accounted for buttons that map to some handler function in this library, which might be a bit of an oversight. That being said, the events should still be handled correctly, since the event manager in the background just prints the exception and hands the event to the next event listener, assuming you've registered your StaffAppListener.

Hope that helps.

@devan-mysterio
Copy link
Author

but the buttons aren't added when i use the cmd

@command
class StaffApp : SlashCommand() {

@Command(description = "The Staff Application System.")
fun staffapp(event: SlashCommandInteractionEvent) {
    val minecraftName: TextInput = TextInput.create("username", "Minecraft Username:", TextInputStyle.SHORT)
        .setPlaceholder("Your in-game name goes here!").setMinLength(3).setMaxLength(16).setRequired(true).build()

    val ageInput: TextInput =
        TextInput.create("age", "Age:", TextInputStyle.SHORT).setPlaceholder("You input your age here.")
            .setMinLength(0).setMaxLength(2).setRequired(true).build()

    val staffQuestion: TextInput =
        TextInput.create("staff", "Why do you want to be staff:", TextInputStyle.PARAGRAPH)
            .setPlaceholder("Explain why you want to be staff here.").setMinLength(30).setMaxLength(1000)
            .setRequired(true).build()

    val expQuestion: TextInput = TextInput.create(
        "experience", "Do you have any experience:", TextInputStyle.PARAGRAPH
    ).setPlaceholder("Explain what experience you do have.").setMinLength(30).setMaxLength(1000).setRequired(true)
        .build()

    val differences: TextInput = TextInput.create(
        "differences",
        "What do you have to bring that others don't:",
        TextInputStyle.PARAGRAPH
    ).setPlaceholder("Explain here.").setMinLength(30).setMaxLength(1000).setRequired(true).build()

    val modal: Modal = Modal.create("staffapp", "Staff Application").addActionRows(
        ActionRow.of(minecraftName),
        ActionRow.of(ageInput),
        ActionRow.of(staffQuestion),
        ActionRow.of(expQuestion),
        ActionRow.of(differences)
    ).build()

    event.replyModal(modal).queue()
}

}

class StaffAppListener : SuspendEventListener() {
override suspend fun onEvent(event: GenericEvent) {
if (event is ModalInteractionEvent) {
if (event.modalId == "staffapp") {

            val builder =
                StringBuilder().appendLine("**Minecraft Username**: \n${event.getValue("username")?.asString}").appendLine()
                    .appendLine("**Age**: \n${event.getValue("age")?.asString}").appendLine()
                    .appendLine("**Why do you want to be staff on Flash-Networks**: \n${event.getValue("staff")?.asString}")
                    .appendLine()
                    .appendLine("**Do you have any experience working as a staff member**: \n${event.getValue("experience")?.asString}")
                    .appendLine().appendLine(
                        "**What do you have to bring to Flash-Networks that other people that are applying don't**: \n${
                            event.getValue(
                                "differences"
                            )?.asString
                        }"
                    )

            event.guild?.getChannelById(
                MessageChannel::class.java, 1133058777000722472L
            )?.sendMessage(
                SuccessAlert(
                    "Incoming Staff Application From: ${event.user.name}\nJoined: ${
                        event.member?.timeJoined?.format(
                            DateTimeFormatter.RFC_1123_DATE_TIME
                        ).toString()
                    }", builder.toString()
                ).asMessage(
                    event.user
                )
            )?.addContent(
                "**Warning** Ensure that whenever an application comes in you check the user's punishment records and look at how long they've been with us on Flash-Networks."
            )?.addActionRow(success("accepted", "Accept Application"), danger("denied", "Deny Application"))
                ?.complete()

            event.reply("Sent Application to Staff Management").setEphemeral(true).queue()
            return
        }
    }
    if (event is ButtonInteractionEvent) {
        if (event.button.id == "accepted") {
            event.message.editMessageComponents().queue()
            event.message.reply("Application has been Accepted!").queue()
            return
        }
        if (event.button.id == "denied") {
            event.message.editMessageComponents().queue()
            event.message.reply("Application has been Denied!").queue()
            return
        }
    }
}

}

@ruffrick
Copy link
Owner

ruffrick commented Jul 25, 2023

You are not adding any buttons in your command, you're simply replying with a modal. The custom listener you wrote only handles ModalInteractionEvents and ButtonInteractionEvents. The only place you add buttons is when handling the modal. Look at your command and listener code and check if they are doing what you think they do.

This is not an issue with this library, I'll be closing this issue.

@devan-mysterio
Copy link
Author

Well it errors saying unknown button https://i.imgur.com/QssSu2n.png

@flerouwu
Copy link
Contributor

It's still erroring because this library also handles ButtonInteractionEvents. You'll need to have the @Button() annotation on a function in your command class, otherwise it'll keep erroring.

e.g.

@Command
class StaffApp : SlashCommand() {
    // other code...

    @Button
    fun denied(event: ButtonClickEvent) {
        // code to run when the button is clicked with the id of `StaffApp.denied`
    }
}

@ruffrick I feel like this error could be silently ignored, rather than throwing an error. Maybe just a println()?

@devan-mysterio
Copy link
Author

I mean but even with events how would I do so?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants