zekroTJA / ken

A cutting edge (haha), object-oriented and highly modular application command handler for Discordgo.
https://pkg.go.dev/github.com/zekrotja/ken
MIT License
44 stars 7 forks source link

Use ken with discordgo.InteractionCreate #15

Open andrebrito16 opened 1 year ago

andrebrito16 commented 1 year ago

Hi, I'm starting to use Ken on a new project. But when I register a listener to discordgo.InteractionCreate events I got panic: MessageComponentData called on interaction of type ApplicationCommand. There is any way to continue using ken and also listen to InteractionCreate?

zekroTJA commented 1 year ago

Hey, can you show me a specific example of your code? That would be very helpful for me so that I can understand the context about what's happening. :)

andrebrito16 commented 1 year ago

Yeah, of course.

First my bot listens to all channels on server (messageCreate Discord API event), when an user sends a specific message, the bot reply with a missage that contains a component with two buttons.

I've created a new listener to InteractionCreate event, my idea is handle when user clicks on those buttons, that have specific customId, for example button1-78905473894 or button2-1890894839. But the discordgo.InteractionCreate listener is in conflict with ken, that I'm using to slash commands.

If I remove listener to new interactions, ken works perfectly.

Here is some code:

func (l *ListenerInteractionCreate) Handler(s *discordgo.Session, e *discordgo.InteractionCreate) {

    fmt.Println(e.Interaction)
       // On this example I'm just checking if user clicked on a button, but later will check if custom id matches with database record.
    if e.MessageComponentData().ComponentType == 2 {
        err := s.InteractionRespond(e.Interaction, &discordgo.InteractionResponse{
            Type: discordgo.InteractionResponseChannelMessageWithSource,
            Data: &discordgo.InteractionResponseData{
                Embeds: []*discordgo.MessageEmbed{
                    {
                        Title: "Hello World!",
                    },
                },
            },
        })

        if err != nil {
            fmt.Println(err)
        }
    }

}
zekroTJA commented 1 year ago

Ah yo, that's unfortunate. I actually didn't tested this use case before. You can actually use ken to handle message components for you even on messages sent by your bot without using ken's framework using ken.Components().Add(). But of course, there should not be a conflict between self registered handlers and ken's registered handlers and I'll look into that as soon as possible, Thank you very much for bringing up that issue. :)

andrebrito16 commented 1 year ago

Thank you very much. I'm just starting with Go and Ken, can you send a small example of how can I implement message handle using ken, please?

zekroTJA commented 1 year ago

Currently, I have no direct example for that in the examples of the package, but here you can see how I am using it to attach and handle message components for a role selection command in my Discord bot.

https://github.com/zekroTJA/shinpuru/blob/master/internal/slashcommands/roleselect.go#L149

andrebrito16 commented 1 year ago

Thanks! I'll try to do this. One last question, please... In this example you created a slash command that will send components buttons, there is any way to don't create new command, just listen to button interactions?

andrebrito16 commented 1 year ago

Hi, I'm facing an issue when implementing solution that you suggested. If I restart the bot, I lose handler for buttons that I appended to message using ken.Components().Add(). Is there any way to listening interaction on old messages after bot restart?

zekroTJA commented 1 year ago

@andrebrito16 Sorry for the very late response.

Yeah, it is possible to re-attach event handlers on an already sent messasge.

I am actually using this in the role select feature of my own discord bot. Here, in the ready event listener, I am looking for roleselect entries in my database and then attaching them to the messages stored in the database.

It works because the Build of the ComponentBuilder simply uses ChannelMessageEditComplex which overwrites the message components set to the message. So it effectively removes the old components and replaces them with the new ones while also creating new handlers in ken to listen to the interaction events.

The code example is a bit complicated to be honest, but I hope it helps your problem (if it is still relevant). If you have problems, feel free to hit me up again. :)