commandwrapper

package module
v0.0.0-...-13ef5e2 Latest Latest
Warning

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

Go to latest
Published: May 23, 2020 License: GPL-3.0 Imports: 5 Imported by: 0

README

command-wrapper


Disclaimer

This Project is a part of doll and uses:

See the examples and docs.

Doll is a discordgo framework, which is written in golang. It simplifies any kind of actions discordgo has to offer. Examples: Events, Connection, Container and in this case, Commands.

See

Getting started

It is assumed that you have already worked with the Go environment. If this is not the case, see this page first.

Installation

go get github.com/projectdoll/command-wrapper

Usage
Import the package
import "github.com/projectdoll/command-wrapper"
Create a BotApplication
Installation commons

go get github.com/projectdoll/commons

If you have no experience with commons, see this.

In the README.MD I use the instance of the BotApplication under the name "BOT".

Create Wrapper

The wrapper is the global handler, which is configured by the configuration.

// simple usage
wrapper := commandwrapper.NewWrapper(BOT, PREFIXES...)

// advanced usage
wrapper := &commandwrapper.PlainWrapper{
    BotApplication:    BOT,
    PrefixGenerator: func(ctx *commandwrapper.Context) []commandwrapper.CommandPrefix {
        return []commandwrapper.CommandPrefix{PREFIXES...}
    },
}

If you want the command wrapper to already accept messages (discordgo.MessageCreate & discordgo.MessageUpdate), use

wrapper.StartListening()
Create a simple Command

The command is used to store information. e.g.: PlainCommand.Keys, PlainCommand.Usage, PlainCommand.Action

// usage
command := &commandwrapper.PlainCommand{
    Keys:        []string{KEYS...},
    Action: func(ctx *commandwrapper.Context) error {
        return nil
    },
}

// example for command, called 'ping'
command := &commandwrapper.PlainCommand{
    Keys: []string{"ping"},
    Action: func(ctx *commandwrapper.Context) error {
        if len(ctx.Args) == 1 && commons.EqualsString(ctx.Args[0], "embed", true) {
            _, err := ctx.SendEmbedTyping(&discordgo.MessageEmbed{Description: "PONG!"})
            return err
        } else {
            _, err := ctx.SendMessageTyping("PONG!")
            return err
        }
    },
}
Add/Register the command in the wrapper

Finally, you must register the command. This is possible with the CommandRepository.

wrapper.GetRepository().RegisterCommand(command)
Configure the Wrapper with an given Configuration

The configuration is there to define basic variables that the actions change the wrapper.

configuration := &commandwrapper.Configuration{
    IgnoreCase: true,
}

wrapper := &commandwrapper.PlainWrapper{
    BotApplication: BOT,
    PrefixGenerator: func(ctx *commandwrapper.Context) []commandwrapper.CommandPrefix {
        return []commandwrapper.CommandPrefix{PREFIXES...}
        },
    Configuration: configuration,
}

Type Definitions
commons.Props

If you have no experience with commons.Props, see docs and commons.

CommandPrefix

A CommandPrefix is, as the name says, the global prefix of a command wrapper with the type of an string.

It could be empty.

e.g.:

Message Prefix
!help '!'
@Bot#0000 help '@Bot#0000 '
help ''
ErrorHandler

The ErrorHandler is a function which is called when an error occurs during processing or execution of the command.

The parameter of type error will not get passed by doll as nil.

See errors.go and docs.

CommandUsage

The CommandUsage is a string that defines the structure of a specific command.

e.g.:

[Command] is the command usage of !help -> !help [Command]

CommandDescription

The CommandDescription is a string that describes the task of a specific command.

e.g.:

commands -> Sends the list of registered commands into the current channel.

CommandAccessor

The CommandAccessor is a command-specific function that returns a bool that defines whether the command is accessible/visible with the current context.

The CommandAccessor is a command specific function that returns whether the command is visible for - i.e. accessible by - the current context.

accessor := func(ctx *commandwrapper.Context) bool {
    return !ctx.Match.GetProps().HasProperty("devOnly") || commons.EqualsString(ctx.Author.ID, "370883999528124416", false)
}

command := &commandwrapper.PlainCommand{
    Keys:     []string{"ping"},
    Accessor: accessor,
    Action: func(ctx *commandwrapper.Context) error {
        _, _ = ctx.SendMessageTyping("super secret shit activated")
        return nil
    },
}
CommandTriggers

Defines whether the respective command can be executed in a specific channel type. If this should not be the case, an error is passed to the ErrorHandler.

The CommandTriggers define whether the respective command can be executed in a specific channel type.

