Files
clawgo/pkg/channels/base.go
2026-02-13 17:09:09 +08:00

96 lines
1.9 KiB
Go

package channels
import (
"context"
"fmt"
"strings"
"sync/atomic"
"clawgo/pkg/bus"
"clawgo/pkg/logger"
)
type Channel interface {
Name() string
Start(ctx context.Context) error
Stop(ctx context.Context) error
Send(ctx context.Context, msg bus.OutboundMessage) error
IsRunning() bool
IsAllowed(senderID string) bool
}
type BaseChannel struct {
config interface{}
bus *bus.MessageBus
running atomic.Bool
name string
allowList []string
}
func NewBaseChannel(name string, config interface{}, bus *bus.MessageBus, allowList []string) *BaseChannel {
return &BaseChannel{
config: config,
bus: bus,
name: name,
allowList: allowList,
}
}
func (c *BaseChannel) Name() string {
return c.name
}
func (c *BaseChannel) IsRunning() bool {
return c.running.Load()
}
func (c *BaseChannel) IsAllowed(senderID string) bool {
if len(c.allowList) == 0 {
return true
}
// Normalize sender id for channels that include display suffix, e.g. "12345|alice".
rawSenderID := senderID
if idx := strings.Index(senderID, "|"); idx > 0 {
rawSenderID = senderID[:idx]
}
for _, allowed := range c.allowList {
if senderID == allowed || rawSenderID == allowed {
return true
}
}
return false
}
func (c *BaseChannel) HandleMessage(senderID, chatID, content string, media []string, metadata map[string]string) {
if !c.IsAllowed(senderID) {
logger.WarnCF("channels", "Message rejected by allowlist", map[string]interface{}{
logger.FieldChannel: c.name,
logger.FieldSenderID: senderID,
logger.FieldChatID: chatID,
})
return
}
// 生成 SessionKey: channel:chatID
sessionKey := fmt.Sprintf("%s:%s", c.name, chatID)
msg := bus.InboundMessage{
Channel: c.name,
SenderID: senderID,
ChatID: chatID,
Content: content,
Media: media,
Metadata: metadata,
SessionKey: sessionKey,
}
c.bus.PublishInbound(msg)
}
func (c *BaseChannel) setRunning(running bool) {
c.running.Store(running)
}