package onebot11 import ( "fmt" "strconv" "cellbot/internal/protocol" "github.com/bytedance/sonic" ) // convertToEvent 将OneBot11原始事件转换为通用事件 func (a *Adapter) convertToEvent(raw *RawEvent) (protocol.Event, error) { baseEvent := &protocol.BaseEvent{ Timestamp: raw.Time, SelfID: strconv.FormatInt(raw.SelfID, 10), Data: make(map[string]interface{}), } switch raw.PostType { case PostTypeMessage: return a.convertMessageEvent(raw, baseEvent) case PostTypeNotice: return a.convertNoticeEvent(raw, baseEvent) case PostTypeRequest: return a.convertRequestEvent(raw, baseEvent) case PostTypeMetaEvent: return a.convertMetaEvent(raw, baseEvent) default: return nil, fmt.Errorf("unknown post_type: %s", raw.PostType) } } // convertMessageEvent 转换消息事件 func (a *Adapter) convertMessageEvent(raw *RawEvent, base *protocol.BaseEvent) (protocol.Event, error) { base.Type = protocol.EventTypeMessage base.DetailType = raw.MessageType base.SubType = raw.SubType // 构建消息数据 base.Data["message_id"] = raw.MessageID base.Data["user_id"] = raw.UserID base.Data["message"] = raw.Message base.Data["raw_message"] = raw.RawMessage base.Data["font"] = raw.Font if raw.GroupID > 0 { base.Data["group_id"] = raw.GroupID } if raw.Sender != nil { senderData := map[string]interface{}{ "user_id": raw.Sender.UserID, "nickname": raw.Sender.Nickname, } if raw.Sender.Sex != "" { senderData["sex"] = raw.Sender.Sex } if raw.Sender.Age > 0 { senderData["age"] = raw.Sender.Age } if raw.Sender.Card != "" { senderData["card"] = raw.Sender.Card } if raw.Sender.Role != "" { senderData["role"] = raw.Sender.Role } base.Data["sender"] = senderData } if raw.Anonymous != nil { base.Data["anonymous"] = map[string]interface{}{ "id": raw.Anonymous.ID, "name": raw.Anonymous.Name, "flag": raw.Anonymous.Flag, } } // 解析消息段 if segments, err := a.parseMessageSegments(raw.Message); err == nil { base.Data["message_segments"] = segments } return base, nil } // convertNoticeEvent 转换通知事件 func (a *Adapter) convertNoticeEvent(raw *RawEvent, base *protocol.BaseEvent) (protocol.Event, error) { base.Type = protocol.EventTypeNotice base.DetailType = raw.NoticeType base.SubType = raw.SubType base.Data["user_id"] = raw.UserID if raw.GroupID > 0 { base.Data["group_id"] = raw.GroupID } if raw.OperatorID > 0 { base.Data["operator_id"] = raw.OperatorID } if raw.Duration > 0 { base.Data["duration"] = raw.Duration } // 根据不同的通知类型添加特定数据 switch raw.NoticeType { case NoticeTypeGroupBan: base.Data["duration"] = raw.Duration case NoticeTypeGroupUpload: // 文件上传信息 if raw.File != nil { base.Data["file"] = map[string]interface{}{ "id": raw.File.ID, "name": raw.File.Name, "size": raw.File.Size, "busid": raw.File.Busid, } } case NoticeTypeGroupRecall, NoticeTypeFriendRecall: base.Data["message_id"] = raw.MessageID case NoticeTypeNotify: // 处理通知子类型 if raw.TargetID > 0 { base.Data["target_id"] = raw.TargetID } if raw.HonorType != "" { base.Data["honor_type"] = raw.HonorType } } return base, nil } // convertRequestEvent 转换请求事件 func (a *Adapter) convertRequestEvent(raw *RawEvent, base *protocol.BaseEvent) (protocol.Event, error) { base.Type = protocol.EventTypeRequest base.DetailType = raw.RequestType base.SubType = raw.SubType base.Data["user_id"] = raw.UserID base.Data["comment"] = raw.Comment base.Data["flag"] = raw.Flag if raw.GroupID > 0 { base.Data["group_id"] = raw.GroupID } return base, nil } // convertMetaEvent 转换元事件 func (a *Adapter) convertMetaEvent(raw *RawEvent, base *protocol.BaseEvent) (protocol.Event, error) { base.Type = protocol.EventTypeMeta base.DetailType = raw.MetaType if raw.Status != nil { statusData := map[string]interface{}{ "online": raw.Status.Online, "good": raw.Status.Good, } if raw.Status.Stat != nil { statusData["stat"] = map[string]interface{}{ "packet_received": raw.Status.Stat.PacketReceived, "packet_sent": raw.Status.Stat.PacketSent, "packet_lost": raw.Status.Stat.PacketLost, "message_received": raw.Status.Stat.MessageReceived, "message_sent": raw.Status.Stat.MessageSent, "disconnect_times": raw.Status.Stat.DisconnectTimes, "lost_times": raw.Status.Stat.LostTimes, "last_message_time": raw.Status.Stat.LastMessageTime, } } base.Data["status"] = statusData } if raw.Interval > 0 { base.Data["interval"] = raw.Interval } return base, nil } // parseMessageSegments 解析消息段 func (a *Adapter) parseMessageSegments(message interface{}) ([]MessageSegment, error) { if message == nil { return nil, fmt.Errorf("message is nil") } // 如果是字符串,转换为文本消息段 if str, ok := message.(string); ok { return []MessageSegment{ { Type: SegmentTypeText, Data: map[string]interface{}{ "text": str, }, }, }, nil } // 如果是数组,解析为消息段数组 var segments []MessageSegment data, err := sonic.Marshal(message) if err != nil { return nil, fmt.Errorf("failed to marshal message: %w", err) } if err := sonic.Unmarshal(data, &segments); err != nil { return nil, fmt.Errorf("failed to unmarshal message segments: %w", err) } return segments, nil } // BuildMessage 构建OneBot11消息 func BuildMessage(segments []MessageSegment) interface{} { if len(segments) == 0 { return "" } // 如果只有一个文本消息段,直接返回文本 if len(segments) == 1 && segments[0].Type == SegmentTypeText { if text, ok := segments[0].Data["text"].(string); ok { return text } } return segments } // BuildTextMessage 构建文本消息 func BuildTextMessage(text string) []MessageSegment { return []MessageSegment{ { Type: SegmentTypeText, Data: map[string]interface{}{ "text": text, }, }, } } // BuildImageMessage 构建图片消息 func BuildImageMessage(file string) []MessageSegment { return []MessageSegment{ { Type: SegmentTypeImage, Data: map[string]interface{}{ "file": file, }, }, } } // BuildAtMessage 构建@消息 func BuildAtMessage(userID int64) MessageSegment { return MessageSegment{ Type: SegmentTypeAt, Data: map[string]interface{}{ "qq": userID, }, } } // BuildReplyMessage 构建回复消息 func BuildReplyMessage(messageID int32) MessageSegment { return MessageSegment{ Type: SegmentTypeReply, Data: map[string]interface{}{ "id": messageID, }, } } // BuildFaceMessage 构建表情消息 func BuildFaceMessage(faceID int) MessageSegment { return MessageSegment{ Type: SegmentTypeFace, Data: map[string]interface{}{ "id": faceID, }, } } // BuildRecordMessage 构建语音消息 func BuildRecordMessage(file string) MessageSegment { return MessageSegment{ Type: SegmentTypeRecord, Data: map[string]interface{}{ "file": file, }, } } // BuildVideoMessage 构建视频消息 func BuildVideoMessage(file string) MessageSegment { return MessageSegment{ Type: SegmentTypeVideo, Data: map[string]interface{}{ "file": file, }, } } // BuildShareMessage 构建分享消息 func BuildShareMessage(url, title string) MessageSegment { return MessageSegment{ Type: SegmentTypeShare, Data: map[string]interface{}{ "url": url, "title": title, }, } } // BuildLocationMessage 构建位置消息 func BuildLocationMessage(lat, lon float64, title, content string) MessageSegment { return MessageSegment{ Type: SegmentTypeLocation, Data: map[string]interface{}{ "lat": lat, "lon": lon, "title": title, "content": content, }, } } // BuildMusicMessage 构建音乐消息 func BuildMusicMessage(musicType, musicID string) MessageSegment { return MessageSegment{ Type: SegmentTypeMusic, Data: map[string]interface{}{ "type": musicType, "id": musicID, }, } } // BuildCustomMusicMessage 构建自定义音乐消息 func BuildCustomMusicMessage(url, audio, title, content, image string) MessageSegment { return MessageSegment{ Type: SegmentTypeMusic, Data: map[string]interface{}{ "type": "custom", "url": url, "audio": audio, "title": title, "content": content, "image": image, }, } }