refactor(plugins): restructure admin and message_gateway into standard layered sub-packages

This commit is contained in:
ryan
2026-08-28 22:33:26 +08:00
parent 85b383a4e0
commit f4975d6732
128 changed files with 12050 additions and 9901 deletions
@@ -7,7 +7,8 @@ package qq
import (
"Wavelet/pkg/logger"
"Wavelet/pkg/util"
"Wavelet/plugins/domain/message_gateway"
"Wavelet/plugins/domain/message_gateway/model"
"Wavelet/plugins/domain/message_gateway/service"
"context"
"fmt"
"strings"
@@ -32,8 +33,8 @@ type qqEvent struct {
// Adapter is an official QQ Bot C2C channel.
type Adapter struct {
cfg message_gateway.ChannelConfig
onInbound message_gateway.Handler
cfg model.ChannelConfig
onInbound service.Handler
api openapi.OpenAPI
tokenSrc oauth2.TokenSource
cancel context.CancelFunc
@@ -42,7 +43,7 @@ type Adapter struct {
}
// New constructs a QQ adapter.
func New(cfg message_gateway.ChannelConfig, onInbound message_gateway.Handler) (message_gateway.Channel, error) {
func New(cfg model.ChannelConfig, onInbound service.Handler) (service.Channel, error) {
if strings.TrimSpace(cfg.Credentials["app_id"]) == "" || strings.TrimSpace(cfg.Credentials["app_secret"]) == "" {
return nil, fmt.Errorf("qq: app_id and app_secret are required")
}
@@ -50,11 +51,11 @@ func New(cfg message_gateway.ChannelConfig, onInbound message_gateway.Handler) (
}
// Type returns qq.
func (a *Adapter) Type() string { return message_gateway.ChannelTypeQQ }
func (a *Adapter) Type() string { return model.ChannelTypeQQ }
// Capabilities reports C2C text/media support.
func (a *Adapter) Capabilities() message_gateway.Capability {
return message_gateway.Capability{Text: true, Image: true, File: true, Reply: true}
func (a *Adapter) Capabilities() model.Capability {
return model.Capability{Text: true, Image: true, File: true, Reply: true}
}
// Connect starts the official WebSocket session (C2C intent).
@@ -127,7 +128,7 @@ func (a *Adapter) Disconnect(_ context.Context) error {
}
// Send posts a C2C text reply.
func (a *Adapter) Send(ctx context.Context, to message_gateway.Recipient, msg message_gateway.OutboundMessage) error {
func (a *Adapter) Send(ctx context.Context, to model.Recipient, msg model.OutboundMessage) error {
a.mu.Lock()
api := a.api
a.mu.Unlock()
@@ -151,9 +152,9 @@ func (a *Adapter) handleEvent(ctx context.Context, ev qqEvent) {
if disconnected || a.onInbound == nil {
return
}
_ = a.onInbound(ctx, message_gateway.InboundMessage{
_ = a.onInbound(ctx, model.InboundMessage{
ChannelID: a.cfg.ID,
ChannelType: message_gateway.ChannelTypeQQ,
ChannelType: model.ChannelTypeQQ,
PlatformUserID: ev.UserID,
ChatID: ev.UserID,
MessageID: ev.MessageID,
@@ -4,14 +4,14 @@
package qq
import (
"Wavelet/plugins/domain/message_gateway"
"Wavelet/plugins/domain/message_gateway/model"
"context"
"testing"
)
func TestHandleEvent_DropsNonC2C(t *testing.T) {
var got int
a := &Adapter{onInbound: func(ctx context.Context, msg message_gateway.InboundMessage) error {
a := &Adapter{onInbound: func(ctx context.Context, msg model.InboundMessage) error {
got++
return nil
}}
@@ -22,8 +22,8 @@ func TestHandleEvent_DropsNonC2C(t *testing.T) {
}
func TestHandleEvent_C2CText(t *testing.T) {
var got message_gateway.InboundMessage
a := &Adapter{cfg: message_gateway.ChannelConfig{ID: 3}, onInbound: func(ctx context.Context, msg message_gateway.InboundMessage) error {
var got model.InboundMessage
a := &Adapter{cfg: model.ChannelConfig{ID: 3}, onInbound: func(ctx context.Context, msg model.InboundMessage) error {
got = msg
return nil
}}
@@ -34,7 +34,7 @@ func TestHandleEvent_C2CText(t *testing.T) {
}
func TestNew_RequiresCreds(t *testing.T) {
_, err := New(message_gateway.ChannelConfig{}, nil)
_, err := New(model.ChannelConfig{}, nil)
if err == nil {
t.Fatal("expected error")
}
@@ -6,7 +6,8 @@ package telegram
import (
"Wavelet/pkg/util"
"Wavelet/plugins/domain/message_gateway"
"Wavelet/plugins/domain/message_gateway/model"
"Wavelet/plugins/domain/message_gateway/service"
"context"
"fmt"
"os"
@@ -19,13 +20,13 @@ import (
// Adapter is a Telegram private-chat channel.
type Adapter struct {
cfg message_gateway.ChannelConfig
onInbound message_gateway.Handler
cfg model.ChannelConfig
onInbound service.Handler
bot *tele.Bot
}
// New constructs a Telegram adapter. Call message_gateway.Register from the runner.
func New(cfg message_gateway.ChannelConfig, onInbound message_gateway.Handler) (message_gateway.Channel, error) {
// New constructs a Telegram adapter. Call service.Register from the runner.
func New(cfg model.ChannelConfig, onInbound service.Handler) (service.Channel, error) {
if strings.TrimSpace(cfg.Credentials["bot_token"]) == "" {
return nil, fmt.Errorf("telegram: bot_token is required")
}
@@ -33,11 +34,11 @@ func New(cfg message_gateway.ChannelConfig, onInbound message_gateway.Handler) (
}
// Type returns telegram.
func (a *Adapter) Type() string { return message_gateway.ChannelTypeTelegram }
func (a *Adapter) Type() string { return model.ChannelTypeTelegram }
// Capabilities reports private-chat media support.
func (a *Adapter) Capabilities() message_gateway.Capability {
return message_gateway.Capability{Text: true, Image: true, File: true, Reply: true}
func (a *Adapter) Capabilities() model.Capability {
return model.Capability{Text: true, Image: true, File: true, Reply: true}
}
// Connect starts long polling.
@@ -85,7 +86,7 @@ func (a *Adapter) Disconnect(_ context.Context) error {
}
// Send replies to a private chat.
func (a *Adapter) Send(_ context.Context, to message_gateway.Recipient, msg message_gateway.OutboundMessage) error {
func (a *Adapter) Send(_ context.Context, to model.Recipient, msg model.OutboundMessage) error {
if a.bot == nil {
return fmt.Errorf("telegram: not connected")
}
@@ -104,9 +105,9 @@ func (a *Adapter) handleTeleMessage(ctx context.Context, m *tele.Message) {
if a.onInbound == nil {
return
}
msg := message_gateway.InboundMessage{
msg := model.InboundMessage{
ChannelID: a.cfg.ID,
ChannelType: message_gateway.ChannelTypeTelegram,
ChannelType: model.ChannelTypeTelegram,
PlatformUserID: strconv.FormatInt(m.Sender.ID, 10),
ChatID: strconv.FormatInt(m.Chat.ID, 10),
MessageID: strconv.Itoa(m.ID),
@@ -121,7 +122,7 @@ func (a *Adapter) handleTeleMessage(ctx context.Context, m *tele.Message) {
_ = a.onInbound(ctx, msg)
}
func (a *Adapter) downloadMedia(m *tele.Message) []message_gateway.Attachment {
func (a *Adapter) downloadMedia(m *tele.Message) []model.Attachment {
var files []*tele.File
var names []string
if m.Photo != nil {
@@ -141,16 +142,16 @@ func (a *Adapter) downloadMedia(m *tele.Message) []message_gateway.Attachment {
}
dir, err := os.MkdirTemp("", "wg-tg-*")
if err != nil {
return []message_gateway.Attachment{{Error: err.Error()}}
return []model.Attachment{{Error: err.Error()}}
}
out := make([]message_gateway.Attachment, 0, len(files))
out := make([]model.Attachment, 0, len(files))
for i, f := range files {
path := filepath.Join(dir, names[i])
if err := a.bot.Download(f, path); err != nil {
out = append(out, message_gateway.Attachment{FileName: names[i], Error: err.Error()})
out = append(out, model.Attachment{FileName: names[i], Error: err.Error()})
continue
}
out = append(out, message_gateway.Attachment{Path: path, FileName: names[i]})
out = append(out, model.Attachment{Path: path, FileName: names[i]})
}
return out
}
@@ -4,7 +4,7 @@
package telegram
import (
"Wavelet/plugins/domain/message_gateway"
"Wavelet/plugins/domain/message_gateway/model"
"context"
"testing"
@@ -13,7 +13,7 @@ import (
func TestHandleUpdate_DropsGroups(t *testing.T) {
var got int
a := &Adapter{onInbound: func(ctx context.Context, msg message_gateway.InboundMessage) error {
a := &Adapter{onInbound: func(ctx context.Context, msg model.InboundMessage) error {
got++
return nil
}}
@@ -29,10 +29,10 @@ func TestHandleUpdate_DropsGroups(t *testing.T) {
}
func TestHandleUpdate_PrivateText(t *testing.T) {
var got message_gateway.InboundMessage
var got model.InboundMessage
a := &Adapter{
cfg: message_gateway.ChannelConfig{ID: 7, Type: "telegram"},
onInbound: func(ctx context.Context, msg message_gateway.InboundMessage) error {
cfg: model.ChannelConfig{ID: 7, Type: "telegram"},
onInbound: func(ctx context.Context, msg model.InboundMessage) error {
got = msg
return nil
},
@@ -49,7 +49,7 @@ func TestHandleUpdate_PrivateText(t *testing.T) {
}
func TestNew_RequiresToken(t *testing.T) {
_, err := New(message_gateway.ChannelConfig{}, nil)
_, err := New(model.ChannelConfig{}, nil)
if err == nil {
t.Fatal("expected error")
}