feat: add discord_messages table and persistence APIs

This adds a new `discord_messages` table and extends the persistence
APIs such that `MessagesByID` and `MessageByID` will return user
messages that include their discord message payload.

It also adds APIs to save individual discord messages.
This commit is contained in:
Pascal Precht 2022-08-04 18:16:56 +02:00 committed by r4bbit.eth
parent d0e0deac95
commit 081974da1e
8 changed files with 517 additions and 77 deletions

View File

@ -171,6 +171,8 @@ type Message struct {
// ContactRequestState is the state of the contact request message // ContactRequestState is the state of the contact request message
ContactRequestState ContactRequestState `json:"contactRequestState,omitempty"` ContactRequestState ContactRequestState `json:"contactRequestState,omitempty"`
DiscordMessage *protobuf.DiscordMessage `json:"discordMessage,omitempty"`
} }
func (m *Message) MarshalJSON() ([]byte, error) { func (m *Message) MarshalJSON() ([]byte, error) {
@ -216,6 +218,7 @@ func (m *Message) MarshalJSON() ([]byte, error) {
EditedAt uint64 `json:"editedAt,omitempty"` EditedAt uint64 `json:"editedAt,omitempty"`
Deleted bool `json:"deleted,omitempty"` Deleted bool `json:"deleted,omitempty"`
ContactRequestState ContactRequestState `json:"contactRequestState,omitempty"` ContactRequestState ContactRequestState `json:"contactRequestState,omitempty"`
DiscordMessage *protobuf.DiscordMessage `json:"discordMessage,omitempty"`
}{ }{
ID: m.ID, ID: m.ID,
WhisperTimestamp: m.WhisperTimestamp, WhisperTimestamp: m.WhisperTimestamp,
@ -264,6 +267,10 @@ func (m *Message) MarshalJSON() ([]byte, error) {
item.AudioDurationMs = audio.DurationMs item.AudioDurationMs = audio.DurationMs
} }
if discordMessage := m.GetDiscordMessage(); discordMessage != nil {
item.DiscordMessage = discordMessage
}
return json.Marshal(item) return json.Marshal(item)
} }

View File

