gommand

package module
v0.0.0-...-25487f3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 18, 2020 License: GPL-2.0 Imports: 11 Imported by: 0

README

gommand

Package gommand provides an easy to use and high performance commands router and processor for Go(lang) using disgord as the base Discord framework. It features the following functionality:

  • Custom prefix support: Gommand allows you to easily set a custom prefix. Gommand has various helper functions for this such as static prefix and mention support.
  • Command alias support: Out ot the box, gommand features support for command aliases. This allows for the ability to easily write commands that have several wordings. This is very useful for bots where you have command names which are changing during migration.
  • Custom commands support: Gommand allows you to easily set a handler for custom commands if this is something which you require for your bot.
  • Custom argument support: Out of the box, gommand features many different argument converters for functionality such as integers and users. Should you need it, gommand also allows for the creation of custom converters through a very simple function.
  • Argument formatting: Gommand supports required, optional, remainder and greedy processors for commands.
  • Middleware support: Need to run something before a bunch of commands which requires repeating yourself? No problem! Gommand supports middleware on both a global (through the router object) and local (through the command object) scale. Simply add the function and it will be executed. There is also a map within the context called MiddlewareParams in which middleware can very easily store data for the commands to run.
  • Permission validators support: If you need to validate permissions, you can simply use permission validators. If false is returned, a IncorrectPermissions will be sent to the error handlers with the string specified.
  • Ease of use: We pride this library on ease of use. The idea is to build a higher level wrapper around handling commands using disgord, and whilst doing this we add in helper functions. Additionally, we patch the member object into messages, meaning that you do not need to get this, solving potential code repetition.
  • Advanced error handling: Gommand features an advanced error handling system. The error is passed through all inserted error handlers in the order which the handlers were inserted. If a handler is able to solve an issue, it will simply return true and gommand will stop iterating through the list. If no handlers return true, it will be passed through to the disgord logger which you set.
  • Battle tested: The Gommand library is heavily unit tested. Feel free to submit a pull request if you feel there is something important which we are not testing, we will accept it. Find a bug? Feel free to file an issue and we will fix it.

An example of the bot is accessable in the example folder.

Contributing

Do you have something which you wish to contribute? Feel free to make a pull request. The following simple criteria applies:

  • Is it useful to everyone?: If this is a domain specific edit, you probably want to keep this as middleware since it will not be accepted into the main project.
  • Does it slow down parsing by >1ms?: This will likely be denied. We want to keep parsing as high performance as possible.
  • Have you ran gofmt -w . and golangci-lint?: We like to stick to using Go standards within this project, therefore if this is not done you may be asked to do this for it to be acccepted.

Have you experienced a bug? If so, please make an issue! We take bugs seriously and this will be a large priority for us.

Creating your router

Creating the router is very simple to do. You can simply create a router object in the part of your project where all of your commands are by calling the NewRouter function with a RouterConfig object. The configuration object can contain the following attributes:

  • PrefixCheck: This is used to set the checker which will be used for prefixes. Gommand contains the following prefix checks which you can use:

    • gommand.StaticPrefix(<prefix>): This will return a function which can be used in the place of the prefix check attribute to specifically look for a static prefix.
    • gommand.MentionPrefix: This is used to check if the bot is mentioned.
    • gommand.MultiplePrefixCheckers(<prefix checker>...) - This allows you to combine prefix checkers. In the event that a prefix checker returns false, the string iterator will be rewinded back to where it was and the next checker will be called.

    In the event that these prefix checkers won't suffice, you can write your own with the function type func(ctx *gommand.Context, r *gommand.StringIterator) bool where true represents if the prefix is used. If the prefix was used, you should also set ctx.Prefix to your prefix. Note that the context does not contain the member object in the message or the command yet. See using the string iterator below on how to use the string iterator. If this is nil, it defaults to no prefix.

  • ErrorHandlers: An array of functions of the ErrorHandler type which will run one after another. This can be nil and you can also add one with the AddErrorHandler function attached to the router.

  • PermissionValidators: This is any permission validators which you wish to add on a global router scale. This can be nil.

  • Middleware: This is any middleware which you wish to add on a global router scale. This can be nil.

  • DeletedMessageHandler: See the deleted message handler documentation below.

The router is then trivial to make:

var router = gommand.NewRouter(&gommand.RouterConfig{
    ...
})

Adding a command

When you have a working router, you should be ready to add commands. We do this with the SetCommand function. To use this function, we simply pass in a Command object:

router.SetCommand(&gommand.Command{
    ...
})

