router.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. package mux
  2. import (
  3. "errors"
  4. "strings"
  5. "github.com/Sirupsen/logrus"
  6. "github.com/thisnthat-dev/discordgo"
  7. )
  8. // RouteOptions holds information about a specific message route handler
  9. type RouteOptions struct {
  10. Name string // match name that should trigger this route handler
  11. Description string // short description of this route
  12. Type RouteType // The type of route this is
  13. Callback Handler // route handler function to call
  14. }
  15. type route struct {
  16. Name string
  17. Description string
  18. Type RouteType
  19. Run Handler
  20. }
  21. // RouteType is the type of route being created
  22. type RouteType int
  23. const (
  24. // MessageRoute is a route for handling OnMessageCreate events
  25. MessageRoute RouteType = 1001
  26. )
  27. // Handler is the function signature required for a message route handler.
  28. type Handler func(*discordgo.Session, *discordgo.Message, *Context)
  29. // Context holds a bit of extra data we pass along to route handlers
  30. // This way processing some of this only needs to happen once.
  31. type Context struct {
  32. Fields []string
  33. Content string
  34. isDirectMessage bool // Indicates the message was sent via direct message
  35. Method Method
  36. }
  37. // Method is the method a command was received
  38. type Method int
  39. const (
  40. // DirectMethod Discord DM to the bot
  41. DirectMethod Method = 1001
  42. // MentionMethod is a message started with a @mention to the bot
  43. MentionMethod Method = 1002
  44. // PrefixMethod is a message started with a command prefix
  45. PrefixMethod Method = 1003
  46. )
  47. // Router is the main struct for all mux methods.
  48. type Router struct {
  49. routes []*route
  50. helpRoute *route
  51. prefix string
  52. }
  53. // New returns a new Discord message route mux
  54. func New() *Router {
  55. r := &Router{}
  56. helpRoute := &route{}
  57. helpRoute.Name = "help"
  58. helpRoute.Description = "Get Help"
  59. helpRoute.Run = r.helpCommandHandler
  60. r.helpRoute = helpRoute
  61. return r
  62. }
  63. // SetCommandPrefix will set the prefix used for message commands
  64. func (r *Router) SetCommandPrefix(cmdPrefix string) {
  65. r.prefix = cmdPrefix + " "
  66. }
  67. // ErrRegisterRouteNameRequired is returned when registering a new route without a name
  68. var ErrRegisterRouteNameRequired = errors.New("All routes must have a name")
  69. // ErrRegisterInvalidRouteType is returned when registering a new route with an invalid type
  70. var ErrRegisterInvalidRouteType = errors.New("Invalid route type")
  71. // ErrRegisterCallbackRequired is returned when registering a new route without a callback
  72. var ErrRegisterCallbackRequired = errors.New("A valid callback must be provided")
  73. // Register allows you to register a route
  74. //func (r *Router) Register(routeType RouteType, name, desc string, callback Handler) (*Route, error) {
  75. func (r *Router) Register(name string, options RouteOptions) error {
  76. if name == "" {
  77. return ErrRegisterRouteNameRequired
  78. }
  79. if !isValidRouteType(options.Type) {
  80. return ErrRegisterInvalidRouteType
  81. }
  82. if options.Callback == nil {
  83. return ErrRegisterCallbackRequired
  84. }
  85. route := route{}
  86. route.Type = options.Type
  87. route.Name = name
  88. route.Description = options.Description
  89. route.Run = options.Callback
  90. r.routes = append(r.routes, &route)
  91. return nil
  92. }
  93. func isValidRouteType(routeType RouteType) bool {
  94. switch routeType {
  95. case MessageRoute:
  96. return true
  97. }
  98. return false
  99. }
  100. func (r *Router) findRoute(searchString string, routeType RouteType) (*route, []string) {
  101. logrus.Printf("Find Route: %s", searchString)
  102. fields := strings.Fields(searchString)
  103. if len(fields) == 0 {
  104. logrus.Printf("No route Found")
  105. return nil, nil
  106. }
  107. commandKey := fields[0]
  108. for _, route := range r.routes {
  109. if route.Type != routeType {
  110. continue
  111. }
  112. if strings.ToLower(commandKey) == strings.ToLower(route.Name) {
  113. logrus.Printf("Route Found: %s", route.Name)
  114. return route, fields[0:]
  115. }
  116. }
  117. return nil, nil
  118. }