refactor(telegram): use shared command dispatcher for incoming commands
This commit is contained in:
parent
5db50ee5ca
commit
9350e9d4c4
4 changed files with 113 additions and 16 deletions
|
|
@ -44,6 +44,7 @@ type TelegramChannel struct {
|
||||||
bot *telego.Bot
|
bot *telego.Bot
|
||||||
bh *telegohandler.BotHandler
|
bh *telegohandler.BotHandler
|
||||||
commands TelegramCommander
|
commands TelegramCommander
|
||||||
|
dispatcher commands.Dispatching
|
||||||
config *config.Config
|
config *config.Config
|
||||||
chatIDs map[string]int64
|
chatIDs map[string]int64
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
|
|
@ -94,6 +95,7 @@ func NewTelegramChannel(cfg *config.Config, bus *bus.MessageBus) (*TelegramChann
|
||||||
return &TelegramChannel{
|
return &TelegramChannel{
|
||||||
BaseChannel: base,
|
BaseChannel: base,
|
||||||
commands: NewTelegramCommands(bot, cfg),
|
commands: NewTelegramCommands(bot, cfg),
|
||||||
|
dispatcher: commands.NewDispatcher(commands.NewRegistry(commands.BuiltinDefinitions(cfg))),
|
||||||
bot: bot,
|
bot: bot,
|
||||||
config: cfg,
|
config: cfg,
|
||||||
chatIDs: make(map[string]int64),
|
chatIDs: make(map[string]int64),
|
||||||
|
|
@ -121,22 +123,9 @@ func (c *TelegramChannel) Start(ctx context.Context) error {
|
||||||
c.bh = bh
|
c.bh = bh
|
||||||
|
|
||||||
bh.HandleMessage(func(ctx *th.Context, message telego.Message) error {
|
bh.HandleMessage(func(ctx *th.Context, message telego.Message) error {
|
||||||
c.commands.Help(ctx, message)
|
if c.dispatchCommand(ctx, message) {
|
||||||
return nil
|
return nil
|
||||||
}, th.CommandEqual("help"))
|
}
|
||||||
bh.HandleMessage(func(ctx *th.Context, message telego.Message) error {
|
|
||||||
return c.commands.Start(ctx, message)
|
|
||||||
}, th.CommandEqual("start"))
|
|
||||||
|
|
||||||
bh.HandleMessage(func(ctx *th.Context, message telego.Message) error {
|
|
||||||
return c.commands.Show(ctx, message)
|
|
||||||
}, th.CommandEqual("show"))
|
|
||||||
|
|
||||||
bh.HandleMessage(func(ctx *th.Context, message telego.Message) error {
|
|
||||||
return c.commands.List(ctx, message)
|
|
||||||
}, th.CommandEqual("list"))
|
|
||||||
|
|
||||||
bh.HandleMessage(func(ctx *th.Context, message telego.Message) error {
|
|
||||||
return c.handleMessage(ctx, &message)
|
return c.handleMessage(ctx, &message)
|
||||||
}, th.AnyMessage())
|
}, th.AnyMessage())
|
||||||
|
|
||||||
|
|
|
||||||
66
pkg/channels/telegram/telegram_dispatch.go
Normal file
66
pkg/channels/telegram/telegram_dispatch.go
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
package telegram
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/mymmrac/telego"
|
||||||
|
|
||||||
|
"github.com/sipeed/picoclaw/pkg/commands"
|
||||||
|
"github.com/sipeed/picoclaw/pkg/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c *TelegramChannel) dispatchCommand(ctx context.Context, message telego.Message) bool {
|
||||||
|
if c.dispatcher == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
senderID := ""
|
||||||
|
if message.From != nil {
|
||||||
|
senderID = strconv.FormatInt(message.From.ID, 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
res := c.dispatcher.Dispatch(ctx, commands.Request{
|
||||||
|
Channel: "telegram",
|
||||||
|
ChatID: strconv.FormatInt(message.Chat.ID, 10),
|
||||||
|
SenderID: senderID,
|
||||||
|
Text: message.Text,
|
||||||
|
MessageID: strconv.Itoa(message.MessageID),
|
||||||
|
})
|
||||||
|
if !res.Matched {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
switch res.Command {
|
||||||
|
case "help":
|
||||||
|
if err := c.commands.Help(ctx, message); err != nil {
|
||||||
|
logger.ErrorCF("telegram", "Command execution failed", map[string]any{
|
||||||
|
"command": "help",
|
||||||
|
"error": err.Error(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
case "start":
|
||||||
|
if err := c.commands.Start(ctx, message); err != nil {
|
||||||
|
logger.ErrorCF("telegram", "Command execution failed", map[string]any{
|
||||||
|
"command": "start",
|
||||||
|
"error": err.Error(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
case "show":
|
||||||
|
if err := c.commands.Show(ctx, message); err != nil {
|
||||||
|
logger.ErrorCF("telegram", "Command execution failed", map[string]any{
|
||||||
|
"command": "show",
|
||||||
|
"error": err.Error(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
case "list":
|
||||||
|
if err := c.commands.List(ctx, message); err != nil {
|
||||||
|
logger.ErrorCF("telegram", "Command execution failed", map[string]any{
|
||||||
|
"command": "list",
|
||||||
|
"error": err.Error(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
32
pkg/channels/telegram/telegram_dispatch_test.go
Normal file
32
pkg/channels/telegram/telegram_dispatch_test.go
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
package telegram
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/mymmrac/telego"
|
||||||
|
|
||||||
|
"github.com/sipeed/picoclaw/pkg/commands"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDispatchCommand_UsesDispatcher(t *testing.T) {
|
||||||
|
ch := &TelegramChannel{}
|
||||||
|
called := false
|
||||||
|
ch.dispatcher = commands.DispatchFunc(func(context.Context, commands.Request) commands.Result {
|
||||||
|
called = true
|
||||||
|
return commands.Result{Matched: true, Command: "noop"}
|
||||||
|
})
|
||||||
|
|
||||||
|
msg := telego.Message{
|
||||||
|
Text: "/help",
|
||||||
|
MessageID: 7,
|
||||||
|
Chat: telego.Chat{
|
||||||
|
ID: 123,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
handled := ch.dispatchCommand(context.Background(), msg)
|
||||||
|
if !handled || !called {
|
||||||
|
t.Fatalf("handled=%v called=%v", handled, called)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -25,6 +25,16 @@ type Dispatcher struct {
|
||||||
reg *Registry
|
reg *Registry
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Dispatching interface {
|
||||||
|
Dispatch(ctx context.Context, req Request) Result
|
||||||
|
}
|
||||||
|
|
||||||
|
type DispatchFunc func(ctx context.Context, req Request) Result
|
||||||
|
|
||||||
|
func (f DispatchFunc) Dispatch(ctx context.Context, req Request) Result {
|
||||||
|
return f(ctx, req)
|
||||||
|
}
|
||||||
|
|
||||||
func NewDispatcher(reg *Registry) *Dispatcher {
|
func NewDispatcher(reg *Registry) *Dispatcher {
|
||||||
return &Dispatcher{reg: reg}
|
return &Dispatcher{reg: reg}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue