package model import ( "fmt" "net/url" "regexp" "strconv" "strings" ) // @某个QQ用户的结构体 type AtMessage struct { Type string `json:"type"` Data AtData `json:"data"` } // @消息数据结构体 type AtData struct { QQ string `json:"qq"` } func (msg *AtMessage) ToCQString() string { return fmt.Sprintf(`\[CQ:at,qq=%s\]`, msg.Data.QQ) } func ParseAtMessage(data string) (*AtMessage, error) { // 使用正则表达式提取QQ号 re := regexp.MustCompile(`\[CQ:at,qq=(\d+)\]`) matches := re.FindStringSubmatch(data) if len(matches) < 2 { return nil, fmt.Errorf("数据格式不正确") } // 返回解析后的结构体 return &AtMessage{ Type: "at", Data: AtData{ QQ: matches[1], }, }, nil } // 回复消息结构体 type ReplyMessage struct { Type string `json:"type"` Data ReplyData `json:"data"` } // 回复消息数据结构体 type ReplyData struct { ID string `json:"id"` } type ImageMessage struct { Type string `json:"type"` Data ImageMessageData `json:"data"` } type ImageMessageData struct { File string SubType string FileID string URL string FileSize int FileUnique string } func (msg *ImageMessage) ToCQString() (string, error) { // URL 转义 escapedURL := url.QueryEscape(msg.Data.URL) // 构造 CQ:image 字符串 cqString := fmt.Sprintf("[CQ:image,file=%s,sub_type=%s,file_id=%s,url=%s,file_size=%d,file_unique=%s]", msg.Data.File, msg.Data.SubType, msg.Data.FileID, escapedURL, msg.Data.FileSize, msg.Data.FileUnique) return cqString, nil } func ParseCQImageMessage(data string) (*ImageMessage, error) { // 使用正则表达式提取各个字段 re := regexp.MustCompile(`\[CQ:image,file=(.*?),sub_type=(.*?),file_id=(.*?),url=(.*?),file_size=(\d+),file_unique=(.*?)\]`) matches := re.FindStringSubmatch(data) if len(matches) < 7 { return nil, fmt.Errorf("数据格式不正确") } // 转换file_size为整数 fileSize, err := strconv.Atoi(matches[5]) if err != nil { return nil, fmt.Errorf("解析 file_size 出错: %v", err) } // 处理URL转义 decodedURL, err := url.QueryUnescape(matches[4]) decodedURL = strings.ReplaceAll(decodedURL, ",", ",") decodedURL = strings.ReplaceAll(decodedURL, "[", "[") decodedURL = strings.ReplaceAll(decodedURL, "]", "]") decodedURL = strings.ReplaceAll(decodedURL, "&", "&") if err != nil { return nil, fmt.Errorf("URL 转义失败: %v", err) } // 返回解析后的结构体 // return &ImageMessageData{ // File: matches[1], // SubType: matches[2], // FileID: matches[3], // URL: decodedURL, // FileSize: fileSize, // FileUnique: matches[6], // }, nil return &ImageMessage{ Type: "image", Data: ImageMessageData{ File: matches[1], SubType: matches[2], FileID: matches[3], URL: decodedURL, FileSize: fileSize, FileUnique: matches[6], }, }, nil }