239 lines
5.5 KiB
Go
239 lines
5.5 KiB
Go
|
|
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,
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|