104 lines
2.9 KiB
Go
104 lines
2.9 KiB
Go
package message
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"net/url"
|
||
"regexp"
|
||
"strings"
|
||
)
|
||
|
||
type ImageMessage struct {
|
||
Type string `json:"type"`
|
||
Data ImageMessageData `json:"data"`
|
||
}
|
||
|
||
type ImageMessageData struct {
|
||
URL string `json:"url,omitzero"`
|
||
Summary string `json:"summary,omitzero"`
|
||
File string `json:"file,omitzero"`
|
||
Key string `json:"key,omitzero"`
|
||
EmojiID string `json:"emoji_id,omitzero"`
|
||
PackageID string `json:"emoji_package_id,omitzero"`
|
||
SubType string `json:"sub_type,omitzero"`
|
||
FileID string `json:"file_id,omitzero"`
|
||
FileSize string `json:"file_size,omitzero"`
|
||
FileUnique string `json:"file_unique,omitzero"`
|
||
}
|
||
|
||
func init() {
|
||
RegisterMessageType(TypeImage, func() CQMessage {
|
||
return NewImageMessage()
|
||
})
|
||
}
|
||
|
||
func NewImageMessage() *ImageMessage {
|
||
return &ImageMessage{
|
||
Type: TypeImage,
|
||
Data: ImageMessageData{},
|
||
}
|
||
}
|
||
|
||
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.QueryUnescape(msg.Data.URL)
|
||
|
||
escapedURL = strings.ReplaceAll(escapedURL, ",", ",")
|
||
escapedURL = strings.ReplaceAll(escapedURL, "[", "[")
|
||
escapedURL = strings.ReplaceAll(escapedURL, "]", "]")
|
||
escapedURL = strings.ReplaceAll(escapedURL, "&", "&")
|
||
|
||
// 构造 CQ:image 字符串
|
||
cqString := fmt.Sprintf("[CQ:image,file=%s,sub_type=%s,file_id=%s,url=%s,file_size=%s,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,(.*?)\]`)
|
||
matches := re.FindStringSubmatch(data)
|
||
if len(matches) != 2 {
|
||
return fmt.Errorf("invalid image message format")
|
||
}
|
||
|
||
attrs := make(map[string]string)
|
||
pairs := strings.Split(matches[1], ",")
|
||
for _, pair := range pairs {
|
||
if kv := strings.SplitN(pair, "=", 2); len(kv) == 2 {
|
||
attrs[kv[0]] = kv[1]
|
||
}
|
||
}
|
||
|
||
msg.Data.URL = attrs["url"]
|
||
msg.Data.URL, _ = url.QueryUnescape(msg.Data.URL)
|
||
msg.Data.URL = strings.ReplaceAll(msg.Data.URL, ",", ",")
|
||
msg.Data.URL = strings.ReplaceAll(msg.Data.URL, "[", "[")
|
||
msg.Data.URL = strings.ReplaceAll(msg.Data.URL, "]", "]")
|
||
msg.Data.URL = strings.ReplaceAll(msg.Data.URL, "&", "&")
|
||
msg.Data.Summary = attrs["summary"]
|
||
msg.Data.File = attrs["file"]
|
||
msg.Data.Key = attrs["key"]
|
||
msg.Data.EmojiID = attrs["emoji_id"]
|
||
msg.Data.PackageID = attrs["emoji_package_id"]
|
||
msg.Data.SubType = attrs["sub_type"]
|
||
msg.Data.FileID = attrs["file_id"]
|
||
msg.Data.FileSize = attrs["file_size"]
|
||
msg.Data.FileUnique = attrs["file_unique"]
|
||
|
||
// URL是必需的字段(接收图片时)
|
||
if msg.Data.URL == "" {
|
||
return fmt.Errorf("missing required url field")
|
||
}
|
||
|
||
return nil
|
||
}
|