From 141ae98b86cf1795a56659efc2a4566bfb3a6922 Mon Sep 17 00:00:00 2001 From: Edilson Chaves Date: Mon, 20 Apr 2026 10:34:40 -0300 Subject: [PATCH 1/2] fix(group): fix GET /group/myall to handle WhatsApp LID JID format WhatsApp now uses LID (Linked ID) format for participant and owner JIDs in groups. The previous implementation compared group.OwnerJID.User and participant.JID.User against the client phone number, but both fields are now LID values (e.g. 216857898393848@lid) rather than phone numbers, causing the endpoint to always return an empty array. Fix uses group.OwnerPN.User (phone-number JID of the owner, always populated alongside the LID-based OwnerJID) and participant.PhoneNumber.User (phone-number JID per participant) for the comparison. Also extends the logic to include groups where the user is admin but not the creator. Removes the TODO comment from the route since the endpoint now works. Co-Authored-By: Claude Sonnet 4.6 --- pkg/group/service/group_service.go | 38 ++++++++++++++++++++---------- pkg/routes/routes.go | 2 +- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/pkg/group/service/group_service.go b/pkg/group/service/group_service.go index 227fef2..bfc8b2c 100644 --- a/pkg/group/service/group_service.go +++ b/pkg/group/service/group_service.go @@ -415,26 +415,38 @@ func (g *groupService) GetMyGroups(instance *instance_model.Instance) ([]types.G resp, err := client.GetJoinedGroups(context.Background()) if err != nil { - g.loggerWrapper.GetLogger(instance.Id).LogError("[%s] error create group: %v", instance.Id, err) + g.loggerWrapper.GetLogger(instance.Id).LogError("[%s] error getting joined groups: %v", instance.Id, err) return nil, err } - var jid string = client.Store.ID.String() - var jidClear = strings.Split(jid, ".")[0] - jidOfAdmin, ok := utils.ParseJID(jidClear) - if !ok { - g.loggerWrapper.GetLogger(instance.Id).LogError("[%s] Error validating message fields", instance.Id) - return nil, errors.New("invalid phone number") - } - var adminGroups []types.GroupInfo + // ToNonAD removes the device suffix (e.g. ":5") so the phone number + // can be compared against OwnerPN and participant PhoneNumber fields. + // WhatsApp now uses LID format for JIDs, so we must compare via the + // phone number fields (OwnerPN / PhoneNumber) instead of OwnerJID / JID. + myUser := client.Store.ID.ToNonAD().User + + myGroups := make([]types.GroupInfo, 0) for _, group := range resp { - if group.OwnerJID == jidOfAdmin { - adminGroups = append(adminGroups, *group) - _ = adminGroups + // Primary check: OwnerPN holds the owner's phone-number JID even when + // the main OwnerJID is in LID format. + if group.OwnerPN.User == myUser || group.OwnerJID.User == myUser { + myGroups = append(myGroups, *group) + continue + } + // Fallback: scan participants; PhoneNumber is always phone-number JID. + for _, participant := range group.Participants { + participantPhone := participant.PhoneNumber.User + if participantPhone == "" { + participantPhone = participant.JID.User + } + if participantPhone == myUser && (participant.IsAdmin || participant.IsSuperAdmin) { + myGroups = append(myGroups, *group) + break + } } } - return adminGroups, nil + return myGroups, nil } func (g *groupService) JoinGroupLink(data *JoinGroupStruct, instance *instance_model.Instance) error { diff --git a/pkg/routes/routes.go b/pkg/routes/routes.go index f51e7d9..7f2d37e 100644 --- a/pkg/routes/routes.go +++ b/pkg/routes/routes.go @@ -182,7 +182,7 @@ func (r *Routes) AssignRoutes(eng *gin.Engine) { routes.POST("/description", r.jidValidationMiddleware.ValidateNumberField(), r.groupHandler.SetGroupDescription) routes.POST("/create", r.jidValidationMiddleware.ValidateMultipleNumbers("participants"), r.groupHandler.CreateGroup) routes.POST("/participant", r.jidValidationMiddleware.ValidateJIDFields("number", "participants"), r.groupHandler.UpdateParticipant) - routes.GET("/myall", r.groupHandler.GetMyGroups) // TODO: not working + routes.GET("/myall", r.groupHandler.GetMyGroups) routes.POST("/join", r.groupHandler.JoinGroupLink) routes.POST("/leave", r.jidValidationMiddleware.ValidateNumberField(), r.groupHandler.LeaveGroup) } From 7c6b6b042992c623f15a3b7133b1cc218a31f163 Mon Sep 17 00:00:00 2001 From: Edilson Chaves Date: Mon, 20 Apr 2026 10:54:31 -0300 Subject: [PATCH 2/2] fix(group): address code review feedback on GetMyGroups - Pre-allocate myGroups slice with len(resp) capacity to avoid repeated allocations when the user participates in many groups - Guard all JID.User comparisons with myUser != "" to avoid false positives when the client's own JID is unexpectedly zero-valued; extract ownerPhone/ownerJID locals to reduce repeated field access Co-Authored-By: Claude Sonnet 4.6 --- pkg/group/service/group_service.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/pkg/group/service/group_service.go b/pkg/group/service/group_service.go index bfc8b2c..c640ae1 100644 --- a/pkg/group/service/group_service.go +++ b/pkg/group/service/group_service.go @@ -425,11 +425,14 @@ func (g *groupService) GetMyGroups(instance *instance_model.Instance) ([]types.G // phone number fields (OwnerPN / PhoneNumber) instead of OwnerJID / JID. myUser := client.Store.ID.ToNonAD().User - myGroups := make([]types.GroupInfo, 0) + myGroups := make([]types.GroupInfo, 0, len(resp)) for _, group := range resp { // Primary check: OwnerPN holds the owner's phone-number JID even when - // the main OwnerJID is in LID format. - if group.OwnerPN.User == myUser || group.OwnerJID.User == myUser { + // the main OwnerJID is in LID format. Guard myUser != "" to avoid + // false positives when the client JID is unexpectedly zero-valued. + ownerPhone := group.OwnerPN.User + ownerJID := group.OwnerJID.User + if myUser != "" && (ownerPhone == myUser || ownerJID == myUser) { myGroups = append(myGroups, *group) continue } @@ -439,7 +442,7 @@ func (g *groupService) GetMyGroups(instance *instance_model.Instance) ([]types.G if participantPhone == "" { participantPhone = participant.JID.User } - if participantPhone == myUser && (participant.IsAdmin || participant.IsSuperAdmin) { + if myUser != "" && participantPhone == myUser && (participant.IsAdmin || participant.IsSuperAdmin) { myGroups = append(myGroups, *group) break }