The command MUST have the Name (the name of the command) and Function (the function that will be called with the context and can return an error, any returned errors will be given to the error handlers) attributes set. The other attributes are optional:

  • Aliases: Any aliases which a command has.
  • Description: The description which is used in help commands.
  • Usage: The usage information for a command.
  • PermissionValidators: An array of permission validators which only applies to this specific command.
  • ArgTransformers: This is an array of the gommand.ArgTransformer type. Each object in this array contains the following attributes:
    • Function: The function which is used to transform the argument which must be set. The function simply takes the context and argument as a string and returns an interface and error (if the error is nil - this parsed properly). The following transformers are supported by gommand right now:
      • gommand.StringTransformer: Transforms the argument into a string.
      • gommand.IntTransformer: Transforms the argument into a integer.
      • gommand.UIntTransformer: Transforms the argument into a unsigned integer.
      • gommand.UserTransformer: Transforms the argument into a user.
      • gommand.MemberTransformer: Transforms the argument into a member.
      • gommand.ChannelTransformer: Transforms the argument into a channel.
      • gommand.MessageURLTransformer: Transforms a message URL into a message.
      • gommand.BooleanTransformer: Transforms the argument into a boolean.
      • gommand.RoleTransformer: Transforms the argument into a role.
    • Optional: If this is true and the argument does not exist, it will be sert to nil. Note that due to what this does, it has to be at the end of the array.
    • Remainder: If this is true, it will just try and parse the raw remainder of the arguments. If the string is blank it will error with not enough arguments unless optional is set. Note that due to what this does, it has to be at the end of the array.
    • Greedy: If this is true, the parser will keep trying to parse the users arguments until it hits the end of their message or a parse fails. When this happens, it will go to the next parser in the array. Note that if the first argument fails, this means that it was not set and an error will be put into the error handler unless it was set as optional. The greedy argument will be of the type []interface{} (unless Optional is set and it was not specified).
  • Middleware: An array of middleware which only applies to this specific command.
  • Category: Allows you to set a Category for your command.

Context

The context is a core part of the gommand functionality. The context contains several crucial bits of information:

  • Message: The base message which the command is relating to. Unless otherwise specified, the member object will be patched into this message.
  • BotUser: The *disgord.User object which is repersenting the bot. Do NOT edit this since it is shared across command calls.
  • Router: The base router.
  • Session: The *disgord.Session which was used to emit this event.
  • Command: The actual command which was called.
  • RawArgs: A string of the raw arguments.
  • Args: The transformed arguments.
  • Prefix: Defines the prefix which was used.
  • MidddlewareParams: The params set by middleware.

It also contains several helper functions:

  • Replay() error: Allows you to replay a command.
  • BotMember() (*disgord.Member, error): Get the bot as a member of the guild which the command is being ran in.
  • Channel() (*disgord.Channel, error): Get the channel which this is being ran in.
  • Reply(data ...interface{}) (*disgord.Message, error): A shorter way to quickly reply to a message.
  • WaitForMessage(CheckFunc func(s disgord.Session, msg *disgord.Message) bool) *disgord.Message: Waits for a message based on the check function you gave.
  • DisplayEmbedMenu(m *EmbedMenu) error: Used to display an embed menu.

Hooking the router to your disgord session

In the initialisation of your disgord session, you will want to hook the gommand handler with the Hook function:

// Your client config can be how you please.
client := disgord.New(disgord.Config{
    BotToken: os.Getenv("TOKEN"),
    Logger:   disgord.DefaultLogger(false),
})

// Hook the router.
router.Hook(client)

// ANY OTHER INITIALISATION OF DISGORD EVENTS HERE

// Connect to Discord.
err := client.StayConnectedUntilInterrupted(context.Background())
if err != nil {
    panic(err)
}

Error Handling

In gommand, every negative action is treated as an error. It is then your job to handle these errors. If the error is not handled within the router, it is then just simply passed off to the logger which was configured in disgord. Error handlers take the context and the error. From this they return a boolean. If the boolean is true, it means the error was caught by the handler. If not it simply goes to the next handler in the array. Gommand has several errors which can pass through of its own:

  • *gommand.CommandNotFound: The command was not found within the router.
  • *gommand.CommandBlank: The command name was blank.
  • *gommand.IncorrectPermissions: The permissions this user has are incorrect for the command.
  • *gommand.InvalidArgCount: The argument count is not correct.
  • *gommand.InvalidTransformation: Passed through from a transformer when it cannot transform properly.

Using this, we can build a simple error handler that ignores command not found events and logs errors to the chat for the others, although you may wish to implement this differently:

