From ec86259a2056a1e8a24539beccfa5ae14e11a677 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 15 Jun 2020 14:56:52 +0300 Subject: [PATCH] Update bridge info when portal metadata changes --- portal.go | 87 ++++++++++++++++++++++++++++++++++++------------------- user.go | 8 ++--- 2 files changed, 62 insertions(+), 33 deletions(-) diff --git a/portal.go b/portal.go index ec6bfce..ba401d9 100644 --- a/portal.go +++ b/portal.go @@ -342,7 +342,7 @@ func (portal *Portal) SyncParticipants(metadata *whatsappExt.GroupInfo) { } } -func (portal *Portal) UpdateAvatar(user *User, avatar *whatsappExt.ProfilePicInfo) bool { +func (portal *Portal) UpdateAvatar(user *User, avatar *whatsappExt.ProfilePicInfo, updateInfo bool) bool { if avatar == nil { var err error avatar, err = user.Conn.GetProfilePicThumb(portal.Key.JID) @@ -382,10 +382,13 @@ func (portal *Portal) UpdateAvatar(user *User, avatar *whatsappExt.ProfilePicInf } } portal.Avatar = avatar.Tag + if updateInfo { + portal.UpdateBridgeInfo() + } return true } -func (portal *Portal) UpdateName(name string, setBy types.WhatsAppID) bool { +func (portal *Portal) UpdateName(name string, setBy types.WhatsAppID, updateInfo bool) bool { if portal.Name != name { intent := portal.MainIntent() if len(setBy) > 0 { @@ -394,6 +397,9 @@ func (portal *Portal) UpdateName(name string, setBy types.WhatsAppID) bool { _, err := intent.SetRoomName(portal.MXID, name) if err == nil { portal.Name = name + if updateInfo { + portal.UpdateBridgeInfo() + } return true } portal.log.Warnln("Failed to set room name:", err) @@ -401,7 +407,7 @@ func (portal *Portal) UpdateName(name string, setBy types.WhatsAppID) bool { return false } -func (portal *Portal) UpdateTopic(topic string, setBy types.WhatsAppID) bool { +func (portal *Portal) UpdateTopic(topic string, setBy types.WhatsAppID, updateInfo bool) bool { if portal.Topic != topic { intent := portal.MainIntent() if len(setBy) > 0 { @@ -410,6 +416,9 @@ func (portal *Portal) UpdateTopic(topic string, setBy types.WhatsAppID) bool { _, err := intent.SetRoomTopic(portal.MXID, topic) if err == nil { portal.Topic = topic + if updateInfo { + portal.UpdateBridgeInfo() + } return true } portal.log.Warnln("Failed to set room topic:", err) @@ -422,8 +431,8 @@ func (portal *Portal) UpdateMetadata(user *User) bool { return false } else if portal.IsStatusBroadcastRoom() { update := false - update = portal.UpdateName("WhatsApp Status Broadcast", "") || update - update = portal.UpdateTopic("WhatsApp status updates from your contacts", "") || update + update = portal.UpdateName("WhatsApp Status Broadcast", "", false) || update + update = portal.UpdateTopic("WhatsApp status updates from your contacts", "", false) || update return update } metadata, err := user.Conn.GetGroupMetaData(portal.Key.JID) @@ -443,8 +452,8 @@ func (portal *Portal) UpdateMetadata(user *User) bool { portal.SyncParticipants(metadata) update := false - update = portal.UpdateName(metadata.Name, metadata.NameSetBy) || update - update = portal.UpdateTopic(metadata.Topic, metadata.TopicSetBy) || update + update = portal.UpdateName(metadata.Name, metadata.NameSetBy, false) || update + update = portal.UpdateTopic(metadata.Topic, metadata.TopicSetBy, false) || update return update } @@ -506,10 +515,11 @@ func (portal *Portal) Sync(user *User, contact whatsapp.Contact) { update := false update = portal.UpdateMetadata(user) || update if !portal.IsStatusBroadcastRoom() { - update = portal.UpdateAvatar(user, nil) || update + update = portal.UpdateAvatar(user, nil, false) || update } if update { portal.Update() + portal.UpdateBridgeInfo() } } @@ -802,6 +812,40 @@ var ( StateHalfShotBridgeInfo = event.Type{Type: "uk.half-shot.bridge", Class: event.StateEventType} ) +func (portal *Portal) getBridgeInfo() (string, event.Content) { + bridgeInfo := event.Content{ + Parsed: BridgeInfoContent{ + BridgeBot: portal.bridge.Bot.UserID, + Creator: portal.MainIntent().UserID, + Protocol: BridgeInfoSection{ + ID: "whatsapp", + DisplayName: "WhatsApp", + AvatarURL: id.ContentURIString(portal.bridge.Config.AppService.Bot.Avatar), + ExternalURL: "https://www.whatsapp.com/", + }, + Channel: BridgeInfoSection{ + ID: portal.Key.JID, + DisplayName: portal.Name, + AvatarURL: portal.AvatarURL.CUString(), + }, + }, + } + bridgeInfoStateKey := fmt.Sprintf("net.maunium.whatsapp://whatsapp/%s", portal.Key.JID) + return bridgeInfoStateKey, bridgeInfo +} + +func (portal *Portal) UpdateBridgeInfo() { + stateKey, content := portal.getBridgeInfo() + _, err := portal.MainIntent().SendStateEvent(portal.MXID, StateBridgeInfo, stateKey, content) + if err != nil { + portal.log.Warnln("Failed to update m.bridge:", err) + } + _, err = portal.MainIntent().SendStateEvent(portal.MXID, StateHalfShotBridgeInfo, stateKey, content) + if err != nil { + portal.log.Warnln("Failed to update uk.half-shot.bridge:", err) + } +} + func (portal *Portal) CreateMatrixRoom(user *User) error { portal.roomCreateLock.Lock() defer portal.roomCreateLock.Unlock() @@ -837,38 +881,23 @@ func (portal *Portal) CreateMatrixRoom(user *User) error { portal.Name = metadata.Name portal.Topic = metadata.Topic } - portal.UpdateAvatar(user, nil) + portal.UpdateAvatar(user, nil, false) } - bridgeInfo := event.Content{ - Parsed: BridgeInfoContent{ - BridgeBot: portal.bridge.Bot.UserID, - Creator: portal.MainIntent().UserID, - Protocol: BridgeInfoSection{ - ID: "whatsapp", - DisplayName: "WhatsApp", - AvatarURL: id.ContentURIString(portal.bridge.Config.AppService.Bot.Avatar), - ExternalURL: "https://www.whatsapp.com/", - }, - Channel: BridgeInfoSection{ - ID: portal.Key.JID, - }, - }, - } - bridgeInfoStateKey := fmt.Sprintf("net.maunium.whatsapp://whatsapp/%s", portal.Key.JID) + bridgeInfoStateKey, bridgeInfo := portal.getBridgeInfo() initialState := []*event.Event{{ Type: event.StatePowerLevels, Content: event.Content{ Parsed: portal.GetBasePowerLevels(), }, }, { - Type: StateBridgeInfo, - Content: bridgeInfo, + Type: StateBridgeInfo, + Content: bridgeInfo, StateKey: &bridgeInfoStateKey, }, { // TODO remove this once https://github.com/matrix-org/matrix-doc/pull/2346 is in spec - Type: StateHalfShotBridgeInfo, - Content: bridgeInfo, + Type: StateHalfShotBridgeInfo, + Content: bridgeInfo, StateKey: &bridgeInfoStateKey, }} if !portal.AvatarURL.IsEmpty() { diff --git a/user.go b/user.go index 9cdcc29..3bda231 100644 --- a/user.go +++ b/user.go @@ -807,7 +807,7 @@ func (user *User) HandleCommand(cmd whatsappExt.Command) { go puppet.UpdateAvatar(user, cmd.ProfilePicInfo) } else { portal := user.GetPortalByJID(cmd.JID) - go portal.UpdateAvatar(user, cmd.ProfilePicInfo) + go portal.UpdateAvatar(user, cmd.ProfilePicInfo, true) } case whatsappExt.CommandDisconnect: var msg string @@ -836,11 +836,11 @@ func (user *User) HandleChatUpdate(cmd whatsappExt.ChatUpdate) { switch cmd.Data.Action { case whatsappExt.ChatActionNameChange: - go portal.UpdateName(cmd.Data.NameChange.Name, cmd.Data.SenderJID) + go portal.UpdateName(cmd.Data.NameChange.Name, cmd.Data.SenderJID, true) case whatsappExt.ChatActionAddTopic: - go portal.UpdateTopic(cmd.Data.AddTopic.Topic, cmd.Data.SenderJID) + go portal.UpdateTopic(cmd.Data.AddTopic.Topic, cmd.Data.SenderJID, true) case whatsappExt.ChatActionRemoveTopic: - go portal.UpdateTopic("", cmd.Data.SenderJID) + go portal.UpdateTopic("", cmd.Data.SenderJID, true) case whatsappExt.ChatActionPromote: go portal.ChangeAdminStatus(cmd.Data.PermissionChange.JIDs, true) case whatsappExt.ChatActionDemote: