diff --git a/src/domains/group/group.go b/src/domains/group/group.go index 59d6764..0cf2909 100644 --- a/src/domains/group/group.go +++ b/src/domains/group/group.go @@ -2,6 +2,7 @@ package group import ( "context" + "go.mau.fi/whatsmeow" ) @@ -10,6 +11,8 @@ type IGroupService interface { LeaveGroup(ctx context.Context, request LeaveGroupRequest) (err error) CreateGroup(ctx context.Context, request CreateGroupRequest) (groupID string, err error) ManageParticipant(ctx context.Context, request ParticipantRequest) (result []ParticipantStatus, err error) + GetGroupRequestParticipants(ctx context.Context, request GetGroupRequestParticipantsRequest) (result []string, err error) + ManageGroupRequestParticipants(ctx context.Context, request GroupRequestParticipantsRequest) (result []ParticipantStatus, err error) } type JoinGroupWithLinkRequest struct { @@ -36,3 +39,13 @@ type ParticipantStatus struct { Status string `json:"status"` Message string `json:"message"` } + +type GetGroupRequestParticipantsRequest struct { + GroupID string `json:"group_id" query:"group_id"` +} + +type GroupRequestParticipantsRequest struct { + GroupID string `json:"group_id" form:"group_id"` + Participants []string `json:"participants" form:"participants"` + Action whatsmeow.ParticipantRequestChange `json:"action" form:"action"` +} diff --git a/src/internal/rest/group.go b/src/internal/rest/group.go index 53f98bd..5cfd369 100644 --- a/src/internal/rest/group.go +++ b/src/internal/rest/group.go @@ -2,6 +2,7 @@ package rest import ( "fmt" + domainGroup "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/group" "github.com/aldinokemal/go-whatsapp-web-multidevice/pkg/utils" "github.com/aldinokemal/go-whatsapp-web-multidevice/pkg/whatsapp" @@ -22,6 +23,9 @@ func InitRestGroup(app *fiber.App, service domainGroup.IGroupService) Group { app.Post("/group/participants/remove", rest.DeleteParticipants) app.Post("/group/participants/promote", rest.PromoteParticipants) app.Post("/group/participants/demote", rest.DemoteParticipants) + app.Get("/group/participants/requested", rest.RequestedParticipants) + app.Post("/group/participants/requested/approve", rest.ApproveRequestedParticipants) + app.Post("/group/participants/requested/reject", rest.RejectRequestedParticipants) return rest } @@ -77,83 +81,78 @@ func (controller *Group) CreateGroup(c *fiber.Ctx) error { }, }) } - func (controller *Group) AddParticipants(c *fiber.Ctx) error { - var request domainGroup.ParticipantRequest - err := c.BodyParser(&request) - utils.PanicIfNeeded(err) - - whatsapp.SanitizePhone(&request.GroupID) + return controller.manageParticipants(c, whatsmeow.ParticipantChangeAdd, "Success add participants") +} - request.Action = whatsmeow.ParticipantChangeAdd +func (controller *Group) DeleteParticipants(c *fiber.Ctx) error { + return controller.manageParticipants(c, whatsmeow.ParticipantChangeRemove, "Success delete participants") +} - result, err := controller.Service.ManageParticipant(c.UserContext(), request) - utils.PanicIfNeeded(err) +func (controller *Group) PromoteParticipants(c *fiber.Ctx) error { + return controller.manageParticipants(c, whatsmeow.ParticipantChangePromote, "Success promote participants") +} - return c.JSON(utils.ResponseData{ - Status: 200, - Code: "SUCCESS", - Message: "Success add participants", - Results: result, - }) +func (controller *Group) DemoteParticipants(c *fiber.Ctx) error { + return controller.manageParticipants(c, whatsmeow.ParticipantChangeDemote, "Success demote participants") } -func (controller *Group) DeleteParticipants(c *fiber.Ctx) error { - var request domainGroup.ParticipantRequest - err := c.BodyParser(&request) +func (controller *Group) RequestedParticipants(c *fiber.Ctx) error { + var request domainGroup.GetGroupRequestParticipantsRequest + err := c.QueryParser(&request) utils.PanicIfNeeded(err) whatsapp.SanitizePhone(&request.GroupID) - request.Action = whatsmeow.ParticipantChangeRemove - - result, err := controller.Service.ManageParticipant(c.UserContext(), request) + result, err := controller.Service.GetGroupRequestParticipants(c.UserContext(), request) utils.PanicIfNeeded(err) return c.JSON(utils.ResponseData{ Status: 200, Code: "SUCCESS", - Message: "Success delete participants", + Message: "Success getting list requested participants", Results: result, }) } -func (controller *Group) PromoteParticipants(c *fiber.Ctx) error { +func (controller *Group) ApproveRequestedParticipants(c *fiber.Ctx) error { + return controller.handleRequestedParticipants(c, whatsmeow.ParticipantChangeApprove, "Success approve requested participants") +} + +func (controller *Group) RejectRequestedParticipants(c *fiber.Ctx) error { + return controller.handleRequestedParticipants(c, whatsmeow.ParticipantChangeReject, "Success reject requested participants") +} + +// Generalized participant management handler +func (controller *Group) manageParticipants(c *fiber.Ctx, action whatsmeow.ParticipantChange, successMsg string) error { var request domainGroup.ParticipantRequest err := c.BodyParser(&request) utils.PanicIfNeeded(err) - whatsapp.SanitizePhone(&request.GroupID) - - request.Action = whatsmeow.ParticipantChangePromote - + request.Action = action result, err := controller.Service.ManageParticipant(c.UserContext(), request) utils.PanicIfNeeded(err) - return c.JSON(utils.ResponseData{ Status: 200, Code: "SUCCESS", - Message: "Success promote participants", + Message: successMsg, Results: result, }) } -func (controller *Group) DemoteParticipants(c *fiber.Ctx) error { - var request domainGroup.ParticipantRequest +// Generalized requested participants handler +func (controller *Group) handleRequestedParticipants(c *fiber.Ctx, action whatsmeow.ParticipantRequestChange, successMsg string) error { + var request domainGroup.GroupRequestParticipantsRequest err := c.BodyParser(&request) utils.PanicIfNeeded(err) - whatsapp.SanitizePhone(&request.GroupID) - - request.Action = whatsmeow.ParticipantChangeDemote - - result, err := controller.Service.ManageParticipant(c.UserContext(), request) + request.Action = action + result, err := controller.Service.ManageGroupRequestParticipants(c.UserContext(), request) utils.PanicIfNeeded(err) - return c.JSON(utils.ResponseData{ Status: 200, Code: "SUCCESS", - Message: "Success demote participants", + Message: successMsg, Results: result, }) } diff --git a/src/services/group.go b/src/services/group.go index afe2aa1..b2710cf 100644 --- a/src/services/group.go +++ b/src/services/group.go @@ -2,6 +2,8 @@ package services import ( "context" + "fmt" + "github.com/aldinokemal/go-whatsapp-web-multidevice/config" domainGroup "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/group" pkgError "github.com/aldinokemal/go-whatsapp-web-multidevice/pkg/error" @@ -113,6 +115,59 @@ func (service groupService) ManageParticipant(ctx context.Context, request domai return result, nil } +func (service groupService) GetGroupRequestParticipants(ctx context.Context, request domainGroup.GetGroupRequestParticipantsRequest) (result []string, err error) { + if err = validations.ValidateGetGroupRequestParticipants(ctx, request); err != nil { + return result, err + } + + groupJID, err := whatsapp.ValidateJidWithLogin(service.WaCli, request.GroupID) + if err != nil { + return result, err + } + + participants, err := service.WaCli.GetGroupRequestParticipants(groupJID) + if err != nil { + return result, err + } + + for _, participant := range participants { + result = append(result, participant.JID.String()) + } + + return result, nil +} + +func (service groupService) ManageGroupRequestParticipants(ctx context.Context, request domainGroup.GroupRequestParticipantsRequest) (result []domainGroup.ParticipantStatus, err error) { + if err = validations.ValidateManageGroupRequestParticipants(ctx, request); err != nil { + return result, err + } + + groupJID, err := whatsapp.ValidateJidWithLogin(service.WaCli, request.GroupID) + if err != nil { + return result, err + } + + participantsJID, err := service.participantToJID(request.Participants) + if err != nil { + return result, err + } + + participants, err := service.WaCli.UpdateGroupRequestParticipants(groupJID, participantsJID, request.Action) + if err != nil { + return result, err + } + + for _, participant := range participants { + result = append(result, domainGroup.ParticipantStatus{ + Participant: participant.JID.String(), + Status: "success", + Message: fmt.Sprintf("Action %s success", request.Action), + }) + } + + return result, nil +} + func (service groupService) participantToJID(participants []string) ([]types.JID, error) { var participantsJID []types.JID for _, participant := range participants { diff --git a/src/validations/group_validation.go b/src/validations/group_validation.go index 0758c1f..be4b92b 100644 --- a/src/validations/group_validation.go +++ b/src/validations/group_validation.go @@ -2,6 +2,7 @@ package validations import ( "context" + domainGroup "github.com/aldinokemal/go-whatsapp-web-multidevice/domains/group" pkgError "github.com/aldinokemal/go-whatsapp-web-multidevice/pkg/error" validation "github.com/go-ozzo/ozzo-validation/v4" @@ -58,3 +59,29 @@ func ValidateParticipant(ctx context.Context, request domainGroup.ParticipantReq return nil } + +func ValidateGetGroupRequestParticipants(ctx context.Context, request domainGroup.GetGroupRequestParticipantsRequest) error { + err := validation.ValidateStructWithContext(ctx, &request, + validation.Field(&request.GroupID, validation.Required), + ) + + if err != nil { + return pkgError.ValidationError(err.Error()) + } + + return nil +} + +func ValidateManageGroupRequestParticipants(ctx context.Context, request domainGroup.GroupRequestParticipantsRequest) error { + err := validation.ValidateStructWithContext(ctx, &request, + validation.Field(&request.GroupID, validation.Required), + validation.Field(&request.Participants, validation.Required), + validation.Field(&request.Participants, validation.Each(validation.Required)), + ) + + if err != nil { + return pkgError.ValidationError(err.Error()) + } + + return nil +}