Skip to content

Commit

Permalink
Publish image and contact code when joining community
Browse files Browse the repository at this point in the history
  • Loading branch information
cammellos committed Sep 8, 2023
1 parent 6237814 commit 0a47d06
Show file tree
Hide file tree
Showing 3 changed files with 180 additions and 146 deletions.
146 changes: 0 additions & 146 deletions protocol/messenger.go
Original file line number Diff line number Diff line change
Expand Up @@ -928,135 +928,6 @@ func (m *Messenger) online() bool {
}
}

func (m *Messenger) buildContactCodeAdvertisement() (*protobuf.ContactCodeAdvertisement, error) {
if m.pushNotificationClient == nil || !m.pushNotificationClient.Enabled() {
return nil, nil
}
m.logger.Debug("adding push notification info to contact code bundle")
info, err := m.pushNotificationClient.MyPushNotificationQueryInfo()
if err != nil {
return nil, err
}
if len(info) == 0 {
return nil, nil
}
return &protobuf.ContactCodeAdvertisement{
PushNotificationInfo: info,
}, nil
}

// publishContactCode sends a public message wrapped in the encryption
// layer, which will propagate our bundle
func (m *Messenger) publishContactCode() error {
var payload []byte
m.logger.Debug("sending contact code")
contactCodeAdvertisement, err := m.buildContactCodeAdvertisement()
if err != nil {
m.logger.Error("could not build contact code advertisement", zap.Error(err))
}

if contactCodeAdvertisement == nil {
contactCodeAdvertisement = &protobuf.ContactCodeAdvertisement{}
}

err = m.attachChatIdentity(contactCodeAdvertisement)
if err != nil {
return err
}

if contactCodeAdvertisement.ChatIdentity != nil {
m.logger.Debug("attached chat identity", zap.Int("images len", len(contactCodeAdvertisement.ChatIdentity.Images)))
} else {
m.logger.Debug("no attached chat identity")
}

payload, err = proto.Marshal(contactCodeAdvertisement)
if err != nil {
return err
}

contactCodeTopic := transport.ContactCodeTopic(&m.identity.PublicKey)
rawMessage := common.RawMessage{
LocalChatID: contactCodeTopic,
MessageType: protobuf.ApplicationMetadataMessage_CONTACT_CODE_ADVERTISEMENT,
Payload: payload,
}
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

_, err = m.sender.SendPublic(ctx, contactCodeTopic, rawMessage)
if err != nil {
m.logger.Warn("failed to send a contact code", zap.Error(err))
}

joinedCommunities, err := m.communitiesManager.Joined()
if err != nil {
return err
}
for _, community := range joinedCommunities {
rawMessage.LocalChatID = community.MemberUpdateChannelID()
rawMessage.PubsubTopic = community.PubsubTopic()
_, err = m.sender.SendPublic(ctx, rawMessage.LocalChatID, rawMessage)
if err != nil {
return err
}
}

m.logger.Debug("contact code sent")
return err
}

// contactCodeAdvertisement attaches a protobuf.ChatIdentity to the given protobuf.ContactCodeAdvertisement,
// if the `shouldPublish` conditions are met
func (m *Messenger) attachChatIdentity(cca *protobuf.ContactCodeAdvertisement) error {
contactCodeTopic := transport.ContactCodeTopic(&m.identity.PublicKey)
shouldPublish, err := m.shouldPublishChatIdentity(contactCodeTopic)
if err != nil {
return err
}

if !shouldPublish {
return nil
}

cca.ChatIdentity, err = m.createChatIdentity(privateChat)
if err != nil {
return err
}

img, err := m.multiAccounts.GetIdentityImage(m.account.KeyUID, images.SmallDimName)
if err != nil {
return err
}

displayName, err := m.settings.DisplayName()
if err != nil {
return err
}

bio, err := m.settings.Bio()
if err != nil {
return err
}

socialLinks, err := m.settings.GetSocialLinks()
if err != nil {
return err
}

identityHash, err := m.getIdentityHash(displayName, bio, img, socialLinks)
if err != nil {
return err
}

err = m.persistence.SaveWhenChatIdentityLastPublished(contactCodeTopic, identityHash)
if err != nil {
return err
}

return nil
}

