package discord_router import "github.com/bwmarrin/discordgo" type HandlerFunc func(*discordgo.Session, *discordgo.InteractionCreate) type RouteEntry struct { CommandName string Handler HandlerFunc } func (re *RouteEntry) Match(i *discordgo.InteractionCreate) bool { switch i.Type { case discordgo.InteractionApplicationCommand: if i.ApplicationCommandData().Name != re.CommandName { return false } case discordgo.InteractionMessageComponent: if i.MessageComponentData().CustomID != re.CommandName { return false } } return true } type Router struct { session *discordgo.Session routes []RouteEntry group []Group } func NewApp(s *discordgo.Session) *Router { return &Router{ session: s, } } func (r *Router) Route(cmd string, handlerFunc HandlerFunc) *Router { r.routes = append(r.routes, RouteEntry{ CommandName: cmd, Handler: handlerFunc, }) return r } func (r *Router) Serve(s *discordgo.Session, i *discordgo.InteractionCreate) { for _, e := range r.routes { ok := e.Match(i) if ok { e.Handler(s, i) } } for _, g := range r.group { for _, e := range g.routes { ok := e.Match(i) if ok { if len(g.middleware) < 1 { e.Handler(s, i) } wrapped := e.Handler // loop in reverse to preserve middleware order for i := len(g.middleware) - 1; i >= 0; i-- { wrapped = g.middleware[i](wrapped) } wrapped(s, i) } } } } type Middleware func(HandlerFunc) HandlerFunc type Group struct { routes []RouteEntry middleware []Middleware } func (r *Router) Use(m ...Middleware) *Group { r.group = append(r.group, Group{ routes: []RouteEntry{}, middleware: m, }) return &r.group[len(r.group)-1] } func (g *Group) Route(cmd string, handlerFunc HandlerFunc) *Group { g.routes = append(g.routes, RouteEntry{ CommandName: cmd, Handler: handlerFunc, }) return g }