diff --git a/coolq/bot.go b/coolq/bot.go index 97dc448..78cfd68 100644 --- a/coolq/bot.go +++ b/coolq/bot.go @@ -5,6 +5,7 @@ import ( "encoding/hex" "encoding/json" "fmt" + "github.com/segmentio/asm/base64" "io" "os" "path" @@ -512,6 +513,34 @@ func (bot *CQBot) InsertTempMessage(target int64, m *message.TempMessage) int32 } */ +// InsertGuildChannelMessage 频道消息入数据库 +func (bot *CQBot) InsertGuildChannelMessage(m *message.GuildChannelMessage) string { + id := base64.StdEncoding.EncodeToString(binary.NewWriterF(func(w *binary.Writer) { + w.WriteUInt64(m.GuildId) + w.WriteUInt64(m.ChannelId) + w.WriteUInt64(m.Id) + w.WriteUInt64(m.InternalId) + })) + msg := &db.StoredGuildChannelMessage{ + ID: id, + Attribute: &db.StoredGuildMessageAttribute{ + MessageSeq: m.Id, + InternalID: m.InternalId, + SenderTinyID: m.Sender.TinyId, + SenderName: m.Sender.Nickname, + Timestamp: m.Time, + }, + GuildID: m.GuildId, + ChannelID: m.ChannelId, + Content: ToMessageContent(m.Elements), + } + if err := db.InsertGuildChannelMessage(msg); err != nil { + log.Warnf("记录聊天数据时出现错误: %v", err) + return "" + } + return msg.ID +} + // Release 释放Bot实例 func (bot *CQBot) Release() { diff --git a/db/database.go b/db/database.go index 21445e2..6495f82 100644 --- a/db/database.go +++ b/db/database.go @@ -19,11 +19,15 @@ type ( GetGroupMessageByGlobalID(int32) (*StoredGroupMessage, error) // GetPrivateMessageByGlobalID 通过 GlobalID 来获取私聊消息 GetPrivateMessageByGlobalID(int32) (*StoredPrivateMessage, error) + // GetGuildChannelMessageByID 通过 ID 来获取频道消息 + GetGuildChannelMessageByID(string) (*StoredGuildChannelMessage, error) // InsertGroupMessage 向数据库写入新的群消息 InsertGroupMessage(*StoredGroupMessage) error // InsertPrivateMessage 向数据库写入新的私聊消息 InsertPrivateMessage(*StoredPrivateMessage) error + // InsertGuildChannelMessage 向数据库写入新的频道消息 + InsertGuildChannelMessage(*StoredGuildChannelMessage) error } StoredMessage interface { @@ -58,6 +62,16 @@ type ( Content []global.MSG `bson:"content"` } + // StoredGuildChannelMessage 持久化频道消息 + StoredGuildChannelMessage struct { + ID string `bson:"_id"` + Attribute *StoredGuildMessageAttribute `bson:"attribute"` + GuildID uint64 `bson:"guildId"` + ChannelID uint64 `bson:"channelId"` + QuotedInfo *QuotedInfo `bson:"quotedInfo"` + Content []global.MSG `bson:"content"` + } + // StoredMessageAttribute 持久化消息属性 StoredMessageAttribute struct { MessageSeq int32 `bson:"messageSeq"` @@ -67,6 +81,15 @@ type ( Timestamp int64 `bson:"timestamp"` } + // StoredGuildMessageAttribute 持久化频道消息属性 + StoredGuildMessageAttribute struct { + MessageSeq uint64 `bson:"messageSeq"` + InternalID uint64 `bson:"internalId"` + SenderTinyID uint64 `bson:"senderTinyId"` + SenderName string `bson:"senderName"` + Timestamp int64 `bson:"timestamp"` + } + // QuotedInfo 引用回复 QuotedInfo struct { PrevID string `bson:"prevId"` diff --git a/db/leveldb/leveldb.go b/db/leveldb/leveldb.go index 3e787e4..9955c1f 100644 --- a/db/leveldb/leveldb.go +++ b/db/leveldb/leveldb.go @@ -3,6 +3,7 @@ package leveldb import ( "bytes" "encoding/gob" + "github.com/Mrs4s/MiraiGo/utils" "path" "github.com/Mrs4s/MiraiGo/binary" @@ -21,16 +22,19 @@ type LevelDBImpl struct { } const ( - group byte = 0x0 - private byte = 0x1 + group byte = 0x0 + private byte = 0x1 + guildChannel byte = 0x2 ) func init() { gob.Register(db.StoredMessageAttribute{}) + gob.Register(db.StoredGuildMessageAttribute{}) gob.Register(db.QuotedInfo{}) gob.Register(global.MSG{}) gob.Register(db.StoredGroupMessage{}) gob.Register(db.StoredPrivateMessage{}) + gob.Register(db.StoredGuildChannelMessage{}) db.Register("leveldb", func(node yaml.Node) db.Database { conf := new(config.LevelDBConfig) @@ -102,6 +106,24 @@ func (ldb *LevelDBImpl) GetPrivateMessageByGlobalID(id int32) (*db.StoredPrivate return p, nil } +func (ldb *LevelDBImpl) GetGuildChannelMessageByID(id string) (*db.StoredGuildChannelMessage, error) { + v, err := ldb.db.Get([]byte(id), nil) + if err != nil { + return nil, errors.Wrap(err, "get value error") + } + r := binary.NewReader(v) + switch r.ReadByte() { + case guildChannel: + g := &db.StoredGuildChannelMessage{} + if err = gob.NewDecoder(bytes.NewReader(r.ReadAvailable())).Decode(g); err != nil { + return nil, errors.Wrap(err, "decode message error") + } + return g, nil + default: + return nil, errors.New("unknown message flag") + } +} + func (ldb *LevelDBImpl) InsertGroupMessage(msg *db.StoredGroupMessage) error { buf := global.NewBuffer() defer global.PutBuffer(buf) @@ -127,3 +149,16 @@ func (ldb *LevelDBImpl) InsertPrivateMessage(msg *db.StoredPrivateMessage) error }), nil) return errors.Wrap(err, "put data error") } + +func (ldb *LevelDBImpl) InsertGuildChannelMessage(msg *db.StoredGuildChannelMessage) error { + buf := global.NewBuffer() + defer global.PutBuffer(buf) + if err := gob.NewEncoder(buf).Encode(msg); err != nil { + return errors.Wrap(err, "encode message error") + } + err := ldb.db.Put(utils.S2B(msg.ID), binary.NewWriterF(func(w *binary.Writer) { + w.WriteByte(guildChannel) + w.Write(buf.Bytes()) + }), nil) + return errors.Wrap(err, "put data error") +} diff --git a/db/mongodb/mongodb.go b/db/mongodb/mongodb.go index 6387d5a..9528743 100644 --- a/db/mongodb/mongodb.go +++ b/db/mongodb/mongodb.go @@ -20,8 +20,9 @@ type MongoDBImpl struct { } const ( - MongoGroupMessageCollection = "group-messages" - MongoPrivateMessageCollection = "private-messages" + MongoGroupMessageCollection = "group-messages" + MongoPrivateMessageCollection = "private-messages" + MongoGuildChannelMessageCollection = "guild-channel-messages" ) func init() { @@ -72,6 +73,15 @@ func (m *MongoDBImpl) GetPrivateMessageByGlobalID(id int32) (*db.StoredPrivateMe return &ret, nil } +func (m *MongoDBImpl) GetGuildChannelMessageByID(id string) (*db.StoredGuildChannelMessage, error) { + coll := m.mongo.Collection(MongoGuildChannelMessageCollection) + var ret db.StoredGuildChannelMessage + if err := coll.FindOne(context.Background(), bson.D{{"_id", id}}).Decode(&ret); err != nil { + return nil, errors.Wrap(err, "query error") + } + return &ret, nil +} + func (m *MongoDBImpl) InsertGroupMessage(msg *db.StoredGroupMessage) error { coll := m.mongo.Collection(MongoGroupMessageCollection) _, err := coll.InsertOne(context.Background(), msg) @@ -83,3 +93,9 @@ func (m *MongoDBImpl) InsertPrivateMessage(msg *db.StoredPrivateMessage) error { _, err := coll.InsertOne(context.Background(), msg) return errors.Wrap(err, "insert error") } + +func (m *MongoDBImpl) InsertGuildChannelMessage(msg *db.StoredGuildChannelMessage) error { + coll := m.mongo.Collection(MongoGuildChannelMessageCollection) + _, err := coll.InsertOne(context.Background(), msg) + return errors.Wrap(err, "insert error") +} diff --git a/db/multidb.go b/db/multidb.go index 741ebf7..83c086f 100644 --- a/db/multidb.go +++ b/db/multidb.go @@ -86,3 +86,12 @@ func InsertPrivateMessage(m *StoredPrivateMessage) error { } return nil } + +func InsertGuildChannelMessage(m *StoredGuildChannelMessage) error { + for _, b := range backends { + if err := b.InsertGuildChannelMessage(m); err != nil { + return errors.Wrap(err, "insert message to backend error") + } + } + return nil +}