// simple usage
triggers := commandwrapper.NewTriggers( /* dm: */ true, /* guild: */ true)

// advanced usage
triggers := &commandwrapper.CommandTriggers{
    DM:    true,
    Guild: true,
    Group: false,
    Other: true,
}


command := &commandwrapper.PlainCommand{
    Keys:     []string{PREFIXES...},
    Triggers: triggers,
    Action: func(ctx *commandwrapper.Context) error {
            // add code here
         return nil
    },
}
The Context

The context contains all variables that were accessible when the function is called.

command := &commandwrapper.PlainCommand{
    Keys: []string{"whoami"},

        // function with Context
    Action: func(ctx *commandwrapper.Context) error {
        if session, err := ctx.BotApplication.Session(); err == nil {
            _, _ = ctx.SendMessageTyping(fmt.Sprintf("My name is %s.", session.State.User.String()))
            return nil
        } else {
            return err
        }
    },

}
Advanced Usage
Create A Custom Command

Doll allows you, to create a completely own command struct.

Here is a little tutorial, how you're able to create such an command.

  • Create a struct and inherit Command.
type CustomCommand struct {
    commandwrapper.Command
}
  • Define in any way the name(s) of the command. I use a []string called "Keys" for this.
type CustomCommand struct {
    commandwrapper.Command

    Keys []string
}
  • Now implement the functions of the Command interface. See this.
type CustomCommand struct {
    commandwrapper.Command

    Keys        []string
    Description commandwrapper.CommandDescription
    Usage       commandwrapper.CommandUsage
    Triggers    *commandwrapper.CommandTriggers

    NeededPermission commons.Permission // 0, if no permission is required, use commons.Permission for an easier permission test

    Props  commons.Props
    Action commandwrapper.CommandFunction
}

func (cmd *CustomCommand) GetPrimaryKey() string {
    return cmd.Keys[0]
}

func (cmd *CustomCommand) IsDesignatedBy(designation string, ignoreCase bool) bool {
    return commons.ContainsString(cmd.Keys, designation, ignoreCase) // test if the Keys contains the designation (=label)
}

func (cmd *CustomCommand) GetProps() commons.Props {
    if cmd.Props == nil {
        cmd.Props = commons.NewProps(nil) // apply default
    }
    return cmd.Props
}

func (cmd *CustomCommand) GetDescription() commandwrapper.CommandDescription {
    return cmd.Description
}

func (cmd *CustomCommand) GetUsage() commandwrapper.CommandUsage {
    return cmd.Usage
}

func (cmd *CustomCommand) GetTriggers() *commandwrapper.CommandTriggers {
    if cmd.Triggers == nil {
        cmd.Triggers = commandwrapper.NewTriggers(true, true) // apply default
    }
    return cmd.Triggers
}

func (cmd *CustomCommand) IsAccessible(ctx *commandwrapper.Context) bool {
    return true // everyone can access/see the command
}

func (cmd *CustomCommand) IsChannelValid(ctx *commandwrapper.Context) bool {
    return (ctx.Channel.Type == discordgo.ChannelTypeDM && cmd.GetTriggers().DM) || (ctx.Channel.Type == discordgo.ChannelTypeGuildText && cmd.GetTriggers().Guild) || (ctx.Channel.Type == discordgo.ChannelTypeGroupDM && cmd.GetTriggers().Group)
}

func (cmd *CustomCommand) IsAuthorPermitted(ctx *commandwrapper.Context) bool {
    if session, err := ctx.BotApplication.Session(); err == nil {
        return cmd.NeededPermission.HasPermission(session, ctx.Author.ID, ctx.ChannelID)
    } else {
        return false // if error appears, I return false
    }
}

func (cmd *CustomCommand) Run(ctx *commandwrapper.Context) error {
    if cmd.Action != nil {
        return cmd.Action(ctx)
    } else {
        return nil
    }
}
wrapper.GetRepository().RegisterCommand(command)

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsAuthorNotPermitted

func IsAuthorNotPermitted(err error) bool

func IsCommandMessage

func IsCommandMessage(composite *MessageComposite) bool

IsCommandMessage returns whether the content of the MessageComposite is valid for the handler.

func IsCommandRun

func IsCommandRun(err error) bool

func IsInvalidChannel

func IsInvalidChannel(err error) bool

func IsNoAccess

func IsNoAccess(err error) bool

func IsNoPrefixUsed

func IsNoPrefixUsed(err error) bool

func IsNotFound

func IsNotFound(err error) bool

func IsPrefixOnly

func IsPrefixOnly(err error) bool

func ReceiveMessage

func ReceiveMessage(composite *MessageComposite)

