From 63b2466b24291ddbb8c9976a83dfe07fa2d4552b Mon Sep 17 00:00:00 2001 From: Gerardo Rodriguez Date: Tue, 10 Nov 2026 06:48:48 +0000 Subject: [PATCH 1/2] chatinfo: keep reactions and poll votes allowed when a group becomes announcement-only --- pkg/connector/chatinfo.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index ce8c7396..83c2b6ef 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -436,24 +436,28 @@ func (wa *WhatsAppClient) wrapGroupInfoChange(ctx context.Context, evt *events.G if memberChanges == nil { memberChanges = &bridgev2.ChatMemberList{} } - memberChanges.PowerLevels = &bridgev2.PowerLevelOverrides{} + memberChanges.PowerLevels = &bridgev2.PowerLevelOverrides{ + Events: make(map[event.Type]int), + } if evt.Announce != nil { if evt.Announce.IsAnnounce { memberChanges.PowerLevels.EventsDefault = ptr.Ptr(adminPL) } else { memberChanges.PowerLevels.EventsDefault = ptr.Ptr(defaultPL) } + memberChanges.PowerLevels.Events[event.EventEncrypted] = defaultPL + memberChanges.PowerLevels.Events[event.EventReaction] = defaultPL + memberChanges.PowerLevels.Events[event.EventRedaction] = defaultPL + memberChanges.PowerLevels.Events[event.EventUnstablePollResponse] = defaultPL } if evt.Locked != nil { metaChangePL := defaultPL if evt.Locked.IsLocked { metaChangePL = adminPL } - memberChanges.PowerLevels.Events = map[event.Type]int{ - event.StateRoomName: metaChangePL, - event.StateRoomAvatar: metaChangePL, - event.StateTopic: metaChangePL, - } + memberChanges.PowerLevels.Events[event.StateRoomName] = metaChangePL + memberChanges.PowerLevels.Events[event.StateRoomAvatar] = metaChangePL + memberChanges.PowerLevels.Events[event.StateTopic] = metaChangePL } } return &bridgev2.ChatInfoChange{ From b744b1f7e3454722c8f3f8ed09d0992fdc567e80 Mon Sep 17 00:00:00 2001 From: Gerardo Rodriguez Date: Tue, 10 Nov 2026 19:07:47 +0000 Subject: [PATCH 2/2] chatinfo: share always-allowed group power level overrides --- pkg/connector/chatinfo.go | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index 83c2b6ef..7447f9c9 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "maps" "time" "github.com/rs/zerolog" @@ -244,6 +245,13 @@ const ( defaultPL = 0 ) +var alwaysAllowedGroupEvents = map[event.Type]int{ + event.EventEncrypted: defaultPL, // Need to always allow encrypted events for poll responses + event.EventReaction: defaultPL, + event.EventRedaction: defaultPL, + event.EventUnstablePollResponse: defaultPL, +} + func setDefaultSubGroupFlag(isCommunityAnnouncementGroup bool) bridgev2.ExtraUpdater[*bridgev2.Portal] { return func(_ context.Context, portal *bridgev2.Portal) bool { meta := portal.Metadata.(*waid.PortalMetadata) @@ -311,10 +319,6 @@ func (wa *WhatsAppClient) wrapGroupInfo(ctx context.Context, info *types.GroupIn event.StateRoomName: metaChangePL, event.StateRoomAvatar: metaChangePL, event.StateTopic: metaChangePL, - event.EventEncrypted: defaultPL, // Need to always allow encrypted events for poll responses - event.EventReaction: defaultPL, - event.EventRedaction: defaultPL, - event.EventUnstablePollResponse: defaultPL, event.StateBeeperDisappearingTimer: metaChangePL, }, }, @@ -326,6 +330,7 @@ func (wa *WhatsAppClient) wrapGroupInfo(ctx context.Context, info *types.GroupIn }, ExtraUpdates: extraUpdater, } + maps.Copy(wrapped.Members.PowerLevels.Events, alwaysAllowedGroupEvents) var hasSelf bool for _, pcp := range info.Participants { member := bridgev2.ChatMember{ @@ -445,10 +450,7 @@ func (wa *WhatsAppClient) wrapGroupInfoChange(ctx context.Context, evt *events.G } else { memberChanges.PowerLevels.EventsDefault = ptr.Ptr(defaultPL) } - memberChanges.PowerLevels.Events[event.EventEncrypted] = defaultPL - memberChanges.PowerLevels.Events[event.EventReaction] = defaultPL - memberChanges.PowerLevels.Events[event.EventRedaction] = defaultPL - memberChanges.PowerLevels.Events[event.EventUnstablePollResponse] = defaultPL + maps.Copy(memberChanges.PowerLevels.Events, alwaysAllowedGroupEvents) } if evt.Locked != nil { metaChangePL := defaultPL