feat: add `DiscordMessageAttachment` types and APIs
This adds a new `DiscordMessageAttachment` type which is part of `DiscordMessage`. Along with that type, there's also a new database table for `discord_message_attachments` and corresponding persistence APIs. This commit also changes how chat messages are retrieved. Here's why: `DiscordMessage` can have multiple `DiscordMessageAttachment`. A chat message can have a `DiscordMessage`. Because we're `LEFT JOIN`'ing the discord message attachments into the chat messages, there's a possibility of multiple rows per message. Hence, this commit ensures we collect queried discord message attachments on chat messages.
This commit is contained in:
parent
c01ad05525
commit
b01a861e8e
|
@ -820,7 +820,7 @@ func _1664392661_add_third_party_id_to_waku_messagesUpSql() (*asset, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1664392661_add_third_party_id_to_waku_messages.up.sql", size: 70, mode: os.FileMode(0664), modTime: time.Unix(1664392691, 0)}
|
||||
info := bindataFileInfo{name: "1664392661_add_third_party_id_to_waku_messages.up.sql", size: 70, mode: os.FileMode(0664), modTime: time.Unix(1664438057, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xfd, 0x67, 0x66, 0x9e, 0x66, 0x74, 0xce, 0x1c, 0xb, 0x1b, 0x9d, 0xd5, 0xfc, 0x65, 0xe, 0x83, 0x90, 0x4c, 0x61, 0x4e, 0x6b, 0xe7, 0x86, 0xbe, 0x36, 0x4f, 0x91, 0x36, 0x4, 0x47, 0x7b, 0x82}}
|
||||
return a, nil
|
||||
}
|
||||
|
|
|
@ -91,6 +91,12 @@ const (
|
|||
OutgoingStatusDelivered = "delivered"
|
||||
)
|
||||
|
||||
type Messages []*Message
|
||||
|
||||
func (m Messages) GetClock(i int) uint64 {
|
||||
return m[i].Clock
|
||||
}
|
||||
|
||||
// Message represents a message record in the database,
|
||||
// more specifically in user_messages table.
|
||||
type Message struct {
|
||||
|
|
|
@ -8,6 +8,12 @@ import (
|
|||
"github.com/status-im/status-go/protocol/protobuf"
|
||||
)
|
||||
|
||||
type PinnedMessages []*PinnedMessage
|
||||
|
||||
func (m PinnedMessages) GetClock(i int) uint64 {
|
||||
return m[i].Message.Clock
|
||||
}
|
||||
|
||||
type PinMessage struct {
|
||||
protobuf.PinMessage
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/status-im/status-go/protocol/common"
|
||||
|
@ -22,6 +23,8 @@ LEFT JOIN discord_messages dm
|
|||
ON m1.discord_message_id = dm.id
|
||||
LEFT JOIN discord_message_authors dm_author
|
||||
ON dm.author_id = dm_author.id
|
||||
LEFT JOIN discord_message_attachments dm_attachment
|
||||
ON dm.id = dm_attachment.discord_message_id
|
||||
`
|
||||
|
||||
var cursor = "substr('0000000000000000000000000000000000000000000000000000000000000000' || m1.clock_value, -64, 64) || m1.id"
|
||||
|
@ -143,6 +146,11 @@ func (db sqlitePersistence) tableUserMessagesAllFieldsJoin() string {
|
|||
COALESCE(dm_author.discriminator, ""),
|
||||
COALESCE(dm_author.nickname, ""),
|
||||
COALESCE(dm_author.avatar_url, ""),
|
||||
COALESCE(dm_attachment.id, ""),
|
||||
COALESCE(dm_attachment.discord_message_id, ""),
|
||||
COALESCE(dm_attachment.url, ""),
|
||||
COALESCE(dm_attachment.file_name, ""),
|
||||
COALESCE(dm_attachment.content_type, ""),
|
||||
m2.source,
|
||||
m2.text,
|
||||
m2.parsed_text,
|
||||
|
@ -187,10 +195,13 @@ func (db sqlitePersistence) tableUserMessagesScanAllFields(row scanner, message
|
|||
audio := &protobuf.AudioMessage{}
|
||||
image := &protobuf.ImageMessage{}
|
||||
discordMessage := &protobuf.DiscordMessage{
|
||||
Author: &protobuf.DiscordMessageAuthor{},
|
||||
Reference: &protobuf.DiscordMessageReference{},
|
||||
Author: &protobuf.DiscordMessageAuthor{},
|
||||
Reference: &protobuf.DiscordMessageReference{},
|
||||
Attachments: []*protobuf.DiscordMessageAttachment{},
|
||||
}
|
||||
|
||||
attachment := &protobuf.DiscordMessageAttachment{}
|
||||
|
||||
args := []interface{}{
|
||||
&message.ID,
|
||||
&message.WhisperTimestamp,
|
||||
|
@ -245,6 +256,11 @@ func (db sqlitePersistence) tableUserMessagesScanAllFields(row scanner, message
|
|||
&discordMessage.Author.Discriminator,
|
||||
&discordMessage.Author.Nickname,
|
||||
&discordMessage.Author.AvatarUrl,
|
||||
&attachment.Id,
|
||||
&attachment.MessageId,
|
||||
&attachment.Url,
|
||||
&attachment.FileName,
|
||||
&attachment.ContentType,
|
||||
"edFrom,
|
||||
"edText,
|
||||
"edParsedText,
|
||||
|
@ -313,6 +329,10 @@ func (db sqlitePersistence) tableUserMessagesScanAllFields(row scanner, message
|
|||
}
|
||||
}
|
||||
|
||||
if attachment.Id != "" {
|
||||
discordMessage.Attachments = append(discordMessage.Attachments, attachment)
|
||||
}
|
||||
|
||||
switch message.ContentType {
|
||||
case protobuf.ChatMessage_STICKER:
|
||||
message.Payload = &protobuf.ChatMessage_Sticker{Sticker: sticker}
|
||||
|
@ -365,8 +385,9 @@ func (db sqlitePersistence) tableUserMessagesAllValues(message *common.Message)
|
|||
discordMessage := message.GetDiscordMessage()
|
||||
if discordMessage == nil {
|
||||
discordMessage = &protobuf.DiscordMessage{
|
||||
Author: &protobuf.DiscordMessageAuthor{},
|
||||
Reference: &protobuf.DiscordMessageReference{},
|
||||
Author: &protobuf.DiscordMessageAuthor{},
|
||||
Reference: &protobuf.DiscordMessageReference{},
|
||||
Attachments: make([]*protobuf.DiscordMessageAttachment, 0),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -459,25 +480,17 @@ func (db sqlitePersistence) messageByID(tx *sql.Tx, id string) (*common.Message,
|
|||
}()
|
||||
}
|
||||
|
||||
var message common.Message
|
||||
|
||||
query := db.buildMessagesQuery("WHERE m1.id = ?")
|
||||
row := tx.QueryRow(query, id)
|
||||
err = db.tableUserMessagesScanAllFields(row, &message)
|
||||
switch err {
|
||||
case sql.ErrNoRows:
|
||||
return nil, common.ErrRecordNotFound
|
||||
case nil:
|
||||
return &message, nil
|
||||
default:
|
||||
rows, err := tx.Query(query, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
return getMessageFromScanRows(db, rows)
|
||||
}
|
||||
|
||||
func (db sqlitePersistence) MessageByCommandID(chatID, id string) (*common.Message, error) {
|
||||
|
||||
var message common.Message
|
||||
|
||||
where := `WHERE
|
||||
m1.command_id = ?
|
||||
AND
|
||||
|
@ -485,16 +498,12 @@ func (db sqlitePersistence) MessageByCommandID(chatID, id string) (*common.Messa
|
|||
ORDER BY m1.clock_value DESC
|
||||
LIMIT 1`
|
||||
query := db.buildMessagesQuery(where)
|
||||
row := db.db.QueryRow(query, id, chatID)
|
||||
err := db.tableUserMessagesScanAllFields(row, &message)
|
||||
switch err {
|
||||
case sql.ErrNoRows:
|
||||
return nil, common.ErrRecordNotFound
|
||||
case nil:
|
||||
return &message, nil
|
||||
default:
|
||||
rows, err := db.db.Query(query, id, chatID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
return getMessageFromScanRows(db, rows)
|
||||
}
|
||||
|
||||
func (db sqlitePersistence) MessageByID(id string) (*common.Message, error) {
|
||||
|
@ -552,17 +561,7 @@ func (db sqlitePersistence) MessagesByIDs(ids []string) ([]*common.Message, erro
|
|||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var result []*common.Message
|
||||
for rows.Next() {
|
||||
var message common.Message
|
||||
if err := db.tableUserMessagesScanAllFields(rows, &message); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, &message)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
return getMessagesFromScanRows(db, rows)
|
||||
}
|
||||
|
||||
// MessageByChatID returns all messages for a given chatID in descending order.
|
||||
|
@ -597,20 +596,9 @@ func (db sqlitePersistence) MessageByChatID(chatID string, currCursor string, li
|
|||
}
|
||||
defer rows.Close()
|
||||
|
||||
var (
|
||||
result []*common.Message
|
||||
cursors []string
|
||||
)
|
||||
for rows.Next() {
|
||||
var (
|
||||
message common.Message
|
||||
cursor string
|
||||
)
|
||||
if err := db.tableUserMessagesScanAllFields(rows, &message, &cursor); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
result = append(result, &message)
|
||||
cursors = append(cursors, cursor)
|
||||
result, cursors, err := getMessagesAndCursorsFromScanRows(db, rows)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
var newCursor string
|
||||
|
@ -670,20 +658,9 @@ func (db sqlitePersistence) PendingContactRequests(currCursor string, limit int)
|
|||
}
|
||||
defer rows.Close()
|
||||
|
||||
var (
|
||||
result []*common.Message
|
||||
cursors []string
|
||||
)
|
||||
for rows.Next() {
|
||||
var (
|
||||
message common.Message
|
||||
cursor string
|
||||
)
|
||||
if err := db.tableUserMessagesScanAllFields(rows, &message, &cursor); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
result = append(result, &message)
|
||||
cursors = append(cursors, cursor)
|
||||
result, cursors, err := getMessagesAndCursorsFromScanRows(db, rows)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
var newCursor string
|
||||
|
@ -785,22 +762,7 @@ func (db sqlitePersistence) AllMessageByChatIDWhichMatchTerm(chatID string, sear
|
|||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var (
|
||||
result []*common.Message
|
||||
)
|
||||
for rows.Next() {
|
||||
var (
|
||||
message common.Message
|
||||
cursor string
|
||||
)
|
||||
if err := db.tableUserMessagesScanAllFields(rows, &message, &cursor); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, &message)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
return getMessagesFromScanRows(db, rows)
|
||||
}
|
||||
|
||||
// AllMessagesFromChatsAndCommunitiesWhichMatchTerm returns all messages which match the search
|
||||
|
@ -862,29 +824,13 @@ func (db sqlitePersistence) AllMessagesFromChatsAndCommunitiesWhichMatchTerm(com
|
|||
ORDER BY cursor DESC`, finalCond)
|
||||
|
||||
finalQuery := db.buildMessagesQueryWithAdditionalFields(cursorField, where)
|
||||
|
||||
rows, err := db.db.Query(finalQuery, idsArgs...)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var (
|
||||
result []*common.Message
|
||||
)
|
||||
for rows.Next() {
|
||||
var (
|
||||
message common.Message
|
||||
cursor string
|
||||
)
|
||||
if err := db.tableUserMessagesScanAllFields(rows, &message, &cursor); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, &message)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
return getMessagesFromScanRows(db, rows)
|
||||
}
|
||||
|
||||
func (db sqlitePersistence) AllChatIDsByCommunity(communityID string) ([]string, error) {
|
||||
|
@ -965,6 +911,11 @@ func (db sqlitePersistence) PinnedMessageByChatIDs(chatIDs []string, currCursor
|
|||
ON
|
||||
dm.author_id = dm_author.id
|
||||
|
||||
LEFT JOIN
|
||||
discord_message_attachments dm_attachment
|
||||
ON
|
||||
dm.id = dm_attachment.discord_message_id
|
||||
|
||||
WHERE
|
||||
pm.pinned = 1
|
||||
AND NOT(m1.hide) AND m1.local_chat_id IN %s %s
|
||||
|
@ -978,27 +929,9 @@ func (db sqlitePersistence) PinnedMessageByChatIDs(chatIDs []string, currCursor
|
|||
}
|
||||
defer rows.Close()
|
||||
|
||||
var (
|
||||
result []*common.PinnedMessage
|
||||
cursors []string
|
||||
)
|
||||
for rows.Next() {
|
||||
var (
|
||||
message common.Message
|
||||
pinnedAt uint64
|
||||
pinnedBy string
|
||||
cursor string
|
||||
)
|
||||
if err := db.tableUserMessagesScanAllFields(rows, &message, &pinnedAt, &pinnedBy, &cursor); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
pinnedMessage := &common.PinnedMessage{
|
||||
Message: &message,
|
||||
PinnedAt: pinnedAt,
|
||||
PinnedBy: pinnedBy,
|
||||
}
|
||||
result = append(result, pinnedMessage)
|
||||
cursors = append(cursors, cursor)
|
||||
result, cursors, err := getPinnedMessagesAndCursorsFromScanRows(db, rows)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
var newCursor string
|
||||
|
@ -1048,20 +981,9 @@ func (db sqlitePersistence) MessageByChatIDs(chatIDs []string, currCursor string
|
|||
}
|
||||
defer rows.Close()
|
||||
|
||||
var (
|
||||
result []*common.Message
|
||||
cursors []string
|
||||
)
|
||||
for rows.Next() {
|
||||
var (
|
||||
message common.Message
|
||||
cursor string
|
||||
)
|
||||
if err := db.tableUserMessagesScanAllFields(rows, &message, &cursor); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
result = append(result, &message)
|
||||
cursors = append(cursors, cursor)
|
||||
result, cursors, err := getMessagesAndCursorsFromScanRows(db, rows)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
var newCursor string
|
||||
|
@ -1884,6 +1806,52 @@ func (db sqlitePersistence) SaveDiscordMessages(messages []*protobuf.DiscordMess
|
|||
return
|
||||
}
|
||||
|
||||
func (db sqlitePersistence) HasDiscordMessageAttachmentPayload(id string) (hasPayload bool, err error) {
|
||||
err = db.db.QueryRow(`SELECT EXISTS(SELECT 1 FROM discord_message_attachments WHERE id = ? AND payload NOT NULL)`, id).Scan(&hasPayload)
|
||||
return hasPayload, err
|
||||
}
|
||||
|
||||
func (db sqlitePersistence) SaveDiscordMessageAttachments(attachments []*protobuf.DiscordMessageAttachment) (err error) {
|
||||
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
if err == nil {
|
||||
err = tx.Commit()
|
||||
return
|
||||
}
|
||||
// don't shadow original error
|
||||
_ = tx.Rollback()
|
||||
}()
|
||||
|
||||
query := "INSERT OR REPLACE INTO discord_message_attachments(id,discord_message_id,url,file_name,file_size_bytes,payload, content_type) VALUES (?,?,?,?,?,?,?)"
|
||||
stmt, err := tx.Prepare(query)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer stmt.Close()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, attachment := range attachments {
|
||||
_, err = stmt.Exec(
|
||||
attachment.GetId(),
|
||||
attachment.GetMessageId(),
|
||||
attachment.GetUrl(),
|
||||
attachment.GetFileName(),
|
||||
attachment.GetFileSizeBytes(),
|
||||
attachment.GetPayload(),
|
||||
attachment.GetContentType(),
|
||||
)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (db sqlitePersistence) SaveEmojiReaction(emojiReaction *EmojiReaction) (err error) {
|
||||
query := "INSERT INTO emoji_reactions(id,clock_value,source,emoji_id,message_id,chat_id,local_chat_id,retracted) VALUES (?,?,?,?,?,?,?,?)"
|
||||
stmt, err := db.db.Prepare(query)
|
||||
|
@ -2241,3 +2209,155 @@ func (db sqlitePersistence) SetContactRequestState(id string, state common.Conta
|
|||
_, err := db.db.Exec(`UPDATE user_messages SET contact_request_state = ? WHERE id = ?`, state, id)
|
||||
return err
|
||||
}
|
||||
|
||||
func getUpdatedChatMessagePayload(originalMessage *protobuf.DiscordMessage, attachmentMessage *protobuf.DiscordMessage) *protobuf.ChatMessage_DiscordMessage {
|
||||
originalMessage.Attachments = append(originalMessage.Attachments, attachmentMessage.Attachments...)
|
||||
return &protobuf.ChatMessage_DiscordMessage{
|
||||
DiscordMessage: originalMessage,
|
||||
}
|
||||
}
|
||||
|
||||
func getMessageFromScanRows(db sqlitePersistence, rows *sql.Rows) (*common.Message, error) {
|
||||
var msg *common.Message
|
||||
|
||||
for rows.Next() {
|
||||
// There's a possibility of multiple rows per message if the
|
||||
// message has a discordMessage and the discordMessage has multiple
|
||||
// attachments
|
||||
//
|
||||
// Hence, we make sure we're aggregating all attachments on a single
|
||||
// common.Message
|
||||
var message common.Message
|
||||
err := db.tableUserMessagesScanAllFields(rows, &message)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if msg == nil {
|
||||
msg = &message
|
||||
} else if discordMessage := msg.GetDiscordMessage(); discordMessage != nil {
|
||||
msg.Payload = getUpdatedChatMessagePayload(discordMessage, message.GetDiscordMessage())
|
||||
}
|
||||
}
|
||||
if msg == nil {
|
||||
return nil, common.ErrRecordNotFound
|
||||
}
|
||||
return msg, nil
|
||||
}
|
||||
|
||||
type HasClocks interface {
|
||||
GetClock(i int) uint64
|
||||
}
|
||||
|
||||
func SortByClock(msgs HasClocks) {
|
||||
sort.Slice(msgs, func(i, j int) bool {
|
||||
return msgs.GetClock(j) < msgs.GetClock(i)
|
||||
})
|
||||
}
|
||||
|
||||
func getMessagesFromScanRows(db sqlitePersistence, rows *sql.Rows) ([]*common.Message, error) {
|
||||
messageIdx := make(map[string]*common.Message, 0)
|
||||
for rows.Next() {
|
||||
// There's a possibility of multiple rows per message if the
|
||||
// message has a discordMessage and the discordMessage has multiple
|
||||
// attachments
|
||||
//
|
||||
// Hence, we make sure we're aggregating all attachments on a single
|
||||
// common.Message
|
||||
var message common.Message
|
||||
if err := db.tableUserMessagesScanAllFields(rows, &message); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if msg, ok := messageIdx[message.ID]; !ok {
|
||||
messageIdx[message.ID] = &message
|
||||
} else if discordMessage := msg.GetDiscordMessage(); discordMessage != nil {
|
||||
msg.Payload = getUpdatedChatMessagePayload(discordMessage, message.GetDiscordMessage())
|
||||
messageIdx[message.ID] = msg
|
||||
}
|
||||
}
|
||||
|
||||
var messages common.Messages
|
||||
for _, message := range messageIdx {
|
||||
messages = append(messages, message)
|
||||
}
|
||||
SortByClock(messages)
|
||||
|
||||
return messages, nil
|
||||
}
|
||||
|
||||
func getMessagesAndCursorsFromScanRows(db sqlitePersistence, rows *sql.Rows) ([]*common.Message, []string, error) {
|
||||
|
||||
var cursors []string
|
||||
messageIdx := make(map[string]*common.Message, 0)
|
||||
|
||||
for rows.Next() {
|
||||
// There's a possibility of multiple rows per message if the
|
||||
// message has a discordMessage and the discordMessage has multiple
|
||||
// attachments
|
||||
//
|
||||
// Hence, we make sure we're aggregating all attachments on a single
|
||||
// common.Message
|
||||
var (
|
||||
message common.Message
|
||||
cursor string
|
||||
)
|
||||
if err := db.tableUserMessagesScanAllFields(rows, &message, &cursor); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if msg, ok := messageIdx[message.ID]; !ok {
|
||||
messageIdx[message.ID] = &message
|
||||
cursors = append(cursors, cursor)
|
||||
} else if discordMessage := msg.GetDiscordMessage(); discordMessage != nil {
|
||||
msg.Payload = getUpdatedChatMessagePayload(discordMessage, message.GetDiscordMessage())
|
||||
messageIdx[message.ID] = msg
|
||||
}
|
||||
}
|
||||
|
||||
var messages common.Messages
|
||||
for _, message := range messageIdx {
|
||||
messages = append(messages, message)
|
||||
}
|
||||
SortByClock(messages)
|
||||
|
||||
return messages, cursors, nil
|
||||
}
|
||||
|
||||
func getPinnedMessagesAndCursorsFromScanRows(db sqlitePersistence, rows *sql.Rows) ([]*common.PinnedMessage, []string, error) {
|
||||
|
||||
var cursors []string
|
||||
messageIdx := make(map[string]*common.PinnedMessage, 0)
|
||||
|
||||
for rows.Next() {
|
||||
var (
|
||||
message common.Message
|
||||
pinnedAt uint64
|
||||
pinnedBy string
|
||||
cursor string
|
||||
)
|
||||
if err := db.tableUserMessagesScanAllFields(rows, &message, &pinnedAt, &pinnedBy, &cursor); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if msg, ok := messageIdx[message.ID]; !ok {
|
||||
pinnedMessage := &common.PinnedMessage{
|
||||
Message: &message,
|
||||
PinnedAt: pinnedAt,
|
||||
PinnedBy: pinnedBy,
|
||||
}
|
||||
messageIdx[message.ID] = pinnedMessage
|
||||
cursors = append(cursors, cursor)
|
||||
} else if discordMessage := msg.Message.GetDiscordMessage(); discordMessage != nil {
|
||||
msg.Message.Payload = getUpdatedChatMessagePayload(discordMessage, message.GetDiscordMessage())
|
||||
messageIdx[message.ID] = msg
|
||||
}
|
||||
}
|
||||
|
||||
var messages common.PinnedMessages
|
||||
for _, message := range messageIdx {
|
||||
messages = append(messages, message)
|
||||
}
|
||||
SortByClock(messages)
|
||||
|
||||
return messages, cursors, nil
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
// 1662106895_add_chat_first_message_timestamp.up.sql (113B)
|
||||
// 1662723928_add_discord_author_image_fields.up.sql (75B)
|
||||
// 1664195977_add_deleted_for_mes.up.sql (352B)
|
||||
// 1664367420_add_discord_attachments_table.up.sql (350B)
|
||||
// README.md (554B)
|
||||
// doc.go (850B)
|
||||
|
||||
|
@ -1372,6 +1373,26 @@ func _1664195977_add_deleted_for_mesUpSql() (*asset, error) {
|
|||
return a, nil
|
||||
}
|
||||
|
||||
var __1664367420_add_discord_attachments_tableUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x7c\x90\xc1\x4e\xc3\x30\x0c\x86\xef\x79\x8a\xff\xc8\x24\xde\x60\xa7\x96\x05\x11\x51\x12\xd4\x79\x5a\x77\x8a\x42\x63\x20\x52\x93\x4e\x4b\x90\x28\x4f\x8f\x80\x55\x1a\xaa\xe0\x68\xff\xfe\x2c\x7f\xbe\x69\x65\x45\x12\x54\xd5\x8d\x84\xba\x85\x36\x04\xd9\xa9\x2d\x6d\xe1\x43\xee\xc7\x93\xb7\x91\x73\x76\x2f\x6c\x5d\x29\xae\x7f\x8d\x9c\x4a\xc6\x95\x00\x82\x07\xc9\x8e\xf0\xd8\xaa\x87\xaa\x3d\xe0\x5e\x1e\xbe\x71\xbd\x6b\x9a\x6b\x81\x05\x3f\xcf\xcf\xf9\xdb\x69\x38\x37\x2e\xa0\xe7\x30\xb0\x4d\x2e\xf2\x1f\x51\x0e\x1f\x6c\x9f\xa6\xc2\x19\x4a\xff\xce\x8f\x6e\x1a\x46\xe7\x51\x37\xa6\xfe\xaa\xfb\x31\x15\x4e\xc5\x96\xe9\xf8\xb3\x4d\xac\xb0\x57\x74\x67\x76\x84\xd6\xec\xd5\x66\x2d\xc4\x59\x5f\xe9\x8d\xec\xe0\xe3\xa5\xe3\x7c\x77\xb6\xc1\xbf\xc3\xe8\xff\xff\xb1\x94\x5d\xad\x85\xf8\x0c\x00\x00\xff\xff\xec\xb0\x4b\x53\x5e\x01\x00\x00")
|
||||
|
||||
func _1664367420_add_discord_attachments_tableUpSqlBytes() ([]byte, error) {
|
||||
return bindataRead(
|
||||
__1664367420_add_discord_attachments_tableUpSql,
|
||||
"1664367420_add_discord_attachments_table.up.sql",
|
||||
)
|
||||
}
|
||||
|
||||
func _1664367420_add_discord_attachments_tableUpSql() (*asset, error) {
|
||||
bytes, err := _1664367420_add_discord_attachments_tableUpSqlBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
info := bindataFileInfo{name: "1664367420_add_discord_attachments_table.up.sql", size: 350, mode: os.FileMode(0664), modTime: time.Unix(1664438057, 0)}
|
||||
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x48, 0xe1, 0xb6, 0x4f, 0x6f, 0x92, 0x0, 0xb4, 0xf, 0x55, 0x12, 0x1c, 0x98, 0x6d, 0xbc, 0x1e, 0xfd, 0xae, 0x1c, 0xce, 0xd1, 0x3d, 0x2, 0x21, 0x2e, 0xc0, 0x13, 0xa, 0xb2, 0xec, 0x81, 0x13}}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
var _readmeMd = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x54\x91\xc1\xce\xd3\x30\x10\x84\xef\x7e\x8a\x91\x7a\x01\xa9\x2a\x8f\xc0\x0d\x71\x82\x03\x48\x1c\xc9\x36\x9e\x36\x96\x1c\x6f\xf0\xae\x93\xe6\xed\x91\xa3\xc2\xdf\xff\x66\xed\xd8\x33\xdf\x78\x4f\xa7\x13\xbe\xea\x06\x57\x6c\x35\x39\x31\xa7\x7b\x15\x4f\x5a\xec\x73\x08\xbf\x08\x2d\x79\x7f\x4a\x43\x5b\x86\x17\xfd\x8c\x21\xea\x56\x5e\x47\x90\x4a\x14\x75\x48\xde\x64\x37\x2c\x6a\x96\xae\x99\x48\x05\xf6\x27\x77\x13\xad\x08\xae\x8a\x51\xe7\x25\xf3\xf1\xa9\x9f\xf9\x58\x58\x2c\xad\xbc\xe0\x8b\x56\xf0\x21\x5d\xeb\x4c\x95\xb3\xae\x84\x60\xd4\xdc\xe6\x82\x5d\x1b\x36\x6d\x39\x62\x92\xf5\xb8\x11\xdb\x92\xd3\x28\xce\xe0\x13\xe1\x72\xcd\x3c\x63\xd4\x65\x87\xae\xac\xe8\xc3\x28\x2e\x67\x44\x66\x3a\x21\x25\xa2\x72\xac\x14\x67\xbc\x84\x9f\x53\x32\x8c\x52\x70\x25\x56\xd6\xfd\x8d\x05\x37\xad\x30\x9d\x9f\xa6\x86\x0f\xcd\x58\x7f\xcf\x34\x93\x3b\xed\x90\x9f\xa4\x1f\xcf\x30\x85\x4d\x07\x58\xaf\x7f\x25\xc4\x9d\xf3\x72\x64\x84\xd0\x7f\xf9\x9b\x3a\x2d\x84\xef\x85\x48\x66\x8d\xd8\x88\x9b\x8c\x8c\x98\x5b\xf6\x74\x14\x4e\x33\x0d\xc9\xe0\x93\x38\xda\x12\xc5\x69\xbd\xe4\xf0\x2e\x7a\x78\x07\x1c\xfe\x13\x9f\x91\x29\x31\x95\x7b\x7f\x62\x59\x37\xb4\xe5\x5e\x25\xfe\x33\xee\xd5\x53\x71\xd6\xda\x3a\xd8\xcb\xde\x2e\xf8\xa1\x90\x55\x53\x0c\xc7\xaa\x0d\xe9\x76\x14\x29\x1c\x7b\x68\xdd\x2f\xe1\x6f\x00\x00\x00\xff\xff\x3c\x0a\xc2\xfe\x2a\x02\x00\x00")
|
||||
|
||||
func readmeMdBytes() ([]byte, error) {
|
||||
|
@ -1627,6 +1648,8 @@ var _bindata = map[string]func() (*asset, error){
|
|||
|
||||
"1664195977_add_deleted_for_mes.up.sql": _1664195977_add_deleted_for_mesUpSql,
|
||||
|
||||
"1664367420_add_discord_attachments_table.up.sql": _1664367420_add_discord_attachments_tableUpSql,
|
||||
|
||||
"README.md": readmeMd,
|
||||
|
||||
"doc.go": docGo,
|
||||
|
@ -1735,8 +1758,9 @@ var _bintree = &bintree{nil, map[string]*bintree{
|
|||
"1662106895_add_chat_first_message_timestamp.up.sql": &bintree{_1662106895_add_chat_first_message_timestampUpSql, map[string]*bintree{}},
|
||||
"1662723928_add_discord_author_image_fields.up.sql": &bintree{_1662723928_add_discord_author_image_fieldsUpSql, map[string]*bintree{}},
|
||||
"1664195977_add_deleted_for_mes.up.sql": &bintree{_1664195977_add_deleted_for_mesUpSql, map[string]*bintree{}},
|
||||
"README.md": &bintree{readmeMd, map[string]*bintree{}},
|
||||
"doc.go": &bintree{docGo, map[string]*bintree{}},
|
||||
"1664367420_add_discord_attachments_table.up.sql": &bintree{_1664367420_add_discord_attachments_tableUpSql, map[string]*bintree{}},
|
||||
"README.md": &bintree{readmeMd, map[string]*bintree{}},
|
||||
"doc.go": &bintree{docGo, map[string]*bintree{}},
|
||||
}}
|
||||
|
||||
// RestoreAsset restores an asset under the given directory.
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
CREATE TABLE IF NOT EXISTS discord_message_attachments (
|
||||
id TEXT PRIMARY KEY NOT NULL,
|
||||
discord_message_id TEXT NULL,
|
||||
url TEXT NOT NULL,
|
||||
file_name TEXT NOT NULL,
|
||||
file_size_bytes INT NOT NULL,
|
||||
payload BLOB,
|
||||
content_type TEXT
|
||||
) WITHOUT ROWID;
|
||||
|
||||
CREATE INDEX dm_attachments_messages_idx ON discord_message_attachments (discord_message_id);
|
||||
|
|
@ -60,6 +60,30 @@ func TestMessagesByIDs(t *testing.T) {
|
|||
require.Len(t, m, 10)
|
||||
}
|
||||
|
||||
func TestMessagesByIDs_WithDiscordMessagesPayload(t *testing.T) {
|
||||
db, err := openTestDB()
|
||||
require.NoError(t, err)
|
||||
p := newSQLitePersistence(db)
|
||||
|
||||
var ids []string
|
||||
for i := 0; i < 10; i++ {
|
||||
id := strconv.Itoa(i)
|
||||
err := insertMinimalMessage(p, id)
|
||||
require.NoError(t, err)
|
||||
err = insertMinimalDiscordMessage(p, id, id)
|
||||
require.NoError(t, err)
|
||||
ids = append(ids, id)
|
||||
}
|
||||
|
||||
m, err := p.MessagesByIDs(ids)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, m, 10)
|
||||
|
||||
for _, _m := range m {
|
||||
require.NotNil(t, _m.GetDiscordMessage())
|
||||
}
|
||||
}
|
||||
|
||||
func TestMessageByID(t *testing.T) {
|
||||
db, err := openTestDB()
|
||||
require.NoError(t, err)
|
||||
|
@ -93,6 +117,29 @@ func TestMessageByID_WithDiscordMessagePayload(t *testing.T) {
|
|||
require.EqualValues(t, "2", m.GetDiscordMessage().Author.Id)
|
||||
}
|
||||
|
||||
func TestMessageByID_WithDiscordMessageAttachmentPayload(t *testing.T) {
|
||||
|
||||
db, err := openTestDB()
|
||||
require.NoError(t, err)
|
||||
p := newSQLitePersistence(db)
|
||||
id := "1"
|
||||
discordMessageID := "2"
|
||||
|
||||
err = insertDiscordMessageWithAttachments(p, id, discordMessageID)
|
||||
require.NoError(t, err)
|
||||
|
||||
m, err := p.MessageByID(id)
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, id, m.ID)
|
||||
|
||||
dm := m.GetDiscordMessage()
|
||||
require.NotNil(t, dm)
|
||||
require.EqualValues(t, discordMessageID, dm.Id)
|
||||
|
||||
require.NotNil(t, dm.Attachments)
|
||||
require.Len(t, dm.Attachments, 2)
|
||||
}
|
||||
|
||||
func TestMessagesExist(t *testing.T) {
|
||||
db, err := openTestDB()
|
||||
require.NoError(t, err)
|
||||
|
@ -734,6 +781,32 @@ func insertMinimalMessage(p *sqlitePersistence, id string) error {
|
|||
}})
|
||||
}
|
||||
|
||||
func insertDiscordMessageWithAttachments(p *sqlitePersistence, id string, discordMessageID string) error {
|
||||
err := insertMinimalDiscordMessage(p, id, discordMessageID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
attachment := &protobuf.DiscordMessageAttachment{
|
||||
Id: "1",
|
||||
MessageId: discordMessageID,
|
||||
Url: "https://does-not-exist.com",
|
||||
Payload: []byte{1, 2, 3, 4},
|
||||
}
|
||||
|
||||
attachment2 := &protobuf.DiscordMessageAttachment{
|
||||
Id: "2",
|
||||
MessageId: discordMessageID,
|
||||
Url: "https://does-not-exist.com",
|
||||
Payload: []byte{5, 6, 7, 8},
|
||||
}
|
||||
|
||||
return p.SaveDiscordMessageAttachments([]*protobuf.DiscordMessageAttachment{
|
||||
attachment,
|
||||
attachment2,
|
||||
})
|
||||
}
|
||||
|
||||
func insertMinimalDiscordMessage(p *sqlitePersistence, id string, discordMessageID string) error {
|
||||
discordMessage := &protobuf.DiscordMessage{
|
||||
Id: discordMessageID,
|
||||
|
|
|
@ -105,7 +105,7 @@ func (x ChatMessage_ContentType) String() string {
|
|||
}
|
||||
|
||||
func (ChatMessage_ContentType) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_263952f55fd35689, []int{9, 0}
|
||||
return fileDescriptor_263952f55fd35689, []int{10, 0}
|
||||
}
|
||||
|
||||
type StickerMessage struct {
|
||||
|
@ -460,16 +460,17 @@ func (m *DeleteForMeMessage) GetMessageId() string {
|
|||
}
|
||||
|
||||
type DiscordMessage struct {
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
|
||||
Timestamp string `protobuf:"bytes,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
|
||||
TimestampEdited string `protobuf:"bytes,4,opt,name=timestampEdited,proto3" json:"timestampEdited,omitempty"`
|
||||
Content string `protobuf:"bytes,5,opt,name=content,proto3" json:"content,omitempty"`
|
||||
Author *DiscordMessageAuthor `protobuf:"bytes,6,opt,name=author,proto3" json:"author,omitempty"`
|
||||
Reference *DiscordMessageReference `protobuf:"bytes,7,opt,name=reference,proto3" json:"reference,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
|
||||
Timestamp string `protobuf:"bytes,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
|
||||
TimestampEdited string `protobuf:"bytes,4,opt,name=timestampEdited,proto3" json:"timestampEdited,omitempty"`
|
||||
Content string `protobuf:"bytes,5,opt,name=content,proto3" json:"content,omitempty"`
|
||||
Author *DiscordMessageAuthor `protobuf:"bytes,6,opt,name=author,proto3" json:"author,omitempty"`
|
||||
Reference *DiscordMessageReference `protobuf:"bytes,7,opt,name=reference,proto3" json:"reference,omitempty"`
|
||||
Attachments []*DiscordMessageAttachment `protobuf:"bytes,8,rep,name=attachments,proto3" json:"attachments,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *DiscordMessage) Reset() { *m = DiscordMessage{} }
|
||||
|
@ -546,6 +547,13 @@ func (m *DiscordMessage) GetReference() *DiscordMessageReference {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *DiscordMessage) GetAttachments() []*DiscordMessageAttachment {
|
||||
if m != nil {
|
||||
return m.Attachments
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type DiscordMessageAuthor struct {
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
||||
|
@ -688,6 +696,101 @@ func (m *DiscordMessageReference) GetGuildId() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
type DiscordMessageAttachment struct {
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
MessageId string `protobuf:"bytes,2,opt,name=messageId,proto3" json:"messageId,omitempty"`
|
||||
Url string `protobuf:"bytes,3,opt,name=url,proto3" json:"url,omitempty"`
|
||||
FileName string `protobuf:"bytes,4,opt,name=fileName,proto3" json:"fileName,omitempty"`
|
||||
FileSizeBytes uint64 `protobuf:"varint,5,opt,name=fileSizeBytes,proto3" json:"fileSizeBytes,omitempty"`
|
||||
ContentType string `protobuf:"bytes,6,opt,name=contentType,proto3" json:"contentType,omitempty"`
|
||||
Payload []byte `protobuf:"bytes,7,opt,name=payload,proto3" json:"payload,omitempty"`
|
||||
LocalUrl string `protobuf:"bytes,8,opt,name=localUrl,proto3" json:"localUrl,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *DiscordMessageAttachment) Reset() { *m = DiscordMessageAttachment{} }
|
||||
func (m *DiscordMessageAttachment) String() string { return proto.CompactTextString(m) }
|
||||
func (*DiscordMessageAttachment) ProtoMessage() {}
|
||||
func (*DiscordMessageAttachment) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_263952f55fd35689, []int{9}
|
||||
}
|
||||
|
||||
func (m *DiscordMessageAttachment) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_DiscordMessageAttachment.Unmarshal(m, b)
|
||||
}
|
||||
func (m *DiscordMessageAttachment) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_DiscordMessageAttachment.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *DiscordMessageAttachment) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_DiscordMessageAttachment.Merge(m, src)
|
||||
}
|
||||
func (m *DiscordMessageAttachment) XXX_Size() int {
|
||||
return xxx_messageInfo_DiscordMessageAttachment.Size(m)
|
||||
}
|
||||
func (m *DiscordMessageAttachment) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_DiscordMessageAttachment.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_DiscordMessageAttachment proto.InternalMessageInfo
|
||||
|
||||
func (m *DiscordMessageAttachment) GetId() string {
|
||||
if m != nil {
|
||||
return m.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *DiscordMessageAttachment) GetMessageId() string {
|
||||
if m != nil {
|
||||
return m.MessageId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *DiscordMessageAttachment) GetUrl() string {
|
||||
if m != nil {
|
||||
return m.Url
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *DiscordMessageAttachment) GetFileName() string {
|
||||
if m != nil {
|
||||
return m.FileName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *DiscordMessageAttachment) GetFileSizeBytes() uint64 {
|
||||
if m != nil {
|
||||
return m.FileSizeBytes
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *DiscordMessageAttachment) GetContentType() string {
|
||||
if m != nil {
|
||||
return m.ContentType
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *DiscordMessageAttachment) GetPayload() []byte {
|
||||
if m != nil {
|
||||
return m.Payload
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *DiscordMessageAttachment) GetLocalUrl() string {
|
||||
if m != nil {
|
||||
return m.LocalUrl
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type ChatMessage struct {
|
||||
// Lamport timestamp of the chat message
|
||||
Clock uint64 `protobuf:"varint,1,opt,name=clock,proto3" json:"clock,omitempty"`
|
||||
|
@ -733,7 +836,7 @@ func (m *ChatMessage) Reset() { *m = ChatMessage{} }
|
|||
func (m *ChatMessage) String() string { return proto.CompactTextString(m) }
|
||||
func (*ChatMessage) ProtoMessage() {}
|
||||
func (*ChatMessage) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_263952f55fd35689, []int{9}
|
||||
return fileDescriptor_263952f55fd35689, []int{10}
|
||||
}
|
||||
|
||||
func (m *ChatMessage) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -944,7 +1047,7 @@ func (m *ContactRequestSignature) Reset() { *m = ContactRequestSignature
|
|||
func (m *ContactRequestSignature) String() string { return proto.CompactTextString(m) }
|
||||
func (*ContactRequestSignature) ProtoMessage() {}
|
||||
func (*ContactRequestSignature) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_263952f55fd35689, []int{10}
|
||||
return fileDescriptor_263952f55fd35689, []int{11}
|
||||
}
|
||||
|
||||
func (m *ContactRequestSignature) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -991,6 +1094,7 @@ func init() {
|
|||
proto.RegisterType((*DiscordMessage)(nil), "protobuf.DiscordMessage")
|
||||
proto.RegisterType((*DiscordMessageAuthor)(nil), "protobuf.DiscordMessageAuthor")
|
||||
proto.RegisterType((*DiscordMessageReference)(nil), "protobuf.DiscordMessageReference")
|
||||
proto.RegisterType((*DiscordMessageAttachment)(nil), "protobuf.DiscordMessageAttachment")
|
||||
proto.RegisterType((*ChatMessage)(nil), "protobuf.ChatMessage")
|
||||
proto.RegisterType((*ContactRequestSignature)(nil), "protobuf.ContactRequestSignature")
|
||||
}
|
||||
|
@ -1000,75 +1104,81 @@ func init() {
|
|||
}
|
||||
|
||||
var fileDescriptor_263952f55fd35689 = []byte{
|
||||
// 1119 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0xcd, 0x6e, 0xdb, 0x46,
|
||||
0x10, 0xb6, 0x64, 0xfd, 0x71, 0x28, 0xcb, 0xec, 0x26, 0x8d, 0xd9, 0x34, 0xb5, 0x1d, 0x22, 0x40,
|
||||
0x74, 0x52, 0x81, 0x34, 0x2d, 0x02, 0xf4, 0x50, 0x30, 0x12, 0x6b, 0xb3, 0xa9, 0x7e, 0xb2, 0xa4,
|
||||
0xda, 0xba, 0x17, 0x62, 0x43, 0xae, 0x2d, 0xc2, 0x22, 0xa9, 0x92, 0x54, 0x50, 0x3f, 0x40, 0xcf,
|
||||
0x7d, 0x92, 0x5e, 0x7b, 0xed, 0xdb, 0xf4, 0x01, 0xfa, 0x04, 0xc5, 0x2e, 0xb9, 0x24, 0x25, 0x58,
|
||||
0xb6, 0x4f, 0xda, 0x99, 0x9d, 0x99, 0xfd, 0xf4, 0xcd, 0xb7, 0xb3, 0x04, 0xe4, 0x2e, 0x48, 0xea,
|
||||
0x04, 0x34, 0x49, 0xc8, 0x15, 0x1d, 0xac, 0xe2, 0x28, 0x8d, 0x50, 0x87, 0xff, 0x7c, 0x58, 0x5f,
|
||||
0x3e, 0x95, 0x69, 0xb8, 0x0e, 0x92, 0xcc, 0xad, 0xbd, 0x81, 0x9e, 0x95, 0xfa, 0xee, 0x35, 0x8d,
|
||||
0xc7, 0x59, 0x38, 0x42, 0xd0, 0x58, 0x90, 0x64, 0xa1, 0xd6, 0x4e, 0x6b, 0x7d, 0x09, 0xf3, 0x35,
|
||||
0xf3, 0xad, 0x88, 0x7b, 0xad, 0xd6, 0x4f, 0x6b, 0xfd, 0x26, 0xe6, 0x6b, 0xed, 0x3d, 0x74, 0xcd,
|
||||
0x80, 0x5c, 0x51, 0x91, 0xa7, 0x42, 0x7b, 0x45, 0x6e, 0x96, 0x11, 0xf1, 0x78, 0x6a, 0x17, 0x0b,
|
||||
0x13, 0xbd, 0x84, 0x46, 0x7a, 0xb3, 0xa2, 0x3c, 0xbb, 0xf7, 0xea, 0xd1, 0x40, 0x20, 0x19, 0xf0,
|
||||
0x7c, 0xfb, 0x66, 0x45, 0x31, 0x0f, 0xd0, 0xfe, 0xae, 0x41, 0x57, 0x5f, 0x7b, 0x7e, 0x74, 0x7f,
|
||||
0xcd, 0xd7, 0x1b, 0x35, 0x4f, 0xcb, 0x9a, 0xd5, 0xfc, 0xcc, 0x28, 0x0f, 0x40, 0x27, 0x20, 0x7b,
|
||||
0xeb, 0x98, 0xa4, 0x7e, 0x14, 0x3a, 0x41, 0xa2, 0xee, 0x9f, 0xd6, 0xfa, 0x0d, 0x0c, 0xc2, 0x35,
|
||||
0x4e, 0xb4, 0xaf, 0x41, 0x2a, 0x72, 0xd0, 0x13, 0x40, 0xf3, 0xc9, 0xbb, 0xc9, 0xf4, 0xe7, 0x89,
|
||||
0xa3, 0xcf, 0x47, 0xe6, 0xd4, 0xb1, 0x2f, 0x66, 0x86, 0xb2, 0x87, 0xda, 0xb0, 0xaf, 0xeb, 0x43,
|
||||
0xa5, 0xc6, 0x17, 0x63, 0xac, 0xd4, 0xb5, 0x7f, 0x6a, 0x20, 0x1b, 0x9e, 0x9f, 0x0a, 0xdc, 0x8f,
|
||||
0xa1, 0xe9, 0x2e, 0x23, 0xf7, 0x9a, 0xa3, 0x6e, 0xe0, 0xcc, 0x60, 0x2c, 0xa6, 0xf4, 0xf7, 0x94,
|
||||
0x63, 0x96, 0x30, 0x5f, 0xa3, 0x23, 0x68, 0xf3, 0x66, 0xf9, 0x1e, 0x47, 0x23, 0xe1, 0x16, 0x33,
|
||||
0x4d, 0x0f, 0x7d, 0x01, 0x90, 0x37, 0x90, 0xed, 0x35, 0xf8, 0x9e, 0x94, 0x7b, 0x4c, 0x8f, 0x9d,
|
||||
0x70, 0x15, 0x93, 0x30, 0x55, 0x9b, 0x9c, 0x97, 0xcc, 0x40, 0x6f, 0xa0, 0x2b, 0x92, 0x38, 0x3b,
|
||||
0x2d, 0xce, 0xce, 0xa7, 0x25, 0x3b, 0x39, 0x40, 0x4e, 0x89, 0x1c, 0x94, 0x86, 0xf6, 0x57, 0x0d,
|
||||
0x0e, 0x46, 0x74, 0x49, 0x53, 0x7a, 0xf7, 0x7f, 0xa8, 0xe0, 0xad, 0xdf, 0x81, 0x77, 0x7f, 0x27,
|
||||
0xde, 0xc6, 0x5d, 0x78, 0x9b, 0x0f, 0xc6, 0x6b, 0x02, 0xca, 0xe0, 0x7e, 0x1f, 0xc5, 0xe3, 0x7b,
|
||||
0x30, 0x6f, 0x42, 0xab, 0x6f, 0x41, 0xd3, 0xfe, 0xac, 0x43, 0x6f, 0xe4, 0x27, 0x6e, 0x14, 0x7b,
|
||||
0xa2, 0x4e, 0x0f, 0xea, 0xbe, 0x97, 0xdf, 0x80, 0xba, 0xef, 0xf1, 0xce, 0x09, 0xb5, 0x49, 0xb9,
|
||||
0x96, 0x9e, 0x81, 0x94, 0xfa, 0x01, 0x4d, 0x52, 0x12, 0xac, 0xc4, 0xff, 0x2d, 0x1c, 0xa8, 0x0f,
|
||||
0x87, 0x85, 0xc1, 0x94, 0x41, 0x45, 0x0f, 0xb7, 0xdd, 0x4c, 0xe3, 0x6e, 0x14, 0xa6, 0x34, 0xef,
|
||||
0xa5, 0x84, 0x85, 0x89, 0xbe, 0x81, 0x16, 0x59, 0xa7, 0x8b, 0x28, 0xe6, 0x7d, 0x94, 0x5f, 0x1d,
|
||||
0x97, 0xbc, 0x6c, 0xe2, 0xd5, 0x79, 0x14, 0xce, 0xa3, 0xd1, 0x77, 0x20, 0xc5, 0xf4, 0x92, 0xc6,
|
||||
0x34, 0x74, 0xa9, 0xda, 0xe6, 0xa9, 0xcf, 0x77, 0xa5, 0x62, 0x11, 0x88, 0xcb, 0x1c, 0xed, 0xdf,
|
||||
0x1a, 0x3c, 0xbe, 0xed, 0x84, 0xdb, 0x78, 0x09, 0x49, 0x50, 0xf0, 0xc2, 0xd6, 0xe8, 0x05, 0x1c,
|
||||
0x78, 0x7e, 0xe2, 0xc6, 0x7e, 0xe0, 0x87, 0x24, 0x8d, 0xe2, 0x9c, 0x9b, 0x4d, 0x27, 0x7a, 0x0a,
|
||||
0x9d, 0xd0, 0x77, 0xaf, 0x79, 0x76, 0x46, 0x4c, 0x61, 0x33, 0x66, 0xc9, 0x47, 0x92, 0x92, 0x78,
|
||||
0x1e, 0x2f, 0x73, 0x4e, 0x4a, 0x07, 0x1a, 0x00, 0xca, 0x0c, 0x3e, 0x3d, 0x66, 0xf9, 0x78, 0x68,
|
||||
0x71, 0x59, 0xdd, 0xb2, 0xc3, 0x4e, 0x5a, 0x46, 0x2e, 0x59, 0xb2, 0x62, 0xed, 0xec, 0x24, 0x61,
|
||||
0x6b, 0x11, 0x1c, 0xed, 0xa0, 0x83, 0x81, 0x28, 0x24, 0x92, 0xff, 0xe3, 0x8a, 0x9c, 0x9f, 0x81,
|
||||
0xe4, 0x2e, 0x48, 0x18, 0xd2, 0xa5, 0x59, 0x28, 0xaa, 0x70, 0xb0, 0x96, 0x5e, 0xad, 0xfd, 0xa5,
|
||||
0x67, 0x8a, 0x8b, 0x20, 0x4c, 0xed, 0xbf, 0x0e, 0xc8, 0xc3, 0x05, 0xb9, 0x67, 0x50, 0x6c, 0x48,
|
||||
0xab, 0xce, 0x77, 0x2a, 0xd2, 0x12, 0x63, 0x64, 0xbf, 0x32, 0x46, 0x4e, 0x40, 0x8e, 0x69, 0xb2,
|
||||
0x8a, 0xc2, 0x84, 0x3a, 0x69, 0x94, 0x33, 0x0a, 0xc2, 0x65, 0x47, 0xe8, 0x33, 0xe8, 0xd0, 0x30,
|
||||
0x71, 0x38, 0xdf, 0xb9, 0xcc, 0x68, 0x98, 0x4c, 0x18, 0xdd, 0x95, 0x2b, 0xdd, 0xda, 0xb8, 0xd2,
|
||||
0xdb, 0xb7, 0xb3, 0xfd, 0xd0, 0xdb, 0x89, 0x46, 0xd0, 0xcd, 0x45, 0x9c, 0x65, 0x76, 0x78, 0x66,
|
||||
0x45, 0x84, 0x15, 0x0e, 0x06, 0xc3, 0x2c, 0x32, 0xab, 0xe2, 0x96, 0x06, 0x7a, 0x0d, 0xed, 0x24,
|
||||
0x7b, 0x9b, 0x54, 0x89, 0xab, 0x58, 0x2d, 0x0b, 0x6c, 0x3e, 0x5a, 0xe7, 0x7b, 0x58, 0x84, 0xa2,
|
||||
0x01, 0x34, 0x7d, 0xd6, 0x7f, 0x15, 0x78, 0xce, 0x93, 0xad, 0xe7, 0xa6, 0xcc, 0xc8, 0xc2, 0x58,
|
||||
0x3c, 0x61, 0x23, 0x5f, 0x95, 0xb7, 0xe3, 0xab, 0x4f, 0x09, 0x8b, 0xe7, 0x61, 0xe8, 0x18, 0x24,
|
||||
0x37, 0x0a, 0x82, 0x75, 0xe8, 0xa7, 0x37, 0x6a, 0x97, 0xc9, 0xee, 0x7c, 0x0f, 0x97, 0x2e, 0x34,
|
||||
0x84, 0x43, 0x2f, 0xd3, 0x94, 0x78, 0x81, 0x55, 0x77, 0x1b, 0xfd, 0xa6, 0xe8, 0xce, 0xf7, 0x70,
|
||||
0xcf, 0xdb, 0x1c, 0x40, 0xc5, 0xb8, 0x3c, 0xa8, 0x8e, 0xcb, 0xe7, 0xd0, 0xf5, 0xfc, 0x64, 0xb5,
|
||||
0x24, 0x37, 0x59, 0x23, 0x7b, 0xbc, 0x5d, 0x72, 0xee, 0xe3, 0xcd, 0xbc, 0x84, 0xe3, 0x84, 0xd1,
|
||||
0xce, 0x78, 0x24, 0x6e, 0xea, 0xc4, 0xf4, 0xb7, 0x35, 0x4d, 0x52, 0x27, 0xf1, 0xaf, 0x42, 0x92,
|
||||
0xae, 0x63, 0xaa, 0x1e, 0x6e, 0x0f, 0x84, 0x61, 0x16, 0x8a, 0xb3, 0x48, 0x4b, 0x04, 0xe2, 0xcf,
|
||||
0x59, 0xa1, 0x1d, 0x9b, 0x28, 0x04, 0x2d, 0xa6, 0x2e, 0xf5, 0x3f, 0x52, 0xef, 0x8e, 0xb3, 0x94,
|
||||
0x87, 0x9e, 0x75, 0x22, 0x8a, 0xed, 0x3a, 0xef, 0x25, 0x1c, 0x8a, 0x63, 0x04, 0xab, 0x9f, 0x9c,
|
||||
0xd6, 0xfa, 0x1d, 0xdc, 0xcb, 0xdd, 0x39, 0x73, 0xda, 0x1f, 0x75, 0x90, 0x2b, 0x8a, 0x42, 0x2a,
|
||||
0x3c, 0x16, 0x8f, 0xf8, 0x70, 0x3a, 0xb1, 0x8d, 0x89, 0x2d, 0x9e, 0xf1, 0x1e, 0x80, 0x6d, 0xfc,
|
||||
0x62, 0x3b, 0xb3, 0x1f, 0x75, 0x73, 0xa2, 0xd4, 0x90, 0x0c, 0x6d, 0xcb, 0x36, 0x87, 0xef, 0x0c,
|
||||
0xac, 0xd4, 0x11, 0x40, 0xcb, 0xb2, 0x75, 0x7b, 0x6e, 0x29, 0xfb, 0x48, 0x82, 0xa6, 0x31, 0x9e,
|
||||
0xfe, 0x60, 0x2a, 0x0d, 0x74, 0x04, 0x8f, 0x6c, 0xac, 0x4f, 0x2c, 0x7d, 0x68, 0x9b, 0x53, 0x56,
|
||||
0x71, 0x3c, 0xd6, 0x27, 0x23, 0xa5, 0x89, 0xfa, 0xf0, 0xc2, 0xba, 0xb0, 0x6c, 0x63, 0xec, 0x8c,
|
||||
0x0d, 0xcb, 0xd2, 0xcf, 0x8c, 0xe2, 0xb4, 0x19, 0x36, 0x7f, 0xd2, 0x6d, 0xc3, 0x39, 0xc3, 0xd3,
|
||||
0xf9, 0x4c, 0x69, 0xb1, 0x6a, 0xe6, 0x58, 0x3f, 0x33, 0x94, 0x36, 0x5b, 0xf2, 0x0f, 0x0b, 0xa5,
|
||||
0x83, 0x0e, 0x40, 0x62, 0xc5, 0xe6, 0x13, 0xd3, 0xbe, 0x50, 0x24, 0xf6, 0xe9, 0xb1, 0x55, 0xee,
|
||||
0x4c, 0x9f, 0x29, 0x80, 0x1e, 0xc1, 0x21, 0xab, 0xab, 0x0f, 0x6d, 0x07, 0x1b, 0xef, 0xe7, 0x86,
|
||||
0x65, 0x2b, 0x32, 0x73, 0x8e, 0x4c, 0x6b, 0x38, 0xc5, 0x23, 0x11, 0xad, 0x74, 0xdf, 0x4a, 0xc5,
|
||||
0xa7, 0x93, 0x36, 0x87, 0xa3, 0x5d, 0xb4, 0x3e, 0x03, 0xa9, 0xec, 0x56, 0xf6, 0x89, 0x55, 0x3a,
|
||||
0xee, 0x9e, 0x43, 0x6f, 0x0f, 0x7e, 0x95, 0x07, 0x5f, 0x7e, 0x2b, 0x5a, 0xfb, 0xa1, 0xc5, 0x57,
|
||||
0x5f, 0xfd, 0x1f, 0x00, 0x00, 0xff, 0xff, 0x5f, 0x62, 0xda, 0x69, 0x7d, 0x0a, 0x00, 0x00,
|
||||
// 1212 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0xdd, 0x8e, 0xdb, 0xc4,
|
||||
0x17, 0xdf, 0x7c, 0xc7, 0xc7, 0xd9, 0xac, 0xff, 0xd3, 0xfe, 0xbb, 0xa6, 0x94, 0x36, 0xb5, 0x2a,
|
||||
0x35, 0x57, 0x41, 0x2a, 0x05, 0x55, 0xe2, 0x02, 0xb9, 0x89, 0xd9, 0x9a, 0x92, 0x64, 0x3b, 0x76,
|
||||
0x80, 0x72, 0x13, 0x4d, 0xed, 0xd9, 0x8d, 0xb5, 0x89, 0x1d, 0xec, 0x49, 0xc5, 0x72, 0xcf, 0xe3,
|
||||
0x70, 0xcb, 0x2d, 0x4f, 0xc1, 0x2b, 0xf0, 0x00, 0x88, 0x07, 0x40, 0x33, 0xf6, 0xf8, 0x23, 0x34,
|
||||
0xdb, 0x5e, 0x79, 0xce, 0xf1, 0xf9, 0xf8, 0xcd, 0xef, 0x9c, 0x39, 0x33, 0x80, 0xbc, 0x15, 0x61,
|
||||
0xcb, 0x0d, 0x4d, 0x12, 0x72, 0x49, 0x47, 0xdb, 0x38, 0x62, 0x11, 0xea, 0x8a, 0xcf, 0x9b, 0xdd,
|
||||
0xc5, 0x5d, 0x95, 0x86, 0xbb, 0x4d, 0x92, 0xaa, 0x8d, 0x67, 0xd0, 0x77, 0x58, 0xe0, 0x5d, 0xd1,
|
||||
0x78, 0x9a, 0x9a, 0x23, 0x04, 0xcd, 0x15, 0x49, 0x56, 0x7a, 0x6d, 0x50, 0x1b, 0x2a, 0x58, 0xac,
|
||||
0xb9, 0x6e, 0x4b, 0xbc, 0x2b, 0xbd, 0x3e, 0xa8, 0x0d, 0x5b, 0x58, 0xac, 0x8d, 0x57, 0xd0, 0xb3,
|
||||
0x37, 0xe4, 0x92, 0x4a, 0x3f, 0x1d, 0x3a, 0x5b, 0x72, 0xbd, 0x8e, 0x88, 0x2f, 0x5c, 0x7b, 0x58,
|
||||
0x8a, 0xe8, 0x31, 0x34, 0xd9, 0xf5, 0x96, 0x0a, 0xef, 0xfe, 0x93, 0x5b, 0x23, 0x89, 0x64, 0x24,
|
||||
0xfc, 0xdd, 0xeb, 0x2d, 0xc5, 0xc2, 0xc0, 0xf8, 0xbd, 0x06, 0x3d, 0x73, 0xe7, 0x07, 0xd1, 0xfb,
|
||||
0x63, 0x3e, 0xad, 0xc4, 0x1c, 0x14, 0x31, 0xcb, 0xfe, 0xa9, 0x50, 0x24, 0x40, 0x0f, 0x40, 0xf5,
|
||||
0x77, 0x31, 0x61, 0x41, 0x14, 0x2e, 0x37, 0x89, 0xde, 0x18, 0xd4, 0x86, 0x4d, 0x0c, 0x52, 0x35,
|
||||
0x4d, 0x8c, 0xcf, 0x41, 0xc9, 0x7d, 0xd0, 0x1d, 0x40, 0x8b, 0xd9, 0xcb, 0xd9, 0xfc, 0xfb, 0xd9,
|
||||
0xd2, 0x5c, 0x4c, 0xec, 0xf9, 0xd2, 0x7d, 0x7d, 0x6e, 0x69, 0x47, 0xa8, 0x03, 0x0d, 0xd3, 0x1c,
|
||||
0x6b, 0x35, 0xb1, 0x98, 0x62, 0xad, 0x6e, 0xfc, 0x51, 0x03, 0xd5, 0xf2, 0x03, 0x26, 0x71, 0xdf,
|
||||
0x86, 0x96, 0xb7, 0x8e, 0xbc, 0x2b, 0x81, 0xba, 0x89, 0x53, 0x81, 0xb3, 0xc8, 0xe8, 0xcf, 0x4c,
|
||||
0x60, 0x56, 0xb0, 0x58, 0xa3, 0x53, 0xe8, 0x88, 0x62, 0x05, 0xbe, 0x40, 0xa3, 0xe0, 0x36, 0x17,
|
||||
0x6d, 0x1f, 0x7d, 0x02, 0x90, 0x15, 0x90, 0xff, 0x6b, 0x8a, 0x7f, 0x4a, 0xa6, 0xb1, 0x7d, 0x9e,
|
||||
0xe1, 0x32, 0x26, 0x21, 0xd3, 0x5b, 0x82, 0x97, 0x54, 0x40, 0xcf, 0xa0, 0x27, 0x9d, 0x04, 0x3b,
|
||||
0x6d, 0xc1, 0xce, 0xff, 0x0b, 0x76, 0x32, 0x80, 0x82, 0x12, 0x75, 0x53, 0x08, 0xc6, 0x6f, 0x35,
|
||||
0x38, 0x9e, 0xd0, 0x35, 0x65, 0xf4, 0xe6, 0x3d, 0x94, 0xf0, 0xd6, 0x6f, 0xc0, 0xdb, 0x38, 0x88,
|
||||
0xb7, 0x79, 0x13, 0xde, 0xd6, 0x07, 0xe3, 0xb5, 0x01, 0xa5, 0x70, 0xbf, 0x8e, 0xe2, 0xe9, 0x7b,
|
||||
0x30, 0x57, 0xa1, 0xd5, 0xf7, 0xa0, 0x19, 0x7f, 0xd6, 0xa1, 0x3f, 0x09, 0x12, 0x2f, 0x8a, 0x7d,
|
||||
0x19, 0xa7, 0x0f, 0xf5, 0xc0, 0xcf, 0x4e, 0x40, 0x3d, 0xf0, 0x45, 0xe5, 0x64, 0xb7, 0x29, 0x59,
|
||||
0x2f, 0xdd, 0x03, 0x85, 0x05, 0x1b, 0x9a, 0x30, 0xb2, 0xd9, 0xca, 0xfd, 0xe6, 0x0a, 0x34, 0x84,
|
||||
0x93, 0x5c, 0xe0, 0x9d, 0x41, 0x65, 0x0d, 0xf7, 0xd5, 0xbc, 0xc7, 0xbd, 0x28, 0x64, 0x34, 0xab,
|
||||
0xa5, 0x82, 0xa5, 0x88, 0xbe, 0x80, 0x36, 0xd9, 0xb1, 0x55, 0x14, 0x8b, 0x3a, 0xaa, 0x4f, 0xee,
|
||||
0x17, 0xbc, 0x54, 0xf1, 0x9a, 0xc2, 0x0a, 0x67, 0xd6, 0xe8, 0x2b, 0x50, 0x62, 0x7a, 0x41, 0x63,
|
||||
0x1a, 0x7a, 0x54, 0xef, 0x08, 0xd7, 0x87, 0x87, 0x5c, 0xb1, 0x34, 0xc4, 0x85, 0x0f, 0x9a, 0x80,
|
||||
0x4a, 0x18, 0x23, 0xde, 0x6a, 0x43, 0x43, 0x96, 0xe8, 0xdd, 0x41, 0x63, 0xa8, 0x3e, 0x31, 0x0e,
|
||||
0x66, 0xcf, 0x4d, 0x71, 0xd9, 0xcd, 0xf8, 0xab, 0x06, 0xb7, 0xdf, 0x85, 0xf3, 0x5d, 0xec, 0x86,
|
||||
0x64, 0x93, 0xb3, 0xcb, 0xd7, 0xe8, 0x11, 0x1c, 0xfb, 0x41, 0xe2, 0xc5, 0xc1, 0x26, 0x08, 0x09,
|
||||
0x8b, 0xe2, 0x8c, 0xe1, 0xaa, 0x12, 0xdd, 0x85, 0x6e, 0x18, 0x78, 0x57, 0xc2, 0x3b, 0xa5, 0x37,
|
||||
0x97, 0x79, 0x7d, 0xc8, 0x5b, 0xc2, 0x48, 0xbc, 0x88, 0xd7, 0x19, 0xb3, 0x85, 0x02, 0x8d, 0x00,
|
||||
0xa5, 0x82, 0x98, 0x41, 0xe7, 0xd9, 0x90, 0x69, 0x8b, 0xe6, 0x7c, 0xc7, 0x1f, 0x9e, 0x69, 0x1d,
|
||||
0x79, 0x64, 0xcd, 0x83, 0x75, 0xd2, 0x4c, 0x52, 0x36, 0x22, 0x38, 0x3d, 0x40, 0x2a, 0x07, 0x91,
|
||||
0x37, 0x5a, 0xb6, 0xe3, 0xd2, 0xa1, 0xb8, 0x07, 0x8a, 0xb7, 0x22, 0x61, 0x48, 0xd7, 0x76, 0xde,
|
||||
0x97, 0xb9, 0x82, 0x37, 0xc6, 0xe5, 0x2e, 0x58, 0xfb, 0xb6, 0x3c, 0x4e, 0x52, 0x34, 0xfe, 0xa9,
|
||||
0x81, 0x7e, 0xa8, 0x06, 0xff, 0x61, 0xb7, 0x02, 0x61, 0xbf, 0xf9, 0x91, 0x06, 0x8d, 0x5d, 0xbc,
|
||||
0xce, 0x12, 0xf0, 0x25, 0xdf, 0xe9, 0x45, 0xb0, 0xa6, 0xb3, 0x12, 0xa7, 0x52, 0xe6, 0x55, 0xe1,
|
||||
0x6b, 0x27, 0xf8, 0x85, 0x3e, 0xbf, 0x66, 0x34, 0x11, 0xbc, 0x36, 0x71, 0x55, 0x89, 0x06, 0xa0,
|
||||
0x66, 0x2d, 0xec, 0xca, 0x21, 0xa4, 0xe0, 0xb2, 0xaa, 0x3c, 0xd7, 0x3b, 0xd5, 0xb9, 0x5e, 0xe6,
|
||||
0xb9, 0xbb, 0xc7, 0xf3, 0xdf, 0x5d, 0x50, 0xc7, 0x2b, 0xf2, 0x9e, 0x29, 0x5b, 0x39, 0x97, 0x75,
|
||||
0xf1, 0xa7, 0x74, 0x2e, 0xe5, 0x0c, 0x6e, 0x94, 0x66, 0xf0, 0x03, 0x50, 0x63, 0x9a, 0x6c, 0xa3,
|
||||
0x30, 0xa1, 0x4b, 0x16, 0x65, 0x9b, 0x06, 0xa9, 0x72, 0x23, 0xf4, 0x11, 0x74, 0x69, 0x98, 0x2c,
|
||||
0x45, 0x9b, 0x65, 0x67, 0x94, 0x86, 0x89, 0x60, 0xa4, 0x34, 0x0f, 0xdb, 0x95, 0x79, 0xb8, 0x3f,
|
||||
0xda, 0x3a, 0x1f, 0x3a, 0xda, 0xd0, 0x04, 0x7a, 0x19, 0x57, 0xa9, 0x67, 0x57, 0x78, 0x96, 0x4e,
|
||||
0x70, 0x89, 0x83, 0xd1, 0xb8, 0x60, 0xb5, 0x4a, 0xf1, 0x53, 0xe8, 0x24, 0xe9, 0xc5, 0xae, 0x2b,
|
||||
0x62, 0x04, 0xe8, 0x45, 0x80, 0xea, 0x8d, 0xff, 0xe2, 0x08, 0x4b, 0x53, 0x34, 0x82, 0x56, 0xc0,
|
||||
0xdb, 0x5e, 0x07, 0xe1, 0x73, 0x67, 0xef, 0xae, 0x2e, 0x3c, 0x52, 0x33, 0x6e, 0x4f, 0xf8, 0x7d,
|
||||
0xa9, 0xab, 0xfb, 0xf6, 0xe5, 0x7b, 0x98, 0xdb, 0x0b, 0x33, 0x74, 0x1f, 0x14, 0x2f, 0xda, 0x6c,
|
||||
0x76, 0x61, 0xc0, 0xae, 0xf5, 0x1e, 0x2f, 0xfd, 0x8b, 0x23, 0x5c, 0xa8, 0xd0, 0x18, 0x4e, 0xfc,
|
||||
0xb4, 0xb1, 0xe5, 0xf3, 0x45, 0xf7, 0xf6, 0xd1, 0x57, 0x3b, 0xff, 0xc5, 0x11, 0xee, 0xfb, 0xd5,
|
||||
0xe9, 0x9d, 0xdf, 0x35, 0xc7, 0xe5, 0xbb, 0xe6, 0x21, 0xf4, 0xfc, 0x20, 0xd9, 0xae, 0xc9, 0x75,
|
||||
0x5a, 0xc8, 0x7e, 0xda, 0x96, 0x99, 0x4e, 0x14, 0xf3, 0x02, 0xee, 0x27, 0x9c, 0x76, 0xce, 0x23,
|
||||
0xf1, 0xd8, 0x32, 0xa6, 0x3f, 0xed, 0x68, 0xc2, 0x96, 0x49, 0x70, 0x19, 0x12, 0xb6, 0x8b, 0xa9,
|
||||
0x7e, 0xb2, 0x3f, 0x4d, 0xc7, 0xa9, 0x29, 0x4e, 0x2d, 0x1d, 0x69, 0x88, 0x3f, 0xe6, 0x81, 0x0e,
|
||||
0xfc, 0x44, 0x21, 0x18, 0x31, 0xf5, 0x68, 0xf0, 0x96, 0xfa, 0x37, 0xe4, 0xd2, 0x3e, 0x34, 0xd7,
|
||||
0x03, 0x19, 0xec, 0x50, 0xbe, 0xc7, 0x70, 0x22, 0xd3, 0x48, 0x56, 0xff, 0x37, 0xa8, 0x0d, 0xbb,
|
||||
0xb8, 0x9f, 0xa9, 0x33, 0xe6, 0x8c, 0x5f, 0xeb, 0xa0, 0x8e, 0x2b, 0xe7, 0xf4, 0xb6, 0x7c, 0x01,
|
||||
0x8d, 0xe7, 0x33, 0xd7, 0x9a, 0xb9, 0xf2, 0x0d, 0xd4, 0x07, 0x70, 0xad, 0x1f, 0xdc, 0xe5, 0xf9,
|
||||
0xb7, 0xa6, 0x3d, 0xd3, 0x6a, 0x48, 0x85, 0x8e, 0xe3, 0xda, 0xe3, 0x97, 0x16, 0xd6, 0xea, 0x08,
|
||||
0xa0, 0xed, 0xb8, 0xa6, 0xbb, 0x70, 0xb4, 0x06, 0x52, 0xa0, 0x65, 0x4d, 0xe7, 0xdf, 0xd8, 0x5a,
|
||||
0x13, 0x9d, 0xc2, 0x2d, 0x17, 0x9b, 0x33, 0xc7, 0x1c, 0xbb, 0xf6, 0x9c, 0x47, 0x9c, 0x4e, 0xcd,
|
||||
0xd9, 0x44, 0x6b, 0xa1, 0x21, 0x3c, 0x72, 0x5e, 0x3b, 0xae, 0x35, 0x5d, 0x4e, 0x2d, 0xc7, 0x31,
|
||||
0xcf, 0xac, 0x3c, 0xdb, 0x39, 0xb6, 0xbf, 0x33, 0x5d, 0x6b, 0x79, 0x86, 0xe7, 0x8b, 0x73, 0xad,
|
||||
0xcd, 0xa3, 0xd9, 0x53, 0xf3, 0xcc, 0xd2, 0x3a, 0x7c, 0x29, 0x5e, 0x65, 0x5a, 0x17, 0x1d, 0x83,
|
||||
0xc2, 0x83, 0x2d, 0x66, 0xb6, 0xfb, 0x5a, 0x53, 0xf8, 0xbb, 0x6d, 0x2f, 0xdc, 0x99, 0x79, 0xae,
|
||||
0x01, 0xba, 0x05, 0x27, 0x3c, 0xae, 0x39, 0x76, 0x97, 0xd8, 0x7a, 0xb5, 0xb0, 0x1c, 0x57, 0x53,
|
||||
0xb9, 0x72, 0x62, 0x3b, 0xe3, 0x39, 0x9e, 0x48, 0x6b, 0xad, 0xf7, 0x5c, 0xc9, 0xe7, 0x93, 0xb1,
|
||||
0x80, 0xd3, 0x43, 0xb4, 0xde, 0x03, 0xa5, 0xa8, 0x56, 0xfa, 0x3e, 0x2d, 0x14, 0x37, 0xcf, 0xa1,
|
||||
0xe7, 0xc7, 0x3f, 0xaa, 0xa3, 0x4f, 0xbf, 0x94, 0xa5, 0x7d, 0xd3, 0x16, 0xab, 0xcf, 0xfe, 0x0d,
|
||||
0x00, 0x00, 0xff, 0xff, 0xc9, 0x29, 0xc8, 0x51, 0xba, 0x0b, 0x00, 0x00,
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@ message DiscordMessage {
|
|||
string content = 5;
|
||||
DiscordMessageAuthor author = 6;
|
||||
DiscordMessageReference reference = 7;
|
||||
repeated DiscordMessageAttachment attachments = 8;
|
||||
}
|
||||
|
||||
message DiscordMessageAuthor {
|
||||
|
@ -85,6 +86,17 @@ message DiscordMessageReference {
|
|||
string guildId = 3;
|
||||
}
|
||||
|
||||
message DiscordMessageAttachment {
|
||||
string id = 1;
|
||||
string messageId = 2;
|
||||
string url = 3;
|
||||
string fileName = 4;
|
||||
uint64 fileSizeBytes = 5;
|
||||
string contentType = 6;
|
||||
bytes payload = 7;
|
||||
string localUrl = 8;
|
||||
}
|
||||
|
||||
message ChatMessage {
|
||||
// Lamport timestamp of the chat message
|
||||
uint64 clock = 1;
|
||||
|
|
Loading…
Reference in New Issue