func basicErrorHandler(ctx *gommand.Context, err error) bool {
    // Check all the different types of errors.
    switch err.(type) {
    case *gommand.CommandNotFound, *gommand.CommandBlank:
        // We will ignore.
        return true
    case *gommand.InvalidTransformation:
        _, _ = ctx.Reply("Invalid argument:", err.Error())
        return true
    case *gommand.IncorrectPermissions:
        _, _ = ctx.Reply("Invalid permissions:", err.Error())
        return true
    case *gommand.InvalidArgCount:
        _, _ = ctx.Reply("Invalid argument count.")
        return true
    }

    // This was not handled here.
    return false
}

This can then be added to the ErrorHandlers array or passed to AddErrorHandler. Note that they execute in the order they were added.

Categories

In Go, categories use the gommand.CategoryInterface interface to ensure that they can be modular. The interface has the following functions which must be set:

  • GetName() string: Gets the name of the category.
  • GetDescription() string: Gets the description of the category.
  • GetPermissionValidators() []gommand.PermissionValidator: Gets the array of permission validators. This array cannot be nil.
  • GetMiddleware() []gommand.Middleware: Gets the array of permission validators. This array cannot be nil.

For ease of use, gommand has the Category struct that implements all of these for you. The following attributes can be set in this:

  • Name: The name of the category.
  • Description: The description of the category.
  • PermissionValidators: An array of permission validators which will be used on each item in the category. This can be nil.
  • Middleware: An array of middleware which will be used on each item in the category. This can be nil.

Note that to allow for the easy categorisation of commands and prevent repatition, a pointer should be created somewhere in your codebase (using var or before your commands) to a category which multiple commands use and they should all just pass through the same pointer.

Embed menus

Gommand contains support for embed menus.

TODO: docs

Permission Validators

Permission validators allow for a quick method to check if the user has permission to run a command.

Gommand contains built-in permission validators for all Discord permisions. To use them, simply use the permission ID as the permission validator function. For example, if you want to check if someone is an administrator, simply add gommand.ADMINISTRATOR to your PermissionValidators array.

If you wish to write your own permission validators, they follow the format func(ctx *Context) (string, bool). If the boolean is true, the user does have permission. If not, the string is used to construct a IncorrectPermissions error.

Middleware

Middleware allows you to write powerful extensions on a per-command or per-router basis. Middleware is seperate from permission validators to allow the application to tell if the user has permission without re-executing all of the middleware which has been set. Middleware follows the format func(ctx *Context) error, with any errors being passed to the error handler. If you wish to get an argument from a middleware function to another function or command during execution, you can use the MiddlewareParams map within the context.

Using The String Iterator

If you are handling parts of the parsing which are very early in the process as is the case with prefixes and custom commands,0 and you are writing your own code to implement them, you will need to handle the gommand.StringIterator type. The objective of this is to try and prevent multiple iterations of the string, which can be computationally expensive, where this is possible. The iterator implements the following:

  • GetRemainder(FillIterator bool) (string, error): This will get the remainder of the iterator. If it's already at the end, the error will be set. FillIterator defines if it should fill the iterator when it is done or if it should leave it where it is.
  • GetChar() (uint8, error): Used to get a character from the iterator. If it's already at the end, the error will be set.
  • Rewind(N uint): Used to rewind by N number of chars. Useful if you only iterated a few times to check something.

Deleted message handler

For some bots, being able to track deleted messages in an easy to use way is important due to the ability to get the content/author of deleted messages. In standalone disgord, you need to manually cache messages. However, gommand has the ability built in to cache deleted messages. To use this handler, simply set the DeletedMessageHandler attribute of the router configuration to a struct of the type &gommand.DeletedMessageHandler. You can then set the following attributes in this handler:

  • Limit: Defines the maximum amount of cached messages. -1 = unlimited (not suggested if it's in-memory since it'll lead to memory leaks), 0 = default, >0 = user set maximum. This should run on a First In First Out (FIFO) basis. By default, this will be set to 1,000 messages. Messages which have been purged due to this limit will not have an event fired for them.
  • Callback: The callback of type func(s disgord.Session, msg *disgord.Message) which is called when a message is deleted. As with commands, for ease of use the Member attribute is set on the message.
  • MessageCacheStorageAdapter: The message cache storage adapter which is used for this. If this is not set, it will default to the built-in in-memory caching adapter.

Message cache storage adapter

