Send notification when your contact invites you to group chat (#2361)
This commit is contained in:
parent
da63894a5a
commit
d65494d1f8
|
@ -465,6 +465,9 @@ func (m *Message) GetSimplifiedText(identity string, canonicalNames map[string]s
|
|||
if m.ContentType == protobuf.ChatMessage_COMMUNITY {
|
||||
return "Community", nil
|
||||
}
|
||||
if m.ContentType == protobuf.ChatMessage_SYSTEM_MESSAGE_CONTENT_PRIVATE_GROUP {
|
||||
return "Group", nil
|
||||
}
|
||||
|
||||
if m.ParsedTextAst == nil {
|
||||
err := m.PrepareContent(identity)
|
||||
|
|
|
@ -74,6 +74,15 @@ func NewCommunityRequestToJoinNotification(id string, community *communities.Com
|
|||
return body.toCommunityRequestToJoinNotification(id)
|
||||
}
|
||||
|
||||
func NewPrivateGroupInviteNotification(id string, chat *Chat, contact *Contact) *localnotifications.Notification {
|
||||
body := &NotificationBody{
|
||||
Chat: chat,
|
||||
Contact: contact,
|
||||
}
|
||||
|
||||
return body.toPrivateGroupInviteNotification(id)
|
||||
}
|
||||
|
||||
func (n NotificationBody) toMessageNotification(id string, contacts *contactMap) (*localnotifications.Notification, error) {
|
||||
var title string
|
||||
if n.Chat.PrivateGroupChat() || n.Chat.Public() || n.Chat.CommunityChat() {
|
||||
|
@ -123,6 +132,24 @@ func (n NotificationBody) toMessageNotification(id string, contacts *contactMap)
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (n NotificationBody) toPrivateGroupInviteNotification(id string) *localnotifications.Notification {
|
||||
return &localnotifications.Notification{
|
||||
ID: gethcommon.HexToHash(id),
|
||||
Body: n,
|
||||
Title: n.Contact.CanonicalName() + " invited you to " + n.Chat.Name,
|
||||
Message: n.Contact.CanonicalName() + " wants you to join group " + n.Chat.Name,
|
||||
BodyType: localnotifications.TypeMessage,
|
||||
Category: localnotifications.CategoryGroupInvite,
|
||||
Deeplink: n.Chat.DeepLink(),
|
||||
Author: localnotifications.NotificationAuthor{
|
||||
Name: n.Contact.CanonicalName(),
|
||||
Icon: n.Contact.CanonicalImage(),
|
||||
ID: n.Contact.ID,
|
||||
},
|
||||
Image: "",
|
||||
}
|
||||
}
|
||||
|
||||
func (n NotificationBody) toCommunityRequestToJoinNotification(id string) *localnotifications.Notification {
|
||||
return &localnotifications.Notification{
|
||||
ID: gethcommon.HexToHash(id),
|
||||
|
|
|
@ -60,6 +60,7 @@ func (m *Messenger) HandleMembershipUpdate(messageState *ReceivedMessageState, c
|
|||
//if chat.InvitationAdmin exists means we are waiting for invitation request approvement, and in that case
|
||||
//we need to create a new chat instance like we don't have a chat and just use a regular invitation flow
|
||||
waitingForApproval := chat != nil && len(chat.InvitationAdmin) > 0
|
||||
ourKey := contactIDFromPublicKey(&m.identity.PublicKey)
|
||||
|
||||
if chat == nil || waitingForApproval {
|
||||
if len(message.Events) == 0 {
|
||||
|
@ -96,7 +97,6 @@ func (m *Messenger) HandleMembershipUpdate(messageState *ReceivedMessageState, c
|
|||
return err
|
||||
}
|
||||
|
||||
ourKey := contactIDFromPublicKey(&m.identity.PublicKey)
|
||||
// A new chat must contain us
|
||||
if !group.IsMember(ourKey) {
|
||||
return errors.New("can't create a new group chat without us being a member")
|
||||
|
@ -107,6 +107,16 @@ func (m *Messenger) HandleMembershipUpdate(messageState *ReceivedMessageState, c
|
|||
isActive := messageState.CurrentMessageState.Contact.IsAdded() || messageState.CurrentMessageState.Contact.ID == ourKey || waitingForApproval
|
||||
newChat.Active = isActive
|
||||
chat = &newChat
|
||||
|
||||
chat.updateChatFromGroupMembershipChanges(group)
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to get group creator")
|
||||
}
|
||||
|
||||
if chat.Active && messageState.CurrentMessageState.Contact.ID != ourKey {
|
||||
messageState.Response.AddNotification(NewPrivateGroupInviteNotification(chat.ID, chat, messageState.CurrentMessageState.Contact))
|
||||
}
|
||||
} else {
|
||||
existingGroup, err := newProtocolGroupFromChat(chat)
|
||||
if err != nil {
|
||||
|
@ -121,10 +131,9 @@ func (m *Messenger) HandleMembershipUpdate(messageState *ReceivedMessageState, c
|
|||
if err != nil {
|
||||
return errors.Wrap(err, "failed to create a group with new membership updates")
|
||||
}
|
||||
chat.updateChatFromGroupMembershipChanges(group)
|
||||
}
|
||||
|
||||
chat.updateChatFromGroupMembershipChanges(group)
|
||||
|
||||
if !chat.Active {
|
||||
m.createMessageNotification(chat, messageState)
|
||||
}
|
||||
|
@ -181,6 +190,7 @@ func (m *Messenger) createMessageNotification(chat *Chat, messageState *Received
|
|||
Timestamp: messageState.CurrentMessageState.WhisperTimestamp,
|
||||
ChatID: chat.ID,
|
||||
}
|
||||
|
||||
err := m.addActivityCenterNotification(messageState, notification)
|
||||
if err != nil {
|
||||
m.logger.Warn("failed to create activity center notification", zap.Error(err))
|
||||
|
|
|
@ -1,11 +1,20 @@
|
|||
package protocol
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
"go.uber.org/zap"
|
||||
|
||||
gethbridge "github.com/status-im/status-go/eth-node/bridge/geth"
|
||||
"github.com/status-im/status-go/eth-node/crypto"
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
"github.com/status-im/status-go/protocol/protobuf"
|
||||
"github.com/status-im/status-go/protocol/tt"
|
||||
v1protocol "github.com/status-im/status-go/protocol/v1"
|
||||
localnotifications "github.com/status-im/status-go/services/local-notifications"
|
||||
"github.com/status-im/status-go/waku"
|
||||
)
|
||||
|
||||
func TestEventToSystemMessageSuite(t *testing.T) {
|
||||
|
@ -14,6 +23,37 @@ func TestEventToSystemMessageSuite(t *testing.T) {
|
|||
|
||||
type EventToSystemMessageSuite struct {
|
||||
suite.Suite
|
||||
m *Messenger // main instance of Messenger
|
||||
privateKey *ecdsa.PrivateKey // private key for the main instance of Messenger
|
||||
// If one wants to send messages between different instances of Messenger,
|
||||
// a single waku service should be shared.
|
||||
shh types.Waku
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
func (s *EventToSystemMessageSuite) newMessenger() *Messenger {
|
||||
privateKey, err := crypto.GenerateKey()
|
||||
s.Require().NoError(err)
|
||||
|
||||
messenger, err := newMessengerWithKey(s.shh, privateKey, s.logger, nil)
|
||||
s.Require().NoError(err)
|
||||
return messenger
|
||||
}
|
||||
|
||||
func (s *EventToSystemMessageSuite) SetupTest() {
|
||||
s.logger = tt.MustCreateTestLogger()
|
||||
|
||||
config := waku.DefaultConfig
|
||||
config.MinimumAcceptedPoW = 0
|
||||
shh := waku.New(&config, s.logger)
|
||||
s.shh = gethbridge.NewGethWakuWrapper(shh)
|
||||
s.Require().NoError(shh.Start())
|
||||
|
||||
s.m = s.newMessenger()
|
||||
s.privateKey = s.m.identity
|
||||
|
||||
_, err := s.m.Start()
|
||||
s.Require().NoError(err)
|
||||
}
|
||||
|
||||
func (s *EventToSystemMessageSuite) TestRun() {
|
||||
|
@ -78,3 +118,62 @@ func (s *EventToSystemMessageSuite) TestRun() {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
func (s *EventToSystemMessageSuite) TestHandleMembershipUpdate() {
|
||||
adminPrivateKey, err := crypto.GenerateKey()
|
||||
s.Require().NoError(err)
|
||||
|
||||
adminPublicKey := types.EncodeHex(crypto.FromECDSAPub(&adminPrivateKey.PublicKey))
|
||||
ourPublicKey := types.EncodeHex(crypto.FromECDSAPub(&s.m.identity.PublicKey))
|
||||
|
||||
event1 := v1protocol.MembershipUpdateEvent{
|
||||
Type: protobuf.MembershipUpdateEvent_CHAT_CREATED,
|
||||
Name: "test",
|
||||
ChatID: "test-" + adminPublicKey,
|
||||
ClockValue: 100,
|
||||
}
|
||||
err = event1.Sign(adminPrivateKey)
|
||||
s.Require().NoError(err)
|
||||
|
||||
event2 := v1protocol.MembershipUpdateEvent{
|
||||
Type: protobuf.MembershipUpdateEvent_MEMBERS_ADDED,
|
||||
Members: []string{adminPublicKey, ourPublicKey},
|
||||
ChatID: "test-" + adminPublicKey,
|
||||
ClockValue: 100,
|
||||
}
|
||||
err = event2.Sign(adminPrivateKey)
|
||||
s.Require().NoError(err)
|
||||
|
||||
testMembershipUpdateMessageStruct2 := v1protocol.MembershipUpdateMessage{
|
||||
ChatID: "test-" + adminPublicKey,
|
||||
Events: []v1protocol.MembershipUpdateEvent{
|
||||
event1,
|
||||
event2,
|
||||
},
|
||||
}
|
||||
|
||||
rawMembershipUpdateMessage2, err := testMembershipUpdateMessageStruct2.ToProtobuf()
|
||||
s.Require().NoError(err)
|
||||
|
||||
contact, err := BuildContactFromPublicKey(&adminPrivateKey.PublicKey)
|
||||
s.Require().NoError(err)
|
||||
|
||||
contact.SystemTags = []string{contactAdded}
|
||||
|
||||
currentMessageState := &CurrentMessageState{
|
||||
Contact: contact,
|
||||
}
|
||||
|
||||
state := &ReceivedMessageState{
|
||||
Response: &MessengerResponse{},
|
||||
Timesource: s.m.transport,
|
||||
CurrentMessageState: currentMessageState,
|
||||
ExistingMessagesMap: map[string]bool{},
|
||||
AllChats: s.m.allChats,
|
||||
}
|
||||
|
||||
err = s.m.HandleMembershipUpdate(state, nil, *rawMembershipUpdateMessage2, defaultSystemMessagesTranslations)
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(state.Response.Notifications(), 1)
|
||||
s.Require().Equal(state.Response.Notifications()[0].Category, localnotifications.CategoryGroupInvite)
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package localnotifications
|
|||
const (
|
||||
CategoryTransaction PushCategory = "transaction"
|
||||
CategoryMessage PushCategory = "newMessage"
|
||||
CategoryGroupInvite PushCategory = "groupInvite"
|
||||
CategoryCommunityRequestToJoin = "communityRequestToJoin"
|
||||
|
||||
TypeTransaction NotificationType = "transaction"
|
||||
|
|
Loading…
Reference in New Issue