Files
cellbot/internal/protocol/event.go
lafay f3220a2381 refactor: modernize codebase for Go 1.26 and fix adapter issues
- Upgrade Go version from 1.24 to 1.26.1 with updated dependencies
- Replace interface{} with any type throughout codebase
- Add message deduplication in OneBot11 adapter to prevent duplicate event processing
- URL-encode access token in WebSocket connections to handle special characters
- Remove duplicate bot startup hooks in DI providers (now handled by botManager.StartAll)
- Use slices.Clone and errgroup.Go patterns for cleaner concurrent code
- Apply omitzero JSON tags for optional fields (Go 1.24+ feature)
2026-03-18 01:22:49 +08:00

179 lines
4.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package protocol
import (
"context"
"time"
"go.uber.org/zap"
)
// EventType 事件类型
type EventType string
const (
// 事件类型常量
EventTypeMessage EventType = "message"
EventTypeNotice EventType = "notice"
EventTypeRequest EventType = "request"
EventTypeMeta EventType = "meta"
EventTypeMessageSent EventType = "message_sent"
EventTypeNoticeSent EventType = "notice_sent"
EventTypeRequestSent EventType = "request_sent"
)
// Event 通用事件接口
// 参考OneBot12协议设计提供统一的事件抽象
type Event interface {
// GetType 获取事件类型
GetType() EventType
// GetDetailType 获取详细类型
GetDetailType() string
// GetSubType 获取子类型
GetSubType() string
// GetTimestamp 获取时间戳
GetTimestamp() time.Time
// GetSelfID 获取机器人自身ID
GetSelfID() string
// GetData 获取事件数据
GetData() map[string]any
// Reply 在消息发生的群/私聊进行回复
Reply(ctx context.Context, botManager *BotManager, logger *zap.Logger, message MessageChain) error
// ReplyText 在消息发生的群/私聊进行文本回复(便捷方法)
ReplyText(ctx context.Context, botManager *BotManager, logger *zap.Logger, text string) error
}
// BaseEvent 基础事件结构
type BaseEvent struct {
Type EventType `json:"type"`
DetailType string `json:"detail_type"`
SubType string `json:"sub_type,omitzero"`
Timestamp int64 `json:"timestamp"`
SelfID string `json:"self_id"`
Data map[string]any `json:"data"`
}
// GetType 获取事件类型
func (e *BaseEvent) GetType() EventType {
return e.Type
}
// GetDetailType 获取详细类型
func (e *BaseEvent) GetDetailType() string {
return e.DetailType
}
// GetSubType 获取子类型
func (e *BaseEvent) GetSubType() string {
return e.SubType
}
// GetTimestamp 获取时间戳
func (e *BaseEvent) GetTimestamp() time.Time {
return time.Unix(e.Timestamp, 0)
}
// GetSelfID 获取机器人自身ID
func (e *BaseEvent) GetSelfID() string {
return e.SelfID
}
// GetData 获取事件数据
func (e *BaseEvent) GetData() map[string]any {
return e.Data
}
// Reply 在消息发生的群/私聊进行回复
func (e *BaseEvent) Reply(ctx context.Context, botManager *BotManager, logger *zap.Logger, message MessageChain) error {
data := e.GetData()
userID, _ := data["user_id"]
groupID, _ := data["group_id"]
// 获取 bot 实例
selfID := e.GetSelfID()
bot, ok := botManager.Get(selfID)
if !ok {
bots := botManager.GetAll()
if len(bots) == 0 {
logger.Error("No bot instance available")
return nil
}
bot = bots[0]
}
// 根据消息类型发送回复
var action *BaseAction
if e.GetDetailType() == "private" {
action = &BaseAction{
Type: ActionTypeSendPrivateMessage,
Params: map[string]any{
"user_id": userID,
"message": message,
},
}
} else {
// 群聊或其他有 group_id 的事件
action = &BaseAction{
Type: ActionTypeSendGroupMessage,
Params: map[string]any{
"group_id": groupID,
"message": message,
},
}
}
_, err := bot.SendAction(ctx, action)
if err != nil {
logger.Error("Failed to send reply",
zap.Any("user_id", userID),
zap.Any("group_id", groupID),
zap.String("detail_type", e.GetDetailType()),
zap.Error(err))
return err
}
logger.Debug("Reply sent",
zap.Any("user_id", userID),
zap.Any("group_id", groupID),
zap.String("detail_type", e.GetDetailType()))
return nil
}
// ReplyText 在消息发生的群/私聊进行文本回复(便捷方法)
func (e *BaseEvent) ReplyText(ctx context.Context, botManager *BotManager, logger *zap.Logger, text string) error {
message := NewMessageChain(
NewTextSegment(text),
)
return e.Reply(ctx, botManager, logger, message)
}
// MessageEvent 消息事件
type MessageEvent struct {
BaseEvent
MessageID string `json:"message_id"`
Message string `json:"message"`
AltText string `json:"alt_text,omitzero"`
}
// NoticeEvent 通知事件
type NoticeEvent struct {
BaseEvent
GroupID string `json:"group_id,omitzero"`
UserID string `json:"user_id,omitzero"`
Operator string `json:"operator,omitzero"`
}
// RequestEvent 请求事件
type RequestEvent struct {
BaseEvent
RequestID string `json:"request_id"`
UserID string `json:"user_id"`
Comment string `json:"comment"`
Flag string `json:"flag"`
}
// MetaEvent 元事件
type MetaEvent struct {
BaseEvent
Status string `json:"status"`
}