By default (like other libraries such as discord.py), gommand keeps a finite amount of messages cached into RAM which is set by the user in the deleted message handler parameters. However, if you wish to keep messages until the guild removes your bot/is deleted or the message/channel is deleted, you will likely want to want to write your own message caching adapter. In gommand, memory cachers use the gommand.MemoryCacheStorageAdapter interface. This contains the following functions which need to be set:

  • Init(): Called on the initialisation of the router.
  • GetAndDelete(ChannelID, MessageID string) *disgord.Message: Gets a message from the cache and then deletes it since this is only called when the message is being deleted so it will then be unneeded.
  • Delete(ChannelID, MessageID string): Deletes a message from the cache.
  • DeleteChannelsMessages(ChannelID string): Deletes all messages cached for a specific channel.
  • Set(ChannelID, MessageID string, Message *disgord.Message, Limit uint): Sets an item in the cache. The limit is passed through so that you can implement a simple First In First Out (FIFO) caching system. The limit will be 0 if it is set to unlimited.

The following manage storing channel/guild ID relationships. This is important so that if a guild is removed, we know what channel ID's to purge from the cache:

  • GetAllChannelIDs(GuildID string) []string: Get all channel ID's which have a relationship with a specific guild ID.
  • AddChannelID(GuildID, ChannelID string): Add a relationship between a guild ID and a channel ID.
  • RemoveChannelID(GuildID, ChannelID string): Remove a channel ID's relationship with a guild ID.
  • RemoveGuild(GuildID string): Remove all channel ID relationships with a specific guild ID.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ADD_REACTIONS = permissionsWrapper("Add Reactions", 0x00000040)

ADD_REACTIONS is a wrapper for the Discord permission.

View Source
var ADMINISTRATOR = permissionsWrapper("Administrator", 0x00000008)

ADMINISTRATOR is a wrapper for the Discord permission.

View Source
var ATTACH_FILES = permissionsWrapper("Attach Files", 0x00008000)

ATTACH_FILES is a wrapper for the Discord permission.

View Source
var BAN_MEMBERS = permissionsWrapper("Ban Members", 0x00000004)

BAN_MEMBERS is a wrapper for the Discord permission.

View Source
var CHANGE_NICKNAME = permissionsWrapper("Change Nickname", 0x04000000)

CHANGE_NICKNAME is a wrapper for the Discord permission.

View Source
var CONNECT = permissionsWrapper("Connect", 0x00100000)

CONNECT is a wrapper for the Discord permission.

View Source
var CREATE_INSTANT_INVITE = permissionsWrapper("Create Instant Invite", 0x00000001)

CREATE_INSTANT_INVITE is a wrapper for the Discord permission.

View Source
var DEAFEN_MEMBERS = permissionsWrapper("Deafen Members", 0x00800000)

DEAFEN_MEMBERS is a wrapper for the Discord permission.

View Source
var EMBED_LINKS = permissionsWrapper("Embed Links", 0x00004000)

EMBED_LINKS is a wrapper for the Discord permission.

View Source
var KICK_MEMBERS = permissionsWrapper("Kick Members", 0x00000002)

KICK_MEMBERS is a wrapper for the Discord permission.

View Source
var MANAGE_CHANNELS = permissionsWrapper("Manage Channels", 0x00000010)

MANAGE_CHANNELS is a wrapper for the Discord permission.

View Source
var MANAGE_EMOJIS = permissionsWrapper("Manage Emojis", 0x40000000)

MANAGE_EMOJIS is a wrapper for the Discord permission.

View Source
var MANAGE_GUILD = permissionsWrapper("Manage Guild", 0x00000020)

MANAGE_GUILD is a wrapper for the Discord permission.

View Source
var MANAGE_MESSAGES = permissionsWrapper("Manage Messages", 0x00002000)

MANAGE_MESSAGES is a wrapper for the Discord permission.

View Source
var MANAGE_NICKNAMES = permissionsWrapper("Manage Nicknames", 0x08000000)

MANAGE_NICKNAMES is a wrapper for the Discord permission.

View Source
var MANAGE_ROLES = permissionsWrapper("Manage Roles", 0x10000000)

MANAGE_ROLES is a wrapper for the Discord permission.

View Source
var MANAGE_WEBHOOKS = permissionsWrapper("Manage Webhooks", 0x20000000)

MANAGE_WEBHOOKS is a wrapper for the Discord permission.

View Source
var MENTION_EVERYONE = permissionsWrapper("Mention Everyone", 0x00020000)

MENTION_EVERYONE is a wrapper for the Discord permission.

View Source
var MOVE_MEMBERS = permissionsWrapper("Move Members", 0x01000000)

MOVE_MEMBERS is a wrapper for the Discord permission.

View Source
var MUTE_MEMBERS = permissionsWrapper("Mute Members", 0x00400000)

MUTE_MEMBERS is a wrapper for the Discord permission.

View Source
var PRIORITY_SPEAKER = permissionsWrapper("Priority Speaker", 0x00000100)

PRIORITY_SPEAKER is a wrapper for the Discord permission.

View Source
var READ_MESSAGE_HISTORY = permissionsWrapper("Read Message History", 0x00010000)

