add endpoint for getting emojis
This commit is contained in:
parent
3e4e1ff663
commit
37a2073008
|
@ -47,15 +47,20 @@ func (e *EmojiReaction) SetMessageType(messageType protobuf.MessageType) {
|
|||
e.MessageType = messageType
|
||||
}
|
||||
|
||||
func (e *EmojiReaction) MarshalJSON() ([]byte, error) {
|
||||
func (e EmojiReaction) MarshalJSON() ([]byte, error) {
|
||||
type EmojiAlias EmojiReaction
|
||||
item := struct {
|
||||
*EmojiAlias
|
||||
ID string `json:"id"`
|
||||
EmojiAlias
|
||||
ID string `json:"id"`
|
||||
EmojiID protobuf.EmojiReaction_Type `json:"emojiId"`
|
||||
}{
|
||||
EmojiAlias: (*EmojiAlias)(e),
|
||||
EmojiAlias: (EmojiAlias)(e),
|
||||
ID: e.ID(),
|
||||
EmojiID: e.Type,
|
||||
}
|
||||
|
||||
// cleanup type
|
||||
item.Type = 0
|
||||
|
||||
return json.Marshal(item)
|
||||
}
|
||||
|
|
|
@ -489,6 +489,64 @@ func (db sqlitePersistence) MessageByChatID(chatID string, currCursor string, li
|
|||
return result, newCursor, nil
|
||||
}
|
||||
|
||||
// EmojiReactionsByChatID returns the emoji reactions for the queried messages, up to a maximum of 100, as it's a potentially unbound number.
|
||||
// NOTE: This is not completely accurate, as the messages in the database might have change since the last call to `MessageByChatID`.
|
||||
func (db sqlitePersistence) EmojiReactionsByChatID(chatID string, currCursor string, limit int) ([]*EmojiReaction, error) {
|
||||
cursorWhere := ""
|
||||
if currCursor != "" {
|
||||
cursorWhere = "AND substr('0000000000000000000000000000000000000000000000000000000000000000' || m.clock_value, -64, 64) <= ?"
|
||||
}
|
||||
args := []interface{}{chatID}
|
||||
if currCursor != "" {
|
||||
args = append(args, currCursor)
|
||||
}
|
||||
// Build a new column `cursor` at the query time by having a fixed-sized clock value at the beginning
|
||||
// concatenated with message ID. Results are sorted using this new column.
|
||||
// This new column values can also be returned as a cursor for subsequent requests.
|
||||
rows, err := db.db.Query(
|
||||
fmt.Sprintf(`
|
||||
SELECT
|
||||
e.clock_value,
|
||||
e.source,
|
||||
e.emoji_id,
|
||||
e.message_id,
|
||||
e.chat_id,
|
||||
e.retracted
|
||||
FROM
|
||||
emoji_reactions e
|
||||
WHERE NOT(e.retracted)
|
||||
AND
|
||||
e.message_id IN
|
||||
(SELECT id FROM user_messages m WHERE NOT(m.hide) AND m.local_chat_id = ? %s
|
||||
ORDER BY substr('0000000000000000000000000000000000000000000000000000000000000000' || m.clock_value, -64, 64) || m.id DESC LIMIT ?)
|
||||
LIMIT 100
|
||||
`, cursorWhere),
|
||||
append(args, limit)...,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var result []*EmojiReaction
|
||||
for rows.Next() {
|
||||
var emojiReaction EmojiReaction
|
||||
err := rows.Scan(&emojiReaction.Clock,
|
||||
&emojiReaction.From,
|
||||
&emojiReaction.Type,
|
||||
&emojiReaction.MessageId,
|
||||
&emojiReaction.ChatId,
|
||||
&emojiReaction.Retracted)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result = append(result, &emojiReaction)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (db sqlitePersistence) SaveMessages(messages []*Message) (err error) {
|
||||
tx, err := db.db.BeginTx(context.Background(), &sql.TxOptions{})
|
||||
if err != nil {
|
||||
|
|
|
@ -279,7 +279,7 @@ func (s *MessageValidatorSuite) TestValidatePlainTextMessage() {
|
|||
Timestamp: 3,
|
||||
ResponseTo: "",
|
||||
EnsName: "",
|
||||
MessageType: protobuf.ChatMessage_ONE_TO_ONE,
|
||||
MessageType: protobuf.MessageType_ONE_TO_ONE,
|
||||
ContentType: protobuf.ChatMessage_EMOJI,
|
||||
},
|
||||
}
|
||||
|
@ -419,7 +419,7 @@ func (s *MessageValidatorSuite) TestValidatePlainTextMessage() {
|
|||
Payload: []byte("some-payload"),
|
||||
},
|
||||
},
|
||||
MessageType: protobuf.ChatMessage_ONE_TO_ONE,
|
||||
MessageType: protobuf.MessageType_ONE_TO_ONE,
|
||||
ContentType: protobuf.ChatMessage_AUDIO,
|
||||
},
|
||||
},
|
||||
|
@ -440,7 +440,7 @@ func (s *MessageValidatorSuite) TestValidatePlainTextMessage() {
|
|||
Payload: []byte("some-payload"),
|
||||
},
|
||||
},
|
||||
MessageType: protobuf.ChatMessage_ONE_TO_ONE,
|
||||
MessageType: protobuf.MessageType_ONE_TO_ONE,
|
||||
ContentType: protobuf.ChatMessage_STICKER,
|
||||
},
|
||||
},
|
||||
|
@ -460,7 +460,7 @@ func (s *MessageValidatorSuite) TestValidatePlainTextMessage() {
|
|||
Type: 1,
|
||||
},
|
||||
},
|
||||
MessageType: protobuf.ChatMessage_ONE_TO_ONE,
|
||||
MessageType: protobuf.MessageType_ONE_TO_ONE,
|
||||
ContentType: protobuf.ChatMessage_AUDIO,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1410,8 +1410,6 @@ func (m *Messenger) SendChatMessage(ctx context.Context, message *Message) (*Mes
|
|||
}
|
||||
}
|
||||
|
||||
logger := m.logger.With(zap.String("site", "Send"), zap.String("chatID", message.ChatId))
|
||||
|
||||
var response MessengerResponse
|
||||
|
||||
// A valid added chat is required.
|
||||
|
@ -3277,6 +3275,10 @@ func (m *Messenger) SendEmojiReaction(ctx context.Context, chatID, messageID str
|
|||
return &response, nil
|
||||
}
|
||||
|
||||
func (m *Messenger) EmojiReactionsByChatID(chatID string, cursor string, limit int) ([]*EmojiReaction, error) {
|
||||
return m.persistence.EmojiReactionsByChatID(chatID, cursor, limit)
|
||||
}
|
||||
|
||||
func (m *Messenger) SendEmojiReactionRetraction(ctx context.Context, emojiReactionID string) (*MessengerResponse, error) {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
|
|
|
@ -2,6 +2,7 @@ package protocol
|
|||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"sort"
|
||||
|
@ -375,6 +376,92 @@ func TestUpdateMessageOutgoingStatus(t *testing.T) {
|
|||
require.Equal(t, "new-status", m.OutgoingStatus)
|
||||
}
|
||||
|
||||
func TestPersistenceEmojiReactions(t *testing.T) {
|
||||
db, err := openTestDB()
|
||||
require.NoError(t, err)
|
||||
p := sqlitePersistence{db: db}
|
||||
// reverse order as we use DESC
|
||||
id1 := "1"
|
||||
id2 := "2"
|
||||
id3 := "3"
|
||||
|
||||
from1 := "from-1"
|
||||
from2 := "from-2"
|
||||
from3 := "from-3"
|
||||
|
||||
chatID := "chat-id"
|
||||
|
||||
err = insertMinimalMessage(p, id1)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = insertMinimalMessage(p, id2)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = insertMinimalMessage(p, id3)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Insert normal emoji reaction
|
||||
require.NoError(t, p.SaveEmojiReaction(&EmojiReaction{
|
||||
EmojiReaction: protobuf.EmojiReaction{
|
||||
Clock: 1,
|
||||
MessageId: id3,
|
||||
ChatId: chatID,
|
||||
Type: protobuf.EmojiReaction_SAD,
|
||||
},
|
||||
From: from1,
|
||||
}))
|
||||
|
||||
// Insert retracted emoji reaction
|
||||
require.NoError(t, p.SaveEmojiReaction(&EmojiReaction{
|
||||
EmojiReaction: protobuf.EmojiReaction{
|
||||
Clock: 1,
|
||||
MessageId: id3,
|
||||
ChatId: chatID,
|
||||
Type: protobuf.EmojiReaction_SAD,
|
||||
Retracted: true,
|
||||
},
|
||||
From: from2,
|
||||
}))
|
||||
|
||||
// Insert retracted emoji reaction out of pagination
|
||||
require.NoError(t, p.SaveEmojiReaction(&EmojiReaction{
|
||||
EmojiReaction: protobuf.EmojiReaction{
|
||||
Clock: 1,
|
||||
MessageId: id1,
|
||||
ChatId: chatID,
|
||||
Type: protobuf.EmojiReaction_SAD,
|
||||
},
|
||||
From: from2,
|
||||
}))
|
||||
|
||||
// Insert retracted emoji reaction out of pagination
|
||||
require.NoError(t, p.SaveEmojiReaction(&EmojiReaction{
|
||||
EmojiReaction: protobuf.EmojiReaction{
|
||||
Clock: 1,
|
||||
MessageId: id1,
|
||||
ChatId: chatID,
|
||||
Type: protobuf.EmojiReaction_SAD,
|
||||
},
|
||||
From: from3,
|
||||
}))
|
||||
|
||||
reactions, err := p.EmojiReactionsByChatID(chatID, "", 1)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, reactions, 1)
|
||||
require.Equal(t, id3, reactions[0].MessageId)
|
||||
|
||||
// Try with a cursor
|
||||
_, cursor, err := p.MessageByChatID(chatID, "", 1)
|
||||
require.NoError(t, err)
|
||||
fmt.Println("CURSOR", cursor)
|
||||
|
||||
reactions, err = p.EmojiReactionsByChatID(chatID, cursor, 2)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, reactions, 2)
|
||||
require.Equal(t, id1, reactions[0].MessageId)
|
||||
require.Equal(t, id1, reactions[1].MessageId)
|
||||
}
|
||||
|
||||
func openTestDB() (*sql.DB, error) {
|
||||
dbPath, err := ioutil.TempFile("", "")
|
||||
if err != nil {
|
||||
|
|
|
@ -522,6 +522,10 @@ func (api *PublicAPI) SendEmojiReactionRetraction(ctx context.Context, emojiReac
|
|||
return api.service.messenger.SendEmojiReactionRetraction(ctx, emojiReactionID)
|
||||
}
|
||||
|
||||
func (api *PublicAPI) EmojiReactionsByChatID(chatID string, cursor string, limit int) ([]*protocol.EmojiReaction, error) {
|
||||
return api.service.messenger.EmojiReactionsByChatID(chatID, cursor, limit)
|
||||
}
|
||||
|
||||
// Echo is a method for testing purposes.
|
||||
func (api *PublicAPI) Echo(ctx context.Context, message string) (string, error) {
|
||||
return message, nil
|
||||
|
|
Loading…
Reference in New Issue