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:
parent
19230b1511
commit
c7f0aed1b7
16
coolq/api.go
16
coolq/api.go
@ -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 {
|
||||
|
144
coolq/bot.go
144
coolq/bot.go
@ -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) {
|
||||
|
@ -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
2
go.mod
@ -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
4
go.sum
@ -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=
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user