Skip to content

Releases: zekroTJA/ken

v0.13.0

17 Mar 15:48
5acec66
Compare
Choose a tag to compare

A new interface has been added called Context which defines the available methods on Ctx and SubCommandCtx. Therefore, additional methods to access public fields in Ctx has been added.

v0.12.1

17 Feb 09:39
1bce276
Compare
Choose a tag to compare

Added Ephemeral flag to Ctx. When this is set to true, all subsequent responses and follow-up messages sent with this context will carry the Ephemeral Message Flag. This will make the command response only visible to the user who invokes the command.

Also added an interface ResponsePolicyCommand which defines a method retuning a response policy for the given command.

This ResponsePolicy object is also subject to be extended in further versions.

// ResponsePolicyCommand defines a command which
// provides a ResponsePolicy.
type ResponsePolicyCommand interface {
	ResponsePolicy() ResponsePolicy
}

You can now set the EphemeralCommand implementation as anonymous field in your command structure to make all responses of this command ephemeral.

type MyCommand struct {
	EphemeralCommand
}

This is what the EphemeralCommand implementaiton looks like.

// EphemeralCommand can be added to your command
// to make all command responses ephemeral.
// This means, that all responses to the command
// from the bot will only be received by the sender
// of the command.
type EphemeralCommand struct{}

var _ ResponsePolicyCommand = (*EphemeralCommand)(nil)

func (EphemeralCommand) ResponsePolicy() ResponsePolicy {
	return ResponsePolicy{
		Ephemeral: true,
	}
}

Acknowledgements

Thanks a lot to @zordem who brought it to my attention that this message flag exists.

v0.11.1

20 Nov 14:04
Compare
Choose a tag to compare

⚠️ Attention: This version introduces breaking changes!
If you are using these interface type checks shown below, you might need to replace ken.Command with ken.SlashCommand for appropriate type checking.

var _ ken.SlashCommand = (*TestCommand)(nil)

This version allows to also handle user and message commands using the same middleware pipeline as used for slash commands. Therefore, 3 new interfaces have been introduced to define slash, user and message commands.

slashcommand.go

// SlashCommand defines a callable slash command.
type SlashCommand interface {
	Command

	// Version returns the commands semantic version.
	Version() string

	// Options returns an array of application
	// command options.
	Options() []*discordgo.ApplicationCommandOption
}

usercommand.go

// UserCommand defines a callable user command.
type UserCommand interface {
	Command

	// TypeUser is used to differenciate between
	// UserCommand and MessageCommand which have
	// the same structure otherwise.
	//
	// This method must only be implemented and
	// will never be called by ken, so it can be
	// completely empty.
	TypeUser()
}

messagecommand.go

// MessageCommand defines a callable message command.
type MessageCommand interface {
	Command

	// TypeMessage is used to differenciate between
	// UserCommand and MessageCommand which have
	// the same structure otherwise.
	//
	// This method must only be implemented and
	// will never be called by ken, so it can be
	// completely empty.
	TypeMessage()
}

As you can see, all three of them extend the Command interface.

command.go

type Command interface {
	// Name returns the unique name of the command.
	Name() string

	// Description returns a brief text which concisely
	// describes the commands purpose.
	Description() string

	// Run is called on command invokation getting
	// passed the invocation context.
	//
	// When something goes wrong during command
	// execution, you can return an error which is
	// then handled by Ken's OnCommandError handler.
	Run(ctx *Ctx) (err error)
}

func toApplicationCommand(c Command) *discordgo.ApplicationCommand {
	switch cm := c.(type) {
	case UserCommand:
		return &discordgo.ApplicationCommand{
			Name: cm.Name(),
			Type: discordgo.UserApplicationCommand,
		}
	case MessageCommand:
		return &discordgo.ApplicationCommand{
			Name: cm.Name(),
			Type: discordgo.MessageApplicationCommand,
		}
	case SlashCommand:
		return &discordgo.ApplicationCommand{
			Name:        cm.Name(),
			Type:        discordgo.ChatApplicationCommand,
			Description: cm.Description(),
			Version:     cm.Version(),
			Options:     cm.Options(),
		}
	default:
		panic(fmt.Sprintf("Command type not implemented for command: %s", cm.Name()))
	}
}

This allows to register user and message commands using the same Ken#RegisterCommand endpoint as before.

To differentiate between user and message commands - because they effectively have the same API structure - there are the two shallow methods TypeUser() and TypeMessage(). These have absolutely no programmatically purpose and are only there for type differentiation. I know, this is kinda janky but otherwise this approach would hardly be possible this way at the moment.

This also allows the re-usage of existing code from slash commands in user commands. To view a "real world" example, please take a look at the implementation of the user slash command and userinfo user command implementation in shinpuru.

v0.10.4

17 Nov 23:02
Compare
Choose a tag to compare

Full Changelog: v0.10.2...v0.10.4

v0.10.2

30 Oct 09:59
Compare
Choose a tag to compare

Full Changelog: v0.10.1...v0.10.2

v0.10.1

23 Oct 10:27
Compare
Choose a tag to compare

Full Changelog: v0.10.0...v0.10.1

v0.10.0

13 Oct 09:41
Compare
Choose a tag to compare

Full Changelog: v0.9.0...v0.10.0

v0.9.0

10 Oct 10:01
Compare
Choose a tag to compare

Full Changelog: v0.8.0...v0.9.0

v0.8.0

09 Oct 09:34
Compare
Choose a tag to compare

Full Changelog: v0.7.1...v0.8.0

v0.7.1

09 Oct 09:35
Compare
Choose a tag to compare

Full Changelog: v0.7.0...v0.7.1