Releases: zekroTJA/ken
v0.20.1
v0.20.0
Sub Command Support [#14]
Finally, you can now register and use sub command groups!
Simply add a sub command option to your command in the Options
implementation of your command.
Example:
func (c *SubsCommand) Options() []*discordgo.ApplicationCommandOption {
return []*discordgo.ApplicationCommandOption{
{
Type: discordgo.ApplicationCommandOptionSubCommandGroup,
Name: "group",
Description: "Some sub command gorup",
Options: []*discordgo.ApplicationCommandOption{
// ...
},
},
}
}
Now, you can add a SubCommandGroup
handler to your HandleSubCommands
method to register sub commands in the group.
Example:
func (c *SubsCommand) Run(ctx ken.Context) (err error) {
err = ctx.HandleSubCommands(
ken.SubCommandGroup{"group", []ken.CommandHandler{
ken.SubCommandHandler{"one", c.one},
ken.SubCommandHandler{"two", c.two},
}},
)
return
}
The full example can be found in examples/subcommandgroups.
Minor Changes
-
The
AutocompleteContext
now implementsObjectMap
so you can pass dependencies down the line just like with command contexts. -
AutocompleteContext
now has a new helper functionGetInputAny
which takes multiple option names and returns the first match found in the event data. -
FoolowUpMessage
has now been added accordingly toRespondMessage
, which was added inv0.19.0
.
Update
go get -v -u github.com/zekrotja/ken@v0.20.0
v0.19.0
Warning
This update contains breaking changes!
In order to make the code of ken more type-safe, I am now using safepool instead of sync.Pool
which uses generic type parameters for ensuring type safety. Therefore, the minimum required module version has been bumped to go1.18
. You might need to upgrade your project accordingly to be able to use ken.
Autocomplete Support [#18]
Command option autocomplete
support has now been added to ken.
Simply enable autocomplete on your command option by setting the Autocomplete
property to true
.
Example:
func (c *TestCommand) Options() []*discordgo.ApplicationCommandOption {
return []*discordgo.ApplicationCommandOption{
{
Type: discordgo.ApplicationCommandOptionString,
Name: "language",
Required: true,
Description: "Choose a programming language.",
Autocomplete: true,
},
}
}
Now, you simply need to implement the AutocompleteCommand
on your command.
Example:
func (c *TestCommand) Autocomplete(ctx *ken.AutocompleteContext) ([]*discordgo.ApplicationCommandOptionChoice, error) {
input, ok := ctx.GetInput("language")
if !ok {
return nil, nil
}
choises := make([]*discordgo.ApplicationCommandOptionChoice, 0, len(programmingLanguages))
input = strings.ToLower(input)
for _, lang := range programmingLanguages {
if strings.HasPrefix(lang[1], input) {
choises = append(choises, &discordgo.ApplicationCommandOptionChoice{
Name: lang[0],
Value: lang[0],
})
}
}
return choises, nil
}
The full example can be found in examples/autocomplete.
To properly handle errors occuring during autocomplete handling, a new command handler hook OnEventError
has been added to the Options
. It will be called every time a non-command related user event error occurs.
RespondMessage
A new respond method has been added to the ContentResponder
called RespondMessage
. It simply takes a message as parameter and responds with a simple message content containing the passed message.
Update
go get -v -u github.com/zekrotja/ken@v0.19.0
v0.18.0
Warning
This update contains breaking changes!
In order to support the attachment of message components to a flollow-up message on creation [see #13],
the methods ContextResponder#FollowUp
, ContextResponder#FollowUpEmbed
and ContextResponder#FollowUpError
now return a *FollowUpMessageBuilder
, which can be used to attach components and handlers before the
follow-up message is sent.
Example
b := ctx.FollowUpEmbed(&discordgo.MessageEmbed{
Description: "Hello",
})
b.AddComponents(func(cb *ken.ComponentBuilder) {
cb.Add(
discordgo.Button{
CustomID: "button-1",
Label: "Absolutely fantastic!",
},
func(ctx ken.ComponentContext) bool {
ctx.RespondEmbed(&discordgo.MessageEmbed{
Description: fmt.Sprintf("Responded to %s", ctx.GetData().CustomID),
})
return true
}, true,
)
})
fum := b.Send()
A full example can be found in examples/components/commands/test.go.
Update
go get -v -u github.com/zekrotja/ken@v0.18.0
v0.17.1
- The
User
method of theContext
interface is now also available for the
ComponentContext
interface. - You can now set a
Condition
on theComponentBuilder
which will be
checked before the registered component handlers are executed.
See component example for further details.
Update
go get -v -u github.com/zekrotja/ken@v0.17.1
v0.17.0
Warning: This update of ken introduces a lot of API changes. Please update carefully.
Modals [#10]
You can now open modals in the component handler function. The ComponentContext
now has a
method OpenModal
which can be used to open a modal in Discord on interaction with the
message component.
// ComponentContext gives access to the underlying
// MessageComponentInteractionData and gives the
// ability to open a Modal afterwards.
type ComponentContext interface {
ContextResponder
// GetData returns the underlying
// MessageComponentInteractionData.
GetData() discordgo.MessageComponentInteractionData
// OpenModal opens a new modal with the given
// title, content and components built with the
// passed build function. A channel is returned
// which will receive a ModalContext when the user
// has interacted with the modal.
OpenModal(
title string,
content string,
build func(b ComponentAssembler),
) (<-chan ModalContext, error)
}
Please take a look at the modals example to see further details on
how to use modals with ken.
Breaking API Changes
A lot of breaking changes have been introduced to use more interfaces instead of struct
instances which allows better testability using mocks.
The Run
method of the Command
interface now is getting passed a Context
interface instead
of a reference to an instance of Ctx
. This also means, if you are directly accessing Session
or Event
for example from the Ctx
instance, you need to change it to accessing these via the
available getter methods (GetSession
or GetEvent
for example).
The SubCommandHandler
now also passes an interface SubCommandContext
to
the Run
instead of a reference to an instance of SubCommandCtx
.
The access to CtxResponder
, SubCommandCtx
, ComponentCtx
and ModalCtx
are now private
for a cleaner API.
Update
go get -v -u github.com/zekrotja/ken@v0.17.0
v0.16.0
Changes
- Fix a bug where the wrapped handler would not be registered in the build wrapper.
- The
ComponentHandlerFunc
now returns a boolean to indicate success of execution. - The
Ken
instance now has a methodSession
which returns the wrapped DiscordgoSession
instance. - The
Build
method of theComponentBuilder
now also returns a function to remove components
from the message as well as unregister the handlers. - The
Unregister
method of theComponentHandler
now can take one or morecustomId
s to
be unregistered at once.
Update
go get -v -u github.com/zekrotja/ken@v0.16.0
v0.15.0
Changes
Message Component Implementation [#8]
You can now attach message components to messages and register interaction handlers
using the ComponentHandler.
It provides a low level implementation to add components to messages and handlers directly
to the handler registry as well as a more sophisticated
ComponentBuilder to simplify
the attachment and handling of message components.
Example
err = fum.AddComponents().
AddActionsRow(func(b ken.ComponentAssembler) {
b.Add(discordgo.Button{
CustomID: "button-1",
Label: "Absolutely fantastic!",
}, func(ctx ken.ComponentContext) {
ctx.RespondEmbed(&discordgo.MessageEmbed{
Description: fmt.Sprintf("Responded to %s", ctx.GetData().CustomID),
})
}, !clearAll)
b.Add(discordgo.Button{
CustomID: "button-2",
Style: discordgo.DangerButton,
Label: "Not so well",
}, func(ctx ken.ComponentContext) {
ctx.RespondEmbed(&discordgo.MessageEmbed{
Description: fmt.Sprintf("Responded to %s", ctx.GetData().CustomID),
})
}, !clearAll)
}, clearAll).
Build()
You can find the complete example in examples/components.
Guild Scopes [#11]
You can now scope commands to specific guilds by implementing the
GuildScopedCommand interface
in you command. Then, the command will only be registered for the guild returned by
the Guild
method of the command.
Example
type Guild1Command struct{}
var (
_ ken.SlashCommand = (*Guild1Command)(nil)
_ ken.GuildScopedCommand = (*Guild1Command)(nil)
)
func (c *Guild1Command) Name() string {
return "guild1"
}
func (c *Guild1Command) Guild() string {
return "362162947738566657"
}
You can find the complete example in examples/guildscoped.
Update
go get -v -u github.com/zekrotja/ken@v0.15.0
v0.14.1
Full Changelog: v0.14.0...v0.14.1
v0.14.0
Full Changelog: v0.13.0...v0.14.0