@ -14,6 +14,13 @@ const (
Error Error
) )
type MessageType string
const (
MessageTypeDefault MessageType = "Default"
MessageTypeReply MessageType = "Reply"
)
type Channel struct { type Channel struct {
ID string `json:"id"` ID string `json:"id"`
CategoryName string `json:"category"` CategoryName string `json:"category"`

View File

@ -55,7 +55,8 @@ func (db sqlitePersistence) tableUserMessagesAllFields() string {
gap_from, gap_from,
gap_to, gap_to,
contact_request_state, contact_request_state,
mentioned` mentioned,
discord_message_id`
} }
func (db sqlitePersistence) tableUserMessagesAllFieldsJoin() string { func (db sqlitePersistence) tableUserMessagesAllFieldsJoin() string {
@ -99,6 +100,18 @@ func (db sqlitePersistence) tableUserMessagesAllFieldsJoin() string {
m1.gap_to, m1.gap_to,
m1.contact_request_state, m1.contact_request_state,
m1.mentioned, m1.mentioned,
COALESCE(m1.discord_message_id, ""),
COALESCE(dm.author_id, ""),
COALESCE(dm.type, ""),
COALESCE(dm.timestamp, ""),
COALESCE(dm.timestamp_edited, ""),
COALESCE(dm.content, ""),
COALESCE(dm.reference_message_id, ""),
COALESCE(dm.reference_channel_id, ""),
COALESCE(dm_author.name, ""),
COALESCE(dm_author.discriminator, ""),
COALESCE(dm_author.nickname, ""),
COALESCE(dm_author.avatar_url, ""),
m2.source, m2.source,
m2.text, m2.text,
m2.parsed_text, m2.parsed_text,
@ -141,6 +154,10 @@ func (db sqlitePersistence) tableUserMessagesScanAllFields(row scanner, message
command := &common.CommandParameters{} command := &common.CommandParameters{}
audio := &protobuf.AudioMessage{} audio := &protobuf.AudioMessage{}
image := &protobuf.ImageMessage{} image := &protobuf.ImageMessage{}
discordMessage := &protobuf.DiscordMessage{
Author: &protobuf.DiscordMessageAuthor{},
Reference: &protobuf.DiscordMessageReference{},
}
args := []interface{}{ args := []interface{}{
&message.ID, &message.ID,
@ -183,6 +200,18 @@ func (db sqlitePersistence) tableUserMessagesScanAllFields(row scanner, message
&gapTo, &gapTo,
&contactRequestState, &contactRequestState,
&message.Mentioned, &message.Mentioned,
&discordMessage.Id,
&discordMessage.Author.Id,
&discordMessage.Type,
&discordMessage.Timestamp,
&discordMessage.TimestampEdited,
&discordMessage.Content,
&discordMessage.Reference.MessageId,
&discordMessage.Reference.ChannelId,
&discordMessage.Author.Name,
&discordMessage.Author.Discriminator,
&discordMessage.Author.Nickname,
&discordMessage.Author.AvatarUrl,
&quotedFrom, &quotedFrom,
&quotedText, &quotedText,
&quotedParsedText, &quotedParsedText,
@ -263,6 +292,11 @@ func (db sqlitePersistence) tableUserMessagesScanAllFields(row scanner, message
Type: image.Type, Type: image.Type,
} }
message.Payload = &protobuf.ChatMessage_Image{Image: &img} message.Payload = &protobuf.ChatMessage_Image{Image: &img}
case protobuf.ChatMessage_DISCORD_MESSAGE:
message.Payload = &protobuf.ChatMessage_DiscordMessage{
DiscordMessage: discordMessage,
}
} }
return nil return nil
@ -291,6 +325,14 @@ func (db sqlitePersistence) tableUserMessagesAllValues(message *common.Message)
command = &common.CommandParameters{} command = &common.CommandParameters{}
} }
discordMessage := message.GetDiscordMessage()
if discordMessage == nil {
discordMessage = &protobuf.DiscordMessage{
Author: &protobuf.DiscordMessageAuthor{},
Reference: &protobuf.DiscordMessageReference{},
}
}
if message.GapParameters != nil { if message.GapParameters != nil {
gapFrom = message.GapParameters.From gapFrom = message.GapParameters.From
gapTo = message.GapParameters.To gapTo = message.GapParameters.To
@ -358,6 +400,7 @@ func (db sqlitePersistence) tableUserMessagesAllValues(message *common.Message)
gapTo, gapTo,
message.ContactRequestState, message.ContactRequestState,
message.Mentioned, message.Mentioned,
discordMessage.Id,
}, nil }, nil
} }
@ -396,6 +439,17 @@ func (db sqlitePersistence) messageByID(tx *sql.Tx, id string) (*common.Message,
contacts c contacts c
ON ON
m1.source = c.id m1.source = c.id
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
WHERE WHERE
m1.id = ? m1.id = ?
`, allFields), `, allFields),
@ -432,6 +486,17 @@ func (db sqlitePersistence) MessageByCommandID(chatID, id string) (*common.Messa
contacts c contacts c
ON ON
m1.source = c.id m1.source = c.id
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
WHERE WHERE
m1.command_id = ? m1.command_id = ?
AND AND
@ -515,8 +580,19 @@ func (db sqlitePersistence) MessagesByIDs(ids []string) ([]*common.Message, erro
LEFT JOIN LEFT JOIN
contacts c contacts c
ON ON
m1.source = c.id m1.source = c.id
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
WHERE NOT(m1.hide) AND m1.id IN (%s)`, allFields, inVector), idsArgs...) WHERE NOT(m1.hide) AND m1.id IN (%s)`, allFields, inVector), idsArgs...)
if err != nil { if err != nil {
return nil, err return nil, err
@ -568,6 +644,17 @@ func (db sqlitePersistence) MessageByChatID(chatID string, currCursor string, li
ON ON
m1.source = c.id m1.source = c.id
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
WHERE WHERE
NOT(m1.hide) AND m1.local_chat_id = ? %s NOT(m1.hide) AND m1.local_chat_id = ? %s
ORDER BY cursor DESC ORDER BY cursor DESC
@ -653,6 +740,17 @@ func (db sqlitePersistence) PendingContactRequests(currCursor string, limit int)
ON ON
m1.source = c.id m1.source = c.id
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
WHERE WHERE
NOT(m1.hide) AND NOT(m1.seen) AND m1.content_type = ? %s NOT(m1.hide) AND NOT(m1.seen) AND m1.content_type = ? %s
ORDER BY cursor DESC ORDER BY cursor DESC
@ -747,6 +845,17 @@ func (db sqlitePersistence) AllMessageByChatIDWhichMatchTerm(chatID string, sear
ON ON
m1.source = c.id m1.source = c.id
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
WHERE WHERE
NOT(m1.hide) AND m1.local_chat_id = ? %s NOT(m1.hide) AND m1.local_chat_id = ? %s
ORDER BY cursor DESC ORDER BY cursor DESC
@ -848,6 +957,17 @@ func (db sqlitePersistence) AllMessagesFromChatsAndCommunitiesWhichMatchTerm(com
ON ON
m1.source = c.id m1.source = c.id
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
WHERE WHERE
NOT(m1.hide) %s NOT(m1.hide) %s
ORDER BY cursor DESC ORDER BY cursor DESC
@ -944,6 +1064,17 @@ func (db sqlitePersistence) PinnedMessageByChatIDs(chatIDs []string, currCursor
contacts c contacts c
ON ON
m1.source = c.id m1.source = c.id
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
WHERE WHERE
pm.pinned = 1 pm.pinned = 1
AND NOT(m1.hide) AND m1.local_chat_id IN %s %s AND NOT(m1.hide) AND m1.local_chat_id IN %s %s
@ -1029,6 +1160,17 @@ func (db sqlitePersistence) MessageByChatIDs(chatIDs []string, currCursor string
ON ON
m1.source = c.id m1.source = c.id
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
WHERE WHERE
NOT(m1.hide) AND m1.local_chat_id IN %s %s NOT(m1.hide) AND m1.local_chat_id IN %s %s
ORDER BY cursor DESC ORDER BY cursor DESC
@ -1758,6 +1900,67 @@ func (db sqlitePersistence) SaveDiscordMessageAuthor(author *protobuf.DiscordMes
return return
} }
func (db sqlitePersistence) SaveDiscordMessage(message *protobuf.DiscordMessage) (err error) {
query := "INSERT INTO discord_messages(id,type,timestamp,timestamp_edited,content,author_id, reference_message_id, reference_channel_id, reference_guild_id) VALUES (?,?,?,?,?,?,?,?,?)"
stmt, err := db.db.Prepare(query)
if err != nil {
return
}
defer stmt.Close()
_, err = stmt.Exec(
message.GetId(),
message.GetType(),
message.GetTimestamp(),
message.GetTimestampEdited(),
message.GetContent(),
message.Author.GetId(),
message.Reference.GetMessageId(),
message.Reference.GetChannelId(),
message.Reference.GetGuildId(),
)
return
}
func (db sqlitePersistence) SaveDiscordMessages(messages []*protobuf.DiscordMessage) (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 INTO discord_messages(id, author_id, type, timestamp, timestamp_edited, content, reference_message_id, reference_channel_id, reference_guild_id) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)"
stmt, err := tx.Prepare(query)
if err != nil {
return
}
defer stmt.Close()
for _, msg := range messages {
_, err = stmt.Exec(
msg.GetId(),
msg.GetType(),
msg.GetTimestamp(),
msg.GetTimestampEdited(),
msg.GetContent(),
msg.Author.GetId(),
msg.Reference.GetMessageId(),
msg.Reference.GetChannelId(),
msg.Reference.GetGuildId(),
)
if err != nil {
return
}
}
return
}
func (db sqlitePersistence) SaveEmojiReaction(emojiReaction *EmojiReaction) (err error) { 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 (?,?,?,?,?,?,?,?)" 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) stmt, err := db.db.Prepare(query)

View File

@ -54,6 +54,7 @@
// 1650373957_add_contact_request_state.up.sql (59B) // 1650373957_add_contact_request_state.up.sql (59B)
// 1656958989_contact_verification.up.sql (624B) // 1656958989_contact_verification.up.sql (624B)
// 1658236268_add_discord_message_authors_table.up.sql (191B) // 1658236268_add_discord_message_authors_table.up.sql (191B)
// 1659619997_add_discord_messages_table.up.sql (371B)
// README.md (554B) // README.md (554B)
// doc.go (850B) // doc.go (850B)
@ -1204,6 +1205,26 @@ func _1658236268_add_discord_message_authors_tableUpSql() (*asset, error) {
return a, nil return a, nil
} }
var __1659619997_add_discord_messages_tableUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x6c\xcf\x41\x6b\xc2\x30\x1c\x05\xf0\x7b\x3e\xc5\xc3\xd3\x06\xfb\x06\x9e\xb2\x36\x62\x58\x6c\x47\xfc\x77\xea\xa9\x94\xe6\x3f\x2d\xd8\x54\x92\xf4\xb0\x6f\x3f\x2a\xeb\x50\xf1\x98\xfc\xf2\xde\x23\xd2\x90\xb2\x20\xf9\x6e\x14\xc6\xc8\xa1\xee\x39\xc6\xe6\xc8\x11\x32\xcf\x91\x95\xa6\xda\x14\x70\x5d\x6c\x87\xe0\x66\xab\x3b\x07\x52\x7b\x42\xae\x56\xb2\x32\x84\xc5\x62\x29\x44\x66\x95\x24\xf5\x57\xa5\x57\x28\x4a\x82\xda\xeb\x2d\x6d\x1f\xf3\x11\x2f\x02\x98\x4b\x3e\xad\xde\x48\x7b\xc0\x87\x3a\x5c\x33\x45\x65\xcc\x9b\x00\x9a\x31\x9d\x86\xf0\xbf\x75\x4b\xe9\xe7\xc2\xf8\x92\x36\x5b\x4b\x7b\x0f\x5d\xcf\x31\x35\xfd\x05\xba\xa0\xe7\x52\xb3\xeb\x12\xbb\xe9\xc1\x74\xdf\x0e\x3e\xb1\x4f\xd7\x8d\xe9\x1c\xf8\x9b\x03\xfb\x96\x1f\x3f\x7b\x8f\xed\xa9\xf1\x9e\xcf\xcf\xf1\x38\x76\x67\x37\x93\x78\xc5\x4e\xd3\xba\xac\x08\xb6\xdc\xe9\x7c\x29\x7e\x03\x00\x00\xff\xff\x0b\x32\xec\x85\x73\x01\x00\x00")
func _1659619997_add_discord_messages_tableUpSqlBytes() ([]byte, error) {
return bindataRead(
__1659619997_add_discord_messages_tableUpSql,
"1659619997_add_discord_messages_table.up.sql",
)
}
func _1659619997_add_discord_messages_tableUpSql() (*asset, error) {
bytes, err := _1659619997_add_discord_messages_tableUpSqlBytes()
if err != nil {
return nil, err
}
info := bindataFileInfo{name: "1659619997_add_discord_messages_table.up.sql", size: 371, mode: os.FileMode(0664), modTime: time.Unix(1660118031, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xde, 0x12, 0x9c, 0x96, 0xe2, 0x42, 0x3f, 0x94, 0x62, 0xc2, 0x76, 0xab, 0x3b, 0x4c, 0x85, 0x36, 0x48, 0xcc, 0x73, 0x60, 0x93, 0x5a, 0xd6, 0x7, 0xd6, 0x0, 0xee, 0x1b, 0x1e, 0x34, 0x58, 0x99}}
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") 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) { func readmeMdBytes() ([]byte, error) {
@ -1443,6 +1464,8 @@ var _bindata = map[string]func() (*asset, error){
"1658236268_add_discord_message_authors_table.up.sql": _1658236268_add_discord_message_authors_tableUpSql, "1658236268_add_discord_message_authors_table.up.sql": _1658236268_add_discord_message_authors_tableUpSql,
"1659619997_add_discord_messages_table.up.sql": _1659619997_add_discord_messages_tableUpSql,
"README.md": readmeMd, "README.md": readmeMd,
"doc.go": docGo, "doc.go": docGo,
@ -1543,6 +1566,7 @@ var _bintree = &bintree{nil, map[string]*bintree{
"1650373957_add_contact_request_state.up.sql": &bintree{_1650373957_add_contact_request_stateUpSql, map[string]*bintree{}}, "1650373957_add_contact_request_state.up.sql": &bintree{_1650373957_add_contact_request_stateUpSql, map[string]*bintree{}},
"1656958989_contact_verification.up.sql": &bintree{_1656958989_contact_verificationUpSql, map[string]*bintree{}}, "1656958989_contact_verification.up.sql": &bintree{_1656958989_contact_verificationUpSql, map[string]*bintree{}},
"1658236268_add_discord_message_authors_table.up.sql": &bintree{_1658236268_add_discord_message_authors_tableUpSql, map[string]*bintree{}}, "1658236268_add_discord_message_authors_table.up.sql": &bintree{_1658236268_add_discord_message_authors_tableUpSql, map[string]*bintree{}},
"1659619997_add_discord_messages_table.up.sql": &bintree{_1659619997_add_discord_messages_tableUpSql, map[string]*bintree{}},
"README.md": &bintree{readmeMd, map[string]*bintree{}}, "README.md": &bintree{readmeMd, map[string]*bintree{}},
"doc.go": &bintree{docGo, map[string]*bintree{}}, "doc.go": &bintree{docGo, map[string]*bintree{}},
}} }}

View File

@ -0,0 +1,13 @@
ALTER TABLE user_messages ADD COLUMN discord_message_id TEXT DEFAULT "";
CREATE TABLE IF NOT EXISTS discord_messages (
id TEXT PRIMARY KEY NOT NULL,
author_id TEXT NOT NULL,
type VARCHAR NOT NULL,
timestamp INT NOT NULL,
timestamp_edited INT,
content TEXT,
reference_message_id TEXT,
reference_channel_id TEXT,
reference_guild_id TEXT
) WITHOUT ROWID;

View File

@ -74,6 +74,25 @@ func TestMessageByID(t *testing.T) {
require.EqualValues(t, id, m.ID) require.EqualValues(t, id, m.ID)
} }
func TestMessageByID_WithDiscordMessagePayload(t *testing.T) {
db, err := openTestDB()
require.NoError(t, err)
p := newSQLitePersistence(db)
id := "1"
discordMessageID := "2"
err = insertMinimalDiscordMessage(p, id, discordMessageID)
require.NoError(t, err)
m, err := p.MessageByID(id)
require.NoError(t, err)
require.EqualValues(t, id, m.ID)
require.NotNil(t, m.GetDiscordMessage())
require.EqualValues(t, discordMessageID, m.GetDiscordMessage().Id)
require.EqualValues(t, "2", m.GetDiscordMessage().Author.Id)
}
func TestMessagesExist(t *testing.T) { func TestMessagesExist(t *testing.T) {
db, err := openTestDB() db, err := openTestDB()
require.NoError(t, err) require.NoError(t, err)
@ -683,6 +702,38 @@ func insertMinimalMessage(p *sqlitePersistence, id string) error {
}}) }})
} }
func insertMinimalDiscordMessage(p *sqlitePersistence, id string, discordMessageID string) error {
discordMessage := &protobuf.DiscordMessage{
Id: discordMessageID,
Type: "Default",
Timestamp: "123456",
Content: "This is the message",
Author: &protobuf.DiscordMessageAuthor{
Id: "2",
},
Reference: &protobuf.DiscordMessageReference{},
}
err := p.SaveDiscordMessage(discordMessage)
if err != nil {
return err
}
return p.SaveMessages([]*common.Message{{
ID: id,
LocalChatID: testPublicChatID,
From: "me",
ChatMessage: protobuf.ChatMessage{
Text: "some-text",
ContentType: protobuf.ChatMessage_DISCORD_MESSAGE,
ChatId: testPublicChatID,
Payload: &protobuf.ChatMessage_DiscordMessage{
DiscordMessage: discordMessage,
},
},
}})
}
func minimalRawMessage(id string, messageType protobuf.ApplicationMetadataMessage_Type) *common.RawMessage { func minimalRawMessage(id string, messageType protobuf.ApplicationMetadataMessage_Type) *common.RawMessage {
return &common.RawMessage{ return &common.RawMessage{
ID: id, ID: id,
@ -1332,3 +1383,41 @@ func TestSaveDiscordMessageAuthor(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.True(t, exists) require.True(t, exists)
} }
func TestSaveDiscordMessage(t *testing.T) {
db, err := openTestDB()
require.NoError(t, err)
p := newSQLitePersistence(db)
require.NoError(t, p.SaveDiscordMessage(&protobuf.DiscordMessage{
Id: "1",
Type: "Default",
Timestamp: "123456",
Content: "This is the message",
Author: &protobuf.DiscordMessageAuthor{
Id: "2",
},
Reference: &protobuf.DiscordMessageReference{},
}))
require.NoError(t, err)
}
func TestSaveDiscordMessages(t *testing.T) {
db, err := openTestDB()
require.NoError(t, err)
p := newSQLitePersistence(db)
for i := 0; i < 10; i++ {
id := strconv.Itoa(i)
err := insertMinimalDiscordMessage(p, id, id)
require.NoError(t, err)
m, err := p.MessageByID(id)
require.NoError(t, err)
dm := m.GetDiscordMessage()
require.NotNil(t, dm)
require.EqualValues(t, id, dm.Id)
}
}

View File

@ -65,6 +65,7 @@ const (
// Only local // Only local
ChatMessage_SYSTEM_MESSAGE_GAP ChatMessage_ContentType = 10 ChatMessage_SYSTEM_MESSAGE_GAP ChatMessage_ContentType = 10
ChatMessage_CONTACT_REQUEST ChatMessage_ContentType = 11 ChatMessage_CONTACT_REQUEST ChatMessage_ContentType = 11
ChatMessage_DISCORD_MESSAGE ChatMessage_ContentType = 12
) )
var ChatMessage_ContentType_name = map[int32]string{ var ChatMessage_ContentType_name = map[int32]string{
@ -80,6 +81,7 @@ var ChatMessage_ContentType_name = map[int32]string{
9: "COMMUNITY", 9: "COMMUNITY",
10: "SYSTEM_MESSAGE_GAP", 10: "SYSTEM_MESSAGE_GAP",
11: "CONTACT_REQUEST", 11: "CONTACT_REQUEST",
12: "DISCORD_MESSAGE",
} }
var ChatMessage_ContentType_value = map[string]int32{ var ChatMessage_ContentType_value = map[string]int32{
@ -95,6 +97,7 @@ var ChatMessage_ContentType_value = map[string]int32{
"COMMUNITY": 9, "COMMUNITY": 9,
"SYSTEM_MESSAGE_GAP": 10, "SYSTEM_MESSAGE_GAP": 10,
"CONTACT_REQUEST": 11, "CONTACT_REQUEST": 11,
"DISCORD_MESSAGE": 12,
} }
func (x ChatMessage_ContentType) String() string { func (x ChatMessage_ContentType) String() string {
@ -102,7 +105,7 @@ func (x ChatMessage_ContentType) String() string {
} }
func (ChatMessage_ContentType) EnumDescriptor() ([]byte, []int) { func (ChatMessage_ContentType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_263952f55fd35689, []int{7, 0} return fileDescriptor_263952f55fd35689, []int{8, 0}
} }
type StickerMessage struct { type StickerMessage struct {
@ -410,15 +413,16 @@ func (m *DeleteMessage) GetMessageType() MessageType {
} }
type DiscordMessage struct { type DiscordMessage struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,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"` Timestamp string `protobuf:"bytes,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"`
TimestampEdited string `protobuf:"bytes,4,opt,name=timestampEdited,proto3" json:"timestampEdited,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"` Content string `protobuf:"bytes,5,opt,name=content,proto3" json:"content,omitempty"`
Author *DiscordMessageAuthor `protobuf:"bytes,6,opt,name=author,proto3" json:"author,omitempty"` Author *DiscordMessageAuthor `protobuf:"bytes,6,opt,name=author,proto3" json:"author,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` Reference *DiscordMessageReference `protobuf:"bytes,7,opt,name=reference,proto3" json:"reference,omitempty"`
XXX_unrecognized []byte `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
} }
func (m *DiscordMessage) Reset() { *m = DiscordMessage{} } func (m *DiscordMessage) Reset() { *m = DiscordMessage{} }
@ -488,6 +492,13 @@ func (m *DiscordMessage) GetAuthor() *DiscordMessageAuthor {
return nil return nil
} }
func (m *DiscordMessage) GetReference() *DiscordMessageReference {
if m != nil {
return m.Reference
}
return nil
}
type DiscordMessageAuthor struct { type DiscordMessageAuthor struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
@ -559,6 +570,61 @@ func (m *DiscordMessageAuthor) GetAvatarUrl() string {
return "" return ""
} }
type DiscordMessageReference struct {
MessageId string `protobuf:"bytes,1,opt,name=messageId,proto3" json:"messageId,omitempty"`
ChannelId string `protobuf:"bytes,2,opt,name=channelId,proto3" json:"channelId,omitempty"`
GuildId string `protobuf:"bytes,3,opt,name=guildId,proto3" json:"guildId,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *DiscordMessageReference) Reset() { *m = DiscordMessageReference{} }
func (m *DiscordMessageReference) String() string { return proto.CompactTextString(m) }
func (*DiscordMessageReference) ProtoMessage() {}
func (*DiscordMessageReference) Descriptor() ([]byte, []int) {
return fileDescriptor_263952f55fd35689, []int{7}
}
func (m *DiscordMessageReference) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_DiscordMessageReference.Unmarshal(m, b)
}
func (m *DiscordMessageReference) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_DiscordMessageReference.Marshal(b, m, deterministic)
}
func (m *DiscordMessageReference) XXX_Merge(src proto.Message) {
xxx_messageInfo_DiscordMessageReference.Merge(m, src)
}
func (m *DiscordMessageReference) XXX_Size() int {
return xxx_messageInfo_DiscordMessageReference.Size(m)
}
func (m *DiscordMessageReference) XXX_DiscardUnknown() {
xxx_messageInfo_DiscordMessageReference.DiscardUnknown(m)
}
var xxx_messageInfo_DiscordMessageReference proto.InternalMessageInfo
func (m *DiscordMessageReference) GetMessageId() string {
if m != nil {
return m.MessageId
}
return ""
}
func (m *DiscordMessageReference) GetChannelId() string {
if m != nil {
return m.ChannelId
}
return ""
}
func (m *DiscordMessageReference) GetGuildId() string {
if m != nil {
return m.GuildId
}
return ""
}
type ChatMessage struct { type ChatMessage struct {
// Lamport timestamp of the chat message // Lamport timestamp of the chat message
Clock uint64 `protobuf:"varint,1,opt,name=clock,proto3" json:"clock,omitempty"` Clock uint64 `protobuf:"varint,1,opt,name=clock,proto3" json:"clock,omitempty"`
@ -585,6 +651,7 @@ type ChatMessage struct {
// *ChatMessage_Image // *ChatMessage_Image
// *ChatMessage_Audio // *ChatMessage_Audio
// *ChatMessage_Community // *ChatMessage_Community
// *ChatMessage_DiscordMessage
Payload isChatMessage_Payload `protobuf_oneof:"payload"` Payload isChatMessage_Payload `protobuf_oneof:"payload"`
// Grant for community chat messages // Grant for community chat messages
Grant []byte `protobuf:"bytes,13,opt,name=grant,proto3" json:"grant,omitempty"` Grant []byte `protobuf:"bytes,13,opt,name=grant,proto3" json:"grant,omitempty"`
@ -602,7 +669,7 @@ func (m *ChatMessage) Reset() { *m = ChatMessage{} }
func (m *ChatMessage) String() string { return proto.CompactTextString(m) } func (m *ChatMessage) String() string { return proto.CompactTextString(m) }
func (*ChatMessage) ProtoMessage() {} func (*ChatMessage) ProtoMessage() {}
func (*ChatMessage) Descriptor() ([]byte, []int) { func (*ChatMessage) Descriptor() ([]byte, []int) {
return fileDescriptor_263952f55fd35689, []int{7} return fileDescriptor_263952f55fd35689, []int{8}
} }
func (m *ChatMessage) XXX_Unmarshal(b []byte) error { func (m *ChatMessage) XXX_Unmarshal(b []byte) error {
@ -699,6 +766,10 @@ type ChatMessage_Community struct {
Community []byte `protobuf:"bytes,12,opt,name=community,proto3,oneof"` Community []byte `protobuf:"bytes,12,opt,name=community,proto3,oneof"`
} }
type ChatMessage_DiscordMessage struct {
DiscordMessage *DiscordMessage `protobuf:"bytes,99,opt,name=discord_message,json=discordMessage,proto3,oneof"`
}
func (*ChatMessage_Sticker) isChatMessage_Payload() {} func (*ChatMessage_Sticker) isChatMessage_Payload() {}
func (*ChatMessage_Image) isChatMessage_Payload() {} func (*ChatMessage_Image) isChatMessage_Payload() {}
@ -707,6 +778,8 @@ func (*ChatMessage_Audio) isChatMessage_Payload() {}
func (*ChatMessage_Community) isChatMessage_Payload() {} func (*ChatMessage_Community) isChatMessage_Payload() {}
func (*ChatMessage_DiscordMessage) isChatMessage_Payload() {}
func (m *ChatMessage) GetPayload() isChatMessage_Payload { func (m *ChatMessage) GetPayload() isChatMessage_Payload {
if m != nil { if m != nil {
return m.Payload return m.Payload
@ -742,6 +815,13 @@ func (m *ChatMessage) GetCommunity() []byte {
return nil return nil
} }
func (m *ChatMessage) GetDiscordMessage() *DiscordMessage {
if x, ok := m.GetPayload().(*ChatMessage_DiscordMessage); ok {
return x.DiscordMessage
}
return nil
}
func (m *ChatMessage) GetGrant() []byte { func (m *ChatMessage) GetGrant() []byte {
if m != nil { if m != nil {
return m.Grant return m.Grant
@ -784,6 +864,7 @@ func (*ChatMessage) XXX_OneofWrappers() []interface{} {
(*ChatMessage_Image)(nil), (*ChatMessage_Image)(nil),
(*ChatMessage_Audio)(nil), (*ChatMessage_Audio)(nil),
(*ChatMessage_Community)(nil), (*ChatMessage_Community)(nil),
(*ChatMessage_DiscordMessage)(nil),
} }
} }
@ -799,7 +880,7 @@ func (m *ContactRequestSignature) Reset() { *m = ContactRequestSignature
func (m *ContactRequestSignature) String() string { return proto.CompactTextString(m) } func (m *ContactRequestSignature) String() string { return proto.CompactTextString(m) }
func (*ContactRequestSignature) ProtoMessage() {} func (*ContactRequestSignature) ProtoMessage() {}
func (*ContactRequestSignature) Descriptor() ([]byte, []int) { func (*ContactRequestSignature) Descriptor() ([]byte, []int) {
return fileDescriptor_263952f55fd35689, []int{8} return fileDescriptor_263952f55fd35689, []int{9}
} }
func (m *ContactRequestSignature) XXX_Unmarshal(b []byte) error { func (m *ContactRequestSignature) XXX_Unmarshal(b []byte) error {
@ -844,6 +925,7 @@ func init() {
proto.RegisterType((*DeleteMessage)(nil), "protobuf.DeleteMessage") proto.RegisterType((*DeleteMessage)(nil), "protobuf.DeleteMessage")
proto.RegisterType((*DiscordMessage)(nil), "protobuf.DiscordMessage") proto.RegisterType((*DiscordMessage)(nil), "protobuf.DiscordMessage")
proto.RegisterType((*DiscordMessageAuthor)(nil), "protobuf.DiscordMessageAuthor") proto.RegisterType((*DiscordMessageAuthor)(nil), "protobuf.DiscordMessageAuthor")
proto.RegisterType((*DiscordMessageReference)(nil), "protobuf.DiscordMessageReference")
proto.RegisterType((*ChatMessage)(nil), "protobuf.ChatMessage") proto.RegisterType((*ChatMessage)(nil), "protobuf.ChatMessage")
proto.RegisterType((*ContactRequestSignature)(nil), "protobuf.ContactRequestSignature") proto.RegisterType((*ContactRequestSignature)(nil), "protobuf.ContactRequestSignature")
} }
@ -851,67 +933,73 @@ func init() {
func init() { proto.RegisterFile("chat_message.proto", fileDescriptor_263952f55fd35689) } func init() { proto.RegisterFile("chat_message.proto", fileDescriptor_263952f55fd35689) }
var fileDescriptor_263952f55fd35689 = []byte{ var fileDescriptor_263952f55fd35689 = []byte{
// 983 bytes of a gzipped FileDescriptorProto // 1075 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x55, 0xcd, 0x6e, 0xdb, 0x46, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x56, 0xcf, 0x6e, 0xdb, 0xc6,
0x10, 0x0e, 0x65, 0xfd, 0x71, 0x28, 0xcb, 0xec, 0xda, 0x8d, 0xd9, 0x34, 0xb5, 0x1d, 0x22, 0x40, 0x13, 0x36, 0x65, 0xfd, 0xe3, 0x50, 0x96, 0xf9, 0x5b, 0xfb, 0x17, 0xb3, 0xa9, 0x6b, 0x3b, 0x44,
0x74, 0x52, 0x81, 0x34, 0x2d, 0x02, 0xf4, 0xc4, 0xc8, 0x84, 0xc3, 0xa6, 0xa2, 0x9c, 0x25, 0xd5, 0x80, 0xe8, 0xa4, 0x02, 0x69, 0x5a, 0x04, 0xe8, 0xa1, 0x60, 0x24, 0xc2, 0x66, 0x53, 0x49, 0xce,
0xd6, 0xbd, 0x10, 0x1b, 0x72, 0x63, 0x13, 0x36, 0x49, 0x95, 0x5c, 0x05, 0xf5, 0x9b, 0x14, 0x7d, 0x92, 0x6a, 0xeb, 0x5e, 0x88, 0x0d, 0xb9, 0xb6, 0x08, 0x8b, 0xa4, 0x4a, 0x52, 0x41, 0xfd, 0x00,
0x87, 0x5e, 0x7b, 0xed, 0x1b, 0xf4, 0x59, 0xfa, 0x08, 0xc5, 0x2e, 0xb9, 0x22, 0x25, 0xc4, 0x8a, 0x3d, 0xf7, 0xde, 0x77, 0xe8, 0xb5, 0xd7, 0xbe, 0x53, 0x9f, 0xa0, 0xd8, 0x25, 0x57, 0xa4, 0x84,
0x4f, 0xdc, 0x99, 0xfd, 0x66, 0xf6, 0xdb, 0x6f, 0x86, 0xb3, 0x80, 0xc2, 0x2b, 0xc2, 0x82, 0x84, 0x48, 0xf1, 0x49, 0x3b, 0xb3, 0x33, 0xb3, 0x1f, 0xbf, 0xf9, 0x76, 0x56, 0x80, 0xbc, 0x19, 0xc9,
0x16, 0x05, 0xb9, 0xa4, 0xe3, 0x45, 0x9e, 0xb1, 0x0c, 0xf5, 0xc5, 0xe7, 0xdd, 0xf2, 0xfd, 0x23, 0xdc, 0x90, 0xa6, 0x29, 0xb9, 0xa3, 0xfd, 0x45, 0x12, 0x67, 0x31, 0x6a, 0xf3, 0x9f, 0xf7, 0xcb,
0x8d, 0xa6, 0xcb, 0xa4, 0x28, 0xdd, 0xe6, 0x4b, 0x18, 0x7a, 0x2c, 0x0e, 0xaf, 0x69, 0x3e, 0x2d, 0xdb, 0xa7, 0x0a, 0x8d, 0x96, 0x61, 0x9a, 0xbb, 0xf5, 0xd7, 0xd0, 0xb5, 0xb3, 0xc0, 0xbb, 0xa7,
0xe1, 0x08, 0x41, 0xfb, 0x8a, 0x14, 0x57, 0x86, 0x72, 0xa2, 0x8c, 0x54, 0x2c, 0xd6, 0xdc, 0xb7, 0xc9, 0x28, 0x0f, 0x47, 0x08, 0xea, 0x33, 0x92, 0xce, 0x34, 0xe9, 0x42, 0xea, 0xc9, 0x98, 0xaf,
0x20, 0xe1, 0xb5, 0xd1, 0x3a, 0x51, 0x46, 0x1d, 0x2c, 0xd6, 0xe6, 0x5b, 0x18, 0x38, 0x09, 0xb9, 0x99, 0x6f, 0x41, 0xbc, 0x7b, 0xad, 0x76, 0x21, 0xf5, 0x1a, 0x98, 0xaf, 0xf5, 0x77, 0xd0, 0xb1,
0xa4, 0x32, 0xce, 0x80, 0xde, 0x82, 0xdc, 0xde, 0x64, 0x24, 0x12, 0xa1, 0x03, 0x2c, 0x4d, 0xf4, 0x42, 0x72, 0x47, 0x45, 0x9e, 0x06, 0xad, 0x05, 0x79, 0x98, 0xc7, 0xc4, 0xe7, 0xa9, 0x1d, 0x2c,
0x0c, 0xda, 0xec, 0x76, 0x41, 0x45, 0xf4, 0xf0, 0xf9, 0xfe, 0x58, 0x32, 0x19, 0x8b, 0x78, 0xff, 0x4c, 0xf4, 0x02, 0xea, 0xd9, 0xc3, 0x82, 0xf2, 0xec, 0xee, 0xcb, 0xa3, 0xbe, 0x40, 0xd2, 0xe7,
0x76, 0x41, 0xb1, 0x00, 0x98, 0x7f, 0x2b, 0x30, 0xb0, 0x96, 0x51, 0x9c, 0x7d, 0x3a, 0xe7, 0x8b, 0xf9, 0xce, 0xc3, 0x82, 0x62, 0x1e, 0xa0, 0xff, 0x2d, 0x41, 0xc7, 0x58, 0xfa, 0x41, 0xfc, 0xe9,
0xb5, 0x9c, 0x27, 0x75, 0xce, 0x66, 0x7c, 0x69, 0xd4, 0x07, 0xa0, 0x63, 0xd0, 0xa2, 0x65, 0x4e, 0x9a, 0xaf, 0xd6, 0x6a, 0x5e, 0x94, 0x35, 0xab, 0xf9, 0xb9, 0x51, 0x1e, 0x80, 0xce, 0x41, 0xf1,
0x58, 0x9c, 0xa5, 0x41, 0x52, 0x18, 0x3b, 0x27, 0xca, 0xa8, 0x8d, 0x41, 0xba, 0xa6, 0x85, 0xf9, 0x97, 0x09, 0xc9, 0x82, 0x38, 0x72, 0xc3, 0x54, 0xdb, 0xbf, 0x90, 0x7a, 0x75, 0x0c, 0xc2, 0x35,
0x2d, 0xa8, 0xab, 0x18, 0xf4, 0x10, 0xd0, 0xdc, 0x7d, 0xe3, 0xce, 0x7e, 0x76, 0x03, 0x6b, 0x7e, 0x4a, 0xf5, 0xaf, 0x41, 0x5e, 0xe5, 0xa0, 0x27, 0x80, 0xa6, 0xe3, 0xb7, 0xe3, 0xc9, 0x4f, 0x63,
0xea, 0xcc, 0x02, 0xff, 0xe2, 0xdc, 0xd6, 0x1f, 0xa0, 0x1e, 0xec, 0x58, 0xd6, 0x44, 0x57, 0xc4, 0xd7, 0x98, 0x0e, 0xad, 0x89, 0xeb, 0xdc, 0x5c, 0x9b, 0xea, 0x1e, 0x6a, 0xc1, 0xbe, 0x61, 0x0c,
0x62, 0x8a, 0xf5, 0x96, 0xf9, 0x8f, 0x02, 0x9a, 0x1d, 0xc5, 0x4c, 0xf2, 0x3e, 0x80, 0x4e, 0x78, 0x54, 0x89, 0x2f, 0x46, 0x58, 0xad, 0xe9, 0xff, 0x48, 0xa0, 0x98, 0x7e, 0x90, 0x09, 0xdc, 0xc7,
0x93, 0x85, 0xd7, 0x82, 0x75, 0x1b, 0x97, 0x06, 0x57, 0x91, 0xd1, 0xdf, 0x99, 0xe0, 0xac, 0x62, 0xd0, 0xf0, 0xe6, 0xb1, 0x77, 0xcf, 0x51, 0xd7, 0x71, 0x6e, 0x30, 0x16, 0x33, 0xfa, 0x5b, 0xc6,
0xb1, 0x46, 0x87, 0xd0, 0x13, 0xc5, 0x8a, 0x23, 0xc1, 0x46, 0xc5, 0x5d, 0x6e, 0x3a, 0x11, 0xfa, 0x31, 0xcb, 0x98, 0xaf, 0xd1, 0x09, 0xb4, 0x78, 0xb3, 0x02, 0x9f, 0xa3, 0x91, 0x71, 0x93, 0x99,
0x0a, 0xa0, 0x2a, 0x20, 0xdf, 0x6b, 0x8b, 0x3d, 0xb5, 0xf2, 0x38, 0x11, 0x3f, 0xe1, 0x32, 0x27, 0x96, 0x8f, 0xbe, 0x00, 0x28, 0x1a, 0xc8, 0xf6, 0xea, 0x7c, 0x4f, 0x2e, 0x3c, 0x96, 0xcf, 0x4e,
0x29, 0x33, 0x3a, 0x42, 0x97, 0xd2, 0x40, 0x2f, 0x61, 0x20, 0x83, 0x84, 0x3a, 0x5d, 0xa1, 0xce, 0xb8, 0x4b, 0x48, 0x94, 0x69, 0x0d, 0xce, 0x4b, 0x6e, 0xa0, 0xd7, 0xd0, 0x11, 0x49, 0x9c, 0x9d,
0xe7, 0xb5, 0x3a, 0x15, 0x41, 0x21, 0x89, 0x96, 0xd4, 0x86, 0xf9, 0x97, 0x02, 0xbb, 0xa7, 0xf4, 0x26, 0x67, 0xe7, 0xff, 0x25, 0x3b, 0x05, 0x40, 0x4e, 0x89, 0x12, 0x96, 0x86, 0xfe, 0x97, 0x04,
0x86, 0x32, 0xba, 0xfd, 0x0e, 0x0d, 0xbe, 0xad, 0x2d, 0x7c, 0x77, 0xee, 0xe4, 0xdb, 0xde, 0xc6, 0x07, 0x43, 0x3a, 0xa7, 0x19, 0xdd, 0xfd, 0x0d, 0x15, 0xbc, 0xb5, 0x1d, 0x78, 0xf7, 0xb7, 0xe2,
0xb7, 0x73, 0x6f, 0xbe, 0xff, 0x2a, 0x30, 0x3c, 0x8d, 0x8b, 0x30, 0xcb, 0x23, 0x49, 0x78, 0x08, 0xad, 0xef, 0xc2, 0xdb, 0x78, 0x34, 0xde, 0x3f, 0x6a, 0xd0, 0x1d, 0x06, 0xa9, 0x17, 0x27, 0xbe,
0xad, 0x38, 0xaa, 0xda, 0xb6, 0x15, 0x47, 0x42, 0x6e, 0xd9, 0x22, 0x6a, 0xd5, 0x00, 0x8f, 0x41, 0x00, 0xdc, 0x85, 0x5a, 0xe0, 0x17, 0xb2, 0xad, 0x05, 0x3e, 0xa7, 0x5b, 0x48, 0x44, 0x2e, 0x04,
0x65, 0x71, 0x42, 0x0b, 0x46, 0x92, 0x85, 0x24, 0xb9, 0x72, 0xa0, 0x11, 0xec, 0xad, 0x0c, 0x5e, 0x70, 0x0a, 0x72, 0x16, 0x84, 0x34, 0xcd, 0x48, 0xb8, 0x10, 0x20, 0x57, 0x0e, 0xd4, 0x83, 0xc3,
0x4e, 0x2a, 0x85, 0xdf, 0x74, 0xf3, 0xc6, 0x0c, 0xb3, 0x94, 0xd1, 0xaa, 0x00, 0x2a, 0x96, 0x26, 0x95, 0xc1, 0xda, 0x49, 0x05, 0xf1, 0x9b, 0x6e, 0x26, 0x4c, 0x2f, 0x8e, 0x32, 0x5a, 0x34, 0x40,
0xfa, 0x0e, 0xba, 0x64, 0xc9, 0xae, 0xb2, 0x5c, 0x88, 0xaf, 0x3d, 0x3f, 0xaa, 0x2f, 0xb3, 0xce, 0xc6, 0xc2, 0x44, 0xdf, 0x40, 0x93, 0x2c, 0xb3, 0x59, 0x9c, 0x70, 0xf2, 0x95, 0x97, 0x67, 0xe5,
0xd7, 0x12, 0x28, 0x5c, 0xa1, 0xcd, 0x3f, 0x15, 0x38, 0xf8, 0x18, 0xe0, 0x63, 0xd7, 0x4a, 0x49, 0xc7, 0xac, 0xe3, 0x35, 0x78, 0x14, 0x2e, 0xa2, 0xd1, 0x77, 0x20, 0x27, 0xf4, 0x96, 0x26, 0x34,
0xb2, 0xba, 0x16, 0x5f, 0xa3, 0xa7, 0xb0, 0x1b, 0xc5, 0x45, 0x98, 0xc7, 0x49, 0x9c, 0x12, 0x96, 0xf2, 0xa8, 0xd6, 0xe2, 0xa9, 0xcf, 0xb6, 0xa5, 0x62, 0x11, 0x88, 0xcb, 0x1c, 0xfd, 0x4f, 0x09,
0xe5, 0xd5, 0xd5, 0xd6, 0x9d, 0xe8, 0x11, 0xf4, 0xd3, 0x38, 0xbc, 0x16, 0xd1, 0xe5, 0xbd, 0x56, 0x8e, 0x3f, 0x76, 0xc2, 0xc7, 0x78, 0x89, 0x48, 0xb8, 0xe2, 0x85, 0xad, 0xd1, 0x73, 0x38, 0xf0,
0x36, 0x17, 0x86, 0x7c, 0x20, 0x8c, 0xe4, 0xf3, 0xfc, 0xa6, 0xba, 0x52, 0xed, 0x30, 0xff, 0xe8, 0x83, 0xd4, 0x4b, 0x82, 0x30, 0x88, 0x48, 0x16, 0x27, 0x05, 0x37, 0xeb, 0x4e, 0xf4, 0x14, 0xda,
0x83, 0x36, 0xb9, 0x22, 0x9f, 0xe8, 0xef, 0x35, 0x71, 0x5b, 0x62, 0xa7, 0x21, 0xae, 0xec, 0xfe, 0x51, 0xe0, 0xdd, 0xf3, 0xec, 0x9c, 0x98, 0x95, 0xcd, 0x98, 0x25, 0x1f, 0x48, 0x46, 0x92, 0x69,
0x9d, 0x46, 0xf7, 0x1f, 0x83, 0x96, 0xd3, 0x62, 0x91, 0xa5, 0x05, 0x0d, 0x58, 0x56, 0x91, 0x02, 0x32, 0x2f, 0x38, 0x29, 0x1d, 0x7a, 0x0c, 0x27, 0x5b, 0x3e, 0x81, 0x25, 0xae, 0x64, 0x52, 0xa0,
0xe9, 0xf2, 0x33, 0xf4, 0x05, 0xf4, 0x69, 0x5a, 0x04, 0x82, 0x72, 0x25, 0x34, 0x4d, 0x0b, 0x97, 0xac, 0xe8, 0xe6, 0x14, 0x64, 0x6f, 0x46, 0xa2, 0x88, 0xce, 0x2d, 0xa1, 0xb8, 0xd2, 0xc1, 0xda,
0x33, 0x6e, 0x74, 0x62, 0x77, 0xad, 0x13, 0x37, 0x9b, 0xaa, 0x77, 0xdf, 0xa6, 0x42, 0xa7, 0x30, 0x70, 0xb7, 0x0c, 0xe6, 0xbe, 0x25, 0x14, 0x27, 0x4c, 0xfd, 0xdf, 0x36, 0x28, 0x83, 0x19, 0xf9,
0xa8, 0xca, 0x58, 0x46, 0xf6, 0x45, 0xe4, 0x93, 0x3a, 0xb2, 0xa1, 0xc1, 0x78, 0x52, 0x22, 0xcb, 0xc4, 0x8d, 0x5c, 0x93, 0x43, 0x8d, 0xef, 0x54, 0xe4, 0x20, 0xee, 0xeb, 0x7e, 0xe5, 0xbe, 0x9e,
0x2c, 0x61, 0x6d, 0xa0, 0x17, 0xd0, 0x2b, 0xca, 0x91, 0x6a, 0xa8, 0xa2, 0x05, 0x8c, 0x3a, 0xc1, 0x83, 0x92, 0xd0, 0x74, 0x11, 0x47, 0x29, 0x75, 0xb3, 0xb8, 0x60, 0x01, 0x84, 0xcb, 0x89, 0xd1,
0xfa, 0xac, 0x7d, 0xfd, 0x00, 0x4b, 0x28, 0x1a, 0x43, 0x27, 0xe6, 0xe3, 0xd0, 0x00, 0x11, 0xf3, 0x67, 0xd0, 0xa6, 0x51, 0xea, 0x72, 0x8e, 0x0a, 0x69, 0xd0, 0x28, 0x1d, 0x33, 0x8a, 0x2a, 0x77,
0x70, 0x63, 0x4a, 0xd6, 0x11, 0x25, 0x8c, 0xe3, 0x09, 0x9f, 0x54, 0x86, 0xb6, 0x89, 0x6f, 0x4e, 0xa7, 0xb9, 0x76, 0x77, 0x36, 0xaf, 0x41, 0xeb, 0xb1, 0xd7, 0x00, 0x0d, 0xa1, 0x53, 0x08, 0x2f,
0x40, 0x8e, 0x17, 0x30, 0x74, 0x04, 0x6a, 0x98, 0x25, 0xc9, 0x32, 0x8d, 0xd9, 0xad, 0x31, 0xe0, 0xcf, 0x6c, 0xf3, 0xcc, 0x8a, 0x70, 0x2a, 0x1c, 0xf4, 0x07, 0x79, 0x64, 0x5e, 0xc5, 0x2b, 0x0d,
0x3f, 0xe1, 0xeb, 0x07, 0xb8, 0x76, 0xd5, 0x3f, 0xe8, 0x6e, 0xf3, 0x07, 0x7d, 0x02, 0x83, 0x28, 0xf4, 0x0a, 0x5a, 0x69, 0xfe, 0x08, 0x68, 0x32, 0x57, 0x9e, 0x56, 0x16, 0x58, 0x7f, 0x1d, 0xae,
0x2e, 0x16, 0x37, 0xe4, 0xb6, 0xac, 0xc1, 0x50, 0x28, 0xad, 0x55, 0x3e, 0x51, 0x87, 0xf7, 0x70, 0xf6, 0xb0, 0x08, 0x45, 0x7d, 0x68, 0x04, 0x6c, 0x80, 0x6b, 0xc0, 0x73, 0x9e, 0x6c, 0xcc, 0xf5,
0x54, 0x70, 0xc5, 0xb8, 0x04, 0x24, 0x64, 0x41, 0x4e, 0x7f, 0x5b, 0xd2, 0x82, 0x05, 0x45, 0x7c, 0x32, 0x23, 0x0f, 0x63, 0xf1, 0x84, 0xcd, 0x56, 0x4d, 0xd9, 0x8c, 0xaf, 0xce, 0x6c, 0x16, 0xcf,
0x99, 0x12, 0xb6, 0xcc, 0xa9, 0xb1, 0x27, 0x18, 0x36, 0x65, 0x2c, 0xa1, 0xb8, 0x44, 0x7a, 0x12, 0xc3, 0xd0, 0x19, 0xc8, 0x5e, 0x1c, 0x86, 0xcb, 0x28, 0xc8, 0x1e, 0xb4, 0x0e, 0x1b, 0x1b, 0x57,
0x88, 0xbf, 0xe4, 0x89, 0xee, 0xd8, 0x44, 0x29, 0x98, 0x39, 0x0d, 0x69, 0xfc, 0x81, 0x46, 0x5b, 0x7b, 0xb8, 0x74, 0xa1, 0x01, 0x1c, 0xfa, 0xb9, 0xa6, 0xc4, 0x53, 0xa7, 0x79, 0x9b, 0xe8, 0xd7,
0xce, 0xd2, 0xef, 0x7b, 0xd6, 0xb1, 0x4c, 0x76, 0xd7, 0x79, 0xcf, 0x60, 0x4f, 0x1e, 0x53, 0xf5, 0x45, 0x77, 0xb5, 0x87, 0xbb, 0xfe, 0xfa, 0xd0, 0x58, 0xcd, 0xa5, 0x83, 0xea, 0x5c, 0x7a, 0x06,
0x88, 0xf1, 0xd9, 0x89, 0x32, 0xea, 0xe3, 0x61, 0xe5, 0xae, 0x24, 0x36, 0xff, 0x53, 0x40, 0x6b, 0x1d, 0x3f, 0x48, 0x17, 0x73, 0xf2, 0x90, 0x37, 0xb2, 0xcb, 0xdb, 0xa5, 0x14, 0x3e, 0xde, 0xcc,
0x34, 0x03, 0x32, 0xe0, 0x40, 0x3e, 0x1b, 0x93, 0x99, 0xeb, 0xdb, 0xae, 0x2f, 0x1f, 0x8e, 0x21, 0x5b, 0x38, 0x4b, 0x19, 0xed, 0x8c, 0x47, 0xe2, 0x65, 0x6e, 0x42, 0x7f, 0x5d, 0xd2, 0x34, 0x73,
0x80, 0x6f, 0xff, 0xe2, 0x07, 0xe7, 0x3f, 0x5a, 0x8e, 0xab, 0x2b, 0x48, 0x83, 0x9e, 0xe7, 0x3b, 0xd3, 0xe0, 0x2e, 0x22, 0xd9, 0x32, 0xa1, 0xda, 0xe1, 0xe6, 0x25, 0x1e, 0xe4, 0xa1, 0x38, 0x8f,
0x93, 0x37, 0x36, 0xd6, 0x5b, 0x08, 0xa0, 0xeb, 0xf9, 0x96, 0x3f, 0xf7, 0xf4, 0x1d, 0xa4, 0x42, 0xb4, 0x45, 0x20, 0xfe, 0x9c, 0x15, 0xda, 0xb2, 0x89, 0x22, 0xd0, 0x13, 0xea, 0xd1, 0xe0, 0x03,
0xc7, 0x9e, 0xce, 0x7e, 0x70, 0xf4, 0x36, 0x3a, 0x84, 0x7d, 0x1f, 0x5b, 0xae, 0x67, 0x4d, 0x7c, 0xf5, 0x77, 0x9c, 0xa5, 0x3e, 0xf6, 0xac, 0x73, 0x51, 0x6c, 0xdb, 0x79, 0x2f, 0xe0, 0x50, 0x1c,
0x67, 0xc6, 0x33, 0x4e, 0xa7, 0x96, 0x7b, 0xaa, 0x77, 0xd0, 0x08, 0x9e, 0x7a, 0x17, 0x9e, 0x6f, 0x23, 0x58, 0xfd, 0xdf, 0x85, 0xd4, 0x6b, 0xe3, 0x6e, 0xe1, 0x2e, 0x98, 0xd3, 0x7f, 0xaf, 0x81,
0x4f, 0x83, 0xa9, 0xed, 0x79, 0xd6, 0x99, 0xbd, 0x3a, 0xed, 0x1c, 0x3b, 0x3f, 0x59, 0xbe, 0x1d, 0x52, 0x51, 0x14, 0xd2, 0xe0, 0x58, 0xbc, 0x96, 0x83, 0xc9, 0xd8, 0x31, 0xc7, 0x8e, 0x78, 0x2f,
0x9c, 0xe1, 0xd9, 0xfc, 0x5c, 0xef, 0xf2, 0x6c, 0xce, 0xd4, 0x3a, 0xb3, 0xf5, 0x1e, 0x5f, 0x8a, 0xbb, 0x00, 0x8e, 0xf9, 0xb3, 0xe3, 0x5e, 0xff, 0x60, 0x58, 0x63, 0x55, 0x42, 0x0a, 0xb4, 0x6c,
0xa7, 0x4c, 0xef, 0xa3, 0x5d, 0x50, 0x79, 0xb2, 0xb9, 0xeb, 0xf8, 0x17, 0xba, 0xca, 0x1f, 0xbb, 0xc7, 0x1a, 0xbc, 0x35, 0xb1, 0x5a, 0x43, 0x00, 0x4d, 0xdb, 0x31, 0x9c, 0xa9, 0xad, 0xee, 0x23,
0x8d, 0x74, 0x67, 0xd6, 0xb9, 0x0e, 0x68, 0x1f, 0xf6, 0x78, 0x5e, 0x6b, 0xe2, 0x07, 0xd8, 0x7e, 0x19, 0x1a, 0xe6, 0x68, 0xf2, 0xbd, 0xa5, 0xd6, 0xd1, 0x09, 0x1c, 0x39, 0xd8, 0x18, 0xdb, 0xc6,
0x3b, 0xb7, 0x3d, 0x5f, 0xd7, 0x5e, 0xa9, 0xab, 0x77, 0xd9, 0x9c, 0xc3, 0xe1, 0x5d, 0x0a, 0x3e, 0xc0, 0xb1, 0x26, 0xac, 0xe2, 0x68, 0x64, 0x8c, 0x87, 0x6a, 0x03, 0xf5, 0xe0, 0xb9, 0x7d, 0x63,
0x06, 0xb5, 0x2e, 0x4c, 0xf9, 0x7e, 0xd7, 0x8e, 0xed, 0xd3, 0xe2, 0xd5, 0xee, 0xaf, 0xda, 0xf8, 0x3b, 0xe6, 0xc8, 0x1d, 0x99, 0xb6, 0x6d, 0x5c, 0x9a, 0xab, 0xd3, 0xae, 0xb1, 0xf5, 0xa3, 0xe1,
0xeb, 0xef, 0x65, 0x15, 0xdf, 0x75, 0xc5, 0xea, 0x9b, 0xff, 0x03, 0x00, 0x00, 0xff, 0xff, 0x2c, 0x98, 0xee, 0x25, 0x9e, 0x4c, 0xaf, 0xd5, 0x26, 0xab, 0x66, 0x8d, 0x8c, 0x4b, 0x53, 0x6d, 0xb1,
0xd6, 0xbd, 0x7d, 0xda, 0x08, 0x00, 0x00, 0x25, 0x7f, 0xc1, 0xd5, 0x36, 0x3a, 0x00, 0x99, 0x15, 0x9b, 0x8e, 0x2d, 0xe7, 0x46, 0x95, 0xd9,
0x1b, 0xbf, 0x51, 0xee, 0xd2, 0xb8, 0x56, 0x01, 0x1d, 0xc1, 0x21, 0xab, 0x6b, 0x0c, 0x1c, 0x17,
0x9b, 0xef, 0xa6, 0xa6, 0xed, 0xa8, 0x0a, 0x73, 0x0e, 0x2d, 0x7b, 0x30, 0xc1, 0x43, 0x11, 0xad,
0x76, 0xde, 0xc8, 0xab, 0xff, 0x28, 0xfa, 0x14, 0x4e, 0xb6, 0xd1, 0x7a, 0x0a, 0x72, 0xd9, 0xad,
0xfc, 0xbf, 0x4c, 0xe9, 0xd8, 0x3d, 0x87, 0xde, 0x1c, 0xfc, 0xa2, 0xf4, 0xbf, 0xfc, 0x56, 0xb4,
0xf6, 0x7d, 0x93, 0xaf, 0xbe, 0xfa, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x81, 0x52, 0xd1, 0xf4, 0xe6,
0x09, 0x00, 0x00,
} }

View File

@ -61,6 +61,7 @@ message DiscordMessage {
string timestampEdited = 4; string timestampEdited = 4;
string content = 5; string content = 5;
DiscordMessageAuthor author = 6; DiscordMessageAuthor author = 6;
DiscordMessageReference reference = 7;
} }
message DiscordMessageAuthor { message DiscordMessageAuthor {
@ -71,6 +72,12 @@ message DiscordMessageAuthor {
string avatarUrl = 5; string avatarUrl = 5;
} }
message DiscordMessageReference {
string messageId = 1;
string channelId = 2;
string guildId = 3;
}
message ChatMessage { message ChatMessage {
// Lamport timestamp of the chat message // Lamport timestamp of the chat message
uint64 clock = 1; uint64 clock = 1;
@ -99,6 +106,7 @@ message ChatMessage {
ImageMessage image = 10; ImageMessage image = 10;
AudioMessage audio = 11; AudioMessage audio = 11;
bytes community = 12; bytes community = 12;
DiscordMessage discord_message = 99;
} }
// Grant for community chat messages // Grant for community chat messages
@ -126,6 +134,7 @@ message ChatMessage {
// Only local // Only local
SYSTEM_MESSAGE_GAP = 10; SYSTEM_MESSAGE_GAP = 10;
CONTACT_REQUEST = 11; CONTACT_REQUEST = 11;
DISCORD_MESSAGE = 12;
} }