mirror of
https://github.com/status-im/status-go.git
synced 2025-02-16 08:50:09 +00:00
Add SendChatMessages endpoints
This commit adds an endpoint to batch the sending of messages. This is useful to simplify client logic when sending a batch of messages and ensuring the correct order in the message stream. It currently implements only what's needed, and naively return an error if any of the messages fail.
This commit is contained in:
parent
0304b3fa46
commit
156c0de832
11
protocol/errors.go
Normal file
11
protocol/errors.go
Normal file
@ -0,0 +1,11 @@
|
||||
package protocol
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrChatIDEmpty = errors.New("chat ID is empty")
|
||||
ErrChatNotFound = errors.New("can't find chat")
|
||||
ErrNotImplemented = errors.New("not implemented")
|
||||
)
|
@ -42,12 +42,6 @@ const PubKeyStringLength = 132
|
||||
|
||||
const transactionSentTxt = "Transaction sent"
|
||||
|
||||
var (
|
||||
ErrChatIDEmpty = errors.New("chat ID is empty")
|
||||
ErrChatNotFound = errors.New("can't find chat")
|
||||
ErrNotImplemented = errors.New("not implemented")
|
||||
)
|
||||
|
||||
// Messenger is a entity managing chats and messages.
|
||||
// It acts as a bridge between the application and encryption
|
||||
// layers.
|
||||
@ -89,19 +83,6 @@ type RawResponse struct {
|
||||
Messages []*v1protocol.StatusMessage `json:"messages"`
|
||||
}
|
||||
|
||||
type MessengerResponse struct {
|
||||
Chats []*Chat `json:"chats,omitempty"`
|
||||
Messages []*common.Message `json:"messages,omitempty"`
|
||||
Contacts []*Contact `json:"contacts,omitempty"`
|
||||
Installations []*multidevice.Installation `json:"installations,omitempty"`
|
||||
EmojiReactions []*EmojiReaction `json:"emojiReactions,omitempty"`
|
||||
Invitations []*GroupChatInvitation `json:"invitations,omitempty"`
|
||||
}
|
||||
|
||||
func (m *MessengerResponse) IsEmpty() bool {
|
||||
return len(m.Chats) == 0 && len(m.Messages) == 0 && len(m.Contacts) == 0 && len(m.Installations) == 0 && len(m.Invitations) == 0
|
||||
}
|
||||
|
||||
type dbConfig struct {
|
||||
dbPath string
|
||||
dbKey string
|
||||
@ -1722,7 +1703,32 @@ func (m *Messenger) dispatchMessage(ctx context.Context, spec common.RawMessage)
|
||||
func (m *Messenger) SendChatMessage(ctx context.Context, message *common.Message) (*MessengerResponse, error) {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
return m.sendChatMessage(ctx, message)
|
||||
}
|
||||
|
||||
// SendChatMessages takes a array of messages and sends it based on the corresponding chats
|
||||
func (m *Messenger) SendChatMessages(ctx context.Context, messages []*common.Message) (*MessengerResponse, error) {
|
||||
m.mutex.Lock()
|
||||
defer m.mutex.Unlock()
|
||||
|
||||
var response MessengerResponse
|
||||
|
||||
for _, message := range messages {
|
||||
messageResponse, err := m.sendChatMessage(ctx, message)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = response.Merge(messageResponse)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &response, nil
|
||||
}
|
||||
|
||||
// SendChatMessage takes a minimal message and sends it based on the corresponding chat
|
||||
func (m *Messenger) sendChatMessage(ctx context.Context, message *common.Message) (*MessengerResponse, error) {
|
||||
if len(message.ImagePath) != 0 {
|
||||
file, err := os.Open(message.ImagePath)
|
||||
if err != nil {
|
||||
|
53
protocol/messenger_response.go
Normal file
53
protocol/messenger_response.go
Normal file
@ -0,0 +1,53 @@
|
||||
package protocol
|
||||
|
||||
import (
|
||||
"github.com/status-im/status-go/protocol/common"
|
||||
"github.com/status-im/status-go/protocol/encryption/multidevice"
|
||||
)
|
||||
|
||||
type MessengerResponse struct {
|
||||
Chats []*Chat `json:"chats,omitempty"`
|
||||
Messages []*common.Message `json:"messages,omitempty"`
|
||||
Contacts []*Contact `json:"contacts,omitempty"`
|
||||
Installations []*multidevice.Installation `json:"installations,omitempty"`
|
||||
EmojiReactions []*EmojiReaction `json:"emojiReactions,omitempty"`
|
||||
Invitations []*GroupChatInvitation `json:"invitations,omitempty"`
|
||||
}
|
||||
|
||||
func (m *MessengerResponse) IsEmpty() bool {
|
||||
return len(m.Chats) == 0 && len(m.Messages) == 0 && len(m.Contacts) == 0 && len(m.Installations) == 0 && len(m.Invitations) == 0
|
||||
}
|
||||
|
||||
func (m *MessengerResponse) Merge(response *MessengerResponse) error {
|
||||
if len(response.Contacts)+len(response.Installations)+len(response.EmojiReactions)+len(response.Invitations) != 0 {
|
||||
return ErrNotImplemented
|
||||
}
|
||||
|
||||
for _, overrideChat := range response.Chats {
|
||||
var found = false
|
||||
for idx, chat := range m.Chats {
|
||||
if chat.ID == overrideChat.ID {
|
||||
m.Chats[idx] = overrideChat
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
m.Chats = append(m.Chats, overrideChat)
|
||||
}
|
||||
}
|
||||
|
||||
for _, overrideMessage := range response.Messages {
|
||||
var found = false
|
||||
for idx, chat := range m.Messages {
|
||||
if chat.ID == overrideMessage.ID {
|
||||
m.Messages[idx] = overrideMessage
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
m.Messages = append(m.Messages, overrideMessage)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
73
protocol/messenger_response_test.go
Normal file
73
protocol/messenger_response_test.go
Normal file
@ -0,0 +1,73 @@
|
||||
package protocol
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/status-im/status-go/protocol/common"
|
||||
"github.com/status-im/status-go/protocol/encryption/multidevice"
|
||||
)
|
||||
|
||||
func TestMessengerResponseMergeChats(t *testing.T) {
|
||||
chat1 := &Chat{ID: "1"}
|
||||
modifiedChat1 := &Chat{ID: "1", Name: "name"}
|
||||
chat2 := &Chat{ID: "3"}
|
||||
response1 := &MessengerResponse{
|
||||
Chats: []*Chat{chat1},
|
||||
}
|
||||
|
||||
response2 := &MessengerResponse{
|
||||
Chats: []*Chat{modifiedChat1, chat2},
|
||||
}
|
||||
|
||||
require.NoError(t, response1.Merge(response2))
|
||||
|
||||
require.Len(t, response1.Chats, 2)
|
||||
require.Equal(t, modifiedChat1, response1.Chats[0])
|
||||
require.Equal(t, chat2, response1.Chats[1])
|
||||
}
|
||||
|
||||
func TestMessengerResponseMergeMessages(t *testing.T) {
|
||||
message1 := &common.Message{ID: "1"}
|
||||
modifiedMessage1 := &common.Message{ID: "1", From: "name"}
|
||||
message2 := &common.Message{ID: "3"}
|
||||
response1 := &MessengerResponse{
|
||||
Messages: []*common.Message{message1},
|
||||
}
|
||||
|
||||
response2 := &MessengerResponse{
|
||||
Messages: []*common.Message{modifiedMessage1, message2},
|
||||
}
|
||||
|
||||
require.NoError(t, response1.Merge(response2))
|
||||
|
||||
require.Len(t, response1.Messages, 2)
|
||||
require.Equal(t, modifiedMessage1, response1.Messages[0])
|
||||
require.Equal(t, message2, response1.Messages[1])
|
||||
}
|
||||
|
||||
func TestMessengerResponseMergeNotImplemented(t *testing.T) {
|
||||
response1 := &MessengerResponse{}
|
||||
|
||||
response2 := &MessengerResponse{
|
||||
Contacts: []*Contact{&Contact{}},
|
||||
}
|
||||
require.Error(t, response1.Merge(response2))
|
||||
|
||||
response2 = &MessengerResponse{
|
||||
Installations: []*multidevice.Installation{&multidevice.Installation{}},
|
||||
}
|
||||
require.Error(t, response1.Merge(response2))
|
||||
|
||||
response2 = &MessengerResponse{
|
||||
EmojiReactions: []*EmojiReaction{&EmojiReaction{}},
|
||||
}
|
||||
require.Error(t, response1.Merge(response2))
|
||||
|
||||
response2 = &MessengerResponse{
|
||||
Invitations: []*GroupChatInvitation{&GroupChatInvitation{}},
|
||||
}
|
||||
require.Error(t, response1.Merge(response2))
|
||||
|
||||
}
|
@ -365,6 +365,10 @@ func (api *PublicAPI) ReSendChatMessage(ctx context.Context, messageID string) e
|
||||
return api.service.messenger.ReSendChatMessage(ctx, messageID)
|
||||
}
|
||||
|
||||
func (api *PublicAPI) SendChatMessages(ctx context.Context, messages []*common.Message) (*protocol.MessengerResponse, error) {
|
||||
return api.service.messenger.SendChatMessages(ctx, messages)
|
||||
}
|
||||
|
||||
func (api *PublicAPI) RequestTransaction(ctx context.Context, chatID, value, contract, address string) (*protocol.MessengerResponse, error) {
|
||||
return api.service.messenger.RequestTransaction(ctx, chatID, value, contract, address)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user