mirror of
https://github.com/YspCoder/clawgo.git
synced 2026-04-13 20:47:49 +08:00
104 lines
2.1 KiB
Go
104 lines
2.1 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
|
|
HealthCheck(ctx context.Context) error
|
|
}
|
|
|
|
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) HealthCheck(ctx context.Context) error {
|
|
if !c.IsRunning() {
|
|
return fmt.Errorf("%s channel not running", c.name)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
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)
|
|
}
|