From 38865584eccde7aa6ce701ed5d04ce3523bc5c02 Mon Sep 17 00:00:00 2001 From: wdvxdr Date: Tue, 3 Aug 2021 15:39:23 +0800 Subject: [PATCH 01/30] update MiraiGo. --- coolq/api.go | 56 ++++++++++++++++++++++++++++++---------------------- go.mod | 4 ++-- go.sum | 8 ++++---- 3 files changed, 38 insertions(+), 30 deletions(-) diff --git a/coolq/api.go b/coolq/api.go index 75a5ff2..878c61b 100644 --- a/coolq/api.go +++ b/coolq/api.go @@ -403,7 +403,7 @@ func (bot *CQBot) CQSendGroupForwardMessage(groupID int64, m gjson.Result) MSG { if m.Type != gjson.JSON { return Failed(100) } - var sendNodes []*message.ForwardNode + fm := message.NewForwardMessage() ts := time.Now().Add(-time.Minute * 5) hasCustom := false m.ForEach(func(_, item gjson.Result) bool { @@ -414,8 +414,8 @@ func (bot *CQBot) CQSendGroupForwardMessage(groupID int64, m gjson.Result) MSG { return true }) - var convert func(e gjson.Result) []*message.ForwardNode - convert = func(e gjson.Result) (nodes []*message.ForwardNode) { + var convert func(e gjson.Result) *message.ForwardNode + convert = func(e gjson.Result) *message.ForwardNode { if e.Get("type").Str != "node" { return nil } @@ -425,7 +425,7 @@ func (bot *CQBot) CQSendGroupForwardMessage(groupID int64, m gjson.Result) MSG { m := bot.GetMessage(int32(i)) if m != nil { sender := m["sender"].(message.Sender) - nodes = append(nodes, &message.ForwardNode{ + return &message.ForwardNode{ SenderId: sender.Uin, SenderName: (&sender).DisplayName(), Time: func() int32 { @@ -436,11 +436,10 @@ func (bot *CQBot) CQSendGroupForwardMessage(groupID int64, m gjson.Result) MSG { return msgTime }(), Message: bot.ConvertStringMessage(m["message"].(string), true), - }) - return + } } log.Warnf("警告: 引用消息 %v 错误或数据库未开启.", e.Get("data.id").Str) - return + return nil } uin := e.Get("data.[user_id,uin].0").Int() msgTime := e.Get("data.time").Int() @@ -450,26 +449,29 @@ func (bot *CQBot) CQSendGroupForwardMessage(groupID int64, m gjson.Result) MSG { name := e.Get("data.name").Str c := e.Get("data.content") if c.IsArray() { - flag := false + nested := false c.ForEach(func(_, value gjson.Result) bool { if value.Get("type").Str == "node" { - flag = true + nested = true return false } return true }) - if flag { - var taowa []*message.ForwardNode + if nested { // 处理嵌套 + nest := message.NewForwardMessage() for _, item := range c.Array() { - taowa = append(taowa, convert(item)...) + node := convert(item) + if node != nil { + nest.AddNode(node) + } } - nodes = append(nodes, &message.ForwardNode{ + elem := bot.Client.UploadGroupForwardMessage(groupID, nest) + return &message.ForwardNode{ SenderId: uin, SenderName: name, Time: int32(msgTime), - Message: []message.IMessageElement{bot.Client.UploadGroupForwardMessage(groupID, &message.ForwardMessage{Nodes: taowa})}, - }) - return + Message: []message.IMessageElement{elem}, + } } } content := bot.ConvertObjectMessage(e.Get("data.content"), true) @@ -487,26 +489,32 @@ func (bot *CQBot) CQSendGroupForwardMessage(groupID int64, m gjson.Result) MSG { } newElem = append(newElem, elem) } - nodes = append(nodes, &message.ForwardNode{ + return &message.ForwardNode{ SenderId: uin, SenderName: name, Time: int32(msgTime), Message: newElem, - }) - return + } } log.Warnf("警告: 非法 Forward node 将跳过. uin: %v name: %v content count: %v", uin, name, len(content)) - return + return nil } if m.IsArray() { for _, item := range m.Array() { - sendNodes = append(sendNodes, convert(item)...) + node := convert(item) + if node != nil { + fm.AddNode(node) + } } } else { - sendNodes = convert(m) + node := convert(m) + if node != nil { + fm.AddNode(node) + } } - if len(sendNodes) > 0 { - ret := bot.Client.SendGroupForwardMessage(groupID, &message.ForwardMessage{Nodes: sendNodes}) + if fm.Length() > 0 { + fe := bot.Client.UploadGroupForwardMessage(groupID, fm) + ret := bot.Client.SendGroupForwardMessage(groupID, fe) if ret == nil || ret.Id == -1 { log.Warnf("合并转发(群)消息发送失败: 账号可能被风控.") return Failed(100, "SEND_MSG_API_ERROR", "请参考 go-cqhttp 端输出") diff --git a/go.mod b/go.mod index a1f6493..83d0d6c 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.16 require ( github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f github.com/Microsoft/go-winio v0.5.0 - github.com/Mrs4s/MiraiGo v0.0.0-20210726103104-1d68826cef0e + github.com/Mrs4s/MiraiGo v0.0.0-20210803073620-cb396f0f5649 github.com/dustin/go-humanize v1.0.0 github.com/gabriel-vasile/mimetype v1.3.1 // indirect github.com/gorilla/websocket v1.4.2 @@ -27,8 +27,8 @@ require ( github.com/wdvxdr1123/go-silk v0.0.0-20210316130616-d47b553def60 github.com/willf/bitset v1.2.0 // indirect golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e - golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d // indirect golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b + golang.org/x/text v0.3.6 // indirect golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b ) diff --git a/go.sum b/go.sum index ce9475e..8d57333 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,8 @@ github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f/g github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= -github.com/Mrs4s/MiraiGo v0.0.0-20210726103104-1d68826cef0e h1:PgFshw1L5TVdiDRLgr/bSotPGaGXYzbtn5cDBBvpL6U= -github.com/Mrs4s/MiraiGo v0.0.0-20210726103104-1d68826cef0e/go.mod h1:CPaznIPn415uQqxJgjyMHLqGLkvLS6R6+bkW3/fe08Q= +github.com/Mrs4s/MiraiGo v0.0.0-20210803073620-cb396f0f5649 h1:9aEo50MD/QMHExoBxeUu/oLrs8gKzuyKWZ2+t+8AaOQ= +github.com/Mrs4s/MiraiGo v0.0.0-20210803073620-cb396f0f5649/go.mod h1:5V3f/+mTYtrI/+hLqbdzZQXuLMl2RyLfx0XYYjCQ90Q= github.com/bits-and-blooms/bitset v1.2.0 h1:Kn4yilvwNtMACtf1eYDlG8H77R07mZSPbMjLyS07ChA= github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -139,8 +139,6 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e h1:gsTQYXdTw2Gq7RBsWvlQ91b+aEQ6bXFUngBGuR8sPpI= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs= -golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -158,6 +156,8 @@ golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAG golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= From 38fff9bac046175fc75e66937d3cab265ec19d01 Mon Sep 17 00:00:00 2001 From: fumiama Date: Tue, 3 Aug 2021 23:52:27 +0800 Subject: [PATCH 02/30] Fix: Image mime scan add type webp --- coolq/bot.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coolq/bot.go b/coolq/bot.go index 2d8e29b..3c725a2 100644 --- a/coolq/bot.go +++ b/coolq/bot.go @@ -81,7 +81,7 @@ var ForceFragmented = false // SkipMimeScan 是否跳过Mime扫描 var SkipMimeScan bool -var lawfulImageTypes = []string{"image/png", "image/jpeg", "image/gif", "image/bmp"} +var lawfulImageTypes = []string{"image/png", "image/jpeg", "image/gif", "image/bmp", "image/webp"} var lawfulAudioTypes = []string{ "audio/mpeg", "audio/flac", "audio/midi", "audio/ogg", From b44f9545a85cf5b9f6a126f759ab2515cad8bcdd Mon Sep 17 00:00:00 2001 From: wdvxdr Date: Wed, 4 Aug 2021 23:57:41 +0800 Subject: [PATCH 03/30] fix(coolq): upload resources when send forward message. Fixes: #987 --- coolq/api.go | 32 +++++++++++++++++--------------- go.mod | 3 +-- go.sum | 1 - 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/coolq/api.go b/coolq/api.go index 878c61b..d500290 100644 --- a/coolq/api.go +++ b/coolq/api.go @@ -414,6 +414,21 @@ func (bot *CQBot) CQSendGroupForwardMessage(groupID int64, m gjson.Result) MSG { return true }) + var resolveElement = func(elems []message.IMessageElement) []message.IMessageElement { + for i, elem := range elems { + switch elem.(type) { + case *LocalImageElement, *LocalVideoElement: + gm, err := bot.uploadMedia(elem, groupID, true) + if err != nil { + log.Warnf("警告: 群 %d %s上传失败: %v", groupID, elem.Type().String(), err) + continue + } + elems[i] = gm + } + } + return elems + } + var convert func(e gjson.Result) *message.ForwardNode convert = func(e gjson.Result) *message.ForwardNode { if e.Get("type").Str != "node" { @@ -435,7 +450,7 @@ func (bot *CQBot) CQSendGroupForwardMessage(groupID int64, m gjson.Result) MSG { } return msgTime }(), - Message: bot.ConvertStringMessage(m["message"].(string), true), + Message: resolveElement(bot.ConvertStringMessage(m["message"].(string), true)), } } log.Warnf("警告: 引用消息 %v 错误或数据库未开启.", e.Get("data.id").Str) @@ -476,24 +491,11 @@ func (bot *CQBot) CQSendGroupForwardMessage(groupID int64, m gjson.Result) MSG { } content := bot.ConvertObjectMessage(e.Get("data.content"), true) if uin != 0 && name != "" && len(content) > 0 { - var newElem []message.IMessageElement - for _, elem := range content { - switch elem.(type) { - case *LocalImageElement, *LocalVideoElement: - gm, err := bot.uploadMedia(elem, groupID, true) - if err != nil { - log.Warnf("警告: 群 %d %s上传失败: %v", groupID, elem.Type().String(), err) - continue - } - elem = gm - } - newElem = append(newElem, elem) - } return &message.ForwardNode{ SenderId: uin, SenderName: name, Time: int32(msgTime), - Message: newElem, + Message: resolveElement(content), } } log.Warnf("警告: 非法 Forward node 将跳过. uin: %v name: %v content count: %v", uin, name, len(content)) diff --git a/go.mod b/go.mod index 83d0d6c..e4ed6c4 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/Microsoft/go-winio v0.5.0 github.com/Mrs4s/MiraiGo v0.0.0-20210803073620-cb396f0f5649 github.com/dustin/go-humanize v1.0.0 - github.com/gabriel-vasile/mimetype v1.3.1 // indirect + github.com/gabriel-vasile/mimetype v1.3.1 github.com/gorilla/websocket v1.4.2 github.com/guonaihong/gout v0.2.1 github.com/jonboulle/clockwork v0.2.2 // indirect @@ -28,7 +28,6 @@ require ( github.com/willf/bitset v1.2.0 // indirect golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b - golang.org/x/text v0.3.6 // indirect golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b ) diff --git a/go.sum b/go.sum index 8d57333..274e54d 100644 --- a/go.sum +++ b/go.sum @@ -148,7 +148,6 @@ golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210505024714-0287a6fb4125 h1:Ugb8sMTWuWRC3+sz5WeN/4kejDx9BvIwnPUiJBjJE+8= golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= From 3326b2aa2fdc1076884f5bc81e8d7616633c0c79 Mon Sep 17 00:00:00 2001 From: wdvxdr Date: Fri, 6 Aug 2021 22:26:42 +0800 Subject: [PATCH 04/30] feat(coolq): mimetypes switch to array. --- coolq/bot.go | 32 ++++++++++++++++++-------------- coolq/cqcode.go | 13 ++++++++++--- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/coolq/bot.go b/coolq/bot.go index 3c725a2..98e998b 100644 --- a/coolq/bot.go +++ b/coolq/bot.go @@ -81,9 +81,9 @@ var ForceFragmented = false // SkipMimeScan 是否跳过Mime扫描 var SkipMimeScan bool -var lawfulImageTypes = []string{"image/png", "image/jpeg", "image/gif", "image/bmp", "image/webp"} +var lawfulImageTypes = [...]string{"image/png", "image/jpeg", "image/gif", "image/bmp", "image/webp"} -var lawfulAudioTypes = []string{ +var lawfulAudioTypes = [...]string{ "audio/mpeg", "audio/flac", "audio/midi", "audio/ogg", "audio/ape", "audio/amr", "audio/wav", "audio/aiff", "audio/mp4", "audio/aac", "audio/x-m4a", @@ -228,18 +228,18 @@ func (bot *CQBot) UploadLocalVideo(target int64, v *LocalVideoElement) (*message // UploadLocalImageAsPrivate 上传本地图片至私聊 func (bot *CQBot) UploadLocalImageAsPrivate(userID int64, img *LocalImageElement) (i *message.FriendImageElement, err error) { - if img.Stream != nil { - i, err = bot.Client.UploadPrivateImage(userID, img.Stream) - } else { - // need update. - f, e := os.Open(img.File) - if e != nil { - return nil, e + if img.File != "" { + f, err := os.Open(img.File) + if err != nil { + return nil, errors.Wrap(err, "open image error") } - defer f.Close() - i, err = bot.Client.UploadPrivateImage(userID, f) + defer func() { _ = f.Close() }() + img.Stream = f } - + if lawful, mime := IsLawfulImage(img.Stream); !lawful { + return nil, errors.New("image type error: " + mime) + } + i, err = bot.Client.UploadPrivateImage(userID, img.Stream) if i != nil { i.Flash = img.Flash } @@ -604,6 +604,10 @@ func IsLawfulImage(r io.ReadSeeker) (bool, string) { log.Debugf("扫描 Mime 时出现问题: %v", err) return false, "" } - mime := t.String() - return mimetype.EqualsAny(mime, lawfulImageTypes...), mime + for _, lt := range lawfulImageTypes { + if t.Is(lt) { + return true, t.String() + } + } + return false, t.String() } diff --git a/coolq/cqcode.go b/coolq/cqcode.go index e7dce37..d7d4e4d 100644 --- a/coolq/cqcode.go +++ b/coolq/cqcode.go @@ -731,9 +731,16 @@ func (bot *CQBot) ToElement(t string, d map[string]string, isGroup bool) (m inte return nil, err } if !SkipMimeScan && !global.IsAMRorSILK(data) { - mt := mimetype.Detect(data).String() - if !mimetype.EqualsAny(mt, lawfulAudioTypes...) { - return nil, errors.New("audio type error: " + mt) + mt := mimetype.Detect(data) + lawful := false + for _, lt := range lawfulAudioTypes { + if mt.Is(lt) { + lawful = true + break + } + } + if !lawful { + return nil, errors.New("audio type error: " + mt.String()) } } if !global.IsAMRorSILK(data) { From e50662239906733e3b28c2b23a662c71033c6324 Mon Sep 17 00:00:00 2001 From: wdvxdr Date: Sat, 7 Aug 2021 12:04:32 +0800 Subject: [PATCH 05/30] feat(codec): enhance ffmpeg output with debug. --- global/codec/codec.go | 4 ++++ ...c_unsupportedarch.go => codec_unsupported.go} | 4 ++-- global/codec/codec_unsupportedos.go | 16 ---------------- global/codec/codec_windows_arm.go | 13 ------------- global/codec/stubs.go | 4 ++++ main.go | 2 ++ 6 files changed, 12 insertions(+), 31 deletions(-) rename global/codec/{codec_unsupportedarch.go => codec_unsupported.go} (62%) delete mode 100644 global/codec/codec_unsupportedos.go delete mode 100644 global/codec/codec_windows_arm.go create mode 100644 global/codec/stubs.go diff --git a/global/codec/codec.go b/global/codec/codec.go index 6e20146..730f001 100644 --- a/global/codec/codec.go +++ b/global/codec/codec.go @@ -29,6 +29,10 @@ func EncodeToSilk(record []byte, tempName string, useCache bool) (silkWav []byte // 2.转换pcm pcmPath := path.Join(silkCachePath, tempName+".pcm") cmd := exec.Command("ffmpeg", "-i", rawPath, "-f", "s16le", "-ar", "24000", "-ac", "1", pcmPath) + if Debug { + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + } if err = cmd.Run(); err != nil { return nil, errors.Wrap(err, "convert pcm file error") } diff --git a/global/codec/codec_unsupportedarch.go b/global/codec/codec_unsupported.go similarity index 62% rename from global/codec/codec_unsupportedarch.go rename to global/codec/codec_unsupported.go index 04c4aef..f991f95 100644 --- a/global/codec/codec_unsupportedarch.go +++ b/global/codec/codec_unsupported.go @@ -1,5 +1,5 @@ -//go:build (!arm && !arm64 && !amd64 && !386) || race -// +build !arm,!arm64,!amd64,!386 race +//go:build (!arm && !arm64 && !amd64 && !386) || race || (!windows && !linux && !darwin) || (windows && arm) +// +build !arm,!arm64,!amd64,!386 race !windows,!linux,!darwin windows,arm package codec diff --git a/global/codec/codec_unsupportedos.go b/global/codec/codec_unsupportedos.go deleted file mode 100644 index f7f51a4..0000000 --- a/global/codec/codec_unsupportedos.go +++ /dev/null @@ -1,16 +0,0 @@ -//go:build !windows && !linux && !darwin -// +build !windows,!linux,!darwin - -package codec - -import "errors" - -// EncodeToSilk 将音频编码为Silk -func EncodeToSilk(record []byte, tempName string, useCache bool) ([]byte, error) { - return nil, errors.New("not supported now") -} - -// RecodeTo24K 将silk重新编码为 24000 bit rate -func RecodeTo24K(data []byte) []byte { - return data -} diff --git a/global/codec/codec_windows_arm.go b/global/codec/codec_windows_arm.go deleted file mode 100644 index 5cfcfc7..0000000 --- a/global/codec/codec_windows_arm.go +++ /dev/null @@ -1,13 +0,0 @@ -package codec - -import "errors" - -// EncodeToSilk 将音频编码为Silk -func EncodeToSilk(record []byte, tempName string, useCache bool) ([]byte, error) { - return nil, errors.New("not supported now") -} - -// RecodeTo24K 将silk重新编码为 24000 bit rate -func RecodeTo24K(data []byte) []byte { - return data -} diff --git a/global/codec/stubs.go b/global/codec/stubs.go new file mode 100644 index 0000000..9821aa3 --- /dev/null +++ b/global/codec/stubs.go @@ -0,0 +1,4 @@ +package codec + +// Debug mode controls the ffmpeg output. +var Debug bool diff --git a/main.go b/main.go index 52f3da2..20fc5b1 100644 --- a/main.go +++ b/main.go @@ -19,6 +19,7 @@ import ( "github.com/Mrs4s/go-cqhttp/coolq" "github.com/Mrs4s/go-cqhttp/global" + "github.com/Mrs4s/go-cqhttp/global/codec" "github.com/Mrs4s/go-cqhttp/global/config" "github.com/Mrs4s/go-cqhttp/global/terminal" "github.com/Mrs4s/go-cqhttp/global/update" @@ -79,6 +80,7 @@ func main() { } if conf.Output.Debug { log.SetReportCaller(true) + codec.Debug = true } logFormatter := &easy.Formatter{ From 605e572b879781f0000650926ac73c676fd52a1f Mon Sep 17 00:00:00 2001 From: wdvxdr Date: Sat, 7 Aug 2021 12:56:49 +0800 Subject: [PATCH 06/30] feat(log): remove logrus-easy-formatter. --- global/log_hook.go | 19 +++++++++++++++++++ go.mod | 1 - go.sum | 6 ------ main.go | 7 +------ 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/global/log_hook.go b/global/log_hook.go index 00ab0d3..eb4f273 100644 --- a/global/log_hook.go +++ b/global/log_hook.go @@ -6,6 +6,7 @@ import ( "os" "path/filepath" "reflect" + "strings" "sync" "github.com/sirupsen/logrus" @@ -174,3 +175,21 @@ func GetLogLevel(level string) []logrus.Level { } } } + +// LogFormat specialize for go-cqhttp +type LogFormat struct{} + +// Format implements logrus.Formatter +func (f LogFormat) Format(entry *logrus.Entry) ([]byte, error) { + buf := NewBuffer() + defer PutBuffer(buf) + buf.WriteByte('[') + buf.WriteString(entry.Time.Format("2006-01-02 15:04:05")) + buf.WriteString("] [") + buf.WriteString(strings.ToUpper(entry.Level.String())) + buf.WriteString("]: ") + buf.WriteString(entry.Message) + buf.WriteString(" \n") + ret := append([]byte(nil), buf.Bytes()...) // copy buffer + return ret, nil +} diff --git a/go.mod b/go.mod index e4ed6c4..91b666c 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,6 @@ require ( github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect github.com/stretchr/testify v1.7.0 github.com/syndtr/goleveldb v1.0.0 - github.com/t-tomalak/logrus-easy-formatter v0.0.0-20190827215021-c074f06c5816 github.com/tidwall/gjson v1.8.1 github.com/tuotoo/qrcode v0.0.0-20190222102259-ac9c44189bf2 github.com/wdvxdr1123/go-silk v0.0.0-20210316130616-d47b553def60 diff --git a/go.sum b/go.sum index 274e54d..b1df252 100644 --- a/go.sum +++ b/go.sum @@ -71,7 +71,6 @@ github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMW github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA= github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8= @@ -104,14 +103,12 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -119,8 +116,6 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= -github.com/t-tomalak/logrus-easy-formatter v0.0.0-20190827215021-c074f06c5816 h1:J6v8awz+me+xeb/cUTotKgceAYouhIB3pjzgRd6IlGk= -github.com/t-tomalak/logrus-easy-formatter v0.0.0-20190827215021-c074f06c5816/go.mod h1:tzym/CEb5jnFI+Q0k4Qq3+LvRF4gO3E2pxS8fHP8jcA= github.com/tidwall/gjson v1.8.1 h1:8j5EE9Hrh3l9Od1OIEDAb7IpezNA20UdRngNAj5N0WU= github.com/tidwall/gjson v1.8.1/go.mod h1:5/xDoumyyDNerp2U36lyolv46b3uF/9Bu6OfyQ9GImk= github.com/tidwall/match v1.0.3 h1:FQUVvBImDutD8wJLN6c5eMzWtjgONK9MwIBCOrUJKeE= @@ -160,7 +155,6 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/main.go b/main.go index 20fc5b1..2646dd8 100644 --- a/main.go +++ b/main.go @@ -30,7 +30,6 @@ import ( "github.com/guonaihong/gout" rotatelogs "github.com/lestrrat-go/file-rotatelogs" log "github.com/sirupsen/logrus" - easy "github.com/t-tomalak/logrus-easy-formatter" "github.com/tidwall/gjson" "golang.org/x/crypto/pbkdf2" "golang.org/x/term" @@ -83,10 +82,6 @@ func main() { codec.Debug = true } - logFormatter := &easy.Formatter{ - TimestampFormat: "2006-01-02 15:04:05", - LogFormat: "[%time%] [%lvl%]: %msg% \n", - } rotateOptions := []rotatelogs.Option{ rotatelogs.WithRotationTime(time.Hour * 24), } @@ -104,7 +99,7 @@ func main() { panic(err) } - log.AddHook(global.NewLocalHook(w, logFormatter, global.GetLogLevel(conf.Output.LogLevel)...)) + log.AddHook(global.NewLocalHook(w, global.LogFormat{}, global.GetLogLevel(conf.Output.LogLevel)...)) mkCacheDir := func(path string, _type string) { if !global.PathExists(path) { From c423f6d6bbf5eab4ca0388db2789e859cd94496f Mon Sep 17 00:00:00 2001 From: wdvxdr Date: Sat, 7 Aug 2021 16:48:00 +0800 Subject: [PATCH 07/30] feat(coolq): new field "shut_up_timestamp" in group members. Fixes: #918 --- coolq/api.go | 11 ++++++----- go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/coolq/api.go b/coolq/api.go index d500290..e988618 100644 --- a/coolq/api.go +++ b/coolq/api.go @@ -1451,11 +1451,12 @@ func convertGroupMemberInfo(groupID int64, m *client.GroupMemberInfo) MSG { // unknown = 0xff return "unknown" }(), - "age": 0, - "area": "", - "join_time": m.JoinTime, - "last_sent_time": m.LastSpeakTime, - "level": strconv.FormatInt(int64(m.Level), 10), + "age": 0, + "area": "", + "join_time": m.JoinTime, + "last_sent_time": m.LastSpeakTime, + "shut_up_timestamp": m.ShutUpTimestamp, + "level": strconv.FormatInt(int64(m.Level), 10), "role": func() string { switch m.Permission { case client.Owner: diff --git a/go.mod b/go.mod index 91b666c..a422534 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.16 require ( github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f github.com/Microsoft/go-winio v0.5.0 - github.com/Mrs4s/MiraiGo v0.0.0-20210803073620-cb396f0f5649 + github.com/Mrs4s/MiraiGo v0.0.0-20210807084313-1d900b302d8f github.com/dustin/go-humanize v1.0.0 github.com/gabriel-vasile/mimetype v1.3.1 github.com/gorilla/websocket v1.4.2 diff --git a/go.sum b/go.sum index b1df252..b8189ab 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,8 @@ github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f/g github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= -github.com/Mrs4s/MiraiGo v0.0.0-20210803073620-cb396f0f5649 h1:9aEo50MD/QMHExoBxeUu/oLrs8gKzuyKWZ2+t+8AaOQ= -github.com/Mrs4s/MiraiGo v0.0.0-20210803073620-cb396f0f5649/go.mod h1:5V3f/+mTYtrI/+hLqbdzZQXuLMl2RyLfx0XYYjCQ90Q= +github.com/Mrs4s/MiraiGo v0.0.0-20210807084313-1d900b302d8f h1:W58s6dzrbXW4MU58jdIq9NBFaoD5ZrEgFyUB/IZ79cQ= +github.com/Mrs4s/MiraiGo v0.0.0-20210807084313-1d900b302d8f/go.mod h1:5V3f/+mTYtrI/+hLqbdzZQXuLMl2RyLfx0XYYjCQ90Q= github.com/bits-and-blooms/bitset v1.2.0 h1:Kn4yilvwNtMACtf1eYDlG8H77R07mZSPbMjLyS07ChA= github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= From a6a666fe310098c27fc2f5b578fa3de20932c70b Mon Sep 17 00:00:00 2001 From: wdvxdr Date: Sat, 7 Aug 2021 19:07:10 +0800 Subject: [PATCH 08/30] fix(config): panic on parsing env. Fixes: #984 --- global/param.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/global/param.go b/global/param.go index 8819edb..f4e6b05 100644 --- a/global/param.go +++ b/global/param.go @@ -96,13 +96,14 @@ func SetAtDefault(variable, value, defaultValue interface{}) { if v.Kind() != reflect.Ptr || v.IsNil() { return } - if v.Elem().Interface() != defaultValue { + v = v.Elem() + if v.Interface() != defaultValue { return } - if v.Elem().Kind() != v2.Kind() { + if v.Kind() != v2.Kind() { return } - v.Elem().Set(v2) + v.Set(v2) } // SetExcludeDefault 在目标值 value 不为默认值 defaultValue 时修改 variable 为 value @@ -112,13 +113,14 @@ func SetExcludeDefault(variable, value, defaultValue interface{}) { if v.Kind() != reflect.Ptr || v.IsNil() { return } - if v2.Elem().Interface() != defaultValue { + v = v.Elem() + if reflect.Indirect(v2).Interface() != defaultValue { return } - if v.Elem().Kind() != v2.Kind() { + if v.Kind() != v2.Kind() { return } - v.Elem().Set(v2) + v.Set(v2) } var ( From fd10f0d0aadcd0f20a7670773af5fd1f93e989cc Mon Sep 17 00:00:00 2001 From: wdvxdr Date: Sat, 7 Aug 2021 23:05:44 +0800 Subject: [PATCH 09/30] doc: format & typo. --- docs/file.md | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/docs/file.md b/docs/file.md index 987a49d..61a5d7e 100644 --- a/docs/file.md +++ b/docs/file.md @@ -1,38 +1,40 @@ # 文件 -go-cqhttp 默认生成的文件树如下所示: +go-cqhttp 默认生成的文件树如下所示: -```` +``` . ├── go-cqhttp -├── config.hjson +├── config.yml ├── device.json ├── logs │ └── xx-xx-xx.log └── data ├── images │ └── xxxx.image - └── db -```` + └── levleldb +``` -| 文件 | 用途 | -| ----------- | ------------------- | -| go-cqhttp | go-cqhttp可执行文件 | -| config.hjson | 运行配置文件 | -| device.json | 虚拟设备配置文件 | -| logs | 日志存放目录 | -| data | 数据目录 | -| data/images | 图片缓存目录 | -| data/db | 数据库目录 | +| 文件 | 用途 | +| ------------ | -------------------- | +| go-cqhttp | go-cqhttp 可执行文件 | +| config.yml | 运行配置文件 | +| device.json | 虚拟设备配置文件 | +| logs | 日志存放目录 | +| data | 数据目录 | +| data/leveldb | 数据库目录 | +| data/images | 图片缓存目录 | +| data/voices | 语音缓存目录 | +| data/videos | 视频缓存目录 | +| data/cache | 发送图片缓存目录 | ## 图片缓存文件 -出于性能考虑,go-cqhttp 并不会将图片源文件下载到本地,而是生成一个可以和QQ服务器对应的缓存文件 (.image),该缓存文件结构如下: +出于性能考虑,go-cqhttp 并不会将图片源文件下载到本地,而是生成一个可以和 QQ 服务器对应的缓存文件 (.image),该缓存文件结构如下: -| 偏移 | 类型 | 说明 | -| --------------- | -------- | ------------------ | -| 0x00 | [16]byte | 图片源文件MD5 HASH | -| 0x10 | uint32 | 图片源文件大小 | +| 偏移 | 类型 | 说明 | +| --------------- | -------- | -------------------- | +| 0x00 | [16]byte | 图片源文件 MD5 HASH | +| 0x10 | uint32 | 图片源文件大小 | | 0x14 | string | 图片原名(QQ内部ID) | -| 0x14 + 原名长度 | string | 图片下载链接 | - +| 0x14 + 原名长度 | string | 图片下载链接 | From d88c30a3c7d6d8968d6094a5fd1c2a7c80f6e7a3 Mon Sep 17 00:00:00 2001 From: Mrs4s Date: Mon, 9 Aug 2021 06:08:04 +0800 Subject: [PATCH 10/30] update dep. --- go.mod | 3 ++- go.sum | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index a422534..36d0fa9 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.16 require ( github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f github.com/Microsoft/go-winio v0.5.0 - github.com/Mrs4s/MiraiGo v0.0.0-20210807084313-1d900b302d8f + github.com/Mrs4s/MiraiGo v0.0.0-20210808220338-0893585b28c6 github.com/dustin/go-humanize v1.0.0 github.com/gabriel-vasile/mimetype v1.3.1 github.com/gorilla/websocket v1.4.2 @@ -26,6 +26,7 @@ require ( github.com/wdvxdr1123/go-silk v0.0.0-20210316130616-d47b553def60 github.com/willf/bitset v1.2.0 // indirect golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e + golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d // indirect golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b diff --git a/go.sum b/go.sum index b8189ab..72bdf9b 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,8 @@ github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f/g github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= -github.com/Mrs4s/MiraiGo v0.0.0-20210807084313-1d900b302d8f h1:W58s6dzrbXW4MU58jdIq9NBFaoD5ZrEgFyUB/IZ79cQ= -github.com/Mrs4s/MiraiGo v0.0.0-20210807084313-1d900b302d8f/go.mod h1:5V3f/+mTYtrI/+hLqbdzZQXuLMl2RyLfx0XYYjCQ90Q= +github.com/Mrs4s/MiraiGo v0.0.0-20210808220338-0893585b28c6 h1:4p8HpX5+PNL5SkqMEGx+2LGdb/+V97xfG8jlRmJe8N8= +github.com/Mrs4s/MiraiGo v0.0.0-20210808220338-0893585b28c6/go.mod h1:5V3f/+mTYtrI/+hLqbdzZQXuLMl2RyLfx0XYYjCQ90Q= github.com/bits-and-blooms/bitset v1.2.0 h1:Kn4yilvwNtMACtf1eYDlG8H77R07mZSPbMjLyS07ChA= github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -134,6 +134,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e h1:gsTQYXdTw2Gq7RBsWvlQ91b+aEQ6bXFUngBGuR8sPpI= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs= +golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= From c6f19016e1aee365b5d646885f709eb0c40ac9fe Mon Sep 17 00:00:00 2001 From: Mrs4s Date: Mon, 9 Aug 2021 06:11:04 +0800 Subject: [PATCH 11/30] update dep. --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 36d0fa9..a2c229b 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.16 require ( github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f github.com/Microsoft/go-winio v0.5.0 - github.com/Mrs4s/MiraiGo v0.0.0-20210808220338-0893585b28c6 + github.com/Mrs4s/MiraiGo v0.0.0-20210808221011-08b19e92efa0 github.com/dustin/go-humanize v1.0.0 github.com/gabriel-vasile/mimetype v1.3.1 github.com/gorilla/websocket v1.4.2 From 1863c44d11e3995a99adb32cc3977d0f1903eea8 Mon Sep 17 00:00:00 2001 From: Mrs4s Date: Mon, 9 Aug 2021 06:11:15 +0800 Subject: [PATCH 12/30] update go.sum --- go.sum | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go.sum b/go.sum index 72bdf9b..ffc8552 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,8 @@ github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f/g github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= -github.com/Mrs4s/MiraiGo v0.0.0-20210808220338-0893585b28c6 h1:4p8HpX5+PNL5SkqMEGx+2LGdb/+V97xfG8jlRmJe8N8= -github.com/Mrs4s/MiraiGo v0.0.0-20210808220338-0893585b28c6/go.mod h1:5V3f/+mTYtrI/+hLqbdzZQXuLMl2RyLfx0XYYjCQ90Q= +github.com/Mrs4s/MiraiGo v0.0.0-20210808221011-08b19e92efa0 h1:SA2FhFNBqlBvu75QY5CjXvW109YwalvPYEYN+5Hc67E= +github.com/Mrs4s/MiraiGo v0.0.0-20210808221011-08b19e92efa0/go.mod h1:5V3f/+mTYtrI/+hLqbdzZQXuLMl2RyLfx0XYYjCQ90Q= github.com/bits-and-blooms/bitset v1.2.0 h1:Kn4yilvwNtMACtf1eYDlG8H77R07mZSPbMjLyS07ChA= github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= From 4bcfe9b8f176c16fc906677f124899ce75d99e59 Mon Sep 17 00:00:00 2001 From: Mrs4s Date: Mon, 9 Aug 2021 06:17:12 +0800 Subject: [PATCH 13/30] feat: member special title updated event. --- coolq/bot.go | 1 + coolq/event.go | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/coolq/bot.go b/coolq/bot.go index 98e998b..8da773c 100644 --- a/coolq/bot.go +++ b/coolq/bot.go @@ -126,6 +126,7 @@ func NewQQBot(cli *client.QQClient, conf *config.Config) *CQBot { bot.Client.OnGroupMessageRecalled(bot.groupRecallEvent) bot.Client.OnGroupNotify(bot.groupNotifyEvent) bot.Client.OnFriendNotify(bot.friendNotifyEvent) + bot.Client.OnMemberSpecialTitleUpdated(bot.memberTitleUpdatedEvent) bot.Client.OnFriendMessageRecalled(bot.friendRecallEvent) bot.Client.OnReceivedOfflineFile(bot.offlineFileEvent) bot.Client.OnJoinGroup(bot.joinGroupEvent) diff --git a/coolq/event.go b/coolq/event.go index 9efb978..f8839a3 100644 --- a/coolq/event.go +++ b/coolq/event.go @@ -282,6 +282,21 @@ func (bot *CQBot) friendNotifyEvent(c *client.QQClient, e client.INotifyEvent) { } } +func (bot *CQBot) memberTitleUpdatedEvent(c *client.QQClient, e *client.MemberSpecialTitleUpdatedEvent) { + group := c.FindGroup(e.GroupCode) + mem := group.FindMember(e.Uin) + log.Infof("群 %v(%v) 内成员 %v(%v) 获得了新的头衔: %v", group.Name, group.Code, mem.DisplayName(), mem.Uin, e.NewTitle) + bot.dispatchEventMessage(MSG{ + "post_type": "notice", + "notice_type": "notify", + "sub_type": "title", + "self_id": c.Uin, + "user_id": e.Uin, + "time": time.Now().Unix(), + "title": e.NewTitle, + }) +} + func (bot *CQBot) friendRecallEvent(c *client.QQClient, e *client.FriendMessageRecalledEvent) { f := c.FindFriend(e.FriendUin) gid := toGlobalID(e.FriendUin, e.MessageId) From 5b705273c25d7f471f64b3451dcf87a8a3fcf68e Mon Sep 17 00:00:00 2001 From: Ink33 Date: Mon, 9 Aug 2021 13:38:49 +0800 Subject: [PATCH 14/30] docs: fix typo (#998) --- docs/config.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/config.md b/docs/config.md index f622a4b..ab396c8 100644 --- a/docs/config.md +++ b/docs/config.md @@ -222,7 +222,7 @@ database: # 数据库相关设置 在部署前,请在本地完成登录,并将 `config.yml` , `device.json` ,`bootstrap` 和 `go-cqhttp` 一起打包。 -在触发器中创建一个API网关触发器,并启用继承响应, 创建完成后即可通过api网关访问go-cqhttp(建议配置 AccessToken)。 +在触发器中创建一个API网关触发器,并启用集成响应,创建完成后即可通过api网关访问go-cqhttp(建议配置 AccessToken)。 > scripts/bootstrap 中使用的工作路径为 /tmp, 这个目录最大能容下500M文件, 如需长期使用, -> 请挂载文件存储(CFS). \ No newline at end of file +> 请挂载文件存储(CFS). From 84488f9bf1007f237dc172dcea981db97946c577 Mon Sep 17 00:00:00 2001 From: wdvxdr Date: Mon, 9 Aug 2021 21:14:36 +0800 Subject: [PATCH 15/30] remove message.ShortVideoElement in LocalVideoElement --- coolq/bot.go | 21 +++++++++------------ coolq/cqcode.go | 15 +++++++++++---- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/coolq/bot.go b/coolq/bot.go index 8da773c..2702ddf 100644 --- a/coolq/bot.go +++ b/coolq/bot.go @@ -212,19 +212,16 @@ func (bot *CQBot) UploadLocalImageAsGroup(groupCode int64, img *LocalImageElemen // UploadLocalVideo 上传本地短视频至群聊 func (bot *CQBot) UploadLocalVideo(target int64, v *LocalVideoElement) (*message.ShortVideoElement, error) { - if v.File != "" { - video, err := os.Open(v.File) - if err != nil { - return nil, err - } - defer video.Close() - hash, _ := utils.ComputeMd5AndLength(io.MultiReader(video, v.thumb)) - cacheFile := path.Join(global.CachePath, hex.EncodeToString(hash)+".cache") - _, _ = video.Seek(0, io.SeekStart) - _, _ = v.thumb.Seek(0, io.SeekStart) - return bot.Client.UploadGroupShortVideo(target, video, v.thumb, cacheFile) + video, err := os.Open(v.File) + if err != nil { + return nil, err } - return &v.ShortVideoElement, nil + defer video.Close() + hash, _ := utils.ComputeMd5AndLength(io.MultiReader(video, v.thumb)) + cacheFile := path.Join(global.CachePath, hex.EncodeToString(hash)+".cache") + _, _ = video.Seek(0, io.SeekStart) + _, _ = v.thumb.Seek(0, io.SeekStart) + return bot.Client.UploadGroupShortVideo(target, video, v.thumb, cacheFile) } // UploadLocalImageAsPrivate 上传本地图片至私聊 diff --git a/coolq/cqcode.go b/coolq/cqcode.go index d7d4e4d..0658767 100644 --- a/coolq/cqcode.go +++ b/coolq/cqcode.go @@ -81,7 +81,6 @@ type LocalVoiceElement struct { // LocalVideoElement 本地视频 type LocalVideoElement struct { - message.ShortVideoElement File string thumb io.ReadSeeker } @@ -97,6 +96,11 @@ func (e *GiftElement) Type() message.ElementType { return message.At } +// Type impl message.IMessageElement +func (e *LocalVideoElement) Type() message.ElementType { + return message.Video +} + // GiftID 礼物ID数组 var GiftID = [...]message.GroupGift{ message.SweetWink, @@ -902,7 +906,10 @@ func (bot *CQBot) ToElement(t string, d map[string]string, isGroup bool) (m inte if err != nil { return nil, err } - v := file.(*LocalVideoElement) + v, ok := file.(*LocalVideoElement) + if !ok { + return file, nil + } if v.File == "" { return v, nil } @@ -1124,14 +1131,14 @@ func (bot *CQBot) makeImageOrVideoElem(d map[string]string, video, group bool) ( if path.Ext(rawPath) == ".video" { b, _ := os.ReadFile(rawPath) r := binary.NewReader(b) - return &LocalVideoElement{ShortVideoElement: message.ShortVideoElement{ // todo 检查缓存是否有效 + return &message.ShortVideoElement{ // todo 检查缓存是否有效 Md5: r.ReadBytes(16), ThumbMd5: r.ReadBytes(16), Size: r.ReadInt32(), ThumbSize: r.ReadInt32(), Name: r.ReadString(), Uuid: r.ReadAvailable(), - }}, nil + }, nil } return &LocalVideoElement{File: rawPath}, nil } From 4c8b2e9f13210d56dbc4d3a57a399b16944a67d6 Mon Sep 17 00:00:00 2001 From: wdvxdr Date: Mon, 9 Aug 2021 21:31:06 +0800 Subject: [PATCH 16/30] drop cache file .cqimg. --- coolq/cqcode.go | 104 +++++++++++++++++++----------------------------- 1 file changed, 41 insertions(+), 63 deletions(-) diff --git a/coolq/cqcode.go b/coolq/cqcode.go index 0658767..ff3a863 100644 --- a/coolq/cqcode.go +++ b/coolq/cqcode.go @@ -1147,72 +1147,50 @@ func (bot *CQBot) makeImageOrVideoElem(d map[string]string, video, group bool) ( exist = true rawPath = path.Join(global.ImagePathOld, f) } - if !exist && global.PathExists(rawPath+".cqimg") { - exist = true - rawPath += ".cqimg" + if !exist { + if d["url"] != "" { + return bot.makeImageOrVideoElem(map[string]string{"file": d["url"]}, false, group) + } + return nil, errors.New("invalid image") } - if !exist && d["url"] != "" { - return bot.makeImageOrVideoElem(map[string]string{"file": d["url"]}, false, group) + if path.Ext(rawPath) != ".image" { + return &LocalImageElement{File: rawPath}, nil } - if exist { - if path.Ext(rawPath) != ".image" && path.Ext(rawPath) != ".cqimg" { - return &LocalImageElement{File: rawPath}, nil - } - b, err := os.ReadFile(rawPath) - if err != nil { - return nil, err - } - if len(b) < 20 { - return nil, errors.New("invalid local file") - } - var ( - size int32 - hash []byte - imageURL 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() - imageURL = r.ReadString() - } - if size == 0 { - if imageURL != "" { - return bot.makeImageOrVideoElem(map[string]string{"file": imageURL}, false, group) - } - return nil, errors.New("img size is 0") - } - if len(hash) != 16 { - return nil, errors.New("invalid hash") - } - var rsp message.IMessageElement - if group { - rsp, err = bot.Client.QueryGroupImage(int64(rand.Uint32()), hash, size) - goto ok - } - rsp, err = bot.Client.QueryFriendImage(int64(rand.Uint32()), hash, size) - ok: - if err != nil { - if imageURL != "" { - return bot.makeImageOrVideoElem(map[string]string{"file": imageURL}, false, group) - } - return nil, err - } - return rsp, nil + b, err := os.ReadFile(rawPath) + if err != nil { + return nil, err } - return nil, errors.New("invalid image") + if len(b) < 20 { + return nil, errors.New("invalid local file") + } + r := binary.NewReader(b) + hash := r.ReadBytes(16) + size := r.ReadInt32() + r.ReadString() + imageURL := r.ReadString() + if size == 0 { + if imageURL != "" { + return bot.makeImageOrVideoElem(map[string]string{"file": imageURL}, false, group) + } + return nil, errors.New("img size is 0") + } + if len(hash) != 16 { + return nil, errors.New("invalid hash") + } + var rsp message.IMessageElement + if group { + rsp, err = bot.Client.QueryGroupImage(int64(rand.Uint32()), hash, size) + goto ok + } + rsp, err = bot.Client.QueryFriendImage(int64(rand.Uint32()), hash, size) +ok: + if err != nil { + if imageURL != "" { + return bot.makeImageOrVideoElem(map[string]string{"file": imageURL}, false, group) + } + return nil, err + } + return rsp, nil } // makeShowPic 一种xml 方式发送的群消息图片 From 75e82eaf3533cbc94fae5af05d61bfec85257c35 Mon Sep 17 00:00:00 2001 From: wdvxdr Date: Tue, 10 Aug 2021 15:10:42 +0800 Subject: [PATCH 17/30] fix(event): friend poke self. --- coolq/event.go | 6 +++++- go.mod | 3 +-- go.sum | 6 ++---- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/coolq/event.go b/coolq/event.go index f8839a3..3781088 100644 --- a/coolq/event.go +++ b/coolq/event.go @@ -268,7 +268,11 @@ func (bot *CQBot) groupNotifyEvent(c *client.QQClient, e client.INotifyEvent) { func (bot *CQBot) friendNotifyEvent(c *client.QQClient, e client.INotifyEvent) { friend := c.FindFriend(e.From()) if notify, ok := e.(*client.FriendPokeNotifyEvent); ok { - log.Infof("好友 %v 戳了戳你.", friend.Nickname) + if notify.Receiver == notify.Sender { + log.Infof("好友 %v 戳了戳自己.", friend.Nickname) + } else { + log.Infof("好友 %v 戳了戳你.", friend.Nickname) + } bot.dispatchEventMessage(MSG{ "post_type": "notice", "notice_type": "notify", diff --git a/go.mod b/go.mod index a2c229b..7bde831 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.16 require ( github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f github.com/Microsoft/go-winio v0.5.0 - github.com/Mrs4s/MiraiGo v0.0.0-20210808221011-08b19e92efa0 + github.com/Mrs4s/MiraiGo v0.0.0-20210810070836-6614d2383adb github.com/dustin/go-humanize v1.0.0 github.com/gabriel-vasile/mimetype v1.3.1 github.com/gorilla/websocket v1.4.2 @@ -26,7 +26,6 @@ require ( github.com/wdvxdr1123/go-silk v0.0.0-20210316130616-d47b553def60 github.com/willf/bitset v1.2.0 // indirect golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e - golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d // indirect golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b diff --git a/go.sum b/go.sum index ffc8552..86af72d 100644 --- a/go.sum +++ b/go.sum @@ -4,8 +4,8 @@ github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f/g github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= -github.com/Mrs4s/MiraiGo v0.0.0-20210808221011-08b19e92efa0 h1:SA2FhFNBqlBvu75QY5CjXvW109YwalvPYEYN+5Hc67E= -github.com/Mrs4s/MiraiGo v0.0.0-20210808221011-08b19e92efa0/go.mod h1:5V3f/+mTYtrI/+hLqbdzZQXuLMl2RyLfx0XYYjCQ90Q= +github.com/Mrs4s/MiraiGo v0.0.0-20210810070836-6614d2383adb h1:agCxYd/ZemDwrEYKpnpKqA0cubxfpkQ/b+GpIlIJK0U= +github.com/Mrs4s/MiraiGo v0.0.0-20210810070836-6614d2383adb/go.mod h1:5V3f/+mTYtrI/+hLqbdzZQXuLMl2RyLfx0XYYjCQ90Q= github.com/bits-and-blooms/bitset v1.2.0 h1:Kn4yilvwNtMACtf1eYDlG8H77R07mZSPbMjLyS07ChA= github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -134,8 +134,6 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e h1:gsTQYXdTw2Gq7RBsWvlQ91b+aEQ6bXFUngBGuR8sPpI= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs= -golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= From c355549c8d7c3be9ba94154f31da944368323afb Mon Sep 17 00:00:00 2001 From: wdvxdr Date: Wed, 11 Aug 2021 22:39:58 +0800 Subject: [PATCH 18/30] fix(server): ws reverse reconnect. --- server/websocket.go | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/server/websocket.go b/server/websocket.go index b49ba29..af3c47f 100644 --- a/server/websocket.go +++ b/server/websocket.go @@ -160,7 +160,12 @@ func (c *websocketClient) connectEvent() { } log.Infof("已连接到反向WebSocket Event服务器 %v", c.conf.Event) - c.eventConn = &webSocketConn{Conn: conn, apiCaller: newAPICaller(c.bot)} + if c.eventConn == nil { + wrappedConn := &webSocketConn{Conn: conn, apiCaller: newAPICaller(c.bot)} + c.eventConn = wrappedConn + } else { + c.eventConn.Conn = conn + } } func (c *websocketClient) connectUniversal() { @@ -189,12 +194,16 @@ func (c *websocketClient) connectUniversal() { log.Warnf("反向WebSocket 握手时出现错误: %v", err) } - wrappedConn := &webSocketConn{Conn: conn, apiCaller: newAPICaller(c.bot)} - if c.conf.RateLimit.Enabled { - wrappedConn.apiCaller.use(rateLimit(c.conf.RateLimit.Frequency, c.conf.RateLimit.Bucket)) + if c.universalConn == nil { + wrappedConn := &webSocketConn{Conn: conn, apiCaller: newAPICaller(c.bot)} + if c.conf.RateLimit.Enabled { + wrappedConn.apiCaller.use(rateLimit(c.conf.RateLimit.Frequency, c.conf.RateLimit.Bucket)) + } + c.universalConn = wrappedConn + } else { + c.universalConn.Conn = conn } - go c.listenAPI(wrappedConn, true) - c.universalConn = wrappedConn + go c.listenAPI(c.universalConn, true) } func (c *websocketClient) listenAPI(conn *webSocketConn, u bool) { From d3b22a7a46886c7dfaf644161deeea0a2cf1e268 Mon Sep 17 00:00:00 2001 From: sam01101 Date: Fri, 13 Aug 2021 18:55:04 +0800 Subject: [PATCH 19/30] [Fix] Using timestamp from server --- coolq/bot.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coolq/bot.go b/coolq/bot.go index 2702ddf..858ffd6 100644 --- a/coolq/bot.go +++ b/coolq/bot.go @@ -514,7 +514,7 @@ func (bot *CQBot) formatGroupMessage(m *message.GroupMessage) MSG { "user_id": m.Sender.Uin, }, "sub_type": "normal", - "time": time.Now().Unix(), + "time": m.Time, "user_id": m.Sender.Uin, } if m.Sender.IsAnonymous() { From 92ad7d593845851d46fa55cb009a6b9165f9600b Mon Sep 17 00:00:00 2001 From: wdvxdr Date: Sat, 14 Aug 2021 14:32:42 +0800 Subject: [PATCH 20/30] fix(scf): fix write response. --- server/scf.go | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/server/scf.go b/server/scf.go index a59d273..2c1f812 100644 --- a/server/scf.go +++ b/server/scf.go @@ -1,6 +1,7 @@ package server import ( + "bytes" "fmt" "io" "net/http" @@ -34,20 +35,22 @@ type lambdaResponse struct { type lambdaResponseWriter struct { statusCode int + buf bytes.Buffer header http.Header } +func (l *lambdaResponseWriter) Write(p []byte) (n int, err error) { + return l.buf.Write(p) +} + func (l *lambdaResponseWriter) Header() http.Header { return l.header } -func (l *lambdaResponseWriter) Write(data []byte) (int, error) { +func (l *lambdaResponseWriter) flush() error { buffer := global.NewBuffer() defer global.PutBuffer(buffer) - body := "" - if data != nil { - body = utils.B2S(data) - } + body := utils.B2S(l.buf.Bytes()) header := make(map[string]string) for k, v := range l.header { header[k] = v[0] @@ -62,10 +65,9 @@ func (l *lambdaResponseWriter) Write(data []byte) (int, error) { r, _ := http.NewRequest("POST", cli.responseURL, buffer) do, err := cli.client.Do(r) if err != nil { - return 0, err + return err } - _ = do.Body.Close() - return len(data), nil + return do.Body.Close() } func (l *lambdaResponseWriter) WriteHeader(statusCode int) { @@ -125,7 +127,11 @@ func RunLambdaClient(bot *coolq.CQBot, conf *config.LambdaServer) { log.Warnf("Lambda 出现不可恢复错误: %v\n%s", e, debug.Stack()) } }() - server.ServeHTTP(&lambdaResponseWriter{header: make(http.Header)}, req) + writer := lambdaResponseWriter{header: make(http.Header)} + server.ServeHTTP(&writer, req) + if err := writer.flush(); err != nil { + log.Warnf("Lambda 发送响应失败: %v", err) + } }() } } From aa46ab0119a60c0a93c5a84ce94c06b9c8ea79fc Mon Sep 17 00:00:00 2001 From: Mrs4s Date: Sun, 15 Aug 2021 01:54:03 +0800 Subject: [PATCH 21/30] add: session delete log. --- go.mod | 1 + go.sum | 2 ++ main.go | 1 + 3 files changed, 4 insertions(+) diff --git a/go.mod b/go.mod index 7bde831..fc414fc 100644 --- a/go.mod +++ b/go.mod @@ -26,6 +26,7 @@ require ( github.com/wdvxdr1123/go-silk v0.0.0-20210316130616-d47b553def60 github.com/willf/bitset v1.2.0 // indirect golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e + golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d // indirect golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b diff --git a/go.sum b/go.sum index 86af72d..86a3b75 100644 --- a/go.sum +++ b/go.sum @@ -134,6 +134,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e h1:gsTQYXdTw2Gq7RBsWvlQ91b+aEQ6bXFUngBGuR8sPpI= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs= +golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= diff --git a/main.go b/main.go index 2646dd8..b29e1fc 100644 --- a/main.go +++ b/main.go @@ -260,6 +260,7 @@ func main() { text := readLineTimeout(time.Second*5, "1") if text == "2" { _ = os.Remove("session.token") + log.Infof("缓存已删除.") os.Exit(0) } } From b43bdc1da5025a48c30847a203a372b3c7021846 Mon Sep 17 00:00:00 2001 From: Mrs4s Date: Sun, 15 Aug 2021 01:58:20 +0800 Subject: [PATCH 22/30] update slider.md --- docs/slider.md | 2 ++ login.go | 16 +--------------- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/docs/slider.md b/docs/slider.md index c29593c..68f1b19 100644 --- a/docs/slider.md +++ b/docs/slider.md @@ -1,5 +1,7 @@ # 滑块验证码 +>> 该文档已过期, 最新版本下可直接使用手机扫描二维码通过验证. + 由于TX最新的限制, 所有协议在陌生设备/IP登录时都有可能被要求通过滑块验证码, 否则将会出现 `当前上网环境异常` 的错误. 目前我们准备了两个临时方案应对该验证码. > 如果您有一台运行Windows的PC/Server 并且不会抓包操作, 我们建议直接使用方案B diff --git a/login.go b/login.go index 10bea15..5e6c064 100644 --- a/login.go +++ b/login.go @@ -117,21 +117,7 @@ func loginResponseProcessor(res *client.LoginResponse) error { var text string switch res.Error { case client.SliderNeededError: - log.Warnf("登录需要滑条验证码. ") - log.Warnf("请参考文档 -> https://docs.go-cqhttp.org/faq/slider.html <- 进行处理") - log.Warnf("1. 自行抓包并获取 Ticket 输入.") - log.Warnf("2. 使用手机QQ扫描二维码登入. (推荐)") - log.Warn("请输入(1 - 2) (将在10秒后自动选择2):") - text = readLineTimeout(time.Second*10, "2") - if strings.Contains(text, "1") { - println() - log.Warnf("请用浏览器打开 -> %v <- 并获取Ticket.", res.VerifyUrl) - println() - log.Warn("请输入Ticket: (Enter 提交)") - text = readLine() - res, err = cli.SubmitTicket(text) - continue - } + log.Warnf("登录需要滑条验证码, 请使用手机QQ扫描二维码以继续登录.") cli.Disconnect() cli.Release() cli = client.NewClientEmpty() From a1e3c574883ec181955c93840deb0d0a0b6705b2 Mon Sep 17 00:00:00 2001 From: Mrs4s Date: Sun, 15 Aug 2021 01:58:43 +0800 Subject: [PATCH 23/30] fix typo. --- docs/slider.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/slider.md b/docs/slider.md index 68f1b19..d668aff 100644 --- a/docs/slider.md +++ b/docs/slider.md @@ -1,6 +1,6 @@ # 滑块验证码 ->> 该文档已过期, 最新版本下可直接使用手机扫描二维码通过验证. +> 该文档已过期, 最新版本下可直接使用手机扫描二维码通过验证. 由于TX最新的限制, 所有协议在陌生设备/IP登录时都有可能被要求通过滑块验证码, 否则将会出现 `当前上网环境异常` 的错误. 目前我们准备了两个临时方案应对该验证码. From 4b4193c6e379639f612205b963e126b98dd0a265 Mon Sep 17 00:00:00 2001 From: Mrs4s Date: Sun, 15 Aug 2021 02:15:33 +0800 Subject: [PATCH 24/30] feat: load leveldb conf from environment variable. close #1002 --- global/config/config.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/global/config/config.go b/global/config/config.go index e0f58b2..d85e9ad 100644 --- a/global/config/config.go +++ b/global/config/config.go @@ -174,6 +174,12 @@ func Get() *Config { global.SetAtDefault(&config.Account.ReLogin.Disabled, !global.EnsureBool(os.Getenv("GCQ_RELOGIN"), false), false) global.SetAtDefault(&config.Account.ReLogin.Delay, uint(toInt64(os.Getenv("GCQ_RELOGIN_DELAY"))), uint(0)) global.SetAtDefault(&config.Account.ReLogin.MaxTimes, uint(toInt64(os.Getenv("GCQ_RELOGIN_MAX_TIMES"))), uint(0)) + dbConf := &LevelDBConfig{Enable: global.EnsureBool(os.Getenv("GCQ_LEVELDB"), true)} + config.Database["leveldb"] = func() yaml.Node { + n := &yaml.Node{} + _ = n.Encode(dbConf) + return *n + }() accessTokenEnv := os.Getenv("GCQ_ACCESS_TOKEN") if os.Getenv("GCQ_HTTP_PORT") != "" { node := &yaml.Node{} From 3c9433d7b7a974654903550ef20ca5736e287716 Mon Sep 17 00:00:00 2001 From: Mrs4s Date: Sun, 15 Aug 2021 02:22:47 +0800 Subject: [PATCH 25/30] remove: mark msg as read. --- coolq/event.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/coolq/event.go b/coolq/event.go index 3781088..db0f6eb 100644 --- a/coolq/event.go +++ b/coolq/event.go @@ -69,9 +69,6 @@ func (bot *CQBot) privateMessageEvent(c *client.QQClient, m *message.PrivateMess }, } bot.dispatchEventMessage(fm) - if m.Sender.Uin != c.Uin { - c.MarkPrivateMessageReaded(m.Sender.Uin, int64(m.Time)) - } } func (bot *CQBot) groupMessageEvent(c *client.QQClient, m *message.GroupMessage) { @@ -109,9 +106,6 @@ func (bot *CQBot) groupMessageEvent(c *client.QQClient, m *message.GroupMessage) } gm["message_id"] = id bot.dispatchEventMessage(gm) - if m.Sender.Uin != c.Uin { - c.MarkGroupMessageReaded(m.GroupCode, int64(m.Id)) - } } func (bot *CQBot) tempMessageEvent(c *client.QQClient, e *client.TempMessageEvent) { From 6240e875ce1d997907d235273691165b8cc3ad5c Mon Sep 17 00:00:00 2001 From: Mrs4s Date: Sun, 15 Aug 2021 02:36:11 +0800 Subject: [PATCH 26/30] add: mark_msg_as_read api. --- coolq/api.go | 16 ++++++++++++++++ coolq/bot.go | 2 +- server/api.go | 5 +++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/coolq/api.go b/coolq/api.go index e988618..19a8433 100644 --- a/coolq/api.go +++ b/coolq/api.go @@ -1418,6 +1418,22 @@ func (bot *CQBot) CQSetModelShow(modelName string, modelShow string) MSG { return OK(nil) } +func (bot *CQBot) CQMarkMessageAsRead(msgId int32) MSG { + m := bot.GetMessage(msgId) + if m == nil { + return Failed(100, "MSG_NOT_FOUND", "消息不存在") + } + if _, ok := m["group"]; ok { + bot.Client.MarkGroupMessageReaded(m["group"].(int64), int64(m["message-id"].(int32))) + return OK(nil) + } + if _, ok := m["from-group"]; ok { + return Failed(100, "MSG_TYPE_ERROR", "不支持标记临时会话") + } + bot.Client.MarkPrivateMessageReaded(m["sender"].(*message.Sender).Uin, m["time"].(int64)) + return OK(nil) +} + // OK 生成成功返回值 func OK(data interface{}) MSG { return MSG{"data": data, "retcode": 0, "status": "ok"} diff --git a/coolq/bot.go b/coolq/bot.go index 858ffd6..8ab23fc 100644 --- a/coolq/bot.go +++ b/coolq/bot.go @@ -426,7 +426,7 @@ func (bot *CQBot) InsertTempMessage(target int64, m *message.TempMessage) int32 val := MSG{ "message-id": m.Id, // FIXME(InsertTempMessage) InternalId missing - "group": m.GroupCode, + "from-group": m.GroupCode, "group-name": m.GroupName, "target": target, "sender": m.Sender, diff --git a/server/api.go b/server/api.go index ecc62d9..2f35884 100644 --- a/server/api.go +++ b/server/api.go @@ -350,6 +350,10 @@ func setModelShow(bot *coolq.CQBot, p resultGetter) coolq.MSG { return bot.CQSetModelShow(p.Get("model").String(), p.Get("model_show").String()) } +func markMSGAsRead(bot *coolq.CQBot, p resultGetter) coolq.MSG { + return bot.CQMarkMessageAsRead(int32(p.Get("message_id").Int())) +} + // API 是go-cqhttp当前支持的所有api的映射表 var API = map[string]func(*coolq.CQBot, resultGetter) coolq.MSG{ "get_login_info": getLoginInfo, @@ -413,6 +417,7 @@ var API = map[string]func(*coolq.CQBot, resultGetter) coolq.MSG{ "qidian_get_account_info": getQiDianAccountInfo, "_get_model_show": getModelShow, "_set_model_show": setModelShow, + "mark_msg_as_read": markMSGAsRead, } func (api *apiCaller) callAPI(action string, p resultGetter) coolq.MSG { From eaa8154a3366a8fcebad1e2d7c2dada3a9e222c8 Mon Sep 17 00:00:00 2001 From: Mrs4s Date: Sun, 15 Aug 2021 02:37:51 +0800 Subject: [PATCH 27/30] update doc. --- docs/cqhttp.md | 311 ++++++++++++++++++++++++++++--------------------- 1 file changed, 178 insertions(+), 133 deletions(-) diff --git a/docs/cqhttp.md b/docs/cqhttp.md index eb02d7e..f08bd44 100644 --- a/docs/cqhttp.md +++ b/docs/cqhttp.md @@ -7,6 +7,7 @@

##### CQCode + - [图片](#图片) - [回复](#回复) - [红包](#红包) @@ -21,6 +22,7 @@ - [图片](#图片) ##### API + - [设置群名](#设置群名) - [设置群头像](#设置群头像) - [获取图片信息](#获取图片信息) @@ -47,6 +49,7 @@ - [重载事件过滤器](#重载事件过滤器) ##### 事件 + - [群消息撤回](#群消息撤回) - [好友消息撤回](#好友消息撤回) - [好友戳一戳](#好友戳一戳) @@ -112,9 +115,7 @@ Type : `reply` | `time` | int64 | 可选. 自定义回复时的时间, 格式为Unix时间 | | `seq` | int64 | 起始消息序号, 可通过 `get_msg` 获得 | - - -示例: `[CQ:reply,id=123456]` +示例: `[CQ:reply,id=123456]` \ 自定义回复示例: `[CQ:reply,text=Hello World,qq=10086,time=3376656000,seq=5123]` @@ -122,11 +123,11 @@ Type : `reply` ```json { - "type": "music", - "data": { - "type": "163", - "id": "28949129" - } + "type": "music", + "data": { + "type": "163", + "id": "28949129" + } } ``` @@ -143,13 +144,13 @@ Type : `reply` ```json { - "type": "music", - "data": { - "type": "custom", - "url": "http://baidu.com", - "audio": "http://baidu.com/1.mp3", - "title": "音乐标题" - } + "type": "music", + "data": { + "type": "custom", + "url": "http://baidu.com", + "audio": "http://baidu.com/1.mp3", + "title": "音乐标题" + } } ``` @@ -231,11 +232,9 @@ Type: `gift` | 12 | 我超忙的 | | 13 | 爱心口罩 | - - 示例: `[CQ:gift,qq=123456,id=8]` - ### 合并转发 +### 合并转发 Type: `forward` @@ -259,32 +258,33 @@ Type: `node` | 参数名 | 类型 | 说明 | 特殊说明 | | --------- | ------- | -------------- | -------------------------------------------------------------------------------------- | -| `id` | int32 | 转发消息id | 直接引用他人的消息合并转发, 实际查看顺序为原消息发送顺序 **与下面的自定义消息二选一** | +| `id` | int32 | 转发消息id | 直接引用他人的消息合并转发, 实际查看顺序为原消息发送顺序 **与下面的自定义消息二选一** | | `name` | string | 发送者显示名字 | 用于自定义消息 (自定义消息并合并转发,实际查看顺序为自定义消息段顺序) | | `uin` | int64 | 发送者QQ号 | 用于自定义消息 | | `content` | message | 具体消息 | 用于自定义消息 | | `seq` | message | 具体消息 | 用于自定义消息 | -特殊说明: **需要使用单独的API `/send_group_forward_msg` 发送,并且由于消息段较为复杂,仅支持Array形式入参。 如果引用消息和自定义消息同时出现,实际查看顺序将取消息段顺序. 另外按 [CQHTTP](https://git.io/JtxtN) 文档说明, `data` 应全为字符串, 但由于需要接收`message` 类型的消息, 所以 *仅限此Type的content字段* 支持Array套娃** +特殊说明: **需要使用单独的API `/send_group_forward_msg` 发送,并且由于消息段较为复杂,仅支持Array形式入参。 如果引用消息和自定义消息同时出现,实际查看顺序将取消息段顺序. +另外按 [CQHTTP](https://git.io/JtxtN) 文档说明, `data` 应全为字符串, 但由于需要接收`message` 类型的消息, 所以 *仅限此Type的content字段* 支持Array套娃** -示例: +示例: 直接引用消息合并转发: ````json [ - { - "type": "node", - "data": { - "id": "123" - } - }, - { - "type": "node", - "data": { - "id": "456" - } + { + "type": "node", + "data": { + "id": "123" } + }, + { + "type": "node", + "data": { + "id": "456" + } + } ] ```` @@ -292,27 +292,29 @@ Type: `node` ````json [ - { - "type": "node", - "data": { - "name": "消息发送者A", - "uin": "10086", - "content": [ - { - "type": "text", - "data": {"text": "测试消息1"} - } - ] - } - }, - { - "type": "node", - "data": { - "name": "消息发送者B", - "uin": "10087", - "content": "[CQ:image,file=xxxxx]测试消息2" + { + "type": "node", + "data": { + "name": "消息发送者A", + "uin": "10086", + "content": [ + { + "type": "text", + "data": { + "text": "测试消息1" + } } + ] } + }, + { + "type": "node", + "data": { + "name": "消息发送者B", + "uin": "10087", + "content": "[CQ:image,file=xxxxx]测试消息2" + } + } ] ```` @@ -320,24 +322,25 @@ Type: `node` ````json [ - { - "type": "node", - "data": { - "name": "自定义发送者", - "uin": "10086", - "content": "我是自定义消息", - "seq": "5123", - "time": "3376656000" - } - }, - { - "type": "node", - "data": { - "id": "123" - } + { + "type": "node", + "data": { + "name": "自定义发送者", + "uin": "10086", + "content": "我是自定义消息", + "seq": "5123", + "time": "3376656000" } + }, + { + "type": "node", + "data": { + "id": "123" + } + } ] ```` + ### 短视频消息 Type: `video` @@ -351,6 +354,7 @@ Type: `video` | `file` | string | 支持http和file发送 | | `cover` | string | 视频封面,支持http,file和base64发送,格式必须为jpg | | `c` | `2` `3` | 通过网络下载视频时的线程数, 默认单线程. (在资源不支持并发时会自动处理) | + 示例: `[CQ:video,file=file:///C:\\Users\Richard\Videos\1.mp4]` ### XML 消息 @@ -375,30 +379,61 @@ Type: `xml` #### qq音乐 ```xml -

陈奕迅 + + + + + + ``` + #### 网易音乐 + ```xml - + + + + + + ``` #### 卡片消息1 + ```xml -生死8秒!女司机高速急刹,他一个操作救下一车性命 - + + 生死8秒!女司机高速急刹,他一个操作救下一车性命 + + ``` #### 卡片消息2 + ```xml - -test title - - + + test title + + ``` @@ -417,23 +452,24 @@ Type: `json` json中的字符串需要进行转义: ->","=> `,` +> ","=> `,` ->"&"=> `&` +> "&"=> `&` ->"["=> `[` +> "["=> `[` ->"]"=> `]` +> "]"=> `]` 否则无法正确得到解析 示例json 的cq码: + ```test [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 接口的消息都存在风控风险,请自行兼容发送失败后的处理(可以失败后走普通图片模式) @@ -454,8 +490,8 @@ Type: `cardimage` | `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] ``` @@ -480,9 +516,9 @@ Type: `tts` ### 设置群名 -终结点: `/set_group_name` +终结点: `/set_group_name` -**参数** +**参数** | 字段 | 类型 | 说明 | | ------------ | ------ | ---- | @@ -491,9 +527,9 @@ Type: `tts` ### 设置群头像 -终结点: `/set_group_portrait` +终结点: `/set_group_portrait` -**参数** +**参数** | 字段 | 类型 | 说明 | | ---------- | ------ | ------------------------ | @@ -505,7 +541,8 @@ Type: `tts` - 绝对路径,例如 `file:///C:\\Users\Richard\Pictures\1.png`,格式使用 [`file` URI](https://tools.ietf.org/html/rfc8089) - 网络 URL,例如 `http://i1.piimg.com/567571/fdd6e7b6d93f1ef0.jpg` -- Base64 编码,例如 `base64://iVBORw0KGgoAAAANSUhEUgAAABQAAAAVCAIAAADJt1n/AAAAKElEQVQ4EWPk5+RmIBcwkasRpG9UM4mhNxpgowFGMARGEwnBIEJVAAAdBgBNAZf+QAAAAABJRU5ErkJggg==` +- Base64 + 编码,例如 `base64://iVBORw0KGgoAAAANSUhEUgAAABQAAAAVCAIAAADJt1n/AAAAKElEQVQ4EWPk5+RmIBcwkasRpG9UM4mhNxpgowFGMARGEwnBIEJVAAAdBgBNAZf+QAAAAABJRU5ErkJggg==` [2]`cache`参数: 通过网络 URL 发送时有效,`1`表示使用缓存,`0`关闭关闭缓存,默认 为`1` @@ -513,7 +550,7 @@ Type: `tts` ### 获取图片信息 -终结点: `/get_image` +终结点: `/get_image` > 该接口为 CQHTTP 接口修改 @@ -533,7 +570,7 @@ Type: `tts` ### 获取消息 -终结点: `/get_msg` +终结点: `/get_msg` 参数 @@ -571,28 +608,29 @@ Type: `tts` ````json5 { - "data": { - "messages": [ - { - "content": "合并转发1", - "sender": { - "nickname": "发送者A", - "user_id": 10086 - }, - "time": 1595694374 - }, - { - "content": "合并转发2[CQ:image,file=xxxx,url=xxxx]", - "sender": { - "nickname": "发送者B", - "user_id": 10087 - }, - "time": 1595694393 // 可选 - } - ] - }, - "retcode": 0, - "status": "ok" + "data": { + "messages": [ + { + "content": "合并转发1", + "sender": { + "nickname": "发送者A", + "user_id": 10086 + }, + "time": 1595694374 + }, + { + "content": "合并转发2[CQ:image,file=xxxx,url=xxxx]", + "sender": { + "nickname": "发送者B", + "user_id": 10087 + }, + "time": 1595694393 + // 可选 + } + ] + }, + "retcode": 0, + "status": "ok" } ```` @@ -600,7 +638,7 @@ Type: `tts` 终结点: `/send_group_forward_msg` -**参数** +**参数** | 字段 | 类型 | 说明 | | ---------- | -------------- | ---------------------------- | @@ -608,16 +646,16 @@ Type: `tts` | `messages` | forward node[] | 自定义转发消息, 具体看 [CQCode](https://github.com/Mrs4s/go-cqhttp/blob/master/docs/cqhttp.md#%E5%90%88%E5%B9%B6%E8%BD%AC%E5%8F%91%E6%B6%88%E6%81%AF%E8%8A%82%E7%82%B9) | 响应数据 - + | 字段 | 类型 | 说明 | | ------------ | ------ | ------ | | `message_id` | string | 消息id | ### 获取中文分词 -终结点: `/.get_word_slices` +终结点: `/.get_word_slices` -**参数** +**参数** | 字段 | 类型 | 说明 | | --------- | ------ | ---- | @@ -685,9 +723,9 @@ Type: `tts` > 注意: 目前图片OCR接口仅支持接受的图片 -终结点: `/ocr_image` +终结点: `/ocr_image` -**参数** +**参数** | 字段 | 类型 | 说明 | | ------- | ------ | ------ | @@ -708,7 +746,6 @@ Type: `tts` | `confidence` | int32 | 置信度 | | `coordinates` | vector2 | 坐标 | - ### 获取群系统消息 终结点: `/get_group_system_msg` @@ -720,9 +757,9 @@ Type: `tts` | `invited_requests` | InvitedRequest[] | 邀请消息列表 | | `join_requests` | JoinRequest[] | 进群消息列表 | - > 注意: 如果列表不存在任何消息, 将返回 `null` +> 注意: 如果列表不存在任何消息, 将返回 `null` - **InvitedRequest** +**InvitedRequest** | 字段 | 类型 | 说明 | | -------------- | ------ | ----------------- | @@ -734,7 +771,7 @@ Type: `tts` | `checked` | bool | 是否已被处理 | | `actor` | int64 | 处理者, 未处理为0 | - **JoinRequest** +**JoinRequest** | 字段 | 类型 | 说明 | | ---------------- | ------ | ----------------- | @@ -751,7 +788,7 @@ Type: `tts` 终结点: `/get_group_file_system_info` -**参数** +**参数** | 字段 | 类型 | 说明 | | ---------- | ----- | ---- | @@ -772,7 +809,7 @@ Type: `tts` 终结点: `/get_group_root_files` -**参数** +**参数** | 字段 | 类型 | 说明 | | ---------- | ----- | ---- | @@ -791,7 +828,7 @@ Type: `tts` 终结点: `/get_group_files_by_folder` -**参数** +**参数** | 字段 | 类型 | 说明 | | ----------- | ------ | --------------------------- | @@ -811,7 +848,7 @@ Type: `tts` 终结点: `/get_group_file_url` -**参数** +**参数** | 字段 | 类型 | 说明 | | ---------- | ------ | ------------------------- | @@ -825,7 +862,7 @@ Type: `tts` | ----- | ------ | ------------ | | `url` | string | 文件下载链接 | - **File** +**File** | 字段 | 类型 | 说明 | | ---------------- | ------ | ---------------------- | @@ -840,7 +877,7 @@ Type: `tts` | `uploader` | int64 | 上传者ID | | `uploader_name` | string | 上传者名字 | - **Folder** +**Folder** | 字段 | 类型 | 说明 | | ------------------ | ------ | ---------- | @@ -855,7 +892,7 @@ Type: `tts` 终结点: `/upload_group_file` -**参数** +**参数** | 字段 | 类型 | 说明 | | ---------- | ------ | ------------------------- | @@ -885,7 +922,6 @@ Type: `tts` **Statistics** - | 字段 | 类型 | 说明 | | ------------------ | ------ | ---------------- | | `packet_received` | uint64 | 收到的数据包总数 | @@ -902,7 +938,7 @@ Type: `tts` 终结点: `/get_group_at_all_remain` -**参数** +**参数** | 字段 | 类型 | 说明 | | ---------- | ----- | ---- | @@ -920,7 +956,7 @@ Type: `tts` 终结点: `/download_file` -**参数** +**参数** | 字段 | 类型 | 说明 | | -------------- | --------------- | ------------ | @@ -960,7 +996,7 @@ JSON数组: 终结点:`/get_group_msg_history` -**参数** +**参数** | 字段 | 类型 | 说明 | | ------------- | ----- | ----------------------------------- | @@ -979,7 +1015,7 @@ JSON数组: 终结点:`/get_online_clients` -**参数** +**参数** | 字段 | 类型 | 说明 | | ---------- | ---- | ------------ | @@ -1003,7 +1039,7 @@ JSON数组: 终结点:`/check_url_safely` -**参数** +**参数** | 字段 | 类型 | 说明 | | ---------- | ------ | ------------------------- | @@ -1076,13 +1112,22 @@ JSON数组: | `ext_name` | string | 用户昵称 | | `create_time` | int64 | 账号创建时间 | +### 标记消息已读 + +终结点: `/mark_msg_as_read` + +**参数** + +| 字段名 | 数据类型 | 默认值 | 说明 | +| ---------- | -------- | ------ | -------- | +| `message_id` | int32 | | 消息ID | + ### 重载事件过滤器 终结点:`/reload_event_filter` `该 API 无需参数也没有响应数据` - ## 事件 ### 群消息撤回 From bf4f7fb41e6d7dffbd24fb7d66f2c7f2c019311d Mon Sep 17 00:00:00 2001 From: Mrs4s Date: Sun, 15 Aug 2021 02:40:39 +0800 Subject: [PATCH 28/30] fix lint. --- coolq/api.go | 1 + 1 file changed, 1 insertion(+) diff --git a/coolq/api.go b/coolq/api.go index 19a8433..adbb4a6 100644 --- a/coolq/api.go +++ b/coolq/api.go @@ -1418,6 +1418,7 @@ func (bot *CQBot) CQSetModelShow(modelName string, modelShow string) MSG { return OK(nil) } +// CQMarkMessageAsRead 标记消息已读 func (bot *CQBot) CQMarkMessageAsRead(msgId int32) MSG { m := bot.GetMessage(msgId) if m == nil { From e13a5bdad0929e039c9a3dfea79ae2bb6958b5ff Mon Sep 17 00:00:00 2001 From: Mrs4s Date: Sun, 15 Aug 2021 02:51:32 +0800 Subject: [PATCH 29/30] update doc & fix typo. --- coolq/event.go | 1 + docs/cqhttp.md | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/coolq/event.go b/coolq/event.go index db0f6eb..8b88c10 100644 --- a/coolq/event.go +++ b/coolq/event.go @@ -288,6 +288,7 @@ func (bot *CQBot) memberTitleUpdatedEvent(c *client.QQClient, e *client.MemberSp "post_type": "notice", "notice_type": "notify", "sub_type": "title", + "group_id": group.Code, "self_id": c.Uin, "user_id": e.Uin, "time": time.Now().Unix(), diff --git a/docs/cqhttp.md b/docs/cqhttp.md index f08bd44..a70b08a 100644 --- a/docs/cqhttp.md +++ b/docs/cqhttp.md @@ -1226,11 +1226,23 @@ JSON数组: | `notice_type` | string | `group_card` | 消息类型 | | `group_id` | int64 | | 群号 | | `user_id` | int64 | | 成员id | -| `card_new` | int64 | | 新名片 | -| `card_old` | int64 | | 旧名片 | +| `card_new` | string | | 新名片 | +| `card_old` | string | | 旧名片 | > PS: 当名片为空时 `card_xx` 字段为空字符串, 并不是昵称 +### 群成员头衔更新事件 + +**上报数据** + +| 字段 | 类型 | 可能的值 | 说明 | +| ------------- | ------ | ------------ | -------- | +| `post_type` | string | `notice` | 上报类型 | +| `notice_type` | string | `notify` | 消息类型 | +| `group_id` | int64 | | 群号 | +| `user_id` | int64 | | 成员id | +| `title` | string | | 新头衔 | + ### 接收到离线文件 **上报数据** From 971cb5d8540bcb64c0dc200bc915d4efdaa03fe3 Mon Sep 17 00:00:00 2001 From: Mrs4s Date: Sun, 15 Aug 2021 02:53:35 +0800 Subject: [PATCH 30/30] fix lint. --- coolq/api.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/coolq/api.go b/coolq/api.go index adbb4a6..e442798 100644 --- a/coolq/api.go +++ b/coolq/api.go @@ -1419,8 +1419,8 @@ func (bot *CQBot) CQSetModelShow(modelName string, modelShow string) MSG { } // CQMarkMessageAsRead 标记消息已读 -func (bot *CQBot) CQMarkMessageAsRead(msgId int32) MSG { - m := bot.GetMessage(msgId) +func (bot *CQBot) CQMarkMessageAsRead(msgID int32) MSG { + m := bot.GetMessage(msgID) if m == nil { return Failed(100, "MSG_NOT_FOUND", "消息不存在") }