diff --git a/coolq/api.go b/coolq/api.go
index d20bf6c..90b4ade 100644
--- a/coolq/api.go
+++ b/coolq/api.go
@@ -119,7 +119,7 @@ func (bot *CQBot) CQSendGroupMessage(groupId int64, i interface{}, autoEscape bo
}
if m, ok := i.(gjson.Result); ok {
if m.Type == gjson.JSON {
- elem := bot.ConvertObjectMessage(m, true)
+ elem := bot.ConvertObjectMessage(m, true,groupId)
fixAt(elem)
mid := bot.SendGroupMessage(groupId, &message.SendingMessage{Elements: elem})
if mid == -1 {
@@ -144,7 +144,7 @@ func (bot *CQBot) CQSendGroupMessage(groupId int64, i interface{}, autoEscape bo
if autoEscape {
elem = append(elem, message.NewText(str))
} else {
- elem = bot.ConvertStringMessage(str, true)
+ elem = bot.ConvertStringMessage(str, true,groupId)
}
fixAt(elem)
mid := bot.SendGroupMessage(groupId, &message.SendingMessage{Elements: elem})
@@ -187,7 +187,7 @@ func (bot *CQBot) CQSendGroupForwardMessage(groupId int64, m gjson.Result) MSG {
}
return m["time"].(int32)
}(),
- Message: bot.ConvertStringMessage(m["message"].(string), true),
+ Message: bot.ConvertStringMessage(m["message"].(string), true,groupId),
})
return
}
@@ -196,7 +196,7 @@ func (bot *CQBot) CQSendGroupForwardMessage(groupId int64, m gjson.Result) MSG {
}
uin, _ := strconv.ParseInt(e.Get("data.uin").Str, 10, 64)
name := e.Get("data.name").Str
- content := bot.ConvertObjectMessage(e.Get("data.content"), true)
+ content := bot.ConvertObjectMessage(e.Get("data.content"), true,groupId)
if uin != 0 && name != "" && len(content) > 0 {
var newElem []message.IMessageElement
for _, elem := range content {
@@ -242,7 +242,7 @@ func (bot *CQBot) CQSendPrivateMessage(userId int64, i interface{}, autoEscape b
var str string
if m, ok := i.(gjson.Result); ok {
if m.Type == gjson.JSON {
- elem := bot.ConvertObjectMessage(m, true)
+ elem := bot.ConvertObjectMessage(m, true,userId)
mid := bot.SendPrivateMessage(userId, &message.SendingMessage{Elements: elem})
if mid == -1 {
return Failed(100)
@@ -265,7 +265,7 @@ func (bot *CQBot) CQSendPrivateMessage(userId int64, i interface{}, autoEscape b
if autoEscape {
elem = append(elem, message.NewText(str))
} else {
- elem = bot.ConvertStringMessage(str, false)
+ elem = bot.ConvertStringMessage(str, false,userId)
}
mid := bot.SendPrivateMessage(userId, &message.SendingMessage{Elements: elem})
if mid == -1 {
diff --git a/coolq/bot.go b/coolq/bot.go
index 12a96e8..e32ca58 100644
--- a/coolq/bot.go
+++ b/coolq/bot.go
@@ -259,3 +259,4 @@ func (m MSG) ToJson() string {
b, _ := json.Marshal(m)
return string(b)
}
+
diff --git a/coolq/cqcode.go b/coolq/cqcode.go
index 0b86843..0f8e77f 100644
--- a/coolq/cqcode.go
+++ b/coolq/cqcode.go
@@ -173,7 +173,7 @@ func ToStringMessage(e []message.IMessageElement, code int64, raw ...bool) (r st
return
}
-func (bot *CQBot) ConvertStringMessage(m string, group bool) (r []message.IMessageElement) {
+func (bot *CQBot) ConvertStringMessage(m string, group bool, uid int64) (r []message.IMessageElement) {
i := matchReg.FindAllStringSubmatchIndex(m, -1)
si := 0
for _, idx := range i {
@@ -205,14 +205,14 @@ func (bot *CQBot) ConvertStringMessage(m string, group bool) (r []message.IMessa
ReplySeq: org["message-id"].(int32),
Sender: org["sender"].(message.Sender).Uin,
Time: org["time"].(int32),
- Elements: bot.ConvertStringMessage(org["message"].(string), group),
+ Elements: bot.ConvertStringMessage(org["message"].(string), group, uid),
},
}, r...)
continue
}
}
}
- elem, err := bot.ToElement(t, d, group)
+ elem, err := bot.ToElement(t, d, group, uid)
if err != nil {
if !IgnoreInvalidCQCode {
log.Warnf("转换CQ码 %v 到MiraiGo Element时出现错误: %v 将原样发送.", code, err)
@@ -230,7 +230,7 @@ func (bot *CQBot) ConvertStringMessage(m string, group bool) (r []message.IMessa
return
}
-func (bot *CQBot) ConvertObjectMessage(m gjson.Result, group bool) (r []message.IMessageElement) {
+func (bot *CQBot) ConvertObjectMessage(m gjson.Result, group bool, uid int64) (r []message.IMessageElement) {
convertElem := func(e gjson.Result) {
t := e.Get("type").Str
if t == "reply" && group {
@@ -249,7 +249,7 @@ func (bot *CQBot) ConvertObjectMessage(m gjson.Result, group bool) (r []message.
ReplySeq: org["message-id"].(int32),
Sender: org["sender"].(message.Sender).Uin,
Time: org["time"].(int32),
- Elements: bot.ConvertStringMessage(org["message"].(string), group),
+ Elements: bot.ConvertStringMessage(org["message"].(string), group, uid),
},
}, r...)
return
@@ -261,7 +261,7 @@ func (bot *CQBot) ConvertObjectMessage(m gjson.Result, group bool) (r []message.
d[key.Str] = value.Str
return true
})
- elem, err := bot.ToElement(t, d, group)
+ elem, err := bot.ToElement(t, d, group, uid)
if err != nil {
log.Warnf("转换CQ码到MiraiGo Element时出现错误: %v 将忽略本段CQ码.", err)
return
@@ -269,7 +269,7 @@ func (bot *CQBot) ConvertObjectMessage(m gjson.Result, group bool) (r []message.
r = append(r, elem)
}
if m.Type == gjson.String {
- return bot.ConvertStringMessage(m.Str, group)
+ return bot.ConvertStringMessage(m.Str, group, uid)
}
if m.IsArray() {
for _, e := range m.Array() {
@@ -282,121 +282,12 @@ func (bot *CQBot) ConvertObjectMessage(m gjson.Result, group bool) (r []message.
return
}
-func (bot *CQBot) ToElement(t string, d map[string]string, group bool) (message.IMessageElement, error) {
+func (bot *CQBot) ToElement(t string, d map[string]string, group bool, uid int64) (message.IMessageElement, error) {
switch t {
case "text":
return message.NewText(d["text"]), nil
case "image":
- f := d["file"]
- if strings.HasPrefix(f, "http") || strings.HasPrefix(f, "https") {
- cache := d["cache"]
- if cache == "" {
- cache = "1"
- }
- hash := md5.Sum([]byte(f))
- cacheFile := path.Join(global.CACHE_PATH, hex.EncodeToString(hash[:])+".cache")
- if global.PathExists(cacheFile) && cache == "1" {
- b, err := ioutil.ReadFile(cacheFile)
- if err == nil {
- return message.NewImage(b), nil
- }
- }
- b, err := global.GetBytes(f)
- if err != nil {
- return nil, err
- }
- _ = ioutil.WriteFile(cacheFile, b, 0644)
- return message.NewImage(b), nil
- }
- if strings.HasPrefix(f, "base64") {
- b, err := base64.StdEncoding.DecodeString(strings.ReplaceAll(f, "base64://", ""))
- if err != nil {
- return nil, err
- }
- return message.NewImage(b), nil
- }
- if strings.HasPrefix(f, "file") {
- fu, err := url.Parse(f)
- if err != nil {
- return nil, err
- }
- if strings.HasPrefix(fu.Path, "/") && runtime.GOOS == `windows` {
- fu.Path = fu.Path[1:]
- }
- b, err := ioutil.ReadFile(fu.Path)
- if err != nil {
- return nil, err
- }
- return message.NewImage(b), nil
- }
- rawPath := path.Join(global.IMAGE_PATH, f)
- if !global.PathExists(rawPath) && global.PathExists(rawPath+".cqimg") {
- rawPath += ".cqimg"
- }
- if !global.PathExists(rawPath) && d["url"] != "" {
- return bot.ToElement(t, map[string]string{"file": d["url"]}, group)
- }
- if global.PathExists(rawPath) {
- b, err := ioutil.ReadFile(rawPath)
- if err != nil {
- return nil, err
- }
- if path.Ext(rawPath) != ".image" && path.Ext(rawPath) != ".cqimg" {
- return message.NewImage(b), nil
- }
- if len(b) < 20 {
- return nil, errors.New("invalid local file")
- }
- var size int32
- var hash []byte
- var url string
- if path.Ext(rawPath) == ".cqimg" {
- for _, line := range strings.Split(global.ReadAllText(rawPath), "\n") {
- kv := strings.SplitN(line, "=", 2)
- switch kv[0] {
- case "md5":
- hash, _ = hex.DecodeString(strings.ReplaceAll(kv[1], "\r", ""))
- case "size":
- t, _ := strconv.Atoi(strings.ReplaceAll(kv[1], "\r", ""))
- size = int32(t)
- }
- }
- } else {
- r := binary.NewReader(b)
- hash = r.ReadBytes(16)
- size = r.ReadInt32()
- r.ReadString()
- url = r.ReadString()
- }
- if size == 0 {
- if url != "" {
- return bot.ToElement(t, map[string]string{"file": url}, group)
- }
- return nil, errors.New("img size is 0")
- }
- if len(hash) != 16 {
- return nil, errors.New("invalid hash")
- }
- if group {
- rsp, err := bot.Client.QueryGroupImage(1, hash, size)
- if err != nil {
- if url != "" {
- return bot.ToElement(t, map[string]string{"file": url}, group)
- }
- return nil, err
- }
- return rsp, nil
- }
- rsp, err := bot.Client.QueryFriendImage(1, hash, size)
- if err != nil {
- if url != "" {
- return bot.ToElement(t, map[string]string{"file": url}, group)
- }
- return nil, err
- }
- return rsp, nil
- }
- return nil, errors.New("invalid image")
+ return bot.makeImageElem(t, d, group, uid)
case "record":
if !group {
return nil, errors.New("private voice unsupported now")
@@ -534,6 +425,11 @@ func (bot *CQBot) ToElement(t string, d map[string]string, group bool) (message.
//resid不为0的情况下走富文本通道,后续补全透传service Id,此处暂时不处理 TODO
msg := message.NewRichJson(CQCodeUnescapeValue(d["data"]))
return msg, nil
+ case "cardimage":
+ source := d["source"]
+ icon := d["icon"]
+ img, _ := bot.makeImageElem(t, d, group, uid)
+ return bot.SendNewPic(uid, img, source, icon, group)
default:
return nil, errors.New("unsupported cq code: " + t)
}
@@ -566,3 +462,142 @@ func CQCodeUnescapeValue(content string) string {
ret = CQCodeUnescapeText(ret)
return ret
}
+
+// 图片 elem 生成器,单独拎出来,用于公用
+func (bot *CQBot) makeImageElem(t string, d map[string]string, group bool, uid int64) (message.IMessageElement, error) {
+ f := d["file"]
+ if strings.HasPrefix(f, "http") || strings.HasPrefix(f, "https") {
+ cache := d["cache"]
+ if cache == "" {
+ cache = "1"
+ }
+ hash := md5.Sum([]byte(f))
+ cacheFile := path.Join(global.CACHE_PATH, hex.EncodeToString(hash[:])+".cache")
+ if global.PathExists(cacheFile) && cache == "1" {
+ b, err := ioutil.ReadFile(cacheFile)
+ if err == nil {
+ return message.NewImage(b), nil
+ }
+ }
+ b, err := global.GetBytes(f)
+ if err != nil {
+ return nil, err
+ }
+ _ = ioutil.WriteFile(cacheFile, b, 0644)
+ return message.NewImage(b), nil
+ }
+ if strings.HasPrefix(f, "base64") {
+ b, err := base64.StdEncoding.DecodeString(strings.ReplaceAll(f, "base64://", ""))
+ if err != nil {
+ return nil, err
+ }
+ return message.NewImage(b), nil
+ }
+ if strings.HasPrefix(f, "file") {
+ fu, err := url.Parse(f)
+ if err != nil {
+ return nil, err
+ }
+ if strings.HasPrefix(fu.Path, "/") && runtime.GOOS == `windows` {
+ fu.Path = fu.Path[1:]
+ }
+ b, err := ioutil.ReadFile(fu.Path)
+ if err != nil {
+ return nil, err
+ }
+ return message.NewImage(b), nil
+ }
+ rawPath := path.Join(global.IMAGE_PATH, f)
+ if !global.PathExists(rawPath) && global.PathExists(rawPath+".cqimg") {
+ rawPath += ".cqimg"
+ }
+ if !global.PathExists(rawPath) && d["url"] != "" {
+ return bot.ToElement(t, map[string]string{"file": d["url"]}, group, uid)
+ }
+ if global.PathExists(rawPath) {
+ b, err := ioutil.ReadFile(rawPath)
+ if err != nil {
+ return nil, err
+ }
+ if path.Ext(rawPath) != ".image" && path.Ext(rawPath) != ".cqimg" {
+ return message.NewImage(b), nil
+ }
+ if len(b) < 20 {
+ return nil, errors.New("invalid local file")
+ }
+ var size int32
+ var hash []byte
+ var url string
+ if path.Ext(rawPath) == ".cqimg" {
+ for _, line := range strings.Split(global.ReadAllText(rawPath), "\n") {
+ kv := strings.SplitN(line, "=", 2)
+ switch kv[0] {
+ case "md5":
+ hash, _ = hex.DecodeString(strings.ReplaceAll(kv[1], "\r", ""))
+ case "size":
+ t, _ := strconv.Atoi(strings.ReplaceAll(kv[1], "\r", ""))
+ size = int32(t)
+ }
+ }
+ } else {
+ r := binary.NewReader(b)
+ hash = r.ReadBytes(16)
+ size = r.ReadInt32()
+ r.ReadString()
+ url = r.ReadString()
+ }
+ if size == 0 {
+ if url != "" {
+ return bot.ToElement(t, map[string]string{"file": url}, group, uid)
+ }
+ return nil, errors.New("img size is 0")
+ }
+ if len(hash) != 16 {
+ return nil, errors.New("invalid hash")
+ }
+ if group {
+ rsp, err := bot.Client.QueryGroupImage(1, hash, size)
+ if err != nil {
+ if url != "" {
+ return bot.ToElement(t, map[string]string{"file": url}, group, uid)
+ }
+ return nil, err
+ }
+ return rsp, nil
+ }
+ rsp, err := bot.Client.QueryFriendImage(1, hash, size)
+ if err != nil {
+ if url != "" {
+ return bot.ToElement(t, map[string]string{"file": url}, group, uid)
+ }
+ return nil, err
+ }
+ return rsp, nil
+ }
+ return nil, errors.New("invalid image")
+}
+
+//SendNewPic 一种xml 方式发送的群消息图片
+func (bot *CQBot) SendNewPic(id int64, i message.ImageElement, source string, icon string, group bool) (*message.ServiceElement, error) {
+ var xml string
+ if group == false {
+ gm, err := bot.Client.UploadPrivateImage(id, i.Data)
+ if err != nil {
+ log.Warnf("警告: 群 %v 消息图片上传失败: %v", id, err)
+ return nil, err
+ }
+ xml = fmt.Sprintf(` `, "", gm.ImageId, gm.Md5, i.Size, "", source, icon)
+
+ } else {
+ gm, err := bot.Client.UploadGroupImage(id, i.Data)
+ if err != nil {
+ log.Warnf("警告: 群 %v 消息图片上传失败: %v", id, err)
+ return nil, err
+ }
+ xml = fmt.Sprintf(` `, "", gm.FileId, gm.Md5, i.Size, "", source, icon)
+ }
+ log.Warn(xml)
+ XmlMsg := message.NewRichXml(xml, 5)
+ return XmlMsg, nil
+ return nil, errors.New("发送xml图片消息失败")
+}
diff --git a/go.sum b/go.sum
index 3eead0b..e24e526 100644
--- a/go.sum
+++ b/go.sum
@@ -35,6 +35,7 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=