qq_bot/message/image.go
lixiangwuxian debc0f6eb4 fix: 修复ImageMessage的ToCQString方法空URL处理
当URL和File均为空时,返回空字符串,避免生成无效的CQ码
2025-03-09 15:12:43 +08:00

84 lines
2.1 KiB
Go

package message
import (
"encoding/json"
"fmt"
"net/url"
"regexp"
"strconv"
"strings"
)
type ImageMessage struct {
Type string `json:"type"`
Data ImageMessageData `json:"data"`
}
type ImageMessageData struct {
File string `json:"file"`
SubType string `json:"sub_type"`
FileID string `json:"file_id"`
URL string `json:"url"`
FileSize int `json:"file_size"`
FileUnique string `json:"file_unique"`
}
func init() {
RegisterMessageType(TypeImage, func() CQMessage {
return &ImageMessage{Type: TypeImage}
})
}
func (msg *ImageMessage) SetData(data json.RawMessage) error {
return json.Unmarshal(data, &msg.Data)
}
func (msg *ImageMessage) ToCQString() string {
if msg.Data.URL == "" && msg.Data.File == "" {
return ""
}
// 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
}
func (msg *ImageMessage) ParseMessage(data string) 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 fmt.Errorf("数据格式不正确")
}
// 转换file_size为整数
fileSize, err := strconv.Atoi(matches[5])
if err != nil {
return fmt.Errorf("解析 file_size 出错: %v", err)
}
// 处理URL转义
decodedURL, err := url.QueryUnescape(matches[4])
decodedURL = strings.ReplaceAll(decodedURL, "&#44;", ",")
decodedURL = strings.ReplaceAll(decodedURL, "&#91;", "[")
decodedURL = strings.ReplaceAll(decodedURL, "&#93;", "]")
decodedURL = strings.ReplaceAll(decodedURL, "&amp;", "&")
if err != nil {
return fmt.Errorf("URL 转义失败: %v", err)
}
msg.Data = ImageMessageData{
File: matches[1],
SubType: matches[2],
FileID: matches[3],
URL: decodedURL,
FileSize: fileSize,
FileUnique: matches[6],
}
return nil
}