|
@@ -0,0 +1,151 @@
|
|
|
+package mux
|
|
|
+
|
|
|
+import (
|
|
|
+ "errors"
|
|
|
+ "strings"
|
|
|
+
|
|
|
+ "github.com/Sirupsen/logrus"
|
|
|
+
|
|
|
+ "github.com/thisnthat-dev/discordgo"
|
|
|
+)
|
|
|
+
|
|
|
+// RouteOptions holds information about a specific message route handler
|
|
|
+type RouteOptions struct {
|
|
|
+ Name string // match name that should trigger this route handler
|
|
|
+ Description string // short description of this route
|
|
|
+ Type RouteType // The type of route this is
|
|
|
+ Callback Handler // route handler function to call
|
|
|
+}
|
|
|
+
|
|
|
+type route struct {
|
|
|
+ Name string
|
|
|
+ Description string
|
|
|
+ Type RouteType
|
|
|
+ Run Handler
|
|
|
+}
|
|
|
+
|
|
|
+// RouteType is the type of route being created
|
|
|
+type RouteType int
|
|
|
+
|
|
|
+const (
|
|
|
+ // MessageRoute is a route for handling OnMessageCreate events
|
|
|
+ MessageRoute RouteType = 1001
|
|
|
+)
|
|
|
+
|
|
|
+// Handler is the function signature required for a message route handler.
|
|
|
+type Handler func(*discordgo.Session, *discordgo.Message, *Context)
|
|
|
+
|
|
|
+// Context holds a bit of extra data we pass along to route handlers
|
|
|
+// This way processing some of this only needs to happen once.
|
|
|
+type Context struct {
|
|
|
+ Fields []string
|
|
|
+ Content string
|
|
|
+ isDirectMessage bool // Indicates the message was sent via direct message
|
|
|
+ Method Method
|
|
|
+}
|
|
|
+
|
|
|
+// Method is the method a command was received
|
|
|
+type Method int
|
|
|
+
|
|
|
+const (
|
|
|
+ // DirectMethod Discord DM to the bot
|
|
|
+ DirectMethod Method = 1001
|
|
|
+ // MentionMethod is a message started with a @mention to the bot
|
|
|
+ MentionMethod Method = 1002
|
|
|
+ // PrefixMethod is a message started with a command prefix
|
|
|
+ PrefixMethod Method = 1003
|
|
|
+)
|
|
|
+
|
|
|
+// Router is the main struct for all mux methods.
|
|
|
+type Router struct {
|
|
|
+ routes []*route
|
|
|
+ helpRoute *route
|
|
|
+ prefix string
|
|
|
+}
|
|
|
+
|
|
|
+// New returns a new Discord message route mux
|
|
|
+func New() *Router {
|
|
|
+ r := &Router{}
|
|
|
+
|
|
|
+ helpRoute := &route{}
|
|
|
+ helpRoute.Name = "help"
|
|
|
+ helpRoute.Description = "Get Help"
|
|
|
+ helpRoute.Run = r.helpCommandHandler
|
|
|
+
|
|
|
+ r.helpRoute = helpRoute
|
|
|
+
|
|
|
+ return r
|
|
|
+}
|
|
|
+
|
|
|
+// SetCommandPrefix will set the prefix used for message commands
|
|
|
+func (r *Router) SetCommandPrefix(cmdPrefix string) {
|
|
|
+ r.prefix = cmdPrefix + " "
|
|
|
+}
|
|
|
+
|
|
|
+// ErrRegisterRouteNameRequired is returned when registering a new route without a name
|
|
|
+var ErrRegisterRouteNameRequired = errors.New("All routes must have a name")
|
|
|
+
|
|
|
+// ErrRegisterInvalidRouteType is returned when registering a new route with an invalid type
|
|
|
+var ErrRegisterInvalidRouteType = errors.New("Invalid route type")
|
|
|
+
|
|
|
+// ErrRegisterCallbackRequired is returned when registering a new route without a callback
|
|
|
+var ErrRegisterCallbackRequired = errors.New("A valid callback must be provided")
|
|
|
+
|
|
|
+// Register allows you to register a route
|
|
|
+//func (r *Router) Register(routeType RouteType, name, desc string, callback Handler) (*Route, error) {
|
|
|
+func (r *Router) Register(name string, options RouteOptions) error {
|
|
|
+ if name == "" {
|
|
|
+ return ErrRegisterRouteNameRequired
|
|
|
+ }
|
|
|
+
|
|
|
+ if !isValidRouteType(options.Type) {
|
|
|
+ return ErrRegisterInvalidRouteType
|
|
|
+ }
|
|
|
+
|
|
|
+ if options.Callback == nil {
|
|
|
+ return ErrRegisterCallbackRequired
|
|
|
+ }
|
|
|
+
|
|
|
+ route := route{}
|
|
|
+ route.Type = options.Type
|
|
|
+ route.Name = name
|
|
|
+ route.Description = options.Description
|
|
|
+ route.Run = options.Callback
|
|
|
+ r.routes = append(r.routes, &route)
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func isValidRouteType(routeType RouteType) bool {
|
|
|
+ switch routeType {
|
|
|
+ case MessageRoute:
|
|
|
+ return true
|
|
|
+ }
|
|
|
+
|
|
|
+ return false
|
|
|
+}
|
|
|
+
|
|
|
+func (r *Router) findRoute(searchString string, routeType RouteType) (*route, []string) {
|
|
|
+ logrus.Printf("Find Route: %s", searchString)
|
|
|
+ fields := strings.Fields(searchString)
|
|
|
+
|
|
|
+ if len(fields) == 0 {
|
|
|
+ logrus.Printf("No route Found")
|
|
|
+ return nil, nil
|
|
|
+ }
|
|
|
+
|
|
|
+ commandKey := fields[0]
|
|
|
+
|
|
|
+ for _, route := range r.routes {
|
|
|
+ if route.Type != routeType {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ if strings.ToLower(commandKey) == strings.ToLower(route.Name) {
|
|
|
+ logrus.Printf("Route Found: %s", route.Name)
|
|
|
+ return route, fields[0:]
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil, nil
|
|
|
+}
|