diff --git a/portal.go b/portal.go index 9051edc..1e98bfb 100644 --- a/portal.go +++ b/portal.go @@ -383,12 +383,13 @@ func (portal *Portal) kickExtraUsers(participantMap map[whatsapp.JID]bool) { } } -func (portal *Portal) SyncBroadcastRecipients(metadata *whatsapp.BroadcastListInfo) { +func (portal *Portal) SyncBroadcastRecipients(source *User, metadata *whatsapp.BroadcastListInfo) { participantMap := make(map[whatsapp.JID]bool) for _, recipient := range metadata.Recipients { participantMap[recipient.JID] = true puppet := portal.bridge.GetPuppetByJID(recipient.JID) + puppet.SyncContactIfNecessary(source) err := puppet.DefaultIntent().EnsureJoined(portal.MXID) if err != nil { portal.log.Warnfln("Failed to make puppet of %s join %s: %v", recipient.JID, portal.MXID, err) @@ -397,7 +398,7 @@ func (portal *Portal) SyncBroadcastRecipients(metadata *whatsapp.BroadcastListIn portal.kickExtraUsers(participantMap) } -func (portal *Portal) SyncParticipants(metadata *whatsapp.GroupInfo) { +func (portal *Portal) SyncParticipants(source *User, metadata *whatsapp.GroupInfo) { changed := false levels, err := portal.MainIntent().PowerLevels(portal.MXID) if err != nil { @@ -411,7 +412,8 @@ func (portal *Portal) SyncParticipants(metadata *whatsapp.GroupInfo) { portal.userMXIDAction(user, portal.ensureMXIDInvited) puppet := portal.bridge.GetPuppetByJID(participant.JID) - err := puppet.IntentFor(portal).EnsureJoined(portal.MXID) + puppet.SyncContactIfNecessary(source) + err = puppet.IntentFor(portal).EnsureJoined(portal.MXID) if err != nil { portal.log.Warnfln("Failed to make puppet of %s join %s: %v", participant.JID, portal.MXID, err) } @@ -550,7 +552,7 @@ func (portal *Portal) UpdateMetadata(user *User) bool { update := false broadcastMetadata, err := user.Conn.GetBroadcastMetadata(portal.Key.JID) if err == nil && broadcastMetadata.Status == 200 { - portal.SyncBroadcastRecipients(broadcastMetadata) + portal.SyncBroadcastRecipients(user, broadcastMetadata) update = portal.UpdateName(broadcastMetadata.Name, "", nil, false) || update } else { contact, _ := user.Conn.Store.Contacts[portal.Key.JID] @@ -574,7 +576,7 @@ func (portal *Portal) UpdateMetadata(user *User) bool { return false } - portal.SyncParticipants(metadata) + portal.SyncParticipants(user, metadata) update := false update = portal.UpdateName(metadata.Name, metadata.NameSetBy, nil, false) || update update = portal.UpdateTopic(metadata.Topic, metadata.TopicSetBy, nil, false) || update @@ -1016,6 +1018,7 @@ func (portal *Portal) CreateMatrixRoom(user *User) error { var broadcastMetadata *whatsapp.BroadcastListInfo if portal.IsPrivateChat() { puppet := portal.bridge.GetPuppetByJID(portal.Key.JID) + puppet.SyncContactIfNecessary(user) if portal.bridge.Config.Bridge.PrivateChatPortalMeta { portal.Name = puppet.Displayname portal.AvatarURL = puppet.AvatarURL @@ -1118,7 +1121,7 @@ func (portal *Portal) CreateMatrixRoom(user *User) error { } if metadata != nil { - portal.SyncParticipants(metadata) + portal.SyncParticipants(user, metadata) if metadata.Announce { portal.RestrictMessageSending(metadata.Announce) } @@ -1129,7 +1132,7 @@ func (portal *Portal) CreateMatrixRoom(user *User) error { } } if broadcastMetadata != nil { - portal.SyncBroadcastRecipients(broadcastMetadata) + portal.SyncBroadcastRecipients(user, broadcastMetadata) } inCommunity := user.addPortalToCommunity(portal) if portal.IsPrivateChat() && !user.IsRelaybot { diff --git a/puppet.go b/puppet.go index 2549e9e..cc49d26 100644 --- a/puppet.go +++ b/puppet.go @@ -21,6 +21,7 @@ import ( "net/http" "regexp" "strings" + "sync" "github.com/Rhymen/go-whatsapp" @@ -155,6 +156,8 @@ type Puppet struct { customIntent *appservice.IntentAPI customTypingIn map[id.RoomID]bool customUser *User + + syncLock sync.Mutex } func (puppet *Puppet) PhoneNumber() string { @@ -285,7 +288,23 @@ func (puppet *Puppet) updatePortalName() { }) } +func (puppet *Puppet) SyncContactIfNecessary(source *User) { + if len(puppet.Displayname) > 0 { + return + } + + contact, ok := source.Conn.Store.Contacts[puppet.JID] + if !ok { + return + } + + puppet.log.Debugfln("Syncing contact info through %s / %s because puppet has no displayname", source.MXID, source.JID) + puppet.Sync(source, contact) +} + func (puppet *Puppet) Sync(source *User, contact whatsapp.Contact) { + puppet.syncLock.Lock() + defer puppet.syncLock.Unlock() err := puppet.DefaultIntent().EnsureRegistered() if err != nil { puppet.log.Errorln("Failed to ensure registered:", err)