READ_MESSAGE_HISTORY is a wrapper for the Discord permission.

View Source
var SEND_MESSAGES = permissionsWrapper("Send Messages", 0x00000800)

SEND_MESSAGES is a wrapper for the Discord permission.

View Source
var SEND_TTS_MESSAGES = permissionsWrapper("Send Tts Messages", 0x00001000)

SEND_TTS_MESSAGES is a wrapper for the Discord permission.

View Source
var SPEAK = permissionsWrapper("Speak", 0x00200000)

SPEAK is a wrapper for the Discord permission.

View Source
var STREAM = permissionsWrapper("Stream", 0x00000200)

STREAM is a wrapper for the Discord permission.

View Source
var USE_EXTERNAL_EMOJIS = permissionsWrapper("Use External Emojis", 0x00040000)

USE_EXTERNAL_EMOJIS is a wrapper for the Discord permission.

View Source
var USE_VAD = permissionsWrapper("Use Vad", 0x02000000)

USE_VAD is a wrapper for the Discord permission.

View Source
var VIEW_AUDIT_LOG = permissionsWrapper("View Audit Log", 0x00000080)

VIEW_AUDIT_LOG is a wrapper for the Discord permission.

View Source
var VIEW_CHANNEL = permissionsWrapper("View Channel", 0x00000400)

VIEW_CHANNEL is a wrapper for the Discord permission.

Functions

func BooleanTransformer

func BooleanTransformer(_ *Context, Arg string) (interface{}, error)

BooleanTransformer is used to transform an argument into a boolean if possible.

func ChannelTransformer

func ChannelTransformer(ctx *Context, Arg string) (channel interface{}, err error)

ChannelTransformer is used to transform a channel if possible.

func EmbedsPaginator

func EmbedsPaginator(ctx *Context, Pages []*disgord.Embed) error

EmbedsPaginator is used to paginate together several embeds.

func IntTransformer

func IntTransformer(_ *Context, Arg string) (interface{}, error)

IntTransformer is used to transform an arg to a integer if possible.

func MemberTransformer

func MemberTransformer(ctx *Context, Arg string) (member interface{}, err error)

MemberTransformer is used to transform a member if possible.

func MentionPrefix

func MentionPrefix(ctx *Context, r *StringIterator) bool

MentionPrefix is used to handle a mention which is being used as a prefix.

func MessageURLTransformer

func MessageURLTransformer(ctx *Context, Arg string) (message interface{}, err error)

MessageURLTransformer is used to transform a message URL to a message if possible.

func MultiplePrefixCheckers

func MultiplePrefixCheckers(Handlers ...PrefixCheck) func(ctx *Context, r *StringIterator) bool

MultiplePrefixCheckers is used to handle multiple prefix checkers.

func RoleTransformer

func RoleTransformer(ctx *Context, Arg string) (role interface{}, err error)

RoleTransformer is used to transform a role if possible.

func StaticPrefix

func StaticPrefix(Prefix string) func(_ *Context, r *StringIterator) bool

StaticPrefix is used for simple static prefixes.

func StringTransformer

func StringTransformer(_ *Context, Arg string) (interface{}, error)

StringTransformer just takes the argument and returns it.

func UIntTransformer

func UIntTransformer(_ *Context, Arg string) (interface{}, error)

UIntTransformer is used to transform an arg to a unsigned integer if possible.

func UserTransformer

func UserTransformer(ctx *Context, Arg string) (user interface{}, err error)

UserTransformer is used to transform a user if possible.

Types

type ArgTransformer

type ArgTransformer struct {
	// Greedy defines if the parser should keep going until an argument fails.
	Greedy bool

	// Optional defines if the argument is optional. This can be mixed with greedy or remainder.
	// This has to be at the end of the argument list.
	Optional bool

	// Remainder defines if it should just parse the rest of the arguments.
	// Remainders need to be at the end of a command.
	Remainder bool

	// Function is used to transform the argument. The function should error if this is not possible.
	Function func(ctx *Context, Arg string) (interface{}, error)
}

ArgTransformer defines a transformer which is to be used on arguments.

type Category

type Category struct {
	Name                 string                `json:"name"`
	Description          string                `json:"description"`
	PermissionValidators []PermissionValidator `json:"-"`
	Middleware           []Middleware          `json:"-"`
}

Category is the generic category struct which uses the category interface.

func (*Category) GetDescription

func (c *Category) GetDescription() string

GetDescription is used to get the description of the category.

func (*Category) GetMiddleware

func (c *Category) GetMiddleware() []Middleware

GetMiddleware is used to get the middleware of the category.

func (*Category) GetName

