diff --git a/coolq/api.go b/coolq/api.go index 72d29b47d..db8673b87 100644 --- a/coolq/api.go +++ b/coolq/api.go @@ -896,7 +896,7 @@ func (bot *CQBot) uploadForwardElement(m gjson.Result, target int64, sourceType SenderId: m.GetAttribute().SenderUin, SenderName: m.GetAttribute().SenderName, Time: int32(msgTime), - Message: resolveElement(bot.ConvertContentMessage(m.GetContent(), mSource)), + Message: resolveElement(bot.ConvertContentMessage(m.GetContent(), mSource, false)), } } log.Warnf("警告: 引用消息 %v 错误或数据库未开启.", e.Get("data.id").Str) @@ -971,7 +971,10 @@ func (bot *CQBot) CQSendGroupForwardMessage(groupID int64, m gjson.Result) globa if m.Type != gjson.JSON { return Failed(100) } - + source := message.Source{ + SourceType: message.SourcePrivate, + PrimaryID: 0, + } fe := bot.uploadForwardElement(m, groupID, message.SourceGroup) if fe == nil { return Failed(100, "EMPTY_NODES", "未找到任何可发送的合并转发信息") @@ -981,7 +984,7 @@ func (bot *CQBot) CQSendGroupForwardMessage(groupID int64, m gjson.Result) globa log.Warnf("合并转发(群)消息发送失败: 账号可能被风控.") return Failed(100, "SEND_MSG_API_ERROR", "请参考 go-cqhttp 端输出") } - mid := bot.InsertGroupMessage(ret) + mid := bot.InsertGroupMessage(ret, source) log.Infof("发送群 %v(%v) 的合并转发消息: %v (%v)", groupID, groupID, limitedString(m.String()), mid) return OK(global.MSG{ "message_id": mid, @@ -1695,7 +1698,7 @@ func (bot *CQBot) CQGetMessage(messageID int32) global.MSG { } o.Content = append(o.Content, elem) } - m["message"] = ToFormattedMessage(bot.ConvertContentMessage(o.Content, message.SourceGroup), message.Source{SourceType: message.SourceGroup, PrimaryID: o.GroupCode}) + m["message"] = ToFormattedMessage(bot.ConvertContentMessage(o.Content, message.SourceGroup, false), message.Source{SourceType: message.SourceGroup, PrimaryID: o.GroupCode}) case *db.StoredPrivateMessage: if o.QuotedInfo != nil { elem := global.MSG{ @@ -1706,7 +1709,7 @@ func (bot *CQBot) CQGetMessage(messageID int32) global.MSG { } o.Content = append(o.Content, elem) } - m["message"] = ToFormattedMessage(bot.ConvertContentMessage(o.Content, message.SourcePrivate), message.Source{SourceType: message.SourcePrivate}) + m["message"] = ToFormattedMessage(bot.ConvertContentMessage(o.Content, message.SourcePrivate, false), message.Source{SourceType: message.SourcePrivate}) } return OK(m) } @@ -1766,7 +1769,7 @@ func (bot *CQBot) CQGetGuildMessage(messageID string, noCache bool) global.MSG { "tiny_id": fU64(channelMsgByDB.Attribute.SenderTinyID), "nickname": channelMsgByDB.Attribute.SenderName, } - m["message"] = ToFormattedMessage(bot.ConvertContentMessage(channelMsgByDB.Content, message.SourceGuildChannel), source) + m["message"] = ToFormattedMessage(bot.ConvertContentMessage(channelMsgByDB.Content, message.SourceGuildChannel, false), source) } case message.SourceGuildDirect: // todo(mrs4s): 支持 direct 消息 @@ -1809,10 +1812,14 @@ func (bot *CQBot) CQGetGroupMessageHistory(groupID int64, seq int64) global.MSG log.Warnf("获取群历史消息失败: %v", err) return Failed(100, "MESSAGES_API_ERROR", err.Error()) } + source := message.Source{ + SourceType: message.SourcePrivate, + PrimaryID: 0, + } ms := make([]*event, 0, len(msg)) for _, m := range msg { bot.checkMedia(m.Elements, groupID) - id := bot.InsertGroupMessage(m) + id := bot.InsertGroupMessage(m, source) t := bot.formatGroupMessage(m) t.Others["message_id"] = id ms = append(ms, t) diff --git a/coolq/bot.go b/coolq/bot.go index 512a1e684..e2e323146 100644 --- a/coolq/bot.go +++ b/coolq/bot.go @@ -288,7 +288,7 @@ func (bot *CQBot) SendGroupMessage(groupID int64, m *message.SendingMessage) (in log.Warnf("警告: 群 %v 富文本消息发送失败: %v", groupID, err) return -1, errors.Wrap(err, "send group music share error") } - return bot.InsertGroupMessage(ret), nil + return bot.InsertGroupMessage(ret, source), nil case *message.AtElement: if i.Target == 0 && group.SelfPermission() == client.Member { e = message.NewText("@全体成员") @@ -307,7 +307,7 @@ func (bot *CQBot) SendGroupMessage(groupID int64, m *message.SendingMessage) (in log.Warnf("群消息发送失败: 账号可能被风控.") return -1, errors.New("send group message failed: blocked by server") } - return bot.InsertGroupMessage(ret), nil + return bot.InsertGroupMessage(ret, source), nil } // SendPrivateMessage 发送私聊消息 @@ -357,7 +357,7 @@ func (bot *CQBot) SendPrivateMessage(target int64, groupID int64, m *message.Sen case bot.Client.FindFriend(target) != nil: // 双向好友 msg := bot.Client.SendPrivateMessage(target, m) if msg != nil { - id = bot.InsertPrivateMessage(msg) + id = bot.InsertPrivateMessage(msg, source) } case ok || groupID != 0: // 临时会话 if !base.AllowTempSession { @@ -395,7 +395,7 @@ func (bot *CQBot) SendPrivateMessage(target int64, groupID int64, m *message.Sen case unidirectionalFriendExists(): // 单向好友 msg := bot.Client.SendPrivateMessage(target, m) if msg != nil { - id = bot.InsertPrivateMessage(msg) + id = bot.InsertPrivateMessage(msg, source) } default: nickname := "Unknown" @@ -444,7 +444,7 @@ func (bot *CQBot) SendGuildChannelMessage(guildID, channelID uint64, m *message. } // InsertGroupMessage 群聊消息入数据库 -func (bot *CQBot) InsertGroupMessage(m *message.GroupMessage) int32 { +func (bot *CQBot) InsertGroupMessage(m *message.GroupMessage, source message.Source) int32 { t := &message.SendingMessage{Elements: m.Elements} replyElem := t.FirstOrNil(func(e message.IMessageElement) bool { _, ok := e.(*message.ReplyElement) @@ -468,7 +468,7 @@ func (bot *CQBot) InsertGroupMessage(m *message.GroupMessage) int32 { } return "" }(), - Content: ToMessageContent(m.Elements), + Content: ToMessageContent(m.Elements, source), } if replyElem != nil { reply := replyElem.(*message.ReplyElement) @@ -476,7 +476,7 @@ func (bot *CQBot) InsertGroupMessage(m *message.GroupMessage) int32 { msg.QuotedInfo = &db.QuotedInfo{ PrevID: encodeMessageID(m.GroupCode, reply.ReplySeq), PrevGlobalID: db.ToGlobalID(m.GroupCode, reply.ReplySeq), - QuotedContent: ToMessageContent(reply.Elements), + QuotedContent: ToMessageContent(reply.Elements, source), } } if err := db.InsertGroupMessage(msg); err != nil { @@ -487,7 +487,7 @@ func (bot *CQBot) InsertGroupMessage(m *message.GroupMessage) int32 { } // InsertPrivateMessage 私聊消息入数据库 -func (bot *CQBot) InsertPrivateMessage(m *message.PrivateMessage) int32 { +func (bot *CQBot) InsertPrivateMessage(m *message.PrivateMessage, source message.Source) int32 { t := &message.SendingMessage{Elements: m.Elements} replyElem := t.FirstOrNil(func(e message.IMessageElement) bool { _, ok := e.(*message.ReplyElement) @@ -511,7 +511,7 @@ func (bot *CQBot) InsertPrivateMessage(m *message.PrivateMessage) int32 { return m.Sender.Uin }(), TargetUin: m.Target, - Content: ToMessageContent(m.Elements), + Content: ToMessageContent(m.Elements, source), } if replyElem != nil { reply := replyElem.(*message.ReplyElement) @@ -519,7 +519,7 @@ func (bot *CQBot) InsertPrivateMessage(m *message.PrivateMessage) int32 { msg.QuotedInfo = &db.QuotedInfo{ PrevID: encodeMessageID(reply.Sender, reply.ReplySeq), PrevGlobalID: db.ToGlobalID(reply.Sender, reply.ReplySeq), - QuotedContent: ToMessageContent(reply.Elements), + QuotedContent: ToMessageContent(reply.Elements, source), } } if err := db.InsertPrivateMessage(msg); err != nil { @@ -562,6 +562,10 @@ func (bot *CQBot) InsertTempMessage(target int64, m *message.TempMessage) int32 // InsertGuildChannelMessage 频道消息入数据库 func (bot *CQBot) InsertGuildChannelMessage(m *message.GuildChannelMessage) string { id := encodeGuildMessageID(m.GuildId, m.ChannelId, m.Id, message.SourceGuildChannel) + source := message.Source{ + SourceType: message.SourceGuildChannel, + PrimaryID: int64(m.Sender.TinyId), + } msg := &db.StoredGuildChannelMessage{ ID: id, Attribute: &db.StoredGuildMessageAttribute{ @@ -573,7 +577,7 @@ func (bot *CQBot) InsertGuildChannelMessage(m *message.GuildChannelMessage) stri }, GuildID: m.GuildId, ChannelID: m.ChannelId, - Content: ToMessageContent(m.Elements), + Content: ToMessageContent(m.Elements, source), } if err := db.InsertGuildChannelMessage(msg); err != nil { log.Warnf("记录聊天数据时出现错误: %v", err) diff --git a/coolq/cqcode.go b/coolq/cqcode.go index 63972809a..8c37f175d 100644 --- a/coolq/cqcode.go +++ b/coolq/cqcode.go @@ -263,13 +263,17 @@ func toElements(e []message.IMessageElement, source message.Source) (r []msg.Ele return } -// ToMessageContent 将消息转换成 Content. 忽略 Reply // 不同于 onebot 的 Array Message, 此函数转换出来的 Content 的 data 段为实际类型 // 方便数据库查询 -func ToMessageContent(e []message.IMessageElement) (r []global.MSG) { +func ToMessageContent(e []message.IMessageElement, source message.Source) (r []global.MSG) { for _, elem := range e { var m global.MSG switch o := elem.(type) { + case *message.ReplyElement: + m = global.MSG{ + "type": "reply", + "data": global.MSG{"id": replyID(o, source)}, + } case *message.TextElement: m = global.MSG{ "type": "text", @@ -384,7 +388,7 @@ func ToMessageContent(e []message.IMessageElement) (r []global.MSG) { // ConvertStringMessage 将消息字符串转为消息元素数组 func (bot *CQBot) ConvertStringMessage(spec *onebot.Spec, raw string, sourceType message.SourceType) (r []message.IMessageElement) { elems := msg.ParseString(raw) - return bot.ConvertElements(spec, elems, sourceType) + return bot.ConvertElements(spec, elems, sourceType, true) } // ConvertObjectMessage 将消息JSON对象转为消息元素数组 @@ -393,11 +397,11 @@ func (bot *CQBot) ConvertObjectMessage(spec *onebot.Spec, m gjson.Result, source return bot.ConvertStringMessage(spec, m.Str, sourceType) } elems := msg.ParseObject(m) - return bot.ConvertElements(spec, elems, sourceType) + return bot.ConvertElements(spec, elems, sourceType, false) } // ConvertContentMessage 将数据库用的 content 转换为消息元素数组 -func (bot *CQBot) ConvertContentMessage(content []global.MSG, sourceType message.SourceType) (r []message.IMessageElement) { +func (bot *CQBot) ConvertContentMessage(content []global.MSG, sourceType message.SourceType, noReply bool) (r []message.IMessageElement) { elems := make([]msg.Element, len(content)) for i, v := range content { elem := msg.Element{Type: v["type"].(string)} @@ -407,13 +411,16 @@ func (bot *CQBot) ConvertContentMessage(content []global.MSG, sourceType message } elems[i] = elem } - return bot.ConvertElements(onebot.V11, elems, sourceType) + return bot.ConvertElements(onebot.V11, elems, sourceType, noReply) } // ConvertElements 将解码后的消息数组转换为MiraiGo表示 -func (bot *CQBot) ConvertElements(spec *onebot.Spec, elems []msg.Element, sourceType message.SourceType) (r []message.IMessageElement) { +func (bot *CQBot) ConvertElements(spec *onebot.Spec, elems []msg.Element, sourceType message.SourceType, noReply bool) (r []message.IMessageElement) { var replyCount int for _, elem := range elems { + if noReply && elem.Type == "reply" { + continue + } me, err := bot.ConvertElement(spec, elem, sourceType) if err != nil { // TODO: don't use cqcode format @@ -497,7 +504,7 @@ func (bot *CQBot) reply(spec *onebot.Spec, elem msg.Element, sourceType message. ReplySeq: org.GetAttribute().MessageSeq, Sender: org.GetAttribute().SenderUin, Time: int32(org.GetAttribute().Timestamp), - Elements: bot.ConvertContentMessage(org.GetContent(), sourceType), + Elements: bot.ConvertContentMessage(org.GetContent(), sourceType, true), } default: diff --git a/coolq/event.go b/coolq/event.go index 605ea3ec8..61e763f48 100644 --- a/coolq/event.go +++ b/coolq/event.go @@ -79,7 +79,7 @@ func (bot *CQBot) privateMessageEvent(_ *client.QQClient, m *message.PrivateMess PrimaryID: m.Sender.Uin, } cqm := toStringMessage(m.Elements, source) - id := bot.InsertPrivateMessage(m) + id := bot.InsertPrivateMessage(m, source) log.Infof("收到好友 %v(%v) 的消息: %v (%v)", m.Sender.DisplayName(), m.Sender.Uin, cqm, id) typ := "message/private/friend" if m.Sender.Uin == bot.Client.Uin { @@ -126,7 +126,7 @@ func (bot *CQBot) groupMessageEvent(c *client.QQClient, m *message.GroupMessage) PrimaryID: m.GroupCode, } cqm := toStringMessage(m.Elements, source) - id := bot.InsertGroupMessage(m) + id := bot.InsertGroupMessage(m, source) log.Infof("收到群 %v(%v) 内 %v(%v) 的消息: %v (%v)", m.GroupName, m.GroupCode, m.Sender.DisplayName(), m.Sender.Uin, cqm, id) gm := bot.formatGroupMessage(m) if gm == nil {