diff --git a/bot.go b/bot.go index 48deae9..118c29f 100644 --- a/bot.go +++ b/bot.go @@ -10,12 +10,21 @@ import ( ) type bot struct { - chatID int64 - me *echo.User echo.API - data StateData - lock sync.Mutex - state Runnable + chatID int64 + me *echo.User + data StateData + lock sync.Mutex + state Runnable + handler UpdateHandler +} + +func DefaultHandler(u *Update) error { + err := u.Bot.state.Call(u) + if err != nil { + u.LogError("", err, true) + } + return err } func (b *bot) Update(u *echo.Update) { @@ -30,8 +39,5 @@ func (b *bot) Update(u *echo.Update) { b.lock.Lock() defer b.lock.Unlock() - err := b.state.Call(upd) - if err != nil { - upd.LogError("", err, true) - } + b.handler(upd) } diff --git a/command.go b/command.go index 894dbee..a3da25c 100644 --- a/command.go +++ b/command.go @@ -1,16 +1,21 @@ package nechotron -import "strings" +import ( + "fmt" + "strings" +) type Command struct { Body string IsAdminOnly bool + Description string } -func NewCommand(body string, isAdminOnly bool) *Command { +func NewCommand(body string, desc string, isAdminOnly bool) *Command { return &Command{ Body: body, IsAdminOnly: isAdminOnly, + Description: desc, } } func (c *Command) String() string { @@ -21,4 +26,12 @@ func (c *Command) Param(text string) string { return strings.TrimPrefix(text, "/"+c.Body+" ") } +func MakeCommandList(commands []*Command, format string) string { + result := "" + for _, command := range commands { + result += fmt.Sprintf(format, command.String(), command.Description) + } + return result +} + // func HandleCommand(command *Command, handler cmdFunc) (bool, error) diff --git a/dispatcher.go b/dispatcher.go index a811e8a..36da8d1 100644 --- a/dispatcher.go +++ b/dispatcher.go @@ -4,8 +4,8 @@ import ( "strings" ) +type UpdateHandler func(u *Update) error type dispatchHandler func(u *Update) (bool, error) -type updateHandler func(u *Update) error type commandHandler func(u *UpdateCommand) error type Dispatcher struct { @@ -45,7 +45,7 @@ func (d *Dispatcher) HandleCommand(command *Command, handler commandHandler) *Di return d } -func (d *Dispatcher) HandleFilter(filter FilterFn, handler updateHandler) *Dispatcher { +func (d *Dispatcher) HandleFilter(filter FilterFn, handler UpdateHandler) *Dispatcher { newHandler := func(u *Update) (bool, error) { if !filter(u) { return false, nil diff --git a/middleware.go b/middleware.go new file mode 100644 index 0000000..79a6334 --- /dev/null +++ b/middleware.go @@ -0,0 +1,3 @@ +package nechotron + +type Middleware func(next UpdateHandler) UpdateHandler diff --git a/nechotron.go b/nechotron.go index 831e4b2..1162496 100644 --- a/nechotron.go +++ b/nechotron.go @@ -10,6 +10,7 @@ type Nechotron struct { Token string DefaultState Runnable ApiServer string + Handler UpdateHandler } func NewTron(token string, defaultState *State) *Nechotron { @@ -20,6 +21,7 @@ func NewTron(token string, defaultState *State) *Nechotron { return &Nechotron{ Token: token, DefaultState: state, + Handler: DefaultHandler, } } @@ -29,11 +31,12 @@ func (n *Nechotron) newBot(chatID int64) echo.Bot { me, _ := a.GetMe() // log.Println("New bot active: ", chatID, me.Result) b := &bot{ - chatID: chatID, - me: me.Result, - API: a, - state: n.DefaultState, - data: make(StateData), + chatID: chatID, + me: me.Result, + API: a, + state: n.DefaultState, + data: make(StateData), + handler: n.Handler, } b.state = n.DefaultState return b @@ -44,3 +47,8 @@ func (n *Nechotron) DispatchPoll() error { log.Println("Nechotron poll dispatcher started") return dispatcher.Poll() } + +func (n *Nechotron) Use(mid Middleware) *Nechotron { + n.Handler = mid(n.Handler) + return n +} diff --git a/update.go b/update.go index 6af009b..f6b8b7a 100644 --- a/update.go +++ b/update.go @@ -14,7 +14,7 @@ type U echotron.Update var emptyOpts = echotron.MessageOptions{} type Event interface { - Update + Upd() *echotron.Update } type Update struct {