package nechotron import ( "strings" "github.com/NicoNex/echotron/v3" ) type UpdateHandler func(u *Update) error type CommandHandler func(u *Update, arg string) error type CallbackHandler func(u *Update, data string) error type dispatchHandler func(u *Update) (bool, error) type Dispatcher struct { handlers []dispatchHandler } func NewDispatcher() *Dispatcher { return &Dispatcher{} } func (d *Dispatcher) Run(u *Update) error { for _, h := range d.handlers { executed, err := h(u) if executed { return err } } return nil } func (d *Dispatcher) Handle(handler func(u *Update) (bool, error)) *Dispatcher { d.handlers = append(d.handlers, handler) return d } func (d *Dispatcher) HandleCommand(command *Command, handler CommandHandler) *Dispatcher { newHandler := func(u *Update) (bool, error) { if !strings.HasPrefix(u.Text(), command.String()) { return false, nil } if command.IsAdminOnly && !IsUserAdmin(u) && u.ChatID() < 0 { return false, nil } err := handler(u, command.Param(u.Text())) return true, err } d.handlers = append(d.handlers, newHandler) return d } func (d *Dispatcher) HandleFilter(filter FilterFn, handler UpdateHandler) *Dispatcher { newHandler := func(u *Update) (bool, error) { if !filter(u) { return false, nil } err := handler(u) return true, err } d.handlers = append(d.handlers, newHandler) return d } func (d *Dispatcher) HandleCallback(filter CallbackFilter, handler UpdateHandler) *Dispatcher { newHandler := func(u *Update) (bool, error) { if !u.IsCallback() { return false, nil } defer u.Bot.AnswerCallbackQuery(u.CallbackQuery.ID, &echotron.CallbackQueryOptions{}) if !filter(u) { return false, nil } err := handler(u) return true, err } d.handlers = append(d.handlers, newHandler) return d } func (d *Dispatcher) HandleReply(handler UpdateHandler) *Dispatcher { newHandler := func(u *Update) (bool, error) { if !u.IsMessage() { return false, nil } if u.Message.ReplyToMessage == nil { return false, nil } err := handler(u) return true, err } d.handlers = append(d.handlers, newHandler) return d } // Runs each dispatcher or handled listed here until error is returned from any func RunEach(u *Update, disps ...*Dispatcher) error { for _, d := range disps { if err := d.Run(u); err != nil { return err } } return nil }