Files

356 lines
8.2 KiB
Go
Raw Permalink Normal View History

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,
},
}
}