ソースを参照

Sync contact info when syncing room members if puppet has no displayname

Tulir Asokan 4 年 前
コミット
93953ec48f
2 ファイル変更29 行追加7 行削除
  1. 10 7
      portal.go
  2. 19 0
      puppet.go

+ 10 - 7
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 {

+ 19 - 0
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)