1
0
mirror of https://github.com/Mrs4s/go-cqhttp.git synced 2025-05-04 19:17:37 +08:00

coolq: adapt new MiraiGo upload api

This commit is contained in:
wdvxdr 2022-02-21 23:44:49 +08:00
parent 19230b1511
commit c7f0aed1b7
No known key found for this signature in database
GPG Key ID: 703F8C071DE7A1B6
6 changed files with 80 additions and 108 deletions

View File

@ -791,6 +791,7 @@ func (bot *CQBot) CQSendGuildChannelMessage(guildID, channelID uint64, m gjson.R
func (bot *CQBot) uploadForwardElement(m gjson.Result, groupID int64) *message.ForwardElement {
ts := time.Now().Add(-time.Minute * 5)
fm := message.NewForwardMessage()
source := message.Source{SourceType: message.SourceGroup, PrimaryID: groupID}
var lazyUpload []func()
var wg sync.WaitGroup
@ -798,11 +799,22 @@ func (bot *CQBot) uploadForwardElement(m gjson.Result, groupID int64) *message.F
for i, elem := range elems {
iescape := i
switch o := elem.(type) {
case *LocalImageElement, *LocalVideoElement:
case *LocalVideoElement:
wg.Add(1)
lazyUpload = append(lazyUpload, func() {
defer wg.Done()
gm, err := bot.uploadMedia(o, groupID, true)
gm, err := bot.uploadLocalVideo(source, o)
if err != nil {
log.Warnf("警告: 群 %d %s上传失败: %v", groupID, o.Type().String(), err)
} else {
elems[iescape] = gm
}
})
case *LocalImageElement:
wg.Add(1)
lazyUpload = append(lazyUpload, func() {
defer wg.Done()
gm, err := bot.uploadLocalImage(source, o)
if err != nil {
log.Warnf("警告: 群 %d %s上传失败: %v", groupID, o.Type().String(), err)
} else {

View File

@ -129,8 +129,8 @@ func (bot *CQBot) OnEventPush(f func(e *Event)) {
bot.lock.Unlock()
}
// UploadLocalImageAsGroup 上传本地图片至群聊
func (bot *CQBot) UploadLocalImageAsGroup(groupCode int64, img *LocalImageElement) (i *message.GroupImageElement, err error) {
// uploadLocalImage 上传本地图片
func (bot *CQBot) uploadLocalImage(target message.Source, img *LocalImageElement) (i message.IMessageElement, err error) {
if img.File != "" {
f, err := os.Open(img.File)
if err != nil {
@ -142,16 +142,19 @@ func (bot *CQBot) UploadLocalImageAsGroup(groupCode int64, img *LocalImageElemen
if lawful, mime := base.IsLawfulImage(img.Stream); !lawful {
return nil, errors.New("image type error: " + mime)
}
i, err = bot.Client.UploadGroupImage(groupCode, img.Stream, 4)
if i != nil {
i, err = bot.Client.UploadImage(target, img.Stream, 4)
switch i := i.(type) {
case *message.GroupImageElement:
i.Flash = img.Flash
i.EffectID = img.EffectID
case *message.FriendImageElement:
i.Flash = img.Flash
}
return
}
// UploadLocalVideo 上传本地短视频至群聊
func (bot *CQBot) UploadLocalVideo(target message.Source, v *LocalVideoElement) (*message.ShortVideoElement, error) {
// uploadLocalVideo 上传本地短视频至群聊
func (bot *CQBot) uploadLocalVideo(target message.Source, v *LocalVideoElement) (*message.ShortVideoElement, error) {
video, err := os.Open(v.File)
if err != nil {
return nil, err
@ -160,55 +163,52 @@ func (bot *CQBot) UploadLocalVideo(target message.Source, v *LocalVideoElement)
return bot.Client.UploadShortVideo(target, video, v.thumb, 4)
}
// UploadLocalImageAsPrivate 上传本地图片至私聊
func (bot *CQBot) UploadLocalImageAsPrivate(userID int64, img *LocalImageElement) (i *message.FriendImageElement, err error) {
if img.File != "" {
f, err := os.Open(img.File)
func (bot *CQBot) uploadMedia(target message.Source, elements []message.IMessageElement) []message.IMessageElement {
var j int
for _, m := range elements {
raw := m // upload failed will make m nil, so copy it
var err error
switch e := m.(type) {
case *LocalImageElement:
m, err = bot.uploadLocalImage(target, e)
case *message.VoiceElement:
if target.SourceType == message.SourceGuildChannel {
continue // todo
}
m, err = bot.Client.UploadVoice(target, bytes.NewReader(e.Data))
case *LocalVideoElement:
m, err = bot.uploadLocalVideo(target, e)
}
if err != nil {
return nil, errors.Wrap(err, "open image error")
var source string
switch target.SourceType { // nolint:exhaustive
case message.SourceGroup:
source = "群"
case message.SourcePrivate:
source = "私聊"
case message.SourceGuildChannel:
source = "频道"
}
defer func() { _ = f.Close() }()
img.Stream = f
log.Warnf("警告: %s %d %s上传失败: %v", source, target.PrimaryID, raw.Type().String(), err)
continue
}
if lawful, mime := base.IsLawfulImage(img.Stream); !lawful {
return nil, errors.New("image type error: " + mime)
elements[j] = m
j++
}
i, err = bot.Client.UploadPrivateImage(userID, img.Stream)
if i != nil {
i.Flash = img.Flash
}
return
}
// UploadLocalImageAsGuildChannel 上传本地图片至频道
func (bot *CQBot) UploadLocalImageAsGuildChannel(guildID, channelID uint64, img *LocalImageElement) (*message.GuildImageElement, error) {
if img.File != "" {
f, err := os.Open(img.File)
if err != nil {
return nil, errors.Wrap(err, "open image error")
}
defer func() { _ = f.Close() }()
img.Stream = f
}
if lawful, mime := base.IsLawfulImage(img.Stream); !lawful {
return nil, errors.New("image type error: " + mime)
}
return bot.Client.GuildService.UploadGuildImage(guildID, channelID, img.Stream)
return elements[:j]
}
// SendGroupMessage 发送群消息
func (bot *CQBot) SendGroupMessage(groupID int64, m *message.SendingMessage) int32 {
newElem := make([]message.IMessageElement, 0, len(m.Elements))
group := bot.Client.FindGroup(groupID)
source := message.Source{
SourceType: message.SourceGroup,
PrimaryID: groupID,
}
m.Elements = bot.uploadMedia(source, m.Elements)
for _, e := range m.Elements {
switch i := e.(type) {
case *LocalImageElement, *message.VoiceElement, *LocalVideoElement:
i, err := bot.uploadMedia(i, groupID, true)
if err != nil {
log.Warnf("警告: 群 %d 消息%s上传失败: %v", groupID, e.Type().String(), err)
continue
}
e = i
case *PokeElement:
if group != nil {
if mem := group.FindMember(i.Target); mem != nil {
@ -247,15 +247,13 @@ func (bot *CQBot) SendGroupMessage(groupID int64, m *message.SendingMessage) int
// SendPrivateMessage 发送私聊消息
func (bot *CQBot) SendPrivateMessage(target int64, groupID int64, m *message.SendingMessage) int32 {
newElem := make([]message.IMessageElement, 0, len(m.Elements))
source := message.Source{
SourceType: message.SourcePrivate,
PrimaryID: target,
}
m.Elements = bot.uploadMedia(source, m.Elements)
for _, e := range m.Elements {
switch i := e.(type) {
case *LocalImageElement, *message.VoiceElement, *LocalVideoElement:
i, err := bot.uploadMedia(i, target, false)
if err != nil {
log.Warnf("警告: 私聊 %d 消息%s上传失败: %v", target, e.Type().String(), err)
continue
}
e = i
case *PokeElement:
bot.Client.SendFriendPoke(i.Target)
return 0
@ -344,33 +342,19 @@ func (bot *CQBot) SendPrivateMessage(target int64, groupID int64, m *message.Sen
// SendGuildChannelMessage 发送频道消息
func (bot *CQBot) SendGuildChannelMessage(guildID, channelID uint64, m *message.SendingMessage) string {
newElem := make([]message.IMessageElement, 0, len(m.Elements))
for _, e := range m.Elements {
switch i := e.(type) {
case *LocalImageElement:
n, err := bot.UploadLocalImageAsGuildChannel(guildID, channelID, i)
if err != nil {
log.Warnf("警告: 频道 %d 消息%s上传失败: %v", channelID, e.Type().String(), err)
continue
}
e = n
case *LocalVideoElement:
n, err := bot.UploadLocalVideo(message.Source{
source := message.Source{
SourceType: message.SourceGuildChannel,
PrimaryID: int64(guildID),
SecondaryID: int64(channelID),
}, i)
if err != nil {
log.Warnf("警告: 频道 %d 消息%s上传失败: %v", channelID, e.Type().String(), err)
continue
}
e = n
m.Elements = bot.uploadMedia(source, m.Elements)
for _, e := range m.Elements {
switch i := e.(type) {
case *message.MusicShareElement:
bot.Client.SendGuildMusicShare(guildID, channelID, i)
return "-1" // todo: fix this
case *LocalVoiceElement, *PokeElement:
case *message.VoiceElement, *PokeElement:
log.Warnf("警告: 频道暂不支持发送 %v 消息", i.Type().String())
continue
}
@ -575,28 +559,6 @@ func formatMemberName(mem *client.GroupMemberInfo) string {
return fmt.Sprintf("%s(%d)", mem.DisplayName(), mem.Uin)
}
func (bot *CQBot) uploadMedia(raw message.IMessageElement, target int64, group bool) (message.IMessageElement, error) {
switch m := raw.(type) {
case *LocalImageElement:
if group {
return bot.UploadLocalImageAsGroup(target, m)
}
return bot.UploadLocalImageAsPrivate(target, m)
case *message.VoiceElement:
if group {
return bot.Client.UploadGroupPtt(target, bytes.NewReader(m.Data))
}
return bot.Client.UploadPrivatePtt(target, bytes.NewReader(m.Data))
case *LocalVideoElement:
source := message.Source{
SourceType: message.SourceGroup,
PrimaryID: target,
}
return bot.UploadLocalVideo(source, m)
}
return nil, errors.New("unsupported message element type")
}
// encodeMessageID 临时先这样, 暂时用不上
func encodeMessageID(target int64, seq int32) string {
return hex.EncodeToString(binary.NewWriterF(func(w *binary.Writer) {

View File

@ -51,12 +51,6 @@ type LocalImageElement struct {
EffectID int32
}
// LocalVoiceElement 本地语音
type LocalVoiceElement struct {
message.VoiceElement
Stream io.ReadSeeker
}
// LocalVideoElement 本地视频
type LocalVideoElement struct {
File string
@ -85,7 +79,7 @@ func (e *PokeElement) Type() message.ElementType {
}
func replyID(r *message.ReplyElement, source message.Source) int32 {
id := int64(source.PrimaryID)
id := source.PrimaryID
seq := r.ReplySeq
if source.SourceType == message.SourcePrivate {
// 私聊似乎腾讯服务器有bug?
@ -1321,9 +1315,13 @@ func (bot *CQBot) makeShowPic(elem message.IMessageElement, source string, brief
if brief == "" {
brief = "[分享]我看到一张很赞的图片,分享给你,快来看!"
}
if _, ok := elem.(*LocalImageElement); ok {
if local, ok := elem.(*LocalImageElement); ok {
r := rand.Uint32()
e, err := bot.uploadMedia(elem, int64(r), group)
typ := message.SourceGroup
if !group {
typ = message.SourcePrivate
}
e, err := bot.uploadLocalImage(message.Source{SourceType: typ, PrimaryID: int64(r)}, local)
if err != nil {
log.Warnf("警告: 图片上传失败: %v", err)
return nil, err

2
go.mod
View File

@ -4,7 +4,7 @@ go 1.17
require (
github.com/Microsoft/go-winio v0.5.1
github.com/Mrs4s/MiraiGo v0.0.0-20220221093105-1e32793eef06
github.com/Mrs4s/MiraiGo v0.0.0-20220221153544-6b5e7d35f04d
github.com/RomiChan/websocket v1.4.3-0.20220123145318-307a86b127bc
github.com/fumiama/go-hide-param v0.1.4
github.com/gabriel-vasile/mimetype v1.4.0

4
go.sum
View File

@ -1,7 +1,7 @@
github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY=
github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Mrs4s/MiraiGo v0.0.0-20220221093105-1e32793eef06 h1:9V7AhNUPJ1vqLAoXjwLdpv06hJWs15UdgYbKaHww60s=
github.com/Mrs4s/MiraiGo v0.0.0-20220221093105-1e32793eef06/go.mod h1:T66Ua3SOfpJMx+DcfQxk95MeR8RmvAVmjYSkoQQ8nwI=
github.com/Mrs4s/MiraiGo v0.0.0-20220221153544-6b5e7d35f04d h1:qnots7MzDtJHOvHPRG60gehAw2pUPBGa0GKBsUQNjRM=
github.com/Mrs4s/MiraiGo v0.0.0-20220221153544-6b5e7d35f04d/go.mod h1:T66Ua3SOfpJMx+DcfQxk95MeR8RmvAVmjYSkoQQ8nwI=
github.com/RomiChan/protobuf v0.0.0-20220213164748-44b69c8bdec0 h1:8CK7Hg+CRGTFhpjvp5V+7wd8/TkuZ6fSuztLVV3bwoQ=
github.com/RomiChan/protobuf v0.0.0-20220213164748-44b69c8bdec0/go.mod h1:CKKOWC7mBxd36zxsCB1V8DTrwlTNRQvkSVbYqyUiGEE=
github.com/RomiChan/websocket v1.4.3-0.20220123145318-307a86b127bc h1:AAx50/fb/xS4lvsdQg+bFbGvqSDhyV1MF+p2PLCamZ0=

View File

@ -30,7 +30,7 @@ func EnsureBool(p interface{}, defaultVal bool) bool {
if !j.Exists() {
return defaultVal
}
switch j.Type {
switch j.Type { // nolint: exhaustive
case gjson.True:
return true
case gjson.False: