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]interface{} // 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,omitempty"` Timestamp int64 `json:"timestamp"` SelfID string `json:"self_id"` Data map[string]interface{} `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]interface{} { 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]interface{}{ "user_id": userID, "message": message, }, } } else { // 群聊或其他有 group_id 的事件 action = &BaseAction{ Type: ActionTypeSendGroupMessage, Params: map[string]interface{}{ "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,omitempty"` } // NoticeEvent 通知事件 type NoticeEvent struct { BaseEvent GroupID string `json:"group_id,omitempty"` UserID string `json:"user_id,omitempty"` Operator string `json:"operator,omitempty"` } // 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"` }