Skip to content

Commit

Permalink
fix: Mrs4s#2112 add CQ code reply to db and solve recursive reply res…
Browse files Browse the repository at this point in the history
…olve (Mrs4s#2115)

Co-authored-by: 源文雨 <[email protected]>
  • Loading branch information
YttriumC and fumiama authored Aug 1, 2023
1 parent 75ad7aa commit 14539ad
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 28 deletions.
21 changes: 14 additions & 7 deletions coolq/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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", "未找到任何可发送的合并转发信息")
Expand All @@ -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,
Expand Down Expand Up @@ -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{
Expand All @@ -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)
}
Expand Down Expand Up @@ -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 消息
Expand Down Expand Up @@ -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)
Expand Down
26 changes: 15 additions & 11 deletions coolq/bot.go
Original file line number Diff line number Diff line change
Expand Up @@ -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("@全体成员")
Expand All @@ -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 发送私聊消息
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand All @@ -468,15 +468,15 @@ 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)
msg.SubType = "quote"
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 {
Expand All @@ -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)
Expand All @@ -511,15 +511,15 @@ 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)
msg.SubType = "quote"
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 {
Expand Down Expand Up @@ -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{
Expand All @@ -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)
Expand Down
23 changes: 15 additions & 8 deletions coolq/cqcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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对象转为消息元素数组
Expand All @@ -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)}
Expand All @@ -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
Expand Down Expand Up @@ -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:
Expand Down
4 changes: 2 additions & 2 deletions coolq/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit 14539ad

Please sign in to comment.