ReceiveMessage processes the MessageComposite within the handler.

func UnwrapCommandRun

func UnwrapCommandRun(err error) error

func UsePermission

func UsePermission(command Command, permission commons.Permission)

UsePermission defines the permission needed for the user to execute the command,

Types

type Command

type Command interface {
	GetPrimaryKey() string
	IsDesignatedBy(designation string, ignoreCase bool) bool

	GetProps() commons.Props

	/* Specs */
	GetDescription() CommandDescription
	GetUsage() CommandUsage
	GetTriggers() *CommandTriggers

	IsAccessible(ctx *Context) bool
	IsChannelValid(ctx *Context) bool
	IsAuthorPermitted(ctx *Context) bool

	Run(ctx *Context) error
}

type CommandAccessor

type CommandAccessor func(ctx *Context) bool

CommandAccessor is a simple type declaration for a Accessibility-Test-Function. See https://github.com/projectdoll/command-wrapper#CommandAccessor

type CommandDescription

type CommandDescription string

CommandDescription is used to describe a command in more detail. See https://github.com/projectdoll/command-wrapper#CommandDescription

func NoDescription

func NoDescription() CommandDescription

NoDescription returns an empty CommandDescription.

type CommandFilter

type CommandFilter func(command Command) bool

type CommandFunction

type CommandFunction func(ctx *Context) error

CommandFunction is a simple type declaration for a Action of an Command. See https://github.com/projectdoll/command-wrapper

type CommandMap

type CommandMap map[string]Command

type CommandPrefix

type CommandPrefix string

type CommandRepository

type CommandRepository struct {
	Map CommandMap
}

func NewRepository

func NewRepository(cmdMap CommandMap) *CommandRepository

func (*CommandRepository) Commands

func (repo *CommandRepository) Commands() []Command

func (*CommandRepository) FilterCommands

func (repo *CommandRepository) FilterCommands(filter CommandFilter) []Command

func (*CommandRepository) FindCommandByPrimaryKey

func (repo *CommandRepository) FindCommandByPrimaryKey(primaryKey string) (Command, error)

func (*CommandRepository) FindCommandsByDesignations

func (repo *CommandRepository) FindCommandsByDesignations(designation string, ignoreCase bool) []Command

func (*CommandRepository) HasCommandWithPrimaryKey

func (repo *CommandRepository) HasCommandWithPrimaryKey(primaryKey string) bool

func (*CommandRepository) RegisterCommand

func (repo *CommandRepository) RegisterCommand(command Command)

func (*CommandRepository) RegisterCommands

func (repo *CommandRepository) RegisterCommands(commands ...Command)

func (*CommandRepository) UnregisterCommand

func (repo *CommandRepository) UnregisterCommand(command Command)

func (*CommandRepository) UnregisterCommandWithPrimaryKey

func (repo *CommandRepository) UnregisterCommandWithPrimaryKey(primaryKey string)

func (*CommandRepository) UnregisterCommands

func (repo *CommandRepository) UnregisterCommands(commands ...Command)

func (*CommandRepository) UnregisterCommandsWithPrimaryKeys

func (repo *CommandRepository) UnregisterCommandsWithPrimaryKeys(primaryKeys ...string)

type CommandTriggers

type CommandTriggers struct {
	DM    bool `default:"true"`
	Guild bool `default:"true`
	Other bool `default:"true`
}

CommandTriggers defines the channel types which are accepted during processing.

func NewTriggers

func NewTriggers(dm, guild bool) *CommandTriggers

NewTriggers creates a new CommandTriggers and returns it.

type CommandUsage

type CommandUsage string

CommandUsage is used to represent the argument structure of a command. See https://github.com/projectdoll/command-wrapper#CommandUsage

func NoUsage

func NoUsage() CommandUsage

NoUsage returns an empty CommandUsage.

type Configuration

type Configuration struct {
	Async      bool
	IgnoreCase bool
}

func NewConfiguration

func NewConfiguration(async, ignoreCase bool) *Configuration

type Context

type Context struct {
	*MessageComposite `json:"-"`
	Prefix            CommandPrefix `json:"prefix"`
	PrefixFound       bool          `json:"prefix_found"`
	Trim              string        `json:"trim"`
	Beheaded          string        `json:"beheaded"`
	Cut               string        `json:"cut"`
	Label             string        `json:"label"`
	Split             []string      `json:"split"`
	Args              []string      `json:"args"`
	Matches           []Command     `json:"-"`
	Match             Command       `json:"-"`
}

func (*Context) EditEmbedTyping

func (ctx *Context) EditEmbedTyping(messageID string, embed *discordgo.MessageEmbed) (*discordgo.Message, error)

