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
|
||||
bh *telegohandler.BotHandler
|
||||
commands TelegramCommander
|
||||
dispatcher commands.Dispatching
|
||||
config *config.Config
|
||||
chatIDs map[string]int64
|
||||
ctx context.Context
|
||||
|
|
@ -94,6 +95,7 @@ func NewTelegramChannel(cfg *config.Config, bus *bus.MessageBus) (*TelegramChann
|
|||
return &TelegramChannel{
|
||||
BaseChannel: base,
|
||||
commands: NewTelegramCommands(bot, cfg),
|
||||
dispatcher: commands.NewDispatcher(commands.NewRegistry(commands.BuiltinDefinitions(cfg))),
|
||||
bot: bot,
|
||||
config: cfg,
|
||||
chatIDs: make(map[string]int64),
|
||||
|
|
@ -121,22 +123,9 @@ func (c *TelegramChannel) Start(ctx context.Context) error {
|
|||
c.bh = bh
|
||||
|
||||
bh.HandleMessage(func(ctx *th.Context, message telego.Message) error {
|
||||
c.commands.Help(ctx, message)
|
||||
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 {
|
||||
if c.dispatchCommand(ctx, message) {
|
||||
return nil
|
||||
}
|
||||
return c.handleMessage(ctx, &message)
|
||||
}, 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
|
||||
}
|
||||
|
||||
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 {
|
||||
return &Dispatcher{reg: reg}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue