mirror of
https://github.com/Mrs4s/go-cqhttp.git
synced 2025-05-05 11:33:48 +08:00
Merge pull request #245 from scjtqs/master
cq码 添加 cardimage 类型,一种xml的 特殊图片格式,json和xml的格式上报
This commit is contained in:
commit
a417ff0881
431
coolq/cqcode.go
431
coolq/cqcode.go
@ -6,6 +6,11 @@ import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/Mrs4s/MiraiGo/binary"
|
||||
"github.com/Mrs4s/MiraiGo/message"
|
||||
"github.com/Mrs4s/go-cqhttp/global"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/tidwall/gjson"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"path"
|
||||
@ -13,12 +18,6 @@ import (
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/Mrs4s/MiraiGo/binary"
|
||||
"github.com/Mrs4s/MiraiGo/message"
|
||||
"github.com/Mrs4s/go-cqhttp/global"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
var matchReg = regexp.MustCompile(`\[CQ:\w+?.*?]`)
|
||||
@ -52,9 +51,13 @@ func ToArrayMessage(e []message.IMessageElement, code int64, raw ...bool) (r []M
|
||||
"data": map[string]string{"text": o.Content},
|
||||
}
|
||||
case *message.LightAppElement:
|
||||
//m = MSG{
|
||||
// "type": "text",
|
||||
// "data": map[string]string{"text": o.Content},
|
||||
//}
|
||||
m = MSG{
|
||||
"type": "text",
|
||||
"data": map[string]string{"text": o.Content},
|
||||
"type": "json",
|
||||
"data": map[string]string{"data": o.Content},
|
||||
}
|
||||
case *message.AtElement:
|
||||
if o.Target == 0 {
|
||||
@ -114,6 +117,18 @@ func ToArrayMessage(e []message.IMessageElement, code int64, raw ...bool) (r []M
|
||||
"data": map[string]string{"file": o.Filename, "url": o.Url},
|
||||
}
|
||||
}
|
||||
case *message.ServiceElement:
|
||||
if isOk := strings.Contains(o.Content, "<?xml"); isOk {
|
||||
m = MSG{
|
||||
"type": "xml",
|
||||
"data": map[string]string{"data": o.Content, "resid": fmt.Sprintf("%d", o.Id)},
|
||||
}
|
||||
} else {
|
||||
m = MSG{
|
||||
"type": "json",
|
||||
"data": map[string]string{"data": o.Content, "resid": fmt.Sprintf("%d", o.Id)},
|
||||
}
|
||||
}
|
||||
}
|
||||
r = append(r, m)
|
||||
}
|
||||
@ -166,8 +181,15 @@ func ToStringMessage(e []message.IMessageElement, code int64, raw ...bool) (r st
|
||||
} else {
|
||||
r += fmt.Sprintf(`[CQ:image,file=%s,url=%s]`, o.Filename, CQCodeEscapeValue(o.Url))
|
||||
}
|
||||
case *message.ServiceElement:
|
||||
if isOk := strings.Contains(o.Content, "<?xml"); isOk {
|
||||
r += fmt.Sprintf(`[CQ:xml,data=%s,resid=%d]`, CQCodeEscapeValue(o.Content), o.Id)
|
||||
} else {
|
||||
r += fmt.Sprintf(`[CQ:json,data=%s,resid=%d]`, CQCodeEscapeValue(o.Content), o.Id)
|
||||
}
|
||||
case *message.LightAppElement:
|
||||
r += CQCodeEscapeText(o.Content)
|
||||
r += fmt.Sprintf(`[CQ:json,data=%s]`, CQCodeEscapeValue(o.Content))
|
||||
//r += CQCodeEscapeText(o.Content)
|
||||
}
|
||||
}
|
||||
return
|
||||
@ -287,6 +309,201 @@ func (bot *CQBot) ToElement(t string, d map[string]string, group bool) (message.
|
||||
case "text":
|
||||
return message.NewText(d["text"]), nil
|
||||
case "image":
|
||||
return bot.makeImageElem(t, d, group)
|
||||
case "record":
|
||||
if !group {
|
||||
return nil, errors.New("private voice unsupported now")
|
||||
}
|
||||
f := d["file"]
|
||||
var data []byte
|
||||
if strings.HasPrefix(f, "http") || strings.HasPrefix(f, "https") {
|
||||
b, err := global.GetBytes(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data = b
|
||||
}
|
||||
if strings.HasPrefix(f, "base64") {
|
||||
b, err := base64.StdEncoding.DecodeString(strings.ReplaceAll(f, "base64://", ""))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data = b
|
||||
}
|
||||
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
|
||||
}
|
||||
data = b
|
||||
}
|
||||
if global.PathExists(path.Join(global.VOICE_PATH, f)) {
|
||||
b, err := ioutil.ReadFile(path.Join(global.VOICE_PATH, f))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data = b
|
||||
}
|
||||
if !global.IsAMRorSILK(data) {
|
||||
return nil, errors.New("unsupported voice file format (please use AMR file for now)")
|
||||
}
|
||||
return &message.VoiceElement{Data: data}, nil
|
||||
case "face":
|
||||
id, err := strconv.Atoi(d["id"])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return message.NewFace(int32(id)), nil
|
||||
case "at":
|
||||
qq := d["qq"]
|
||||
if qq == "all" {
|
||||
return message.AtAll(), nil
|
||||
}
|
||||
t, _ := strconv.ParseInt(qq, 10, 64)
|
||||
return message.NewAt(t), nil
|
||||
case "share":
|
||||
return message.NewUrlShare(d["url"], d["title"], d["content"], d["image"]), nil
|
||||
case "music":
|
||||
if d["type"] == "qq" {
|
||||
info, err := global.QQMusicSongInfo(d["id"])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !info.Get("track_info").Exists() {
|
||||
return nil, errors.New("song not found")
|
||||
}
|
||||
aid := strconv.FormatInt(info.Get("track_info.album.id").Int(), 10)
|
||||
name := info.Get("track_info.name").Str + " - " + info.Get("track_info.singer.0.name").Str
|
||||
mid := info.Get("track_info.mid").Str
|
||||
albumMid := info.Get("track_info.album.mid").Str
|
||||
pinfo, _ := global.GetBytes("http://u.y.qq.com/cgi-bin/musicu.fcg?g_tk=2034008533&uin=0&format=json&data={\"comm\":{\"ct\":23,\"cv\":0},\"url_mid\":{\"module\":\"vkey.GetVkeyServer\",\"method\":\"CgiGetVkey\",\"param\":{\"guid\":\"4311206557\",\"songmid\":[\"" + mid + "\"],\"songtype\":[0],\"uin\":\"0\",\"loginflag\":1,\"platform\":\"23\"}}}&_=1599039471576")
|
||||
jumpUrl := "https://i.y.qq.com/v8/playsong.html?platform=11&appshare=android_qq&appversion=10030010&hosteuin=oKnlNenz7i-s7c**&songmid=" + mid + "&type=0&appsongtype=1&_wv=1&source=qq&ADTAG=qfshare"
|
||||
purl := gjson.ParseBytes(pinfo).Get("url_mid.data.midurlinfo.0.purl").Str
|
||||
preview := "http://y.gtimg.cn/music/photo_new/T002R180x180M000" + albumMid + ".jpg"
|
||||
if len(aid) < 2 {
|
||||
return nil, errors.New("song error")
|
||||
}
|
||||
content := "来自go-cqhttp"
|
||||
if d["content"] != "" {
|
||||
content = d["content"]
|
||||
}
|
||||
json := fmt.Sprintf("{\"app\": \"com.tencent.structmsg\",\"desc\": \"音乐\",\"meta\": {\"music\": {\"desc\": \"%s\",\"jumpUrl\": \"%s\",\"musicUrl\": \"%s\",\"preview\": \"%s\",\"tag\": \"QQ音乐\",\"title\": \"%s\"}},\"prompt\": \"[分享]%s\",\"ver\": \"0.0.0.1\",\"view\": \"music\"}", content, jumpUrl, purl, preview, name, name)
|
||||
return message.NewLightApp(json), nil
|
||||
}
|
||||
if d["type"] == "163" {
|
||||
info, err := global.NeteaseMusicSongInfo(d["id"])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !info.Exists() {
|
||||
return nil, errors.New("song not found")
|
||||
}
|
||||
name := info.Get("name").Str
|
||||
jumpUrl := "https://y.music.163.com/m/song/" + d["id"]
|
||||
musicUrl := "http://music.163.com/song/media/outer/url?id=" + d["id"]
|
||||
picUrl := info.Get("album.picUrl").Str
|
||||
artistName := ""
|
||||
if info.Get("artists.0").Exists() {
|
||||
artistName = info.Get("artists.0.name").Str
|
||||
}
|
||||
json := fmt.Sprintf("{\"app\": \"com.tencent.structmsg\",\"desc\":\"音乐\",\"view\":\"music\",\"prompt\":\"[分享]%s\",\"ver\":\"0.0.0.1\",\"meta\":{ \"music\": { \"desc\": \"%s\", \"jumpUrl\": \"%s\", \"musicUrl\": \"%s\", \"preview\": \"%s\", \"tag\": \"网易云音乐\", \"title\":\"%s\"}}}", name, artistName, jumpUrl, musicUrl, picUrl, name)
|
||||
return message.NewLightApp(json), nil
|
||||
}
|
||||
if d["type"] == "custom" {
|
||||
xml := fmt.Sprintf(`<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><msg serviceID="2" templateID="1" action="web" brief="[分享] %s" sourceMsgId="0" url="%s" flag="0" adverSign="0" multiMsgFlag="0"><item layout="2"><audio cover="%s" src="%s"/><title>%s</title><summary>%s</summary></item><source name="音乐" icon="https://i.gtimg.cn/open/app_icon/01/07/98/56/1101079856_100_m.png" url="http://web.p.qq.com/qqmpmobile/aio/app.html?id=1101079856" action="app" a_actionData="com.tencent.qqmusic" i_actionData="tencent1101079856://" appid="1101079856" /></msg>`,
|
||||
d["title"], d["url"], d["image"], d["audio"], d["title"], d["content"])
|
||||
return &message.ServiceElement{
|
||||
Id: 60,
|
||||
Content: xml,
|
||||
SubType: "music",
|
||||
}, nil
|
||||
}
|
||||
return nil, errors.New("unsupported music type: " + d["type"])
|
||||
case "xml":
|
||||
resId := d["resid"]
|
||||
template := CQCodeEscapeValue(d["data"])
|
||||
//println(template)
|
||||
i, _ := strconv.ParseInt(resId, 10, 64)
|
||||
msg := message.NewRichXml(template, i)
|
||||
return msg, nil
|
||||
case "json":
|
||||
resId := d["resid"]
|
||||
i, _ := strconv.ParseInt(resId, 10, 64)
|
||||
log.Warnf("json msg=%s", d["data"])
|
||||
if i == 0 {
|
||||
//默认情况下走小程序通道
|
||||
msg := message.NewLightApp(CQCodeUnescapeValue(d["data"]))
|
||||
return msg, nil
|
||||
}
|
||||
//resid不为0的情况下走富文本通道,后续补全透传service Id,此处暂时不处理 TODO
|
||||
msg := message.NewRichJson(CQCodeUnescapeValue(d["data"]))
|
||||
return msg, nil
|
||||
case "cardimage":
|
||||
source := d["source"]
|
||||
icon := d["icon"]
|
||||
minwidth, _ := strconv.ParseInt(d["minwidth"], 10, 64)
|
||||
if minwidth == 0 {
|
||||
minwidth = 200
|
||||
}
|
||||
minheight, _ := strconv.ParseInt(d["minheight"], 10, 64)
|
||||
if minheight == 0 {
|
||||
minheight = 200
|
||||
}
|
||||
maxwidth, _ := strconv.ParseInt(d["maxwidth"], 10, 64)
|
||||
if maxwidth == 0 {
|
||||
maxwidth = 500
|
||||
}
|
||||
maxheight, _ := strconv.ParseInt(d["maxheight"], 10, 64)
|
||||
if maxheight == 0 {
|
||||
maxheight = 1000
|
||||
}
|
||||
img, err := bot.makeImageElem(t, d, group)
|
||||
if err != nil {
|
||||
return nil, errors.New("send cardimage faild")
|
||||
}
|
||||
return bot.SendNewPic(img, source, icon, minwidth, minheight, maxwidth, maxheight, group)
|
||||
default:
|
||||
return nil, errors.New("unsupported cq code: " + t)
|
||||
}
|
||||
}
|
||||
|
||||
func CQCodeEscapeText(raw string) string {
|
||||
ret := raw
|
||||
ret = strings.ReplaceAll(ret, "&", "&")
|
||||
ret = strings.ReplaceAll(ret, "[", "[")
|
||||
ret = strings.ReplaceAll(ret, "]", "]")
|
||||
return ret
|
||||
}
|
||||
|
||||
func CQCodeEscapeValue(value string) string {
|
||||
ret := CQCodeEscapeText(value)
|
||||
ret = strings.ReplaceAll(ret, ",", ",")
|
||||
return ret
|
||||
}
|
||||
|
||||
func CQCodeUnescapeText(content string) string {
|
||||
ret := content
|
||||
ret = strings.ReplaceAll(ret, "[", "[")
|
||||
ret = strings.ReplaceAll(ret, "]", "]")
|
||||
ret = strings.ReplaceAll(ret, "&", "&")
|
||||
return ret
|
||||
}
|
||||
|
||||
func CQCodeUnescapeValue(content string) string {
|
||||
ret := strings.ReplaceAll(content, ",", ",")
|
||||
ret = CQCodeUnescapeText(ret)
|
||||
return ret
|
||||
}
|
||||
|
||||
// 图片 elem 生成器,单独拎出来,用于公用
|
||||
func (bot *CQBot) makeImageElem(t string, d map[string]string, group bool) (message.IMessageElement, error) {
|
||||
f := d["file"]
|
||||
if strings.HasPrefix(f, "http") || strings.HasPrefix(f, "https") {
|
||||
cache := d["cache"]
|
||||
@ -397,170 +614,40 @@ func (bot *CQBot) ToElement(t string, d map[string]string, group bool) (message.
|
||||
return rsp, nil
|
||||
}
|
||||
return nil, errors.New("invalid image")
|
||||
case "record":
|
||||
if !group {
|
||||
return nil, errors.New("private voice unsupported now")
|
||||
}
|
||||
f := d["file"]
|
||||
var data []byte
|
||||
if strings.HasPrefix(f, "http") || strings.HasPrefix(f, "https") {
|
||||
b, err := global.GetBytes(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data = b
|
||||
}
|
||||
if strings.HasPrefix(f, "base64") {
|
||||
b, err := base64.StdEncoding.DecodeString(strings.ReplaceAll(f, "base64://", ""))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data = b
|
||||
}
|
||||
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
|
||||
}
|
||||
data = b
|
||||
}
|
||||
if global.PathExists(path.Join(global.VOICE_PATH, f)) {
|
||||
b, err := ioutil.ReadFile(path.Join(global.VOICE_PATH, f))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data = b
|
||||
}
|
||||
if !global.IsAMRorSILK(data) {
|
||||
return nil, errors.New("unsupported voice file format (please use AMR file for now)")
|
||||
}
|
||||
return &message.VoiceElement{Data: data}, nil
|
||||
case "face":
|
||||
id, err := strconv.Atoi(d["id"])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return message.NewFace(int32(id)), nil
|
||||
case "at":
|
||||
qq := d["qq"]
|
||||
if qq == "all" {
|
||||
return message.AtAll(), nil
|
||||
}
|
||||
t, _ := strconv.ParseInt(qq, 10, 64)
|
||||
return message.NewAt(t), nil
|
||||
case "share":
|
||||
return message.NewUrlShare(d["url"], d["title"], d["content"], d["image"]), nil
|
||||
case "music":
|
||||
if d["type"] == "qq" {
|
||||
info, err := global.QQMusicSongInfo(d["id"])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !info.Get("track_info").Exists() {
|
||||
return nil, errors.New("song not found")
|
||||
}
|
||||
aid := strconv.FormatInt(info.Get("track_info.album.id").Int(), 10)
|
||||
name := info.Get("track_info.name").Str + " - " + info.Get("track_info.singer.0.name").Str
|
||||
mid := info.Get("track_info.mid").Str
|
||||
albumMid := info.Get("track_info.album.mid").Str
|
||||
pinfo, _ := global.GetBytes("http://u.y.qq.com/cgi-bin/musicu.fcg?g_tk=2034008533&uin=0&format=json&data={\"comm\":{\"ct\":23,\"cv\":0},\"url_mid\":{\"module\":\"vkey.GetVkeyServer\",\"method\":\"CgiGetVkey\",\"param\":{\"guid\":\"4311206557\",\"songmid\":[\"" + mid + "\"],\"songtype\":[0],\"uin\":\"0\",\"loginflag\":1,\"platform\":\"23\"}}}&_=1599039471576")
|
||||
jumpUrl := "https://i.y.qq.com/v8/playsong.html?platform=11&appshare=android_qq&appversion=10030010&hosteuin=oKnlNenz7i-s7c**&songmid=" + mid + "&type=0&appsongtype=1&_wv=1&source=qq&ADTAG=qfshare"
|
||||
purl := gjson.ParseBytes(pinfo).Get("url_mid.data.midurlinfo.0.purl").Str
|
||||
preview := "http://y.gtimg.cn/music/photo_new/T002R180x180M000" + albumMid + ".jpg"
|
||||
if len(aid) < 2 {
|
||||
return nil, errors.New("song error")
|
||||
}
|
||||
content := "来自go-cqhttp"
|
||||
if d["content"] != "" {
|
||||
content = d["content"]
|
||||
}
|
||||
json := fmt.Sprintf("{\"app\": \"com.tencent.structmsg\",\"desc\": \"音乐\",\"meta\": {\"music\": {\"desc\": \"%s\",\"jumpUrl\": \"%s\",\"musicUrl\": \"%s\",\"preview\": \"%s\",\"tag\": \"QQ音乐\",\"title\": \"%s\"}},\"prompt\": \"[分享]%s\",\"ver\": \"0.0.0.1\",\"view\": \"music\"}", content, jumpUrl, purl, preview, name, name)
|
||||
return message.NewLightApp(json), nil
|
||||
}
|
||||
if d["type"] == "163" {
|
||||
info, err := global.NeteaseMusicSongInfo(d["id"])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !info.Exists() {
|
||||
return nil, errors.New("song not found")
|
||||
}
|
||||
name := info.Get("name").Str
|
||||
jumpUrl := "https://y.music.163.com/m/song/" + d["id"]
|
||||
musicUrl := "http://music.163.com/song/media/outer/url?id=" + d["id"]
|
||||
picUrl := info.Get("album.picUrl").Str
|
||||
artistName := ""
|
||||
if info.Get("artists.0").Exists() {
|
||||
artistName = info.Get("artists.0.name").Str
|
||||
}
|
||||
json := fmt.Sprintf("{\"app\": \"com.tencent.structmsg\",\"desc\":\"音乐\",\"view\":\"music\",\"prompt\":\"[分享]%s\",\"ver\":\"0.0.0.1\",\"meta\":{ \"music\": { \"desc\": \"%s\", \"jumpUrl\": \"%s\", \"musicUrl\": \"%s\", \"preview\": \"%s\", \"tag\": \"网易云音乐\", \"title\":\"%s\"}}}", name,artistName, jumpUrl, musicUrl, picUrl, name)
|
||||
return message.NewLightApp(json), nil
|
||||
}
|
||||
if d["type"] == "custom" {
|
||||
xml := fmt.Sprintf(`<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><msg serviceID="2" templateID="1" action="web" brief="[分享] %s" sourceMsgId="0" url="%s" flag="0" adverSign="0" multiMsgFlag="0"><item layout="2"><audio cover="%s" src="%s"/><title>%s</title><summary>%s</summary></item><source name="音乐" icon="https://i.gtimg.cn/open/app_icon/01/07/98/56/1101079856_100_m.png" url="http://web.p.qq.com/qqmpmobile/aio/app.html?id=1101079856" action="app" a_actionData="com.tencent.qqmusic" i_actionData="tencent1101079856://" appid="1101079856" /></msg>`,
|
||||
d["title"], d["url"], d["image"], d["audio"], d["title"], d["content"])
|
||||
return &message.ServiceElement{
|
||||
Id: 60,
|
||||
Content: xml,
|
||||
SubType: "music",
|
||||
}, nil
|
||||
}
|
||||
return nil, errors.New("unsupported music type: " + d["type"])
|
||||
case "xml":
|
||||
resId := d["resid"]
|
||||
template := CQCodeEscapeValue(d["data"])
|
||||
//println(template)
|
||||
i, _ := strconv.ParseInt(resId, 10, 64)
|
||||
msg := message.NewRichXml(template, i)
|
||||
return msg, nil
|
||||
case "json":
|
||||
resId := d["resid"]
|
||||
i, _ := strconv.ParseInt(resId, 10, 64)
|
||||
log.Warnf("json msg=%s", d["data"])
|
||||
if i == 0 {
|
||||
//默认情况下走小程序通道
|
||||
msg := message.NewLightApp(CQCodeUnescapeValue(d["data"]))
|
||||
return msg, nil
|
||||
}
|
||||
//resid不为0的情况下走富文本通道,后续补全透传service Id,此处暂时不处理 TODO
|
||||
msg := message.NewRichJson(CQCodeUnescapeValue(d["data"]))
|
||||
return msg, nil
|
||||
default:
|
||||
return nil, errors.New("unsupported cq code: " + t)
|
||||
}
|
||||
}
|
||||
|
||||
func CQCodeEscapeText(raw string) string {
|
||||
ret := raw
|
||||
ret = strings.ReplaceAll(ret, "&", "&")
|
||||
ret = strings.ReplaceAll(ret, "[", "[")
|
||||
ret = strings.ReplaceAll(ret, "]", "]")
|
||||
return ret
|
||||
}
|
||||
//SendNewPic 一种xml 方式发送的群消息图片
|
||||
func (bot *CQBot) SendNewPic(elem message.IMessageElement, source string, icon string, minwidth int64, minheigt int64, maxwidth int64, maxheight int64, group bool) (*message.ServiceElement, error) {
|
||||
var xml string
|
||||
xml = ""
|
||||
if i, ok := elem.(*message.ImageElement); ok {
|
||||
if group == false {
|
||||
gm, err := bot.Client.UploadPrivateImage(1, i.Data)
|
||||
if err != nil {
|
||||
log.Warnf("警告: 好友消息 %v 消息图片上传失败: %v", 1, err)
|
||||
return nil, err
|
||||
}
|
||||
xml = fmt.Sprintf(`<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><msg serviceID="5" templateID="12345" action="" brief="[分享]我看到一张很赞的图片,分享给你,快来看!" sourceMsgId="0" url="%s" flag="0" adverSign="0" multiMsgFlag="0"><item layout="0" advertiser_id="0" aid="0"><image uuid="%x" md5="%x" GroupFiledid="0" filesize="%d" local_path="%s" minWidth="%d" minHeight="%d" maxWidth="%d" maxHeight="%d" /></item><source name="%s" icon="%s" action="" appid="-1" /></msg>`, "", gm.Md5, gm.Md5, len(i.Data), "", minwidth, minheigt, maxwidth, maxheight, source, icon)
|
||||
|
||||
func CQCodeEscapeValue(value string) string {
|
||||
ret := CQCodeEscapeText(value)
|
||||
ret = strings.ReplaceAll(ret, ",", ",")
|
||||
return ret
|
||||
}
|
||||
|
||||
func CQCodeUnescapeText(content string) string {
|
||||
ret := content
|
||||
ret = strings.ReplaceAll(ret, "[", "[")
|
||||
ret = strings.ReplaceAll(ret, "]", "]")
|
||||
ret = strings.ReplaceAll(ret, "&", "&")
|
||||
return ret
|
||||
}
|
||||
|
||||
func CQCodeUnescapeValue(content string) string {
|
||||
ret := strings.ReplaceAll(content, ",", ",")
|
||||
ret = CQCodeUnescapeText(ret)
|
||||
return ret
|
||||
} else {
|
||||
gm, err := bot.Client.UploadGroupImage(1, i.Data)
|
||||
if err != nil {
|
||||
log.Warnf("警告: 群 %v 消息图片上传失败: %v", 1, err)
|
||||
return nil, err
|
||||
}
|
||||
xml = fmt.Sprintf(`<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><msg serviceID="5" templateID="12345" action="" brief="[分享]我看到一张很赞的图片,分享给你,快来看!" sourceMsgId="0" url="%s" flag="0" adverSign="0" multiMsgFlag="0"><item layout="0" advertiser_id="0" aid="0"><image uuid="%x" md5="%x" GroupFiledid="0" filesize="%d" local_path="%s" minWidth="%d" minHeight="%d" maxWidth="%d" maxHeight="%d" /></item><source name="%s" icon="%s" action="" appid="-1" /></msg>`, "", gm.Md5, gm.Md5, len(i.Data), "", minwidth, minheigt, maxwidth, maxheight, source, icon)
|
||||
}
|
||||
}
|
||||
if i, ok := elem.(*message.GroupImageElement); ok {
|
||||
xml = fmt.Sprintf(`<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><msg serviceID="5" templateID="12345" action="" brief="[分享]我看到一张很赞的图片,分享给你,快来看!" sourceMsgId="0" url="%s" flag="0" adverSign="0" multiMsgFlag="0"><item layout="0" advertiser_id="0" aid="0"><image uuid="%x" md5="%x" GroupFiledid="0" filesize="%d" local_path="%s" minWidth="%d" minHeight="%d" maxWidth="%d" maxHeight="%d" /></item><source name="%s" icon="%s" action="" appid="-1" /></msg>`, "", i.Md5, i.Md5, 0, "", minwidth, minheigt, maxwidth, maxheight, source, icon)
|
||||
}
|
||||
if i, ok := elem.(*message.FriendImageElement); ok {
|
||||
xml = fmt.Sprintf(`<?xml version='1.0' encoding='UTF-8' standalone='yes' ?><msg serviceID="5" templateID="12345" action="" brief="[分享]我看到一张很赞的图片,分享给你,快来看!" sourceMsgId="0" url="%s" flag="0" adverSign="0" multiMsgFlag="0"><item layout="0" advertiser_id="0" aid="0"><image uuid="%x" md5="%x" GroupFiledid="0" filesize="%d" local_path="%s" minWidth="%d" minHeight="%d" maxWidth="%d" maxHeight="%d" /></item><source name="%s" icon="%s" action="" appid="-1" /></msg>`, "", i.Md5, i.Md5, 0, "", minwidth, minheigt, maxwidth, maxheight, source, icon)
|
||||
}
|
||||
if xml != "" {
|
||||
log.Warn(xml)
|
||||
XmlMsg := message.NewRichXml(xml, 5)
|
||||
return XmlMsg, nil
|
||||
}
|
||||
return nil, errors.New("发送xml图片消息失败")
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ Type: `node`
|
||||
|
||||
Type: `xml`
|
||||
|
||||
范围: **发送**
|
||||
范围: **发送/接收**
|
||||
|
||||
参数:
|
||||
|
||||
@ -168,11 +168,11 @@ Type: `xml`
|
||||
</msg>
|
||||
```
|
||||
|
||||
###json消息支持
|
||||
### json消息支持
|
||||
|
||||
Type: `json`
|
||||
|
||||
范围: **发送**
|
||||
范围: **发送/接收**
|
||||
|
||||
参数:
|
||||
|
||||
@ -198,6 +198,33 @@ json中的字符串需要进行转义:
|
||||
[CQ:json,data={"app":"com.tencent.miniapp","desc":"","view":"notification","ver":"0.0.0.1","prompt":"[应用]","appID":"","sourceName":"","actionData":"","actionData_A":"","sourceUrl":"","meta":{"notification":{"appInfo":{"appName":"全国疫情数据统计","appType":4,"appid":1109659848,"iconUrl":"http:\/\/gchat.qpic.cn\/gchatpic_new\/719328335\/-2010394141-6383A777BEB79B70B31CE250142D740F\/0"},"data":[{"title":"确诊","value":"80932"},{"title":"今日确诊","value":"28"},{"title":"疑似","value":"72"},{"title":"今日疑似","value":"5"},{"title":"治愈","value":"60197"},{"title":"今日治愈","value":"1513"},{"title":"死亡","value":"3140"},{"title":"今**亡","value":"17"}],"title":"中国加油,武汉加油","button":[{"name":"病毒:SARS-CoV-2,其导致疾病命名 COVID-19","action":""},{"name":"传染源:新冠肺炎的患者。无症状感染者也可能成为传染源。","action":""}],"emphasis_keyword":""}},"text":"","sourceAd":""}]
|
||||
```
|
||||
|
||||
|
||||
### cardimage 一种xml的图片消息(装逼大图)
|
||||
|
||||
ps: xml 接口的消息都存在风控风险,请自行兼容发送失败后的处理(可以失败后走普通图片模式)
|
||||
|
||||
Type: `cardimage`
|
||||
|
||||
范围: **发送**
|
||||
|
||||
参数:
|
||||
|
||||
| 参数名 | 类型 | 说明 |
|
||||
| ------ | ------ | ------------------------------------------------------------ |
|
||||
| file | string | 和image的file字段对齐,支持也是一样的|
|
||||
| minwidth | int64 | 默认不填为400,最小width|
|
||||
| minheight | int64 | 默认不填为400,最小height|
|
||||
| maxwidth | int64 | 默认不填为500,最大width|
|
||||
| maxheight | int64 | 默认不填为1000,最大height|
|
||||
| source | string | 分享来源的名称,可以留空|
|
||||
| icon | string | 分享来源的icon图标url,可以留空|
|
||||
|
||||
|
||||
示例cardimage 的cq码:
|
||||
```test
|
||||
[CQ:cardimage,file=https://i.pixiv.cat/img-master/img/2020/03/25/00/00/08/80334602_p0_master1200.jpg]
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### 设置群名
|
||||
|
1
go.sum
1
go.sum
@ -34,6 +34,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=
|
||||
|
Loading…
x
Reference in New Issue
Block a user