func (*Context) EditMessageTyping

func (ctx *Context) EditMessageTyping(messageID, content string) (*discordgo.Message, error)

func (*Context) SendEmbedTyping

func (ctx *Context) SendEmbedTyping(embed *discordgo.MessageEmbed) (*discordgo.Message, error)

func (*Context) SendMessageTyping

func (ctx *Context) SendMessageTyping(content string) (*discordgo.Message, error)

func (*Context) String

func (ctx *Context) String() (string, error)

type ErrorHandler

type ErrorHandler func(ctx *Context, err error)

type MessageComposite

type MessageComposite struct {
	*discordgo.Message
	BotApplication commons.BotApplication
	Wrapper        Wrapper
	Channel        *discordgo.Channel
}

type PlainCommand

type PlainCommand struct {
	Command

	Keys  []string
	Props commons.Props

	Description CommandDescription
	Usage       CommandUsage
	Triggers    *CommandTriggers

	Accessor CommandAccessor

	Action CommandFunction
}

PlainCommand is a simple command implementation for a command. See: https://github.com/projectdoll/command-wrapper#Command, https://github.com/projectdoll/command-wrapper#create-a-custom-command

func (*PlainCommand) GetDescription

func (plain *PlainCommand) GetDescription() CommandDescription

GetDescription returns the Description of the PlainCommand.

func (*PlainCommand) GetPrimaryKey

func (plain *PlainCommand) GetPrimaryKey() string

GetPrimaryKey returns the first key of PlainCommand.

func (*PlainCommand) GetProps

func (plain *PlainCommand) GetProps() commons.Props

GetProps returns the Props of the PlainCommand.

func (*PlainCommand) GetTriggers

func (plain *PlainCommand) GetTriggers() *CommandTriggers

GetTriggers returns the Triggers of the PlainCommand.

func (*PlainCommand) GetUsage

func (plain *PlainCommand) GetUsage() CommandUsage

GetUsage returns the Usage of the PlainCommand.

func (*PlainCommand) IsAccessible

func (plain *PlainCommand) IsAccessible(ctx *Context) bool

func (*PlainCommand) IsAuthorPermitted

func (plain *PlainCommand) IsAuthorPermitted(ctx *Context) bool

func (*PlainCommand) IsChannelValid

func (plain *PlainCommand) IsChannelValid(ctx *Context) bool

func (*PlainCommand) IsDesignatedBy

func (plain *PlainCommand) IsDesignatedBy(designated string, ignoreCase bool) bool

IsDesignatedBy tests if the Keys of the PlainCommand contains a designation.

func (*PlainCommand) Run

func (plain *PlainCommand) Run(ctx *Context) error

Run executes the command.

type PlainWrapper

type PlainWrapper struct {
	Wrapper

	BotApplication commons.BotApplication

	Repository    *CommandRepository
	Configuration *Configuration

	PrefixGenerator   PrefixGenerator
	ErrorHandler      ErrorHandler
	PrefixOnlyHandler PrefixOnlyHandler

	Props commons.Props
}

func (*PlainWrapper) GeneratePrefixes

func (plain *PlainWrapper) GeneratePrefixes(ctx *Context) []CommandPrefix

func (*PlainWrapper) GetBotApplication

func (plain *PlainWrapper) GetBotApplication() commons.BotApplication

func (*PlainWrapper) GetConfiguration

func (plain *PlainWrapper) GetConfiguration() *Configuration

func (*PlainWrapper) GetRepository

func (plain *PlainWrapper) GetRepository() *CommandRepository

func (*PlainWrapper) HandleError

func (plain *PlainWrapper) HandleError(ctx *Context, err error)

func (*PlainWrapper) HandlePrefixOnly

func (plain *PlainWrapper) HandlePrefixOnly(ctx *Context)

func (*PlainWrapper) StartListening

func (plain *PlainWrapper) StartListening()

type PrefixGenerator

type PrefixGenerator func(ctx *Context) []CommandPrefix

type PrefixOnlyHandler

type PrefixOnlyHandler func(ctx *Context)

type Wrapper

type Wrapper interface {
	GetBotApplication() commons.BotApplication

	GetRepository() *CommandRepository
	GetConfiguration() *Configuration

	GeneratePrefixes(ctx *Context) []CommandPrefix
	HandleError(ctx *Context, err error)
	HandlePrefixOnly(ctx *Context)

	StartListening()

	GetProps() commons.Props
}

func NewWrapper

func NewWrapper(botApplication commons.BotApplication, prefixes ...CommandPrefix) Wrapper

Jump to

Keyboard shortcuts

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