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()
|
b.lock.Lock()
|
||||||
defer b.lock.Unlock()
|
defer b.lock.Unlock()
|
||||||
newState, err := b.state.Call(upd)
|
err := b.state.Call(upd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
upd.LogError("", err, true)
|
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 {
|
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)
|
// a := echo.NewAPI(n.Token)
|
||||||
me, _ := a.GetMe()
|
me, _ := a.GetMe()
|
||||||
// log.Println("New bot active: ", chatID, me.Result)
|
// 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 StateData map[string]interface{}
|
||||||
|
|
||||||
type Runnable interface {
|
type Runnable interface {
|
||||||
Call(*Update) (Runnable, error)
|
Call(*Update) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type State struct {
|
type State struct {
|
||||||
Fn stateFn
|
Fn stateFn
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *State) Call(u *Update) (Runnable, error) {
|
func (s *State) Call(u *Update) error {
|
||||||
return s.Fn(u)
|
return s.Fn(u)
|
||||||
}
|
}
|
||||||
|
|
||||||
type stateFn func(*Update) (Runnable, error)
|
type stateFn func(*Update) error
|
||||||
|
|
||||||
func (d StateData) Set(name string, data interface{}) {
|
func (d StateData) Set(name string, data interface{}) {
|
||||||
d[name] = data
|
d[name] = data
|
||||||
|
@ -49,7 +49,7 @@ var EchoState = State{
|
||||||
Fn: EchoFunc,
|
Fn: EchoFunc,
|
||||||
}
|
}
|
||||||
|
|
||||||
func EchoFunc(u *Update) (Runnable, error) {
|
func EchoFunc(u *Update) error {
|
||||||
u.AnswerText(u.Text(), &echotron.MessageOptions{})
|
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{}
|
var emptyOpts = echotron.MessageOptions{}
|
||||||
|
|
||||||
|
type Event interface {
|
||||||
|
Update
|
||||||
|
}
|
||||||
|
|
||||||
type Update struct {
|
type Update struct {
|
||||||
U
|
U
|
||||||
Bot *bot
|
Bot *bot
|
||||||
|
@ -20,6 +24,11 @@ type Update struct {
|
||||||
Ctx context.Context
|
Ctx context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UpdateCommand struct {
|
||||||
|
Update
|
||||||
|
Param string
|
||||||
|
}
|
||||||
|
|
||||||
func (u *Update) Upd() *echotron.Update {
|
func (u *Update) Upd() *echotron.Update {
|
||||||
return (*echotron.Update)(&u.U)
|
return (*echotron.Update)(&u.U)
|
||||||
}
|
}
|
||||||
|
@ -169,17 +178,11 @@ func (u *Update) Entities() []*echotron.MessageEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *Update) IsUserAdmin() bool {
|
func (u *Update) IsUserAdmin() bool {
|
||||||
ids := []int64{
|
member, err := u.Bot.GetChatMember(u.ChatID(), u.From().ID)
|
||||||
60441930, // v.rud
|
if err != nil {
|
||||||
327487258, // vika shet
|
|
||||||
}
|
|
||||||
from := u.From()
|
|
||||||
for i := range ids {
|
|
||||||
if from.ID == ids[i] {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
return false
|
||||||
|
}
|
||||||
|
return member.Result.Status == "administrator" || member.Result.Status == "creator"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *Update) LogError(text string, e error, send bool) {
|
func (u *Update) LogError(text string, e error, send bool) {
|
||||||
|
|
Loading…
Reference in New Issue