feat: 重构消息处理模块,引入统一的消息接口和类型安全的消息解析
This commit is contained in:
@@ -1,143 +0,0 @@
|
||||
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 int `json:"id"`
|
||||
}
|
||||
|
||||
func ParseReplyData(data string) (*ReplyMessage, error) {
|
||||
// 使用正则表达式提取ID
|
||||
re := regexp.MustCompile(`\[CQ:reply,id=(\d+)\]`)
|
||||
matches := re.FindStringSubmatch(data)
|
||||
if len(matches) < 2 {
|
||||
return nil, fmt.Errorf("数据格式不正确")
|
||||
}
|
||||
|
||||
id, _ := strconv.Atoi(matches[1])
|
||||
|
||||
// 返回解析后的结构体
|
||||
return &ReplyMessage{
|
||||
Type: "reply",
|
||||
Data: ReplyData{
|
||||
ID: id,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user