package onebot11 import ( "fmt" "cellbot/internal/protocol" ) // ConvertMessageChainToOB11 将通用消息链转换为 OneBot11 格式 func ConvertMessageChainToOB11(chain protocol.MessageChain) interface{} { if len(chain) == 0 { return "" } // 转换为 OneBot11 消息段格式 segments := make([]MessageSegment, 0, len(chain)) for _, seg := range chain { ob11Seg := convertSegmentToOB11(seg) if ob11Seg != nil { segments = append(segments, *ob11Seg) } } // 如果只有一个文本消息段,直接返回文本字符串 if len(segments) == 1 && segments[0].Type == SegmentTypeText { if text, ok := segments[0].Data["text"].(string); ok { return text } } return segments } // convertSegmentToOB11 将通用消息段转换为 OneBot11 消息段 func convertSegmentToOB11(seg protocol.MessageSegment) *MessageSegment { switch seg.Type { case protocol.SegmentTypeText: // 文本消息段 return &MessageSegment{ Type: SegmentTypeText, Data: map[string]interface{}{ "text": seg.Data["text"], }, } case protocol.SegmentTypeMention: // @提及(OneBot12 -> OneBot11) userID := seg.Data["user_id"] return &MessageSegment{ Type: SegmentTypeAt, Data: map[string]interface{}{ "qq": userID, }, } case protocol.SegmentTypeAt: // OneBot11 兼容格式 userID, ok := seg.Data["user_id"] if !ok { userID = seg.Data["qq"] } return &MessageSegment{ Type: SegmentTypeAt, Data: map[string]interface{}{ "qq": userID, }, } case protocol.SegmentTypeImage: // 图片消息段 fileID, ok := seg.Data["file_id"].(string) if !ok { // 兼容 file 字段 fileID, _ = seg.Data["file"].(string) } return &MessageSegment{ Type: SegmentTypeImage, Data: map[string]interface{}{ "file": fileID, }, } case protocol.SegmentTypeVoice: // 语音消息段(OneBot12 -> OneBot11) fileID, ok := seg.Data["file_id"].(string) if !ok { fileID, _ = seg.Data["file"].(string) } return &MessageSegment{ Type: SegmentTypeRecord, Data: map[string]interface{}{ "file": fileID, }, } case protocol.SegmentTypeRecord: // OneBot11 兼容格式 fileID, ok := seg.Data["file"].(string) if !ok { fileID, _ = seg.Data["file_id"].(string) } return &MessageSegment{ Type: SegmentTypeRecord, Data: map[string]interface{}{ "file": fileID, }, } case protocol.SegmentTypeVideo: // 视频消息段 fileID, ok := seg.Data["file_id"].(string) if !ok { fileID, _ = seg.Data["file"].(string) } return &MessageSegment{ Type: SegmentTypeVideo, Data: map[string]interface{}{ "file": fileID, }, } case protocol.SegmentTypeReply: // 回复消息段 messageID := seg.Data["message_id"] return &MessageSegment{ Type: SegmentTypeReply, Data: map[string]interface{}{ "id": messageID, }, } case protocol.SegmentTypeFace: // 表情消息段 faceID := seg.Data["id"] return &MessageSegment{ Type: SegmentTypeFace, Data: map[string]interface{}{ "id": faceID, }, } default: // 其他类型,尝试直接转换 return &MessageSegment{ Type: seg.Type, Data: seg.Data, } } } // ConvertOB11ToMessageChain 将 OneBot11 消息段转换为通用消息链 func ConvertOB11ToMessageChain(ob11Message interface{}) (protocol.MessageChain, error) { chain := protocol.MessageChain{} // 如果是字符串,转换为文本消息段 if str, ok := ob11Message.(string); ok { return protocol.NewMessageChain(protocol.NewTextSegment(str)), nil } // 如果是数组,解析为消息段数组 if segments, ok := ob11Message.([]MessageSegment); ok { for _, seg := range segments { genericSeg := convertOB11SegmentToGeneric(seg) chain = append(chain, genericSeg) } return chain, nil } // 如果是接口数组,尝试转换 if segments, ok := ob11Message.([]interface{}); ok { for _, seg := range segments { if segMap, ok := seg.(map[string]interface{}); ok { segType, _ := segMap["type"].(string) segData, _ := segMap["data"].(map[string]interface{}) genericSeg := convertOB11SegmentToGeneric(MessageSegment{ Type: segType, Data: segData, }) chain = append(chain, genericSeg) } } return chain, nil } return nil, fmt.Errorf("unsupported message format: %T", ob11Message) } // convertOB11SegmentToGeneric 将 OneBot11 消息段转换为通用消息段 func convertOB11SegmentToGeneric(seg MessageSegment) protocol.MessageSegment { switch seg.Type { case SegmentTypeText: return protocol.NewTextSegment(seg.Data["text"].(string)) case SegmentTypeAt: // OneBot11 @ 转换为 OneBot12 mention userID := seg.Data["qq"] return protocol.NewMentionSegment(userID) case SegmentTypeImage: fileID, ok := seg.Data["file"].(string) if !ok { fileID, _ = seg.Data["file_id"].(string) } return protocol.NewImageSegment(fileID) case SegmentTypeRecord: // OneBot11 record 转换为 OneBot12 voice fileID, ok := seg.Data["file"].(string) if !ok { fileID, _ = seg.Data["file_id"].(string) } return protocol.MessageSegment{ Type: protocol.SegmentTypeVoice, Data: map[string]interface{}{ "file_id": fileID, }, } case SegmentTypeReply: messageID := seg.Data["id"] return protocol.NewReplySegment(messageID) case SegmentTypeFace: return protocol.MessageSegment{ Type: protocol.SegmentTypeFace, Data: map[string]interface{}{ "id": seg.Data["id"], }, } default: // 其他类型,直接转换 return protocol.MessageSegment{ Type: seg.Type, Data: seg.Data, } } }