func (c *Category) GetName() string

GetName is used to get the name of the category.

func (*Category) GetPermissionValidators

func (c *Category) GetPermissionValidators() []PermissionValidator

GetPermissionValidators is used to get the permission validators of the category.

type CategoryInterface

type CategoryInterface interface {
	GetName() string
	GetDescription() string
	GetPermissionValidators() []func(ctx *Context) (string, bool) // If I change this to the PermissionValidator type, it triggers #25838 in Go.
	GetMiddleware() []Middleware
}

CategoryInterface is the interface which is used for categories. This can be used to write your own category handler if you wish.

type Command

type Command struct {
	Name                 string                   `json:"name"`
	Aliases              []string                 `json:"aliases"`
	Description          string                   `json:"description"`
	Usage                string                   `json:"usage"`
	Category             CategoryInterface        `json:"category"`
	PermissionValidators []PermissionValidator    `json:"-"`
	ArgTransformers      []ArgTransformer         `json:"-"`
	Middleware           []Middleware             `json:"-"`
	Function             func(ctx *Context) error `json:"-"`
}

Command defines a command which can be used within the Router.

func (*Command) HasPermission

func (c *Command) HasPermission(ctx *Context) error

HasPermission is used to run through the permission validators and check if the user has permission. The error will be of the IncorrectPermissions type if they do not have permission.

type CommandBlank

type CommandBlank struct {
	// contains filtered or unexported fields
}

CommandBlank is the error which is thrown when the command is blank.

func (*CommandBlank) Error

func (c *CommandBlank) Error() string

Error is used to give the error description.

type CommandNotFound

type CommandNotFound struct {
	// contains filtered or unexported fields
}

CommandNotFound is the error which is thrown when a command is not found.

func (*CommandNotFound) Error

func (c *CommandNotFound) Error() string

Error is used to give the error description.

type Context

type Context struct {
	Prefix           string                 `json:"prefix"`
	Message          *disgord.Message       `json:"message"`
	BotUser          *disgord.User          `json:"botUser"`
	Router           *Router                `json:"-"`
	Session          disgord.Session        `json:"session"`
	Command          *Command               `json:"command"`
	RawArgs          string                 `json:"rawArgs"`
	Args             []interface{}          `json:"args"`
	MiddlewareParams map[string]interface{} `json:"middlewareParams"`
}

Context defines the information which might be required to run the command.

func (*Context) BotMember

func (c *Context) BotMember() (*disgord.Member, error)

BotMember is used to get the bot as a member of the server this was within.

func (*Context) Channel

func (c *Context) Channel() (*disgord.Channel, error)

Channel is used to get the channel if the bot needs it.

func (*Context) DisplayEmbedMenu

func (c *Context) DisplayEmbedMenu(m *EmbedMenu) error

DisplayEmbedMenu is used to allow you to easily display a embed menu.

func (*Context) Replay

func (c *Context) Replay() error

Replay is used to replay a command.

func (*Context) Reply

func (c *Context) Reply(data ...interface{}) (*disgord.Message, error)

Reply is used to quickly reply to a command with a message.

func (*Context) WaitForMessage

func (c *Context) WaitForMessage(CheckFunc func(s disgord.Session, msg *disgord.Message) bool) *disgord.Message

WaitForMessage allows you to wait for a message.

type CustomCommandsHandler

type CustomCommandsHandler = func(ctx *Context, cmdname string, r *StringIterator) (bool, error)

CustomCommandsHandler is the handler which is used for custom commands. An error being returned by the custom commands handler will return in that being passed through to the error handler instead. true here represents this being a custom command. This means the Router will not go through the errors handler unless an error is set.

type DeletedMessageHandler

type DeletedMessageHandler struct {
	MessageCacheStorageAdapter MessageCacheStorageAdapter                    `json:"-"`
	Callback                   func(s disgord.Session, msg *disgord.Message) `json:"-"`

	// Limit defines the amount of messages.
	// -1 = unlimited (not suggested if it's in-memory since it'll lead to memory leaks), 0 = default, >0 = user set maximum
	Limit int `json:"limit"`
}

DeletedMessageHandler is used to handle dispatching events for deleted messages. It does this by using the storage adapter to log messages, then the message is deleted from the database at the message limit or when the deleted message handler is called.

type EmbedMenu

type EmbedMenu struct {
	Reactions *MenuReactions

	Embed    *disgord.Embed
	MenuInfo *MenuInfo
	// contains filtered or unexported fields
}

EmbedMenu is the base menu.

func NewEmbedMenu

func NewEmbedMenu(embed *disgord.Embed, ctx *Context) *EmbedMenu

NewEmbedMenu is used to create a new menu handler.

