nechotron/dispatcher.go

105 lines
2.3 KiB
Go

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
}