Răsfoiți Sursa

Add support for setting group avatar from Matrix

Tulir Asokan 3 ani în urmă
părinte
comite
94e880c2cc
5 a modificat fișierele cu 44 adăugiri și 16 ștergeri
  1. 1 0
      CHANGELOG.md
  2. 2 2
      ROADMAP.md
  3. 1 1
      go.mod
  4. 2 2
      go.sum
  5. 38 11
      portal.go

+ 1 - 0
CHANGELOG.md

@@ -2,6 +2,7 @@
 
 * Added tracking for incoming events from the primary device to warn the user
   if their phone is offline for too long.
+* (Re-)Added support for setting group avatar from Matrix.
 * Fixed some issues with read receipt bridging
 * Fixed `!wa open` not working with new-style group IDs.
 * Fixed panic in disappearing message handling code if a portal is deleted with

+ 2 - 2
ROADMAP.md

@@ -15,9 +15,9 @@
     * [x] Invite
     * [x] Leave
     * [x] Kick
-  * [ ] Room metadata changes
+  * [x] Room metadata changes
     * [x] Name
-    * [ ] Avatar
+    * [x] Avatar
     * [x] Topic
   * [ ] Initial room metadata
 * WhatsApp → Matrix

+ 1 - 1
go.mod

@@ -10,7 +10,7 @@ require (
 	github.com/prometheus/client_golang v1.11.0
 	github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
 	github.com/tidwall/gjson v1.13.0
-	go.mau.fi/whatsmeow v0.0.0-20220204210537-a425ddb0b16c
+	go.mau.fi/whatsmeow v0.0.0-20220210104450-b05cf0cef136
 	golang.org/x/image v0.0.0-20211028202545-6944b10bf410
 	google.golang.org/protobuf v1.27.1
 	gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b

+ 2 - 2
go.sum

@@ -140,8 +140,8 @@ github.com/tidwall/sjson v1.2.4 h1:cuiLzLnaMeBhRmEv00Lpk3tkYrcxpmbU81tAY4Dw0tc=
 github.com/tidwall/sjson v1.2.4/go.mod h1:098SZ494YoMWPmMO6ct4dcFnqxwj9r/gF0Etp19pSNM=
 go.mau.fi/libsignal v0.0.0-20211109153248-a67163214910 h1:9FFhG0OmkuMau5UEaTgiUQ+7cSbtbOQ7hiWKdN8OI3I=
 go.mau.fi/libsignal v0.0.0-20211109153248-a67163214910/go.mod h1:AufGrvVh+00Nc07Jm4hTquh7yleZyn20tKJI2wCPAKg=
-go.mau.fi/whatsmeow v0.0.0-20220204210537-a425ddb0b16c h1:hwuZ1W55J2uSwm029dREAr6crSVa+i5VsF91ltK389k=
-go.mau.fi/whatsmeow v0.0.0-20220204210537-a425ddb0b16c/go.mod h1:8jUjOAi3xtGubxcZgG8uSHpAdyQXBRbWAfxkctX/4y4=
+go.mau.fi/whatsmeow v0.0.0-20220210104450-b05cf0cef136 h1:AeE8izwMOwAbzNGC+GGOY821w6EWSpPxVmQcpRgyff4=
+go.mau.fi/whatsmeow v0.0.0-20220210104450-b05cf0cef136/go.mod h1:8jUjOAi3xtGubxcZgG8uSHpAdyQXBRbWAfxkctX/4y4=
 golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=

+ 38 - 11
portal.go

@@ -202,6 +202,7 @@ type Portal struct {
 	roomCreateLock sync.Mutex
 	encryptLock    sync.Mutex
 	backfillLock   sync.Mutex
+	avatarLock     sync.Mutex
 
 	recentlyHandled      [recentlyHandledLength]recentlyHandledWrapper
 	recentlyHandledLock  sync.Mutex
@@ -821,6 +822,8 @@ func (portal *Portal) SyncParticipants(source *User, metadata *types.GroupInfo)
 }
 
 func (portal *Portal) UpdateAvatar(user *User, setBy types.JID, updateInfo bool) bool {
+	portal.avatarLock.Lock()
+	defer portal.avatarLock.Unlock()
 	avatar, err := user.Client.GetProfilePictureInfo(portal.Key.JID, false)
 	if err != nil {
 		if !errors.Is(err, whatsmeow.ErrProfilePictureUnauthorized) {
@@ -2717,28 +2720,52 @@ func (portal *Portal) HandleMatrixInvite(sender *User, target *Puppet) {
 }
 
 func (portal *Portal) HandleMatrixMeta(sender *User, evt *event.Event) {
-	var err error
 	switch content := evt.Content.Parsed.(type) {
 	case *event.RoomNameEventContent:
 		if content.Name == portal.Name {
 			return
 		}
 		portal.Name = content.Name
-		err = sender.Client.SetGroupName(portal.Key.JID, content.Name)
+		err := sender.Client.SetGroupName(portal.Key.JID, content.Name)
+		if err != nil {
+			portal.log.Errorln("Failed to update group name:", err)
+		}
 	case *event.TopicEventContent:
 		if content.Topic == portal.Topic {
 			return
 		}
 		portal.Topic = content.Topic
-		err = sender.Client.SetGroupTopic(portal.Key.JID, "", "", content.Topic)
+		err := sender.Client.SetGroupTopic(portal.Key.JID, "", "", content.Topic)
+		if err != nil {
+			portal.log.Errorln("Failed to update group description:", err)
+		}
 	case *event.RoomAvatarEventContent:
-		// TODO implement
-		return
-	}
-	if err != nil {
-		portal.log.Errorln("Failed to update metadata:", err)
-	} else {
-		//out := <-resp
-		//portal.log.Debugln("Successfully updated metadata:", out)
+		portal.avatarLock.Lock()
+		defer portal.avatarLock.Unlock()
+		if content.URL == portal.AvatarURL || (content.URL.IsEmpty() && portal.Avatar == "remove") {
+			return
+		}
+		var data []byte
+		var err error
+		if !content.URL.IsEmpty() {
+			data, err = portal.MainIntent().DownloadBytes(content.URL)
+			if err != nil {
+				portal.log.Errorfln("Failed to download updated avatar %s: %v", content.URL, err)
+				return
+			}
+			portal.log.Debugfln("%s set the group avatar to %s", sender.MXID, content.URL)
+		} else {
+			portal.log.Debugfln("%s removed the group avatar", sender.MXID)
+		}
+		newID, err := sender.Client.SetGroupPhoto(portal.Key.JID, data)
+		if err != nil {
+			portal.log.Errorfln("Failed to update group avatar: %v", err)
+			return
+		}
+		portal.log.Debugfln("Successfully updated group avatar to %s", newID)
+		portal.Avatar = newID
+		portal.AvatarURL = content.URL
+		portal.UpdateBridgeInfo()
+		portal.Update()
 	}
 }