func (*EmbedMenu) AddBackButton

func (e *EmbedMenu) AddBackButton()

AddBackButton is used to add a back Button to the page.

func (*EmbedMenu) AddParentMenu

func (e *EmbedMenu) AddParentMenu(Menu *EmbedMenu)

AddParent is used to add a new parent menu.

func (*EmbedMenu) Display

func (e *EmbedMenu) Display(ChannelID, MessageID snowflake.Snowflake, client disgord.Session) error

Display is used to show a menu. This is un-protected so that people can write their own things on top of embed menus, but you probably want to use ctx.DisplayEmbedMenu(menu).

func (*EmbedMenu) NewChildMenu

func (e *EmbedMenu) NewChildMenu(embed *disgord.Embed, item MenuButton) *EmbedMenu

NewChildMenu is used to create a new child menu.

type ErrorHandler

type ErrorHandler = func(ctx *Context, err error) bool

ErrorHandler is a function which is used to handle errors. true here means that the error was handled by this handler. If this is false, the processor will go to the next handler.

type InMemoryMessageCacheStorageAdapter

type InMemoryMessageCacheStorageAdapter struct {
	// contains filtered or unexported fields
}

InMemoryMessageCacheStorageAdapter is used to hold cached messages in RAM. This is extremely fast, but will lead to increased RAM usage.

func (*InMemoryMessageCacheStorageAdapter) AddChannelID

func (c *InMemoryMessageCacheStorageAdapter) AddChannelID(GuildID, ChannelID string)

AddChannelID is used to add a channel ID to the guild.

func (*InMemoryMessageCacheStorageAdapter) Delete

func (c *InMemoryMessageCacheStorageAdapter) Delete(ChannelID, MessageID string)

Delete is used to delete a specific message from the cache.

func (*InMemoryMessageCacheStorageAdapter) DeleteChannelsMessages

func (c *InMemoryMessageCacheStorageAdapter) DeleteChannelsMessages(ChannelID string)

DeleteChannelsMessages is used to delete a channels messages from a cache.

func (*InMemoryMessageCacheStorageAdapter) GetAllChannelIDs

func (c *InMemoryMessageCacheStorageAdapter) GetAllChannelIDs(GuildID string) []string

GetAllChannelIDs is used to get all of the channel ID's.

func (*InMemoryMessageCacheStorageAdapter) GetAndDelete

func (c *InMemoryMessageCacheStorageAdapter) GetAndDelete(ChannelID, MessageID string) *disgord.Message

GetAndDelete is used to get and delete from the cache where this is possible.

func (*InMemoryMessageCacheStorageAdapter) Init

Init is used to initialise the in-memory message cache.

func (*InMemoryMessageCacheStorageAdapter) RemoveChannelID

func (c *InMemoryMessageCacheStorageAdapter) RemoveChannelID(GuildID, ChannelID string)

RemoveChannelID is used to remove a channel ID to the guild.

func (*InMemoryMessageCacheStorageAdapter) RemoveGuild

func (c *InMemoryMessageCacheStorageAdapter) RemoveGuild(GuildID string)

RemoveGuild is used to remove a guild from the cache.

func (*InMemoryMessageCacheStorageAdapter) Set

func (c *InMemoryMessageCacheStorageAdapter) Set(ChannelID, MessageID string, Message *disgord.Message, Limit uint)

Set is used to set a item in the cache.

type IncorrectPermissions

type IncorrectPermissions struct {
	// contains filtered or unexported fields
}

IncorrectPermissions is the error which is thrown when the user does not have enough permissions.

func (*IncorrectPermissions) Error

func (c *IncorrectPermissions) Error() string

Error is used to give the error description.

type InvalidArgCount

type InvalidArgCount struct {
	// contains filtered or unexported fields
}

InvalidArgCount is the error when the arg count is not correct.

func (*InvalidArgCount) Error

func (c *InvalidArgCount) Error() string

Error is used to give the error description.

type InvalidTransformation

type InvalidTransformation struct {
	Description string
}

InvalidTransformation is the error argument parsers should use when they can't transform.

func (*InvalidTransformation) Error

func (c *InvalidTransformation) Error() string

Error is used to give the error description.

type MenuButton struct {
	Emoji       string
	Name        string
	Description string
}

MenuButton is the datatype containing information about the button.

type MenuInfo struct {
	Author string
	Info   []string
}

MenuInfo contains the information about the menu.

type MenuReaction struct {
	Button   MenuButton
	Function func(ChannelID, MessageID snowflake.Snowflake, _ *EmbedMenu, client disgord.Session)
}

MenuReaction represents the button and the function which it triggers.

