CommandMeta is another interface consisting of getters for the command's metadata. You don't really need to worry about the methods it requires, as the command package provides us with predefined types.
Creating a Command
Using that knowledge, you can create your first command. Create a package with your commands name, as detailed in Project Layout, and add a {{package_name}}.go file to it.
Example: A Ping Command
In the ping package create a ping.go file where you create your command type. To implement the plugin.CommandMeta interface, which is part of the plugin.Command interface, you can embed command.Meta in your Ping type.
plugins/ping/ping.go
packagepingimport ("github.com/mavolin/adam/pkg/impl/command""github.com/mavolin/adam/pkg/plugin")typePingstruct {command.Meta}var _ plugin.Command=new(Ping) // compile time check
This leaves your Ping command with only Invoke left, to fully satisfy plugin.Command.
Now that we've added Invoke, let's add a constructor function where we create a new Ping instance and fill the command.Meta struct we embedded earlier.
command.Meta has a lot more fields than just those we used for the Ping command. Refer to its documentation for more information.
Invoke's Return Values
As you might have noticed, plugin.Command.Invoke has two return values, and while the error return value might be a bit more self-explanatory, interface{} is probably not. So what can you use it for?
Everything you return as the first value will get turned into a message and sent in the invoking channel back to the user using the plugin.Context's Replier. Obviously, not everything can be turned into a message, at least not without causing confusion. Therefore, only the following return types are allowed:
uint, uint8, uint16, uint32, uint64
int, int8, int16, int32, int64
float32, float64
string
discord.Embed and *discord.Embed
*embedutil.Builder
api.SendMessageData
i18n.Term
*i18n.Config
any type implementingplugin.Reply
Of course, justnil is also valid, and won't create any response.
The second return value, error, is handed to the bot's error handler if it's not nil. While you can define a custom error handler, the default one will wrap every error not implementing errors.Error into a errors.InternalError and call Handle on it. We'll take a closer look at this later on in the Error Types chapter.