// handleStandaloneChatIdentity sends a standalone ChatIdentity message to a public or private channel if the publish criteria is met
func (m *Messenger) handleStandaloneChatIdentity(chat *Chat) error {
if chat.ChatType != ChatTypePublic && chat.ChatType != ChatTypeOneToOne {
Expand Down Expand Up @@ -1551,23 +1422,6 @@ func (m *Messenger) watchPendingCommunityRequestToJoin() {
}()
}

func (m *Messenger) PublishIdentityImage() error {
// Reset last published time for ChatIdentity so new contact can receive data
err := m.resetLastPublishedTimeForChatIdentity()
if err != nil {
m.logger.Error("failed to reset publish time", zap.Error(err))
return err
}

// If not online, we schedule it
if !m.online() {
m.shouldPublishContactCode = true
return nil
}

return m.publishContactCode()
}

// handlePushNotificationClientRegistration handles registration events
func (m *Messenger) handlePushNotificationClientRegistrations(c chan struct{}) {
go func() {
Expand Down
5 changes: 5 additions & 0 deletions protocol/messenger_communities.go
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,11 @@ func (m *Messenger) joinCommunity(ctx context.Context, communityID types.HexByte
if err = m.subscribeToCommunityShard(communityID); err != nil {
return nil, err
}

if err = m.publishContactCodeInCommunity(community); err != nil {
return nil, err
}

}

communitySettings, err := m.communitiesManager.GetCommunitySettingsByID(communityID)
Expand Down
175 changes: 175 additions & 0 deletions protocol/messenger_contact_code.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
package protocol

import (
"context"
"time"

"github.com/golang/protobuf/proto"
"github.com/status-im/status-go/images"
"github.com/status-im/status-go/protocol/common"
"github.com/status-im/status-go/protocol/communities"
"github.com/status-im/status-go/protocol/protobuf"
"github.com/status-im/status-go/protocol/transport"
"go.uber.org/zap"
)

func (m *Messenger) buildContactCodeAdvertisement() (*protobuf.ContactCodeAdvertisement, error) {
if m.pushNotificationClient == nil || !m.pushNotificationClient.Enabled() {
return nil, nil
}
m.logger.Debug("adding push notification info to contact code bundle")
info, err := m.pushNotificationClient.MyPushNotificationQueryInfo()
if err != nil {
return nil, err
}
if len(info) == 0 {
return nil, nil
}
return &protobuf.ContactCodeAdvertisement{
PushNotificationInfo: info,
}, nil
}

func (m *Messenger) PublishIdentityImage() error {
// Reset last published time for ChatIdentity so new contact can receive data
err := m.resetLastPublishedTimeForChatIdentity()
if err != nil {
m.logger.Error("failed to reset publish time", zap.Error(err))
return err
}

// If not online, we schedule it
if !m.online() {
m.shouldPublishContactCode = true
return nil
}

return m.publishContactCode()
}

func (m *Messenger) buildContactCodeRawMessage() (common.RawMessage, error) {
var payload []byte
m.logger.Debug("sending contact code")
contactCodeAdvertisement, err := m.buildContactCodeAdvertisement()
if err != nil {
m.logger.Error("could not build contact code advertisement", zap.Error(err))
}

if contactCodeAdvertisement == nil {
contactCodeAdvertisement = &protobuf.ContactCodeAdvertisement{}
}

err = m.attachChatIdentity(contactCodeAdvertisement)
if err != nil {
return common.RawMessage{}, err
}

if contactCodeAdvertisement.ChatIdentity != nil {
m.logger.Debug("attached chat identity", zap.Int("images len", len(contactCodeAdvertisement.ChatIdentity.Images)))
} else {
m.logger.Debug("no attached chat identity")
}

payload, err = proto.Marshal(contactCodeAdvertisement)
if err != nil {
return common.RawMessage{}, err
}

contactCodeTopic := transport.ContactCodeTopic(&m.identity.PublicKey)
return common.RawMessage{
LocalChatID: contactCodeTopic,
MessageType: protobuf.ApplicationMetadataMessage_CONTACT_CODE_ADVERTISEMENT,
Payload: payload,
}, nil

}

func (m *Messenger) publishContactCodeInCommunity(community *communities.Community) error {
rawMessage, err := m.buildContactCodeRawMessage()
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
rawMessage.LocalChatID = community.MemberUpdateChannelID()
rawMessage.PubsubTopic = community.PubsubTopic()
_, err = m.sender.SendPublic(ctx, rawMessage.LocalChatID, rawMessage)
return err
}

// publishContactCode sends a public message wrapped in the encryption
// layer, which will propagate our bundle
func (m *Messenger) publishContactCode() error {
rawMessage, err := m.buildContactCodeRawMessage()
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

_, err = m.sender.SendPublic(ctx, rawMessage.LocalChatID, rawMessage)
if err != nil {
m.logger.Warn("failed to send a contact code", zap.Error(err))
}

joinedCommunities, err := m.communitiesManager.Joined()
if err != nil {
return err
}
for _, community := range joinedCommunities {
rawMessage.LocalChatID = community.MemberUpdateChannelID()
rawMessage.PubsubTopic = community.PubsubTopic()
_, err = m.sender.SendPublic(ctx, rawMessage.LocalChatID, rawMessage)
if err != nil {
return err
}
}

m.logger.Debug("contact code sent")
return err
}

// contactCodeAdvertisement attaches a protobuf.ChatIdentity to the given protobuf.ContactCodeAdvertisement,
// if the `shouldPublish` conditions are met
func (m *Messenger) attachChatIdentity(cca *protobuf.ContactCodeAdvertisement) error {
contactCodeTopic := transport.ContactCodeTopic(&m.identity.PublicKey)
shouldPublish, err := m.shouldPublishChatIdentity(contactCodeTopic)
if err != nil {
return err
}

if !shouldPublish {
return nil
}

cca.ChatIdentity, err = m.createChatIdentity(privateChat)
if err != nil {
return err
}

img, err := m.multiAccounts.GetIdentityImage(m.account.KeyUID, images.SmallDimName)
if err != nil {
return err
}

displayName, err := m.settings.DisplayName()
if err != nil {
return err
}

bio, err := m.settings.Bio()
if err != nil {
return err
}

socialLinks, err := m.settings.GetSocialLinks()
if err != nil {
return err
}

identityHash, err := m.getIdentityHash(displayName, bio, img, socialLinks)
if err != nil {
return err
}

err = m.persistence.SaveWhenChatIdentityLastPublished(contactCodeTopic, identityHash)
if err != nil {
return err
}

return nil
}

0 comments on commit 0a47d06

Please sign in to comment.