type MenuReactions struct {
	ReactionSlice []MenuReaction
}

MenuReactions are all of the reactions which the menu has.

func (mr *MenuReactions) Add(reaction MenuReaction)

Add is used to add a menu reaction.

type MessageCacheStorageAdapter

type MessageCacheStorageAdapter interface {
	// Called when the router is created.
	Init()

	// Related to message caching.
	GetAndDelete(ChannelID, MessageID string) *disgord.Message
	Delete(ChannelID, MessageID string)
	DeleteChannelsMessages(ChannelID string)
	Set(ChannelID, MessageID string, Message *disgord.Message, Limit uint)

	// Related to channel and guild ID relationship caching.
	// Channel ID's are NOT confirmed to be unique and will be repeated on bot reboot as per the Discord API.
	// You should manage this in your adapter.
	GetAllChannelIDs(GuildID string) []string
	AddChannelID(GuildID, ChannelID string)
	RemoveChannelID(GuildID, ChannelID string)
	RemoveGuild(GuildID string)
}

MessageCacheStorageAdapter is the interface which is used for message cache storage adapters.

type Middleware

type Middleware = func(ctx *Context) error

Middleware is used to handle setting data within the context before the command is ran. This is useful if there is stuff you want to do, but you don't want to type on every command. If this errors, it will just get passed through to the error handler.

type PermissionValidator

type PermissionValidator = func(ctx *Context) (string, bool)

PermissionValidator is a function which is used to validate someones permissions who is running a command. If the boolean is set to true, it means the user has permissions. If it is false, the user does not, and the string will be used as the error with the IncorrectPermissions type.

type PrefixCheck

type PrefixCheck = func(ctx *Context, r *StringIterator) bool

PrefixCheck is the type for a function to check the prefix. true here means the prefix is there and was read. Note that prefix functions cannot see the member object in the message since that is patched in AFTER this is ran.

type Router

type Router struct {
	BotUser               *disgord.User         `json:"-"`
	PrefixCheck           PrefixCheck           `json:"-"`
	CustomCommandsHandler CustomCommandsHandler `json:"-"`

	DeletedMessageHandler *DeletedMessageHandler
	// contains filtered or unexported fields
}

Router defines the command router which is being used. Please call NewRouter to initialise this rather than creating a new struct.

func NewRouter

func NewRouter(Config *RouterConfig) *Router

NewRouter creates a new command Router.

func (*Router) AddErrorHandler

func (r *Router) AddErrorHandler(Handler ErrorHandler)

AddErrorHandler is used to add a error handler to the Router. An error handler takes the structure of the ErrorHandler type above. Error handlers are executed in the order in which they are added to the Router.

func (*Router) GetAllCommands

func (r *Router) GetAllCommands() []*Command

GetAllCommands is used to get all of the commands.

func (*Router) GetCommand

func (r *Router) GetCommand(Name string) *Command

GetCommand is used to get a command from the Router if it exists. If the command doesn't exist, this will be a nil pointer.

func (*Router) GetCommandsOrderedByCategory

func (r *Router) GetCommandsOrderedByCategory() map[CategoryInterface][]*Command

GetCommandsOrderedByCategory is used to order commands by the categories.

func (*Router) Hook

func (r *Router) Hook(s disgord.Session)

Hook is used to hook all required events into the disgord client.

func (*Router) RemoveCommand

func (r *Router) RemoveCommand(c *Command)

RemoveCommand is used to remove a command from the Router.

func (*Router) SetCommand

func (r *Router) SetCommand(c *Command)

SetCommand is used to set a command.

type RouterConfig

type RouterConfig struct {
	DeletedMessageHandler *DeletedMessageHandler
	PrefixCheck           PrefixCheck
	ErrorHandlers         []ErrorHandler
	PermissionValidators  []PermissionValidator
	Middleware            []Middleware
}

RouterConfig defines the config which will be used for the Router.

type StringIterator

type StringIterator struct {
	Text string `json:"text"`
	Pos  uint   `json:"pos"`
	// contains filtered or unexported fields
}

StringIterator is used to iterate through a string but keep track of the position. This also allows for the ability to rewind a string. This is NOT designed to be thread safe.

func (*StringIterator) GetChar

func (s *StringIterator) GetChar() (char uint8, err error)

GetChar is used to get a character from the string.

func (*StringIterator) GetRemainder

func (s *StringIterator) GetRemainder(FillIterator bool) (remainder string, err error)

GetRemainder is used to get the remainder of a string. FillIterator defines if the iterators count should be affected by this.

func (*StringIterator) Rewind

func (s *StringIterator) Rewind(N uint)

Rewind is used to rewind a string iterator N number of chars.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL