Skip to content

Releases: zekroTJA/ken

v0.20.1

25 Apr 21:18
Compare
Choose a tag to compare
  • Update compatibility to discordgo v0.28.1 [#20]

v0.20.0

22 Jul 10:36
Compare
Choose a tag to compare

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

Update

go get -v -u github.com/zekrotja/ken@v0.20.0

v0.19.0

21 Jul 10:29
Compare
Choose a tag to compare

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

31 Dec 09:40
Compare
Choose a tag to compare

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

01 Sep 09:35
Compare
Choose a tag to compare
  • The User method of the Context interface is now also available for the
    ComponentContext interface.
  • You can now set a Condition on the ComponentBuilder 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

31 Aug 10:46
82f6b5b
Compare
Choose a tag to compare

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

17 Aug 18:06
Compare
Choose a tag to compare

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 method Session which returns the wrapped Discordgo Session
    instance.
  • The Build method of the ComponentBuilder now also returns a function to remove components
    from the message as well as unregister the handlers.
  • The Unregister method of the ComponentHandler now can take one or more customIds to
    be unregistered at once.

Update

go get -v -u github.com/zekrotja/ken@v0.16.0

v0.15.0

16 Aug 20:59
Compare
Choose a tag to compare

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

16 Aug 20:58
Compare
Choose a tag to compare

Full Changelog: v0.14.0...v0.14.1

v0.14.0

16 Aug 20:58
Compare
Choose a tag to compare

Full Changelog: v0.13.0...v0.14.0