694 lines
21 KiB
Go
694 lines
21 KiB
Go
|
|
package milky
|
||
|
|
|
||
|
|
import (
|
||
|
|
"cellbot/internal/protocol"
|
||
|
|
"fmt"
|
||
|
|
"strconv"
|
||
|
|
|
||
|
|
"github.com/bytedance/sonic"
|
||
|
|
"go.uber.org/zap"
|
||
|
|
)
|
||
|
|
|
||
|
|
// EventConverter 事件转换器
|
||
|
|
// 将 Milky 事件转换为通用 protocol.Event
|
||
|
|
type EventConverter struct {
|
||
|
|
logger *zap.Logger
|
||
|
|
}
|
||
|
|
|
||
|
|
// NewEventConverter 创建事件转换器
|
||
|
|
func NewEventConverter(logger *zap.Logger) *EventConverter {
|
||
|
|
return &EventConverter{
|
||
|
|
logger: logger.Named("event-converter"),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Convert 转换事件
|
||
|
|
func (c *EventConverter) Convert(raw []byte) (protocol.Event, error) {
|
||
|
|
// 解析原始事件
|
||
|
|
var milkyEvent Event
|
||
|
|
if err := sonic.Unmarshal(raw, &milkyEvent); err != nil {
|
||
|
|
return nil, fmt.Errorf("failed to unmarshal event: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
c.logger.Debug("Converting event",
|
||
|
|
zap.String("event_type", milkyEvent.EventType),
|
||
|
|
zap.Int64("self_id", milkyEvent.SelfID))
|
||
|
|
|
||
|
|
// 根据事件类型转换
|
||
|
|
switch milkyEvent.EventType {
|
||
|
|
case EventTypeMessageReceive:
|
||
|
|
return c.convertMessageEvent(&milkyEvent)
|
||
|
|
case EventTypeFriendRequest:
|
||
|
|
return c.convertFriendRequestEvent(&milkyEvent)
|
||
|
|
case EventTypeGroupJoinRequest:
|
||
|
|
return c.convertGroupJoinRequestEvent(&milkyEvent)
|
||
|
|
case EventTypeGroupInvitedJoinRequest:
|
||
|
|
return c.convertGroupInvitedJoinRequestEvent(&milkyEvent)
|
||
|
|
case EventTypeGroupInvitation:
|
||
|
|
return c.convertGroupInvitationEvent(&milkyEvent)
|
||
|
|
case EventTypeMessageRecall:
|
||
|
|
return c.convertMessageRecallEvent(&milkyEvent)
|
||
|
|
case EventTypeBotOffline:
|
||
|
|
return c.convertBotOfflineEvent(&milkyEvent)
|
||
|
|
case EventTypeFriendNudge:
|
||
|
|
return c.convertFriendNudgeEvent(&milkyEvent)
|
||
|
|
case EventTypeFriendFileUpload:
|
||
|
|
return c.convertFriendFileUploadEvent(&milkyEvent)
|
||
|
|
case EventTypeGroupAdminChange:
|
||
|
|
return c.convertGroupAdminChangeEvent(&milkyEvent)
|
||
|
|
case EventTypeGroupEssenceMessageChange:
|
||
|
|
return c.convertGroupEssenceMessageChangeEvent(&milkyEvent)
|
||
|
|
case EventTypeGroupMemberIncrease:
|
||
|
|
return c.convertGroupMemberIncreaseEvent(&milkyEvent)
|
||
|
|
case EventTypeGroupMemberDecrease:
|
||
|
|
return c.convertGroupMemberDecreaseEvent(&milkyEvent)
|
||
|
|
case EventTypeGroupNameChange:
|
||
|
|
return c.convertGroupNameChangeEvent(&milkyEvent)
|
||
|
|
case EventTypeGroupMessageReaction:
|
||
|
|
return c.convertGroupMessageReactionEvent(&milkyEvent)
|
||
|
|
case EventTypeGroupMute:
|
||
|
|
return c.convertGroupMuteEvent(&milkyEvent)
|
||
|
|
case EventTypeGroupWholeMute:
|
||
|
|
return c.convertGroupWholeMuteEvent(&milkyEvent)
|
||
|
|
case EventTypeGroupNudge:
|
||
|
|
return c.convertGroupNudgeEvent(&milkyEvent)
|
||
|
|
case EventTypeGroupFileUpload:
|
||
|
|
return c.convertGroupFileUploadEvent(&milkyEvent)
|
||
|
|
default:
|
||
|
|
c.logger.Warn("Unknown event type", zap.String("event_type", milkyEvent.EventType))
|
||
|
|
return nil, fmt.Errorf("unknown event type: %s", milkyEvent.EventType)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// convertMessageEvent 转换消息事件
|
||
|
|
func (c *EventConverter) convertMessageEvent(milkyEvent *Event) (protocol.Event, error) {
|
||
|
|
selfID := strconv.FormatInt(milkyEvent.SelfID, 10)
|
||
|
|
|
||
|
|
// 解析消息数据
|
||
|
|
var msgData IncomingMessage
|
||
|
|
dataBytes, _ := sonic.Marshal(milkyEvent.Data)
|
||
|
|
if err := sonic.Unmarshal(dataBytes, &msgData); err != nil {
|
||
|
|
return nil, fmt.Errorf("failed to parse message data: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
// 构建消息文本
|
||
|
|
messageText := c.buildMessageText(msgData.Segments)
|
||
|
|
|
||
|
|
event := &protocol.MessageEvent{
|
||
|
|
BaseEvent: protocol.BaseEvent{
|
||
|
|
Type: protocol.EventTypeMessage,
|
||
|
|
DetailType: msgData.MessageScene, // friend, group, temp
|
||
|
|
SubType: "",
|
||
|
|
Timestamp: milkyEvent.Time,
|
||
|
|
SelfID: selfID,
|
||
|
|
Data: map[string]interface{}{
|
||
|
|
"peer_id": msgData.PeerID,
|
||
|
|
"message_seq": msgData.MessageSeq,
|
||
|
|
"sender_id": msgData.SenderID,
|
||
|
|
"time": msgData.Time,
|
||
|
|
"segments": msgData.Segments,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
MessageID: strconv.FormatInt(msgData.MessageSeq, 10),
|
||
|
|
Message: messageText,
|
||
|
|
AltText: messageText,
|
||
|
|
}
|
||
|
|
|
||
|
|
// 添加场景特定数据
|
||
|
|
if msgData.Friend != nil {
|
||
|
|
event.Data["friend"] = msgData.Friend
|
||
|
|
}
|
||
|
|
if msgData.Group != nil {
|
||
|
|
event.Data["group"] = msgData.Group
|
||
|
|
}
|
||
|
|
if msgData.GroupMember != nil {
|
||
|
|
event.Data["group_member"] = msgData.GroupMember
|
||
|
|
}
|
||
|
|
|
||
|
|
return event, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// convertFriendRequestEvent 转换好友请求事件
|
||
|
|
func (c *EventConverter) convertFriendRequestEvent(milkyEvent *Event) (protocol.Event, error) {
|
||
|
|
selfID := strconv.FormatInt(milkyEvent.SelfID, 10)
|
||
|
|
|
||
|
|
var data FriendRequestEventData
|
||
|
|
dataBytes, _ := sonic.Marshal(milkyEvent.Data)
|
||
|
|
if err := sonic.Unmarshal(dataBytes, &data); err != nil {
|
||
|
|
return nil, fmt.Errorf("failed to parse friend request data: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
event := &protocol.RequestEvent{
|
||
|
|
BaseEvent: protocol.BaseEvent{
|
||
|
|
Type: protocol.EventTypeRequest,
|
||
|
|
DetailType: "friend",
|
||
|
|
SubType: "",
|
||
|
|
Timestamp: milkyEvent.Time,
|
||
|
|
SelfID: selfID,
|
||
|
|
Data: map[string]interface{}{
|
||
|
|
"initiator_id": data.InitiatorID,
|
||
|
|
"initiator_uid": data.InitiatorUID,
|
||
|
|
"comment": data.Comment,
|
||
|
|
"via": data.Via,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
RequestID: strconv.FormatInt(data.InitiatorID, 10),
|
||
|
|
UserID: strconv.FormatInt(data.InitiatorID, 10),
|
||
|
|
Comment: data.Comment,
|
||
|
|
Flag: data.InitiatorUID,
|
||
|
|
}
|
||
|
|
|
||
|
|
return event, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// convertGroupJoinRequestEvent 转换入群申请事件
|
||
|
|
func (c *EventConverter) convertGroupJoinRequestEvent(milkyEvent *Event) (protocol.Event, error) {
|
||
|
|
selfID := strconv.FormatInt(milkyEvent.SelfID, 10)
|
||
|
|
|
||
|
|
var data GroupJoinRequestEventData
|
||
|
|
dataBytes, _ := sonic.Marshal(milkyEvent.Data)
|
||
|
|
if err := sonic.Unmarshal(dataBytes, &data); err != nil {
|
||
|
|
return nil, fmt.Errorf("failed to parse group join request data: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
event := &protocol.RequestEvent{
|
||
|
|
BaseEvent: protocol.BaseEvent{
|
||
|
|
Type: protocol.EventTypeRequest,
|
||
|
|
DetailType: "group",
|
||
|
|
SubType: "add",
|
||
|
|
Timestamp: milkyEvent.Time,
|
||
|
|
SelfID: selfID,
|
||
|
|
Data: map[string]interface{}{
|
||
|
|
"group_id": data.GroupID,
|
||
|
|
"notification_seq": data.NotificationSeq,
|
||
|
|
"is_filtered": data.IsFiltered,
|
||
|
|
"initiator_id": data.InitiatorID,
|
||
|
|
"comment": data.Comment,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
RequestID: strconv.FormatInt(data.NotificationSeq, 10),
|
||
|
|
UserID: strconv.FormatInt(data.InitiatorID, 10),
|
||
|
|
Comment: data.Comment,
|
||
|
|
Flag: strconv.FormatInt(data.NotificationSeq, 10),
|
||
|
|
}
|
||
|
|
|
||
|
|
return event, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// convertGroupInvitedJoinRequestEvent 转换群成员邀请他人入群事件
|
||
|
|
func (c *EventConverter) convertGroupInvitedJoinRequestEvent(milkyEvent *Event) (protocol.Event, error) {
|
||
|
|
selfID := strconv.FormatInt(milkyEvent.SelfID, 10)
|
||
|
|
|
||
|
|
var data GroupInvitedJoinRequestEventData
|
||
|
|
dataBytes, _ := sonic.Marshal(milkyEvent.Data)
|
||
|
|
if err := sonic.Unmarshal(dataBytes, &data); err != nil {
|
||
|
|
return nil, fmt.Errorf("failed to parse group invited join request data: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
event := &protocol.RequestEvent{
|
||
|
|
BaseEvent: protocol.BaseEvent{
|
||
|
|
Type: protocol.EventTypeRequest,
|
||
|
|
DetailType: "group",
|
||
|
|
SubType: "invite",
|
||
|
|
Timestamp: milkyEvent.Time,
|
||
|
|
SelfID: selfID,
|
||
|
|
Data: map[string]interface{}{
|
||
|
|
"group_id": data.GroupID,
|
||
|
|
"notification_seq": data.NotificationSeq,
|
||
|
|
"initiator_id": data.InitiatorID,
|
||
|
|
"target_user_id": data.TargetUserID,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
RequestID: strconv.FormatInt(data.NotificationSeq, 10),
|
||
|
|
UserID: strconv.FormatInt(data.InitiatorID, 10),
|
||
|
|
Comment: "",
|
||
|
|
Flag: strconv.FormatInt(data.NotificationSeq, 10),
|
||
|
|
}
|
||
|
|
|
||
|
|
return event, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// convertGroupInvitationEvent 转换他人邀请自身入群事件
|
||
|
|
func (c *EventConverter) convertGroupInvitationEvent(milkyEvent *Event) (protocol.Event, error) {
|
||
|
|
selfID := strconv.FormatInt(milkyEvent.SelfID, 10)
|
||
|
|
|
||
|
|
var data GroupInvitationEventData
|
||
|
|
dataBytes, _ := sonic.Marshal(milkyEvent.Data)
|
||
|
|
if err := sonic.Unmarshal(dataBytes, &data); err != nil {
|
||
|
|
return nil, fmt.Errorf("failed to parse group invitation data: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
event := &protocol.RequestEvent{
|
||
|
|
BaseEvent: protocol.BaseEvent{
|
||
|
|
Type: protocol.EventTypeRequest,
|
||
|
|
DetailType: "group",
|
||
|
|
SubType: "invite_self",
|
||
|
|
Timestamp: milkyEvent.Time,
|
||
|
|
SelfID: selfID,
|
||
|
|
Data: map[string]interface{}{
|
||
|
|
"group_id": data.GroupID,
|
||
|
|
"invitation_seq": data.InvitationSeq,
|
||
|
|
"initiator_id": data.InitiatorID,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
RequestID: strconv.FormatInt(data.InvitationSeq, 10),
|
||
|
|
UserID: strconv.FormatInt(data.InitiatorID, 10),
|
||
|
|
Comment: "",
|
||
|
|
Flag: strconv.FormatInt(data.InvitationSeq, 10),
|
||
|
|
}
|
||
|
|
|
||
|
|
return event, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// convertMessageRecallEvent 转换消息撤回事件
|
||
|
|
func (c *EventConverter) convertMessageRecallEvent(milkyEvent *Event) (protocol.Event, error) {
|
||
|
|
selfID := strconv.FormatInt(milkyEvent.SelfID, 10)
|
||
|
|
|
||
|
|
var data MessageRecallEventData
|
||
|
|
dataBytes, _ := sonic.Marshal(milkyEvent.Data)
|
||
|
|
if err := sonic.Unmarshal(dataBytes, &data); err != nil {
|
||
|
|
return nil, fmt.Errorf("failed to parse message recall data: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
event := &protocol.NoticeEvent{
|
||
|
|
BaseEvent: protocol.BaseEvent{
|
||
|
|
Type: protocol.EventTypeNotice,
|
||
|
|
DetailType: "message_recall",
|
||
|
|
SubType: data.MessageScene,
|
||
|
|
Timestamp: milkyEvent.Time,
|
||
|
|
SelfID: selfID,
|
||
|
|
Data: map[string]interface{}{
|
||
|
|
"message_scene": data.MessageScene,
|
||
|
|
"peer_id": data.PeerID,
|
||
|
|
"message_seq": data.MessageSeq,
|
||
|
|
"sender_id": data.SenderID,
|
||
|
|
"operator_id": data.OperatorID,
|
||
|
|
"display_suffix": data.DisplaySuffix,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
UserID: strconv.FormatInt(data.SenderID, 10),
|
||
|
|
Operator: strconv.FormatInt(data.OperatorID, 10),
|
||
|
|
}
|
||
|
|
|
||
|
|
return event, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// convertBotOfflineEvent 转换机器人离线事件
|
||
|
|
func (c *EventConverter) convertBotOfflineEvent(milkyEvent *Event) (protocol.Event, error) {
|
||
|
|
selfID := strconv.FormatInt(milkyEvent.SelfID, 10)
|
||
|
|
|
||
|
|
var data BotOfflineEventData
|
||
|
|
dataBytes, _ := sonic.Marshal(milkyEvent.Data)
|
||
|
|
if err := sonic.Unmarshal(dataBytes, &data); err != nil {
|
||
|
|
return nil, fmt.Errorf("failed to parse bot offline data: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
event := &protocol.MetaEvent{
|
||
|
|
BaseEvent: protocol.BaseEvent{
|
||
|
|
Type: protocol.EventTypeMeta,
|
||
|
|
DetailType: "bot_offline",
|
||
|
|
SubType: "",
|
||
|
|
Timestamp: milkyEvent.Time,
|
||
|
|
SelfID: selfID,
|
||
|
|
Data: map[string]interface{}{
|
||
|
|
"reason": data.Reason,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
Status: "offline",
|
||
|
|
}
|
||
|
|
|
||
|
|
return event, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// convertFriendNudgeEvent 转换好友戳一戳事件
|
||
|
|
func (c *EventConverter) convertFriendNudgeEvent(milkyEvent *Event) (protocol.Event, error) {
|
||
|
|
selfID := strconv.FormatInt(milkyEvent.SelfID, 10)
|
||
|
|
|
||
|
|
var data FriendNudgeEventData
|
||
|
|
dataBytes, _ := sonic.Marshal(milkyEvent.Data)
|
||
|
|
if err := sonic.Unmarshal(dataBytes, &data); err != nil {
|
||
|
|
return nil, fmt.Errorf("failed to parse friend nudge data: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
event := &protocol.NoticeEvent{
|
||
|
|
BaseEvent: protocol.BaseEvent{
|
||
|
|
Type: protocol.EventTypeNotice,
|
||
|
|
DetailType: "friend_nudge",
|
||
|
|
SubType: "",
|
||
|
|
Timestamp: milkyEvent.Time,
|
||
|
|
SelfID: selfID,
|
||
|
|
Data: map[string]interface{}(milkyEvent.Data),
|
||
|
|
},
|
||
|
|
UserID: strconv.FormatInt(data.UserID, 10),
|
||
|
|
}
|
||
|
|
|
||
|
|
return event, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// convertFriendFileUploadEvent 转换好友文件上传事件
|
||
|
|
func (c *EventConverter) convertFriendFileUploadEvent(milkyEvent *Event) (protocol.Event, error) {
|
||
|
|
selfID := strconv.FormatInt(milkyEvent.SelfID, 10)
|
||
|
|
|
||
|
|
var data FriendFileUploadEventData
|
||
|
|
dataBytes, _ := sonic.Marshal(milkyEvent.Data)
|
||
|
|
if err := sonic.Unmarshal(dataBytes, &data); err != nil {
|
||
|
|
return nil, fmt.Errorf("failed to parse friend file upload data: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
event := &protocol.NoticeEvent{
|
||
|
|
BaseEvent: protocol.BaseEvent{
|
||
|
|
Type: protocol.EventTypeNotice,
|
||
|
|
DetailType: "friend_file_upload",
|
||
|
|
SubType: "",
|
||
|
|
Timestamp: milkyEvent.Time,
|
||
|
|
SelfID: selfID,
|
||
|
|
Data: map[string]interface{}(milkyEvent.Data),
|
||
|
|
},
|
||
|
|
UserID: strconv.FormatInt(data.UserID, 10),
|
||
|
|
}
|
||
|
|
|
||
|
|
return event, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// convertGroupAdminChangeEvent 转换群管理员变更事件
|
||
|
|
func (c *EventConverter) convertGroupAdminChangeEvent(milkyEvent *Event) (protocol.Event, error) {
|
||
|
|
selfID := strconv.FormatInt(milkyEvent.SelfID, 10)
|
||
|
|
|
||
|
|
var data GroupAdminChangeEventData
|
||
|
|
dataBytes, _ := sonic.Marshal(milkyEvent.Data)
|
||
|
|
if err := sonic.Unmarshal(dataBytes, &data); err != nil {
|
||
|
|
return nil, fmt.Errorf("failed to parse group admin change data: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
subType := "unset"
|
||
|
|
if data.IsSet {
|
||
|
|
subType = "set"
|
||
|
|
}
|
||
|
|
|
||
|
|
event := &protocol.NoticeEvent{
|
||
|
|
BaseEvent: protocol.BaseEvent{
|
||
|
|
Type: protocol.EventTypeNotice,
|
||
|
|
DetailType: "group_admin",
|
||
|
|
SubType: subType,
|
||
|
|
Timestamp: milkyEvent.Time,
|
||
|
|
SelfID: selfID,
|
||
|
|
Data: map[string]interface{}(milkyEvent.Data),
|
||
|
|
},
|
||
|
|
GroupID: strconv.FormatInt(data.GroupID, 10),
|
||
|
|
UserID: strconv.FormatInt(data.UserID, 10),
|
||
|
|
}
|
||
|
|
|
||
|
|
return event, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// convertGroupEssenceMessageChangeEvent 转换群精华消息变更事件
|
||
|
|
func (c *EventConverter) convertGroupEssenceMessageChangeEvent(milkyEvent *Event) (protocol.Event, error) {
|
||
|
|
selfID := strconv.FormatInt(milkyEvent.SelfID, 10)
|
||
|
|
|
||
|
|
var data GroupEssenceMessageChangeEventData
|
||
|
|
dataBytes, _ := sonic.Marshal(milkyEvent.Data)
|
||
|
|
if err := sonic.Unmarshal(dataBytes, &data); err != nil {
|
||
|
|
return nil, fmt.Errorf("failed to parse group essence message change data: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
subType := "delete"
|
||
|
|
if data.IsSet {
|
||
|
|
subType = "add"
|
||
|
|
}
|
||
|
|
|
||
|
|
event := &protocol.NoticeEvent{
|
||
|
|
BaseEvent: protocol.BaseEvent{
|
||
|
|
Type: protocol.EventTypeNotice,
|
||
|
|
DetailType: "group_essence",
|
||
|
|
SubType: subType,
|
||
|
|
Timestamp: milkyEvent.Time,
|
||
|
|
SelfID: selfID,
|
||
|
|
Data: map[string]interface{}(milkyEvent.Data),
|
||
|
|
},
|
||
|
|
GroupID: strconv.FormatInt(data.GroupID, 10),
|
||
|
|
}
|
||
|
|
|
||
|
|
return event, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// convertGroupMemberIncreaseEvent 转换群成员增加事件
|
||
|
|
func (c *EventConverter) convertGroupMemberIncreaseEvent(milkyEvent *Event) (protocol.Event, error) {
|
||
|
|
selfID := strconv.FormatInt(milkyEvent.SelfID, 10)
|
||
|
|
|
||
|
|
var data GroupMemberIncreaseEventData
|
||
|
|
dataBytes, _ := sonic.Marshal(milkyEvent.Data)
|
||
|
|
if err := sonic.Unmarshal(dataBytes, &data); err != nil {
|
||
|
|
return nil, fmt.Errorf("failed to parse group member increase data: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
event := &protocol.NoticeEvent{
|
||
|
|
BaseEvent: protocol.BaseEvent{
|
||
|
|
Type: protocol.EventTypeNotice,
|
||
|
|
DetailType: "group_increase",
|
||
|
|
SubType: "",
|
||
|
|
Timestamp: milkyEvent.Time,
|
||
|
|
SelfID: selfID,
|
||
|
|
Data: map[string]interface{}(milkyEvent.Data),
|
||
|
|
},
|
||
|
|
GroupID: strconv.FormatInt(data.GroupID, 10),
|
||
|
|
UserID: strconv.FormatInt(data.UserID, 10),
|
||
|
|
}
|
||
|
|
|
||
|
|
if data.OperatorID != nil {
|
||
|
|
event.Operator = strconv.FormatInt(*data.OperatorID, 10)
|
||
|
|
}
|
||
|
|
|
||
|
|
return event, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// convertGroupMemberDecreaseEvent 转换群成员减少事件
|
||
|
|
func (c *EventConverter) convertGroupMemberDecreaseEvent(milkyEvent *Event) (protocol.Event, error) {
|
||
|
|
selfID := strconv.FormatInt(milkyEvent.SelfID, 10)
|
||
|
|
|
||
|
|
var data GroupMemberDecreaseEventData
|
||
|
|
dataBytes, _ := sonic.Marshal(milkyEvent.Data)
|
||
|
|
if err := sonic.Unmarshal(dataBytes, &data); err != nil {
|
||
|
|
return nil, fmt.Errorf("failed to parse group member decrease data: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
event := &protocol.NoticeEvent{
|
||
|
|
BaseEvent: protocol.BaseEvent{
|
||
|
|
Type: protocol.EventTypeNotice,
|
||
|
|
DetailType: "group_decrease",
|
||
|
|
SubType: "",
|
||
|
|
Timestamp: milkyEvent.Time,
|
||
|
|
SelfID: selfID,
|
||
|
|
Data: map[string]interface{}(milkyEvent.Data),
|
||
|
|
},
|
||
|
|
GroupID: strconv.FormatInt(data.GroupID, 10),
|
||
|
|
UserID: strconv.FormatInt(data.UserID, 10),
|
||
|
|
}
|
||
|
|
|
||
|
|
if data.OperatorID != nil {
|
||
|
|
event.Operator = strconv.FormatInt(*data.OperatorID, 10)
|
||
|
|
}
|
||
|
|
|
||
|
|
return event, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// convertGroupNameChangeEvent 转换群名称变更事件
|
||
|
|
func (c *EventConverter) convertGroupNameChangeEvent(milkyEvent *Event) (protocol.Event, error) {
|
||
|
|
selfID := strconv.FormatInt(milkyEvent.SelfID, 10)
|
||
|
|
|
||
|
|
var data GroupNameChangeEventData
|
||
|
|
dataBytes, _ := sonic.Marshal(milkyEvent.Data)
|
||
|
|
if err := sonic.Unmarshal(dataBytes, &data); err != nil {
|
||
|
|
return nil, fmt.Errorf("failed to parse group name change data: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
event := &protocol.NoticeEvent{
|
||
|
|
BaseEvent: protocol.BaseEvent{
|
||
|
|
Type: protocol.EventTypeNotice,
|
||
|
|
DetailType: "group_name_change",
|
||
|
|
SubType: "",
|
||
|
|
Timestamp: milkyEvent.Time,
|
||
|
|
SelfID: selfID,
|
||
|
|
Data: map[string]interface{}(milkyEvent.Data),
|
||
|
|
},
|
||
|
|
GroupID: strconv.FormatInt(data.GroupID, 10),
|
||
|
|
Operator: strconv.FormatInt(data.OperatorID, 10),
|
||
|
|
}
|
||
|
|
|
||
|
|
return event, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// convertGroupMessageReactionEvent 转换群消息回应事件
|
||
|
|
func (c *EventConverter) convertGroupMessageReactionEvent(milkyEvent *Event) (protocol.Event, error) {
|
||
|
|
selfID := strconv.FormatInt(milkyEvent.SelfID, 10)
|
||
|
|
|
||
|
|
var data GroupMessageReactionEventData
|
||
|
|
dataBytes, _ := sonic.Marshal(milkyEvent.Data)
|
||
|
|
if err := sonic.Unmarshal(dataBytes, &data); err != nil {
|
||
|
|
return nil, fmt.Errorf("failed to parse group message reaction data: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
subType := "remove"
|
||
|
|
if data.IsAdd {
|
||
|
|
subType = "add"
|
||
|
|
}
|
||
|
|
|
||
|
|
event := &protocol.NoticeEvent{
|
||
|
|
BaseEvent: protocol.BaseEvent{
|
||
|
|
Type: protocol.EventTypeNotice,
|
||
|
|
DetailType: "group_message_reaction",
|
||
|
|
SubType: subType,
|
||
|
|
Timestamp: milkyEvent.Time,
|
||
|
|
SelfID: selfID,
|
||
|
|
Data: map[string]interface{}(milkyEvent.Data),
|
||
|
|
},
|
||
|
|
GroupID: strconv.FormatInt(data.GroupID, 10),
|
||
|
|
UserID: strconv.FormatInt(data.UserID, 10),
|
||
|
|
}
|
||
|
|
|
||
|
|
return event, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// convertGroupMuteEvent 转换群禁言事件
|
||
|
|
func (c *EventConverter) convertGroupMuteEvent(milkyEvent *Event) (protocol.Event, error) {
|
||
|
|
selfID := strconv.FormatInt(milkyEvent.SelfID, 10)
|
||
|
|
|
||
|
|
var data GroupMuteEventData
|
||
|
|
dataBytes, _ := sonic.Marshal(milkyEvent.Data)
|
||
|
|
if err := sonic.Unmarshal(dataBytes, &data); err != nil {
|
||
|
|
return nil, fmt.Errorf("failed to parse group mute data: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
subType := "ban"
|
||
|
|
if data.Duration == 0 {
|
||
|
|
subType = "lift_ban"
|
||
|
|
}
|
||
|
|
|
||
|
|
event := &protocol.NoticeEvent{
|
||
|
|
BaseEvent: protocol.BaseEvent{
|
||
|
|
Type: protocol.EventTypeNotice,
|
||
|
|
DetailType: "group_ban",
|
||
|
|
SubType: subType,
|
||
|
|
Timestamp: milkyEvent.Time,
|
||
|
|
SelfID: selfID,
|
||
|
|
Data: map[string]interface{}(milkyEvent.Data),
|
||
|
|
},
|
||
|
|
GroupID: strconv.FormatInt(data.GroupID, 10),
|
||
|
|
UserID: strconv.FormatInt(data.UserID, 10),
|
||
|
|
Operator: strconv.FormatInt(data.OperatorID, 10),
|
||
|
|
}
|
||
|
|
|
||
|
|
return event, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// convertGroupWholeMuteEvent 转换群全体禁言事件
|
||
|
|
func (c *EventConverter) convertGroupWholeMuteEvent(milkyEvent *Event) (protocol.Event, error) {
|
||
|
|
selfID := strconv.FormatInt(milkyEvent.SelfID, 10)
|
||
|
|
|
||
|
|
var data GroupWholeMuteEventData
|
||
|
|
dataBytes, _ := sonic.Marshal(milkyEvent.Data)
|
||
|
|
if err := sonic.Unmarshal(dataBytes, &data); err != nil {
|
||
|
|
return nil, fmt.Errorf("failed to parse group whole mute data: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
subType := "ban"
|
||
|
|
if !data.IsMute {
|
||
|
|
subType = "lift_ban"
|
||
|
|
}
|
||
|
|
|
||
|
|
event := &protocol.NoticeEvent{
|
||
|
|
BaseEvent: protocol.BaseEvent{
|
||
|
|
Type: protocol.EventTypeNotice,
|
||
|
|
DetailType: "group_whole_ban",
|
||
|
|
SubType: subType,
|
||
|
|
Timestamp: milkyEvent.Time,
|
||
|
|
SelfID: selfID,
|
||
|
|
Data: map[string]interface{}(milkyEvent.Data),
|
||
|
|
},
|
||
|
|
GroupID: strconv.FormatInt(data.GroupID, 10),
|
||
|
|
Operator: strconv.FormatInt(data.OperatorID, 10),
|
||
|
|
}
|
||
|
|
|
||
|
|
return event, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// convertGroupNudgeEvent 转换群戳一戳事件
|
||
|
|
func (c *EventConverter) convertGroupNudgeEvent(milkyEvent *Event) (protocol.Event, error) {
|
||
|
|
selfID := strconv.FormatInt(milkyEvent.SelfID, 10)
|
||
|
|
|
||
|
|
var data GroupNudgeEventData
|
||
|
|
dataBytes, _ := sonic.Marshal(milkyEvent.Data)
|
||
|
|
if err := sonic.Unmarshal(dataBytes, &data); err != nil {
|
||
|
|
return nil, fmt.Errorf("failed to parse group nudge data: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
event := &protocol.NoticeEvent{
|
||
|
|
BaseEvent: protocol.BaseEvent{
|
||
|
|
Type: protocol.EventTypeNotice,
|
||
|
|
DetailType: "group_nudge",
|
||
|
|
SubType: "",
|
||
|
|
Timestamp: milkyEvent.Time,
|
||
|
|
SelfID: selfID,
|
||
|
|
Data: map[string]interface{}(milkyEvent.Data),
|
||
|
|
},
|
||
|
|
GroupID: strconv.FormatInt(data.GroupID, 10),
|
||
|
|
UserID: strconv.FormatInt(data.SenderID, 10),
|
||
|
|
}
|
||
|
|
|
||
|
|
return event, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// convertGroupFileUploadEvent 转换群文件上传事件
|
||
|
|
func (c *EventConverter) convertGroupFileUploadEvent(milkyEvent *Event) (protocol.Event, error) {
|
||
|
|
selfID := strconv.FormatInt(milkyEvent.SelfID, 10)
|
||
|
|
|
||
|
|
var data GroupFileUploadEventData
|
||
|
|
dataBytes, _ := sonic.Marshal(milkyEvent.Data)
|
||
|
|
if err := sonic.Unmarshal(dataBytes, &data); err != nil {
|
||
|
|
return nil, fmt.Errorf("failed to parse group file upload data: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
event := &protocol.NoticeEvent{
|
||
|
|
BaseEvent: protocol.BaseEvent{
|
||
|
|
Type: protocol.EventTypeNotice,
|
||
|
|
DetailType: "group_file_upload",
|
||
|
|
SubType: "",
|
||
|
|
Timestamp: milkyEvent.Time,
|
||
|
|
SelfID: selfID,
|
||
|
|
Data: map[string]interface{}(milkyEvent.Data),
|
||
|
|
},
|
||
|
|
GroupID: strconv.FormatInt(data.GroupID, 10),
|
||
|
|
UserID: strconv.FormatInt(data.UserID, 10),
|
||
|
|
}
|
||
|
|
|
||
|
|
return event, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// buildMessageText 构建消息文本
|
||
|
|
func (c *EventConverter) buildMessageText(segments []IncomingSegment) string {
|
||
|
|
var text string
|
||
|
|
for _, seg := range segments {
|
||
|
|
if seg.Type == "text" {
|
||
|
|
if textData, ok := seg.Data["text"].(string); ok {
|
||
|
|
text += textData
|
||
|
|
}
|
||
|
|
} else if seg.Type == "mention" {
|
||
|
|
if userID, ok := seg.Data["user_id"].(float64); ok {
|
||
|
|
text += fmt.Sprintf("@%d", int64(userID))
|
||
|
|
}
|
||
|
|
} else if seg.Type == "image" {
|
||
|
|
text += "[图片]"
|
||
|
|
} else if seg.Type == "voice" {
|
||
|
|
text += "[语音]"
|
||
|
|
} else if seg.Type == "video" {
|
||
|
|
text += "[视频]"
|
||
|
|
} else if seg.Type == "file" {
|
||
|
|
text += "[文件]"
|
||
|
|
} else if seg.Type == "face" {
|
||
|
|
text += "[表情]"
|
||
|
|
} else if seg.Type == "forward" {
|
||
|
|
text += "[转发消息]"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return text
|
||
|
|
}
|