Dispatcher, Commands, Filters, Markdown escaping
This commit is contained in:
parent
677f28182a
commit
e2ba9565d5
5
bot.go
5
bot.go
|
@ -30,11 +30,8 @@ func (b *bot) Update(u *echo.Update) {
|
|||
|
||||
b.lock.Lock()
|
||||
defer b.lock.Unlock()
|
||||
newState, err := b.state.Call(upd)
|
||||
err := b.state.Call(upd)
|
||||
if err != nil {
|
||||
upd.LogError("", err, true)
|
||||
}
|
||||
if newState != nil {
|
||||
b.state = newState
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package nechotron
|
||||
|
||||
import "strings"
|
||||
|
||||
type Command struct {
|
||||
Body string
|
||||
IsAdminOnly bool
|
||||
}
|
||||
|
||||
func NewCommand(body string, isAdminOnly bool) *Command {
|
||||
return &Command{
|
||||
Body: body,
|
||||
IsAdminOnly: isAdminOnly,
|
||||
}
|
||||
}
|
||||
func (c *Command) String() string {
|
||||
return "/" + c.Body
|
||||
}
|
||||
|
||||
func (c *Command) Param(text string) string {
|
||||
return strings.TrimPrefix(text, "/"+c.Body+" ")
|
||||
}
|
||||
|
||||
// func HandleCommand(command *Command, handler cmdFunc) (bool, error)
|
|
@ -0,0 +1,58 @@
|
|||
package nechotron
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
type dispatchHandler func(u *Update) (bool, error)
|
||||
type updateHandler func(u *Update) error
|
||||
type commandHandler func(u *UpdateCommand) 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) 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 && !u.IsUserAdmin() {
|
||||
return false, nil
|
||||
}
|
||||
upd := &UpdateCommand{
|
||||
Update: *u,
|
||||
Param: command.Param(u.Text()),
|
||||
}
|
||||
err := handler(upd)
|
||||
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
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package nechotron
|
||||
|
||||
import "strings"
|
||||
|
||||
type FilterFn func(u *Update) bool
|
||||
|
||||
func TextStartsWith(text string) FilterFn {
|
||||
return func(u *Update) bool {
|
||||
return strings.HasPrefix(u.Text(), text)
|
||||
}
|
||||
}
|
||||
|
||||
func TextHas(text string) FilterFn {
|
||||
return func(u *Update) bool {
|
||||
return strings.Contains(u.Text(), text)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package nechotron
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var chars = []string{"_", "*", "\\[", "\\]", "\\(", "\\)", "~", "`", ">", "#", "+", "-", "=", "|", "{", "}", ".", "!"}
|
||||
var r = strings.Join(chars, "")
|
||||
var reg = regexp.MustCompile("[" + r + "]+")
|
||||
|
||||
func EscapeMd2(s string) string {
|
||||
return reg.ReplaceAllString(s, "\\$0")
|
||||
}
|
|
@ -24,7 +24,7 @@ func NewTron(token string, defaultState *State) *Nechotron {
|
|||
}
|
||||
|
||||
func (n *Nechotron) newBot(chatID int64) echo.Bot {
|
||||
a := echo.NewCustomAPI(n.Token, n.ApiServer)
|
||||
a := echo.NewAPI(n.Token)
|
||||
// a := echo.NewAPI(n.Token)
|
||||
me, _ := a.GetMe()
|
||||
// log.Println("New bot active: ", chatID, me.Result)
|
||||
|
|
10
state.go
10
state.go
|
@ -9,18 +9,18 @@ import (
|
|||
type StateData map[string]interface{}
|
||||
|
||||
type Runnable interface {
|
||||
Call(*Update) (Runnable, error)
|
||||
Call(*Update) error
|
||||
}
|
||||
|
||||
type State struct {
|
||||
Fn stateFn
|
||||
}
|
||||
|
||||
func (s *State) Call(u *Update) (Runnable, error) {
|
||||
func (s *State) Call(u *Update) error {
|
||||
return s.Fn(u)
|
||||
}
|
||||
|
||||
type stateFn func(*Update) (Runnable, error)
|
||||
type stateFn func(*Update) error
|
||||
|
||||
func (d StateData) Set(name string, data interface{}) {
|
||||
d[name] = data
|
||||
|
@ -49,7 +49,7 @@ var EchoState = State{
|
|||
Fn: EchoFunc,
|
||||
}
|
||||
|
||||
func EchoFunc(u *Update) (Runnable, error) {
|
||||
func EchoFunc(u *Update) error {
|
||||
u.AnswerText(u.Text(), &echotron.MessageOptions{})
|
||||
return nil, nil
|
||||
return nil
|
||||
}
|
||||
|
|
23
update.go
23
update.go
|
@ -13,6 +13,10 @@ type U echotron.Update
|
|||
|
||||
var emptyOpts = echotron.MessageOptions{}
|
||||
|
||||
type Event interface {
|
||||
Update
|
||||
}
|
||||
|
||||
type Update struct {
|
||||
U
|
||||
Bot *bot
|
||||
|
@ -20,6 +24,11 @@ type Update struct {
|
|||
Ctx context.Context
|
||||
}
|
||||
|
||||
type UpdateCommand struct {
|
||||
Update
|
||||
Param string
|
||||
}
|
||||
|
||||
func (u *Update) Upd() *echotron.Update {
|
||||
return (*echotron.Update)(&u.U)
|
||||
}
|
||||
|
@ -169,18 +178,12 @@ func (u *Update) Entities() []*echotron.MessageEntity {
|
|||
}
|
||||
|
||||
func (u *Update) IsUserAdmin() bool {
|
||||
ids := []int64{
|
||||
60441930, // v.rud
|
||||
327487258, // vika shet
|
||||
}
|
||||
from := u.From()
|
||||
for i := range ids {
|
||||
if from.ID == ids[i] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
member, err := u.Bot.GetChatMember(u.ChatID(), u.From().ID)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return member.Result.Status == "administrator" || member.Result.Status == "creator"
|
||||
}
|
||||
|
||||
func (u *Update) LogError(text string, e error, send bool) {
|
||||
if text != "" {
|
||||
|
|
Loading…
Reference in New Issue